fix(pleno-vue): exclude spot-free-lastbil from audited add-on note dialog (#301)

## Problem

The mobile POS step 2 \"enter note\" dialog was triggering for product
24
(\"Højtryk - ekstra tid\" / spotfree-lastbil) because product 24 was
listed
in both:

- `AUDITED_ORDER_ITEM_PRODUCT_IDS` in
`src/components/shop/OrdersItems.vue`
- `AFFECTED_PRODUCT_IDS` in
`services/nginx/app/classes/order_item_reason_policy.php`

Product 24 is the \"spot-free-lastbil\" package, not an audited
extra-time
add-on — the dialog should only appear for {21, 22, 25, 26, 27}.

## Fix

Drop product 24 from both source-of-truth lists, plus the matching test
fixtures and the e2e fixture.

## Changes

- `src/components/shop/OrdersItems.vue`: drop 24 from
  `AUDITED_ORDER_ITEM_PRODUCT_IDS` Set.
- `tests/unit/orders-items.spec.js`: drop 24 from `auditedProductIds`,
  swap the three `createOrderItem(...)` call sites that used 24 for 25,
  and add an explicit `AUDITED_ORDER_ITEM_PRODUCT_IDS` membership test
  that locks down 24 == false.
- `tests/e2e/support/mobilePos.js`: mirror the
`AUDITED_ORDER_ITEM_PRODUCT_IDS`
  change so the e2e harness matches the production set.
- `tests/e2e/pos-mobile-order-flow.spec.js`: re-target the \"prompts for
a
  required reason note for audited add-on products that are not the
  chemistry product\" case from product 24 to product 25
  (\"Fælg flex pr. enhed\"), since 24 is no longer audited.
- (api) `services/nginx/app/classes/order_item_reason_policy.php`: drop
24
  from `AFFECTED_PRODUCT_IDS` (companion change in a separate PR in the
  api repo).

## Verification

- 1761/1762 unit tests pass locally (the one failure is an unrelated
  `cpanel-deploy.spec.js` case that requires the system `zip` binary).
- Lint passes.
- Production build succeeds.

Tracked under workboard-94209138-31f6-422e-ac8c-181ad391b8a7.

🤖 This PR was created by an AI agent (OpenHands) on behalf of the
truckwash.io team.

Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
Jeppe B
2026-08-13 21:00:32 +02:00
committed by GitHub
co-authored by openhands
parent b1e0c61df0
commit 4db3be34f8
4 changed files with 13 additions and 10 deletions
+1 -1
View File
@@ -3,7 +3,7 @@
import axios from 'axios'
import {API_URL} from "@/config.js";
export const AUDITED_ORDER_ITEM_PRODUCT_IDS = new Set([21, 22, 24, 25, 26, 27]);
export const AUDITED_ORDER_ITEM_PRODUCT_IDS = new Set([21, 22, 25, 26, 27]);
export const DEFAULT_AUDITED_ORDER_ITEM_REASON_CODE = "customer_approved_extra_work";
export const DEFAULT_AUDITED_ORDER_ITEM_REASON_LABEL = "Kunde godkendte ekstra arbejde";
+3 -3
View File
@@ -4219,13 +4219,13 @@ test.describe("POS mobile order flow", () => {
const orderId = 9416;
const baseFixture = createMobilePosFixture();
const auditedProduct = {
id: 24,
name: "Højtryk - ekstra tid",
id: 25,
name: "Fælg flex pr. enhed",
description: "Audited addon that requires a reason comment",
price: 95,
subscription_allowed: true,
category: 8,
piktogram: "24",
piktogram: "25",
apply_category_discount: false,
requires_note: false,
is_wash: false,
+1 -1
View File
@@ -11,7 +11,7 @@ export const CARD_CUSTOMER_ID = 999;
export const WASH_CERTIFICATE_PRODUCT_ID = 41;
const EXTRAORDINARY_CHEMISTRY_PRODUCT_ID = 27;
const EXTRAORDINARY_CHEMISTRY_PRODUCT_NAME = "Ekstraordinær pr. 10 min inkl. kemi";
const AUDITED_ORDER_ITEM_PRODUCT_IDS = new Set([21, 22, 24, 25, 26, 27]);
const AUDITED_ORDER_ITEM_PRODUCT_IDS = new Set([21, 22, 25, 26, 27]);
export const MOBILE_PERMISSIONS = ["admin", "department_access_1"];
export const MOBILE_NEXT_STEP_COOLDOWN_MS = 2100;
+8 -5
View File
@@ -75,7 +75,7 @@ describe("createOrderItem (audited products)", () => {
axios.post.mockResolvedValue({ data: { success: true, data: { id: 1 } } });
});
const auditedProductIds = [21, 22, 24, 25, 26, 27];
const auditedProductIds = [21, 22, 25, 26, 27];
const DEFAULT_REASON_LABEL = "Kunde godkendte ekstra arbejde";
it.each(auditedProductIds)(
@@ -101,7 +101,7 @@ describe("createOrderItem (audited products)", () => {
);
it("falls back to notes when reason_comment is not provided", async () => {
await createOrderItem(51207, 24, 1, null, " Customer approved graffiti removal ");
await createOrderItem(51207, 25, 1, null, " Customer approved graffiti removal ");
const [, body] = axios.post.mock.calls[0];
expect(body.reason_comment).toBe("Customer approved graffiti removal");
@@ -111,7 +111,7 @@ describe("createOrderItem (audited products)", () => {
});
it("prefers an explicit reason_comment when the caller passes reasonData", async () => {
await createOrderItem(51207, 24, 1, null, "free-form notes", null, {
await createOrderItem(51207, 25, 1, null, "free-form notes", null, {
reason_comment: "Explicit override",
reason_label_snapshot: "Custom label",
reason_code: "custom_code",
@@ -133,7 +133,7 @@ describe("createOrderItem (audited products)", () => {
});
it("treats whitespace-only notes as empty and falls back to the default label", async () => {
await createOrderItem(51207, 24, 1, null, " ");
await createOrderItem(51207, 25, 1, null, " ");
const [, body] = axios.post.mock.calls[0];
expect(body.reason_comment).toBe(DEFAULT_REASON_LABEL);
@@ -144,9 +144,12 @@ describe("AUDITED_ORDER_ITEM_PRODUCT_IDS membership", () => {
it("contains the expected audited product ids", () => {
expect(AUDITED_ORDER_ITEM_PRODUCT_IDS.has(21)).toBe(true);
expect(AUDITED_ORDER_ITEM_PRODUCT_IDS.has(22)).toBe(true);
expect(AUDITED_ORDER_ITEM_PRODUCT_IDS.has(24)).toBe(true);
expect(AUDITED_ORDER_ITEM_PRODUCT_IDS.has(25)).toBe(true);
expect(AUDITED_ORDER_ITEM_PRODUCT_IDS.has(26)).toBe(true);
expect(AUDITED_ORDER_ITEM_PRODUCT_IDS.has(27)).toBe(true);
});
it("does not include the spot-free-lastbil product id", () => {
expect(AUDITED_ORDER_ITEM_PRODUCT_IDS.has(24)).toBe(false);
});
});