Files
orderPRO/.paul/phases/99-order-delivery-payment-edit/99-01-PLAN.md
2026-04-13 22:31:06 +02:00

10 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, delegation
phase plan type wave depends_on files_modified autonomous delegation
99-order-delivery-payment-edit 01 execute 1
src/Modules/Orders/OrdersController.php
src/Modules/Orders/OrdersRepository.php
resources/views/orders/show.php
resources/scss/views/orders/_show.scss
routes/web.php
false off
## Goal Umozliwic uzytkownikowi zmiane formy dostawy (delivery_method) oraz formy platnosci (payment_method + external_payment_type_id) w istniejacym zamowieniu z poziomu widoku szczegolow /orders/{id} — ze szczegolnym wsparciem scenariusza "przedplata -> pobranie".

Purpose

Klient kontaktuje sie po zlozeniu zamowienia i prosi o zmiane sposobu dostawy albo o zmiane formy platnosci na pobranie. Dzis wymaga to edycji w zrodle (shopPRO/Allegro) i re-importu albo recznej ingerencji w DB. Funkcja pozwoli obsluzyc to w jednym miejscu, spojnie z reszta przeplywu (activity log, automatyzacje oparte o order.payment_method z Phase 96, warunek COD w presetach przesylek).

Output

  • Nowy formularz edycji w karcie "payment_shipping" w show.php (modal lub inline form) z dwoma polami: forma dostawy + forma platnosci
  • Nowa akcja POST /orders/{id}/details/update w OrdersController
  • Metoda OrdersRepository::updateDeliveryAndPayment() z walidacja i atomowym zapisem
  • Wpis w order_activity_log (event_type = 'details_change') z before/after w details_json
  • Automatyczna synchronizacja external_payment_type_id do CASH_ON_DELIVERY przy wyborze pobrania, aby Phase 96 warunek COD i presety autofill dzialaly bez re-importu
## Project Context @.paul/PROJECT.md @.paul/ROADMAP.md @.paul/STATE.md

Prior Work

@.paul/phases/96-automation-payment-method/96-01-SUMMARY.md @.paul/phases/77-cod-amount-fix/

Source Files

@src/Modules/Orders/OrdersController.php @src/Modules/Orders/OrdersRepository.php @resources/views/orders/show.php @src/Core/Support/StringHelper.php @routes/web.php

<acceptance_criteria>

AC-1: Edycja formy dostawy

Given zamowienie w /orders/{id} z delivery_method = "Kurier DPD"
When uzytkownik otworzy formularz edycji, wybierze "InPost Paczkomat" i zatwierdzi
Then delivery_method w DB = "InPost Paczkomat"
  And widok po przeladowaniu pokazuje nowa wartosc
  And w order_activity_log jest wpis event_type='details_change' z before/after w details_json

AC-2: Zmiana platnosci przedplata -> pobranie

Given zamowienie z payment_method = "Przelew" i external_payment_type_id != 'CASH_ON_DELIVERY'
When uzytkownik wybierze forme platnosci "Pobranie" i zatwierdzi
Then payment_method zawiera wartosc wybrana przez uzytkownika (np. "Pobranie")
  And external_payment_type_id = 'CASH_ON_DELIVERY'
  And StringHelper::isCodPayment($order['external_payment_type_id']) zwraca true
  And warunek automatyzacji `order.payment_method = COD` (Phase 96) wyzwala regule na tym zamowieniu
  And autofill kwoty pobrania w formularzu przesylki (Phase 77) dziala dla tego zamowienia

AC-3: Walidacja i bezpieczenstwo

Given uzytkownik wysyla POST /orders/{id}/details/update
When brakuje _token CSRF lub zamowienie nie istnieje
Then kontroler zwraca blad (403 dla CSRF, 404 dla brak zamowienia) bez modyfikacji DB
  And gdy payment_method i delivery_method sa puste po trim, zwraca walidacyjny Flash error i nie zapisuje nic

</acceptance_criteria>

Task 1: Repository + route + controller action src/Modules/Orders/OrdersRepository.php, src/Modules/Orders/OrdersController.php, routes/web.php 1. `OrdersRepository::updateDeliveryAndPayment(int $orderId, ?string $deliveryMethod, ?string $paymentMethod, ?string $externalPaymentTypeId, array $actor): bool` - Pobierz biezacy order przez `findDetails()` (before-snapshot) - Buduj UPDATE dynamicznie (tylko pola != null po trim, reszta bez zmian) - Prepared statement Medoo, bez sklejania SQL - Po UPDATE: `recordActivity($orderId, 'details_change', summary, detailsJson)` — detailsJson zawiera pola zmienione z kluczami `before` / `after` - Zwroc true gdy faktycznie cokolwiek zmienione, false gdy no-op - Zero efektow ubocznych poza orders + order_activity_log (NIE pushuj do shopPRO/Allegro — out of scope) 2. `OrdersController::updateDetails(int $orderId): Response` - Walidacja _token (wzorzec jak `updateStatus()` linia 267) - `findDetails()` -> 404 gdy brak - Odczyt `delivery_method`, `payment_method` z POST, trim, oba puste -> Flash::set('orders.error') + redirect - Gdy uzytkownik zaznaczyl checkbox/flaga `is_cod` (patrz Task 2) ustaw `externalPaymentTypeId = 'CASH_ON_DELIVERY'`, w przeciwnym razie przepusz istniejaca wartosc bez zmiany (null → repo pominie pole) - Wywolaj repo, Flash::set('orders.success', 'Dane zamowienia zaktualizowane'), redirect do /orders/{id} - Actor z SessionUserContext jak w istniejacych akcjach 3. `routes/web.php`: zarejestruj POST `/orders/{id}/details/update` → `OrdersController@updateDetails`, middleware identyczny jak inne POST na /orders (csrf + auth) Avoid: dodawania logiki push do zrodla (shopPRO/Allegro) — zaznaczone jako out of scope. Avoid: sklejania SQL. Avoid: zmiany `findDetails()` — tylko odczyt snapshot przez istniejaca metode. curl -X POST z validnym CSRF i body `delivery_method=Kurier&payment_method=Pobranie&is_cod=1` zwraca 302 do /orders/{id}; SELECT z orders pokazuje zaktualizowane 3 pola; SELECT z order_activity_log pokazuje wpis event_type='details_change' z details_json zawierajacym `delivery_method.before/after` i `external_payment_type_id.before/after` AC-1, AC-3 satisfied na poziomie backend Task 2: UI form w karcie payment_shipping resources/views/orders/show.php, resources/scss/views/orders/_show.scss 1. W `show.php` w karcie "payment_shipping" dodaj ikonke ✎ (pattern zgodny z feedback memory — hover + dropdown/inline) ktora otwiera inline form pod naglowkiem karty. 2. Form: - `` - Ukryty `_token` - `` z listą datalist bazujaca na DISTINCT delivery_method z ostatnich 50 zamowien (lekki helper w controllerze — przekaz przez $data) - `` analogicznie - `> Pobranie (COD)` — wyjasnia ze zaznaczenie ustawi external_payment_type_id - Submit button "Zapisz" + cancel (ukryj form) 3. Kompaktowy uklad (zgodnie z CLAUDE.md: gesty), style w `_show.scss`, zero CSS w widoku 4. OrderProAlerts dla ewentualnych komunikatow (nie natywne alert) Avoid: natywnego alert/confirm, CSS w widoku, duplikacji — jezeli datalist juz istnieje dla formy, reuse Otworz /orders/{id} w przegladarce; kliknij ✎ przy payment_shipping; zmien pola; zatwierdz; po redirect widac zaktualizowane dane w karcie AC-1, AC-2 satisfied na poziomie UI Edycja formy dostawy i platnosci w /orders/{id}: - Ikonka ✎ w karcie payment_shipping, inline form, datalist podpowiedzi - Checkbox "Pobranie (COD)" ustawia external_payment_type_id = CASH_ON_DELIVERY - Wpis w activity log details_change 1. Otworz /orders/{id} z zamowieniem platnym przelewem (external_payment_type_id != CASH_ON_DELIVERY) 2. Kliknij ✎ w karcie Platnosc i wysylka 3. Zmien delivery_method na dowolna inna wartosc, zmien payment_method na "Pobranie", zaznacz checkbox COD, zapisz 4. Po redirect sprawdz: - karta pokazuje nowe wartosci - zakladka Historia (activity log) ma wpis "Zmiana danych zamowienia" (details_change) - Przejdz do formularza przesylki — autofill kwoty pobrania (Phase 77) dziala - Jesli masz regule automatyzacji z warunkiem Metoda platnosci = COD (Phase 96) + jakims triggerem manualnym — zweryfikuj ze regula pasuje do tego zamowienia 5. Test walidacji: sprobuj zapisac z obydwoma polami pustymi — powinien pojawic sie Flash error i brak zmian Type "approved" to continue, or describe issues to fix

DO NOT CHANGE

  • OrderImportRepository.php — logika importu jest stabilna (Phase 62/75 re-import safety)
  • ShopproApiClient, AllegroApiClient — push do zrodla poza zakresem
  • findDetails(), paginate() — tylko konsumenci, nie modyfikacja
  • Schemat DB — wszystkie pola juz istnieja (delivery_method, payment_method, external_payment_type_id)

SCOPE LIMITS

  • Brak push zmiany formy platnosci / dostawy do shopPRO ani Allegro (jeden kierunek: orderPRO lokalnie)
  • Brak nowej tabeli / migracji
  • Brak rozszerzania modulu Automatyzacji o nowy event details_changed — to osobna faza jezeli potrzebne
  • Brak walidacji ze slownika form platnosci — free text z datalist podpowiedzi (spojne z dzisiejszym importem)
  • Brak edycji delivery_price / kwoty pobrania — tylko metody
  • Brak edycji danych odbiorcy / adresu — osobny scope
Przed zamknieciem planu: - [ ] `php -l` na zmodyfikowanych plikach PHP - [ ] Manualny test AC-1, AC-2, AC-3 w przegladarce - [ ] SELECT z order_activity_log potwierdza wpis details_change z poprawnym JSON - [ ] Po zmianie na COD: autofill kwoty pobrania (Phase 77) dziala, warunek Metoda platnosci = COD (Phase 96) matchuje - [ ] Brak natywnych alert/confirm w dodanym UI - [ ] Brak CSS w widoku, style w `_show.scss`

<success_criteria>

  • Wszystkie 3 AC spelnione
  • Zero regresji w istniejacych akcjach /orders/{id} (status change, add payment)
  • Spojnosc z Phase 77 (COD autofill) i Phase 96 (automation COD condition) — obie korzystaja z nowego stanu bez zadnych dodatkowych zmian
  • Nowa akcja ma CSRF + auth, Medoo prepared statements </success_criteria>
After completion, create `.paul/phases/99-order-delivery-payment-edit/99-01-SUMMARY.md`