feat: integrate Luoyang pharmacy workflow

This commit is contained in:
2026-07-22 18:00:17 +08:00
parent 31312ae975
commit e1fe818dce
27 changed files with 1925 additions and 163 deletions
@@ -234,6 +234,45 @@ $assertSame(
EjPharmacyShipmentPolicy::isShippedEvent(['event_type' => 'ORDER_UPDATED', 'status' => 'PROCESSING']),
'non-shipment callbacks must not change local fulfillment'
);
$assertSame(
true,
EjPharmacyShipmentPolicy::isCompletedEvent(['event_type' => 'WORKFLOW_STEP_COMPLETED', 'status' => 'COMPLETED', 'final' => true]),
'a final EJ workflow callback must be recognized as order completion'
);
$assertSame(
3,
EjPharmacyShipmentPolicy::nextFulfillmentStatus(
2,
['event_type' => 'WORKFLOW_STEP_COMPLETED', 'status' => 'COMPLETED', 'final' => true]
),
'a final EJ workflow callback must advance ZYT fulfillment to completed'
);
$assertSame(
2,
EjPharmacyShipmentPolicy::nextFulfillmentStatus(
2,
['event_type' => 'REVIEW_REJECTED', 'status' => 'REJECTED'],
2
),
'EJ review rejection must restore the fulfillment status captured before upload'
);
$assertSame(
2,
EjPharmacyShipmentPolicy::nextFulfillmentStatus(
2,
['event_type' => 'INVENTORY_SHORTAGE', 'status' => 'STOCK_SHORTAGE'],
2
),
'EJ inventory shortage must not become a ZYT customer refusal'
);
$assertSame(
2,
EjPharmacyShipmentPolicy::nextFulfillmentStatus(
9,
['event_type' => 'REVIEW_REJECTED', 'status' => 'REJECTED']
),
'legacy EJ rejection rows already marked as ZYT refusal must reopen to uploadable fulfillment'
);
foreach ([1, 2] as $pendingFulfillment) {
$assertSame(
5,
@@ -350,7 +389,7 @@ $assertSame(
&& str_contains($controllerSource, "where('process_status', '<>', \$protectedStatus)"),
'callback failure persistence must use a conditional status CAS that protects PROCESSED'
);
$versionGateStart = strpos($controllerSource, 'if ($incomingVersion >');
$versionGateStart = strpos($controllerSource, 'if ($versionAdvanced)');
$versionGateEnd = strpos($controllerSource, '$inboxModel->save', $versionGateStart);
$versionGatedSource = substr($controllerSource, $versionGateStart, $versionGateEnd - $versionGateStart);
$assertSame(
@@ -375,5 +414,21 @@ $assertSame(
&& str_contains($controllerSource, "'order_type' => 'prescription_history'"),
'EJ callbacks must isolate replacement numbers and reject cross-order tracking ownership conflicts'
);
$assertSame(
true,
str_contains($controllerSource, "\$log->action = 'ej_pharmacy_callback'")
&& str_contains($controllerSource, '操作人:')
&& str_contains($controllerSource, '版本已处理,保留回传日志'),
'every unique EJ callback must be written to the prescription order operation timeline with operator and version context'
);
$assertSame(
true,
str_contains($controllerSource, '订单药房流转制作中')
&& str_contains($controllerSource, '订单已完成')
&& str_contains($controllerSource, '流程:')
&& str_contains($controllerSource, '药房:洛阳药房')
&& str_contains($controllerSource, "implode(\$isWorkflowStep ? ' | ' : '', \$summaryParts)"),
'EJ workflow callback logs must use the same production-flow presentation as Gancao callbacks'
);
echo "zyt pharmacy callback/auth integration tests passed: {$passed}\n";