## 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 `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 server-side reason policy should only enforce the comment
requirement on {21, 22, 25, 26, 27}, matching the frontend
`AUDITED_ORDER_ITEM_PRODUCT_IDS` set.
Companion to the frontend PR copenhagentruckwash/pleno-vue#301.
## Fix
Drop product 24 from `AFFECTED_PRODUCT_IDS`.
## Verification
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>
74 lines
2.5 KiB
PHP
74 lines
2.5 KiB
PHP
<?php
|
|
|
|
namespace classes;
|
|
|
|
use InvalidArgumentException;
|
|
|
|
class order_item_reason_policy
|
|
{
|
|
public const EXTRAORDINARY_CHEMISTRY_PRODUCT_ID = 27;
|
|
public const AFFECTED_PRODUCT_IDS = [21, 22, 25, 26, 27];
|
|
|
|
public static function reasons(): array
|
|
{
|
|
return [
|
|
'customer_approved_extra_work' => [
|
|
'label' => 'Kunde godkendte ekstra arbejde',
|
|
'requires_comment' => true,
|
|
'active' => true,
|
|
],
|
|
'vehicle_condition_extra_work' => [
|
|
'label' => 'Køretøjets tilstand krævede ekstra tid',
|
|
'requires_comment' => true,
|
|
'active' => true,
|
|
],
|
|
'quality_rework' => [
|
|
'label' => 'Kvalitetsopfølgning eller omvask',
|
|
'requires_comment' => true,
|
|
'active' => true,
|
|
],
|
|
'legacy_note_only' => [
|
|
'label' => 'Legacy note only',
|
|
'requires_comment' => true,
|
|
'active' => false,
|
|
],
|
|
];
|
|
}
|
|
|
|
public static function productRequiresReason(int $productId): bool
|
|
{
|
|
return in_array($productId, self::AFFECTED_PRODUCT_IDS, true);
|
|
}
|
|
|
|
public static function validateForProduct(int $productId, array $data): array
|
|
{
|
|
if (!self::productRequiresReason($productId)) {
|
|
return ['reason_code' => null, 'reason_label_snapshot' => null, 'reason_comment' => null];
|
|
}
|
|
|
|
$code = trim((string)($data['reason_code'] ?? $data['order_item_reason_code'] ?? ''));
|
|
if ($code === '') {
|
|
throw new InvalidArgumentException('Reason code is required for this product');
|
|
}
|
|
|
|
$reasons = self::reasons();
|
|
if (!array_key_exists($code, $reasons)) {
|
|
throw new InvalidArgumentException('Reason code is invalid for this product');
|
|
}
|
|
|
|
$reason = $reasons[$code];
|
|
if (!$reason['active']) {
|
|
throw new InvalidArgumentException('Reason code is deprecated for this product');
|
|
}
|
|
|
|
$comment = trim((string)($data['reason_comment'] ?? $data['comment'] ?? $data['notes'] ?? ''));
|
|
if ($reason['requires_comment'] && $comment === '') {
|
|
throw new InvalidArgumentException('Reason comment is required for this product');
|
|
}
|
|
|
|
$snapshot = $reason['label'];
|
|
|
|
return ['reason_code' => $code, 'reason_label_snapshot' => $snapshot, 'reason_comment' => $comment];
|
|
}
|
|
}
|