--- phase: 57-payment-automation-event plan: 01 type: execute wave: 1 depends_on: ["56-01"] files_modified: - src/Modules/Automation/AutomationController.php - src/Modules/Automation/AutomationService.php - src/Modules/Orders/OrdersController.php - src/Modules/Settings/ShopproPaymentStatusSyncService.php - src/Modules/Cron/CronHandlerFactory.php - resources/views/automation/form.php - public/assets/js/modules/automation-form.js - routes/web.php - DOCS/ARCHITECTURE.md - DOCS/TECH_CHANGELOG.md autonomous: true --- ## Goal Dodanie zdarzenia automatyzacji `payment.status_changed` emitowanego przy zmianie statusu platnosci zamowienia. Warunek `payment_status` pozwala filtrowac po konkretnym statusie (oplacone, czesciowo oplacone, nieoplacone). ## Purpose Sprzedawca moze tworzyc reguly automatyzacji reagujace na zmiane statusu platnosci — np. wyslij email po oplaceniu, zmien status zamowienia, wystaw paragon. ## Output - Nowy event `payment.status_changed` w silniku automatyzacji - Nowy warunek `payment_status` z checkboxami statusow - Emisja eventu z OrdersController::addPayment() i ShopproPaymentStatusSyncService - UI: event i warunek widoczne w formularzu regul ## Project Context @.paul/PROJECT.md @.paul/ROADMAP.md ## Prior Work @.paul/phases/56-order-payments/56-01-SUMMARY.md (addPayment, payment_status update) ## Source Files @src/Modules/Automation/AutomationController.php (ALLOWED_EVENTS linia 19, ALLOWED_CONDITION_TYPES linia 20) @src/Modules/Automation/AutomationService.php (evaluateSingleCondition, evaluateShipmentStatusCondition — wzorzec) @src/Modules/Orders/OrdersController.php (addPayment — miejsce emisji eventu) @src/Modules/Settings/ShopproPaymentStatusSyncService.php (syncSingleOrderPayment — miejsce emisji eventu) @src/Modules/Cron/CronHandlerFactory.php (kompozycja ShopproPaymentStatusSyncService) @resources/views/automation/form.php (eventLabels, condition select, JS data) @public/assets/js/modules/automation-form.js (addCondition, onConditionTypeChange, buildShipmentStatusCheckboxes — wzorzec) @routes/web.php (tworzenie $automationService linia 253, $ordersController linia 264) ## AC-1: Event payment.status_changed dostepny w formularzu ```gherkin Given otwieram Ustawienia > Zadania automatyczne > Nowa regula When klikam dropdown "Zdarzenie" Then widze opcje "Zmiana statusu platnosci" obok istniejacych zdarzen ``` ## AC-2: Warunek payment_status dostepny w formularzu ```gherkin Given wybralem zdarzenie "Zmiana statusu platnosci" When dodaje warunek i wybieram typ "Status platnosci" Then widze checkboxy: Nieoplacone, Czesciowo oplacone, Oplacone And moge zaznaczyc jeden lub wiecej statusow ``` ## AC-3: Event emitowany przy recznym dodaniu platnosci ```gherkin Given istnieje aktywna regula: event=payment.status_changed, warunek=payment_status IN [oplacone], akcja=update_order_status When dodaje platnosc pokrywajaca pelna kwote zamowienia Then regula sie odpala i status zamowienia zmienia sie automatycznie And w historii automatyzacji widze wpis o wykonaniu reguly ``` ## AC-4: Event emitowany przy sync platnosci z shopPRO ```gherkin Given zamowienie source=shoppro zmienia payment_status przez cron sync When nowy payment_status rozni sie od poprzedniego Then event payment.status_changed jest emitowany z kontekstem (old/new status) ``` ## AC-5: Warunek filtruje poprawnie ```gherkin Given regula z warunkiem payment_status = [oplacone] When event jest emitowany z new_payment_status = 1 (czesciowo oplacone) Then regula NIE odpala sie When event jest emitowany z new_payment_status = 2 (oplacone) Then regula odpala sie ``` Task 1: Backend — event + warunek w silniku automatyzacji src/Modules/Automation/AutomationController.php, src/Modules/Automation/AutomationService.php 1. W AutomationController: - Dodaj 'payment.status_changed' do ALLOWED_EVENTS (linia 19) - Dodaj 'payment_status' do ALLOWED_CONDITION_TYPES (linia 20) - W metodzie parseConditions(): obsluz 'payment_status' — zbierz payment_status_keys[] z POST, zapisz jako condition_value.status_keys (wzorzec jak shipment_status) 2. W AutomationService::evaluateSingleCondition(): - Dodaj branch: if ($type === 'payment_status') return $this->evaluatePaymentStatusCondition($value, $context); 3. Dodaj metode evaluatePaymentStatusCondition(array $value, array $context): bool: - Pobierz status_keys z $value (tablica dozwolonych statusow: '0', '1', '2') - Pobierz new_payment_status z $context (string) - Return true jesli new_payment_status jest w status_keys - Mapowanie: 0=nieoplacone, 1=czesciowo_oplacone, 2=oplacone Wzoruj sie dokladnie na evaluateShipmentStatusCondition() — analogiczna logika. PHP lint — brak bledow skladniowych AC-1, AC-2, AC-5 satisfied: event i warunek zarejestrowane w silniku Task 2: Emisja eventu z OrdersController i ShopproPaymentStatusSyncService src/Modules/Orders/OrdersController.php, src/Modules/Settings/ShopproPaymentStatusSyncService.php, src/Modules/Cron/CronHandlerFactory.php, routes/web.php 1. W OrdersController: - Dodaj ?AutomationService $automation = null do konstruktora (po $shopproIntegrations) - W addPayment(), po zapisie platnosci i activity log, przed pushPaymentToShoppro: try { $this->automation?->trigger('payment.status_changed', $orderId, [ 'new_payment_status' => (string) $result['payment_status'], 'total_paid' => $result['total_paid'], 'payment_type_id' => $paymentTypeId, ]); } catch (Throwable) {} 2. W routes/web.php: - Przekaz $automationService do OrdersController (juz istnieje w scope na linii 253) - Dodaj do wywolania new OrdersController(..., $automationService) 3. W ShopproPaymentStatusSyncService: - Dodaj ?AutomationService $automation = null do konstruktora (po $pdo) - W syncSingleOrderPayment(), po uaktualnieniu payment status (po commit, przed recordActivity): if ($existingPaymentStatus !== $newPaymentStatus) { try { $this->automation?->trigger('payment.status_changed', $orderId, [ 'new_payment_status' => (string) $newPaymentStatus, 'old_payment_status' => $existingPaymentStatus !== null ? (string) $existingPaymentStatus : '', 'total_paid' => $newTotalPaid, 'payment_method' => $paymentMethod, ]); } catch (Throwable) {} } 4. W CronHandlerFactory: - Przekaz $automationService do ShopproPaymentStatusSyncService - AutomationService jest juz tworzony w CronHandlerFactory (buildAutomationHandler) — uzyj go - UWAGA: ShopproPaymentStatusSyncHandler jest tworzony w innym miejscu niz automation — sprawdz czy $automationService jest dostepny i przekaz go PHP lint — brak bledow skladniowych. Przejrzyj CronHandlerFactory ze szczegolna uwaga na kolejnosc tworzenia obiektow. AC-3, AC-4 satisfied: event emitowany z obu zrodel Task 3: UI — event i warunek w formularzu automatyzacji resources/views/automation/form.php, public/assets/js/modules/automation-form.js, DOCS/ARCHITECTURE.md, DOCS/TECH_CHANGELOG.md 1. W resources/views/automation/form.php: - Dodaj do $eventLabels: 'payment.status_changed' => 'Zmiana statusu platnosci' - W sekcji warunków (condition select): dodaj option value="payment_status">Status platnosci - W sekcji renderowania warunku (PHP): dodaj branch elseif ($conditionType === 'payment_status') z checkboxami: Statusy: ['0' => 'Nieoplacone', '1' => 'Czesciowo oplacone', '2' => 'Oplacone'] Input name: conditions[idx][payment_status_keys][] - Dodaj paymentStatusOptions do window.AutomationFormData 2. W public/assets/js/modules/automation-form.js: - Dodaj function buildPaymentStatusCheckboxes(namePrefix) — analogicznie do buildShipmentStatusCheckboxes ale z paymentStatusOptions - W addCondition(): dodaj option value="payment_status">Status platnosci w select - W onConditionTypeChange(): dodaj branch if (select.value === 'payment_status') { configDiv.innerHTML = buildPaymentStatusCheckboxes(namePrefix); } 3. Zaktualizuj DOCS/ARCHITECTURE.md i DOCS/TECH_CHANGELOG.md. Otworz formularz reguly — widoczne nowe zdarzenie i warunek. PHP lint. AC-1, AC-2 satisfied: UI gotowe ## DO NOT CHANGE - database/migrations/* (brak zmian schematu — event_type to VARCHAR, nowy typ nie wymaga migracji) - src/Modules/Automation/AutomationRepository.php (warstwa danych bez zmian) - src/Modules/Automation/AutomationExecutionLogRepository.php ## SCOPE LIMITS - Tylko event payment.status_changed i warunek payment_status - Nie dodajemy nowych akcji (istniejace: send_email, issue_receipt, update_shipment_status, update_order_status wystarczaja) - Nie modyfikujemy istniejacych eventow ani warunkow Before declaring plan complete: - [ ] PHP lint — brak bledow we wszystkich zmodyfikowanych plikach - [ ] Formularz reguly: widoczne zdarzenie "Zmiana statusu platnosci" - [ ] Formularz reguly: warunek "Status platnosci" z checkboxami - [ ] Dodanie platnosci emituje event - [ ] Sync platnosci z shopPRO emituje event - [ ] DOCS zaktualizowane - Wszystkie taski ukonczone - Nowy event i warunek widoczne w UI - Event emitowany z obu zrodel (reczne + cron sync) - Warunek filtruje po statusie platnosci After completion, create `.paul/phases/57-payment-automation-event/57-01-SUMMARY.md`