$payload */ public static function isShippedEvent(array $payload): bool { return strtoupper(trim((string) ($payload['event_type'] ?? ''))) === 'ORDER_SHIPPED' || strtoupper(trim((string) ($payload['status'] ?? ''))) === 'SHIPPED'; } /** @param array $payload */ public static function isCompletedEvent(array $payload): bool { return strtoupper(trim((string) ($payload['status'] ?? ''))) === 'COMPLETED' || (strtoupper(trim((string) ($payload['event_type'] ?? ''))) === 'WORKFLOW_STEP_COMPLETED' && (bool) ($payload['final'] ?? false)); } /** @param array $payload */ public static function isRejectedEvent(array $payload): bool { return in_array(strtoupper(trim((string) ($payload['event_type'] ?? ''))), [ 'REVIEW_REJECTED', 'INVENTORY_SHORTAGE', ], true) || strtoupper(trim((string) ($payload['status'] ?? ''))) === 'REJECTED' || strtoupper(trim((string) ($payload['review_status'] ?? ''))) === 'REJECTED'; } /** @param array $payload */ public static function nextFulfillmentStatus( int $currentStatus, array $payload, ?int $rollbackStatus = null ): int { if (self::isRejectedEvent($payload)) { // EJ rejection means the pharmacy did not accept the submission; // it must not turn the ZYT business order into a customer refusal. // Restore the status captured immediately before the submission. return $rollbackStatus !== null && $rollbackStatus > 0 ? $rollbackStatus : ($currentStatus === 9 ? 2 : $currentStatus); } if (self::isShippedEvent($payload) && in_array($currentStatus, [1, 2], true)) { return 5; } if (self::isCompletedEvent($payload) && in_array($currentStatus, [1, 2, 5], true)) { return 3; } return $currentStatus; } }