From 5cde8103f91b89dac60fa1753174a29c82bddb73 Mon Sep 17 00:00:00 2001 From: Jeppe B <2jepp9350@gmail.com> Date: Sat, 15 Aug 2026 22:18:18 +0200 Subject: [PATCH] fix(api): include wash_id in xlvask_missing_order_link flag text (AUT-49/TRU-49) (#375) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary The XL Vask missing-order-link flag previously rendered the literal placeholder text `'XL Vask wash'` as the interactive link text. `wash_id` was already present in the per-flag message context but was not being threaded into the link text, so users couldn't tell which wash the warning referred to. This wires `wash_id` through both `messageParts()` (used to render the clickable link) and `automaticMessage()` (the plain-text fallback) for the `xlvask_missing_order_link` flag. ## Changes `services/nginx/app/classes/invoice_period_flag_service.php` - `messageParts()` `xlvask_missing_order_link` branch: split into three parts so the `xlvask_usage_log` button text comes from `$params['wash_id']`, with the literal "XL Vask wash " as a leading text part and " is neither ignored nor linked to an order in the selected period." as a trailing text part. - `automaticMessage()` `xlvask_missing_order_link` branch: now interpolates `wash_id` into the message string ("XL Vask wash {wash_id} is neither ignored nor linked to an order in the selected period."), with a sensible fallback to the original wording when `wash_id` is missing. `services/nginx/app/tests/Unit/Invoicing/InvoicePeriodFlagServiceTest.php` - Updated the `message_parts` expectation in `it builds interactive message parts for order and wash certificate warnings` to assert the new three-part structure with the actual `wash-55` id. ## Verification - `vendor/bin/pest tests/Unit/Invoicing/InvoicePeriodFlagServiceTest.php --compact` → `Tests: 34 passed (183 assertions)`, exit 0 - `vendor/bin/pest tests/Unit/Invoicing/ --compact` → `Tests: 245 passed (1 warning, 1 skipped)`, exit 0 - `vendor/bin/phpstan analyse classes/invoice_period_flag_service.php` → `[OK] No errors` ## Issue AUT-49 / TRU-49 — XL Vask missing-order-link flag text should reference the actual wash (not 'XL Vask wash'). ## Out of scope - The Vue side at `copenhagentruckwash/pleno-vue` still has a hardcoded fallback `"XL Vask wash"` for the i18n token `invoice_period.flags.tokens.xlvask_usage_log`. That path is only used when `flag.message_parts` is absent, which no longer happens for this flag now that the backend populates it correctly. A follow-up on the Vue side could remove that fallback or repurpose it as a tooltip label. - No `Writerside2` topic covers `message_parts`, and `openapi.yaml` does not formally document the field, so no spec update was required for this content-only fix. --- _This pull request was created by an AI agent (OpenHands) on behalf of Jeppe B._ Co-authored-by: Jeppe Co-authored-by: openhands --- .../nginx/app/classes/invoice_period_flag_service.php | 8 ++++++-- .../tests/Unit/Invoicing/InvoicePeriodFlagServiceTest.php | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/services/nginx/app/classes/invoice_period_flag_service.php b/services/nginx/app/classes/invoice_period_flag_service.php index 2b1f823f..2646ee4b 100644 --- a/services/nginx/app/classes/invoice_period_flag_service.php +++ b/services/nginx/app/classes/invoice_period_flag_service.php @@ -1495,6 +1495,7 @@ class invoice_period_flag_service { $product = (string)($params['product'] ?? 'Item'); $expectedProduct = (string)($params['expected_product'] ?? 'expected product'); + $washId = (string)($params['wash_id'] ?? ''); return match ($definitionKey) { 'price_mismatch' => "{$product} product price differs from expected.", 'customer_rule_restrict_addon_services' => "{$product} violates restricted addon services.", @@ -1514,7 +1515,9 @@ class invoice_period_flag_service 'duplicate_vehicle_subscription_charge_same_month' => "Duplicate vehicle subscription charges exist in the same month.", 'vehicle_subscription_type_mismatch' => "{$product} does not match the vehicle subscription type {$expectedProduct}.", 'historical_primary_product_mismatch' => "{$product} differs from the registration number's usual product {$expectedProduct}.", - 'xlvask_missing_order_link' => "XL Vask wash is neither ignored nor linked to an order in the selected period.", + 'xlvask_missing_order_link' => $washId === '' + ? 'XL Vask wash is neither ignored nor linked to an order in the selected period.' + : "XL Vask wash {$washId} is neither ignored nor linked to an order in the selected period.", default => "Automatically detected invoice-period issue.", }; } @@ -1541,7 +1544,8 @@ class invoice_period_flag_service ['type' => 'text', 'text' => ' is attached without a wash certificate item.'], ], 'xlvask_missing_order_link' => [ - ['type' => 'xlvask_usage_log', 'text' => 'XL Vask wash'], + ['type' => 'text', 'text' => 'XL Vask wash '], + ['type' => 'xlvask_usage_log', 'text' => (string)($params['wash_id'] ?? '')], ['type' => 'text', 'text' => ' is neither ignored nor linked to an order in the selected period.'], ], default => [], diff --git a/services/nginx/app/tests/Unit/Invoicing/InvoicePeriodFlagServiceTest.php b/services/nginx/app/tests/Unit/Invoicing/InvoicePeriodFlagServiceTest.php index f9d1be45..d2449e66 100644 --- a/services/nginx/app/tests/Unit/Invoicing/InvoicePeriodFlagServiceTest.php +++ b/services/nginx/app/tests/Unit/Invoicing/InvoicePeriodFlagServiceTest.php @@ -167,7 +167,8 @@ it('builds interactive message parts for order and wash certificate warnings', f ['type' => 'text', 'text' => ' is present without a wash certificate.'], ]); expect($xlVaskFlag['message_parts'])->toBe([ - ['type' => 'xlvask_usage_log', 'text' => 'XL Vask wash'], + ['type' => 'text', 'text' => 'XL Vask wash '], + ['type' => 'xlvask_usage_log', 'text' => 'wash-55'], ['type' => 'text', 'text' => ' is neither ignored nor linked to an order in the selected period.'], ]); });