feat(111): payment transition event for Allegro+shopPRO re-import

Re-import zamowienia wykrywa tranzycje payment_status 0/1->2 i emituje
payment.status_changed, dzieki czemu chain reguly automatyzacji #7 zmienia
status na w_realizacji.

- OrderImportRepository: rozdzielenie paymentTransition (event 0/1->2) i
  statusOverwriteAllowed (preservacja status_code z Phase 62)
- AllegroOrderImportService + ShopproOrdersSyncService: emit
  payment.status_changed na re-imporcie (gate !wasCreated && wasPaymentTransition)
- bin/backfill_payment_transition_111.php: jednorazowy CLI dla zamowien
  payment_status=2 && status_code='nieoplacone' (Allegro + shopPRO)
- Naprawa luki znalezionej w analizie zamowienia #864

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-05 23:35:14 +02:00
parent 0da0241ebf
commit 5cf531d718
12 changed files with 691 additions and 31 deletions

View File

@@ -39,12 +39,18 @@ final class OrderImportRepository
$existingOrderId = $this->findOrderIdBySource($source, $sourceOrderId);
$created = $existingOrderId === null;
$paymentTransition = false;
$statusOverwriteAllowed = false;
if (!$created) {
$currentStatus = $this->getCurrentStatus($existingOrderId);
$existing = $this->getCurrentStatusAndPaymentStatus($existingOrderId);
$currentStatus = $existing['status_code'];
$oldPaymentStatus = $existing['payment_status'];
$newPaymentStatus = (int) ($orderData['payment_status'] ?? 0);
$paymentTransition = $currentStatus === 'nieoplacone' && $newPaymentStatus === 2;
if (!$paymentTransition) {
$paymentTransition = in_array($oldPaymentStatus, [0, 1], true) && $newPaymentStatus === 2;
$statusOverwriteAllowed = $currentStatus === 'nieoplacone' && $newPaymentStatus === 2;
if (!$statusOverwriteAllowed) {
$orderData['status_code'] = $currentStatus;
}
}
@@ -61,7 +67,7 @@ final class OrderImportRepository
$this->replacePayments($orderId, $payments);
$this->replaceShipments($orderId, $shipments);
$this->replaceStatusHistory($orderId, $statusHistory);
} elseif ($paymentTransition) {
} elseif ($paymentTransition || $statusOverwriteAllowed) {
$this->replacePayments($orderId, $payments);
}
@@ -101,15 +107,25 @@ final class OrderImportRepository
return $id > 0 ? $id : null;
}
private function getCurrentStatus(int $orderId): string
/**
* @return array{status_code:string, payment_status:int}
*/
private function getCurrentStatusAndPaymentStatus(int $orderId): array
{
$statement = $this->pdo->prepare(
'SELECT status_code FROM orders WHERE id = :id LIMIT 1'
'SELECT status_code, payment_status FROM orders WHERE id = :id LIMIT 1'
);
$statement->execute(['id' => $orderId]);
$value = $statement->fetchColumn();
$row = $statement->fetch(PDO::FETCH_ASSOC);
return strtolower(trim((string) ($value ?: '')));
if (!is_array($row)) {
return ['status_code' => '', 'payment_status' => 0];
}
return [
'status_code' => strtolower(trim((string) ($row['status_code'] ?? ''))),
'payment_status' => (int) ($row['payment_status'] ?? 0),
];
}
/**