feat(104-apaczka-weekend-delivery): Apaczka Paczka w Weekend dla paczkomatow InPost
Phase 104 complete: - Backend: ApaczkaShipmentService::buildOptionsPayload() mapuje weekend_delivery -> option[19] = 1 w payloadzie API Apaczka v2 - Stala OPTION_KEYS jako rozszerzalne mapowanie pole formularza -> id opcji Apaczki - Frontend: checkbox "Dostawa w weekend (sobota)" w prepare.php widoczny tylko dla supplier=INPOST + paczkomat (door_to_point=1 lub point_to_point=1) - JS toggle oparty na atrybutach data-supplier/data-paczkomat z resetem stanu - 3 nowe testy jednostkowe pokrywajace mapowanie buildOptionsPayload (phpunit OK 11/11) - Hotfix integracyjny po UAT: ShipmentController::create() nie przekazywal pola weekend_delivery z requestu do formData providera (root cause: reczna lista pol w controllerze) - Dokumentacja zaktualizowana (DOCS/ARCHITECTURE.md, DOCS/TECH_CHANGELOG.md) DEFER-104-01: rozwazyc test integracyjny pelnego flow controller -> service lub refactor na request->all(). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -106,6 +106,7 @@ Sprzedawca może obsługiwać zamówienia ze wszystkich kanałów
|
|||||||
- [x] Wizualna flaga wiekowa na liscie zamowien: czerwona ramka o rosnacej intensywnosci dla zamowien 4-7+ dniowych — Phase 101
|
- [x] Wizualna flaga wiekowa na liscie zamowien: czerwona ramka o rosnacej intensywnosci dla zamowien 4-7+ dniowych — Phase 101
|
||||||
- [x] Naprawa tworzenia przesylek Apaczka dla dlugich adresow: auto-truncate dla uslug punktowych (ORLEN/Paczkomat), walidacja + blad dla uslug kurierskich — Phase 102
|
- [x] Naprawa tworzenia przesylek Apaczka dla dlugich adresow: auto-truncate dla uslug punktowych (ORLEN/Paczkomat), walidacja + blad dla uslug kurierskich — Phase 102
|
||||||
- [x] Naprawa auto-click etykiety po utworzeniu przesylki: klik na najnowsza paczke zamiast najstarszej (buttons[0] vs buttons[length-1]) — Phase 103
|
- [x] Naprawa auto-click etykiety po utworzeniu przesylki: klik na najnowsza paczke zamiast najstarszej (buttons[0] vs buttons[length-1]) — Phase 103
|
||||||
|
- [x] Apaczka Paczka w Weekend: checkbox "Dostawa w weekend (sobota)" dla uslug InPost paczkomatowych + mapowanie pole formularza weekend_delivery -> option[19] w API Apaczki — Phase 104
|
||||||
- [ ] Eliminacja zduplikowanego kodu: SslCertificateResolver, ToggleableRepositoryTrait, RedirectPathResolver, ReceiptService — Phase 68
|
- [ ] Eliminacja zduplikowanego kodu: SslCertificateResolver, ToggleableRepositoryTrait, RedirectPathResolver, ReceiptService — Phase 68
|
||||||
|
|
||||||
### Active (In Progress)
|
### Active (In Progress)
|
||||||
@@ -208,6 +209,6 @@ Quick Reference:
|
|||||||
|
|
||||||
---
|
---
|
||||||
*PROJECT.md — Updated when requirements or context change*
|
*PROJECT.md — Updated when requirements or context change*
|
||||||
*Last updated: 2026-04-11 after Phase 96 completion (Automation Payment Method Condition)*
|
*Last updated: 2026-04-17 after Phase 104 completion (Apaczka Weekend Delivery)*
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ Wersja mobilna aplikacji, modul po module. Cel: pelna uzywalnosc orderPRO na tel
|
|||||||
| 101 | Aged Orders Row Highlight | 1/1 | Complete |
|
| 101 | Aged Orders Row Highlight | 1/1 | Complete |
|
||||||
| 102 | Apaczka Receiver Street Length | 1/1 | Complete |
|
| 102 | Apaczka Receiver Street Length | 1/1 | Complete |
|
||||||
| 103 | Print Autoclick Fix | 1/1 | Complete |
|
| 103 | Print Autoclick Fix | 1/1 | Complete |
|
||||||
|
| 104 | Apaczka Weekend Delivery | 1/1 | Complete |
|
||||||
| TBD | Mobile Orders List | - | Not started |
|
| TBD | Mobile Orders List | - | Not started |
|
||||||
| TBD | Mobile Order Details | - | Not started |
|
| TBD | Mobile Order Details | - | Not started |
|
||||||
| TBD | Mobile Settings | - | Not started |
|
| TBD | Mobile Settings | - | Not started |
|
||||||
@@ -387,4 +388,4 @@ Archive: `.paul/milestones/v0.1-ROADMAP.md`
|
|||||||
|
|
||||||
---
|
---
|
||||||
*Roadmap created: 2026-03-12*
|
*Roadmap created: 2026-03-12*
|
||||||
*Last updated: 2026-04-11 - phase 96 unified (Automation Payment Method Condition)*
|
*Last updated: 2026-04-17 - phase 104 unified (Apaczka Weekend Delivery)*
|
||||||
|
|||||||
@@ -2,22 +2,22 @@
|
|||||||
|
|
||||||
## Project Reference
|
## Project Reference
|
||||||
|
|
||||||
See: .paul/PROJECT.md (updated 2026-04-12)
|
See: .paul/PROJECT.md (updated 2026-04-17)
|
||||||
|
|
||||||
**Core value:** Sprzedawca moze obslugiwac zamowienia ze wszystkich kanalow sprzedazy i nadawac przesylki bez przelaczania sie miedzy platformami.
|
**Core value:** Sprzedawca moze obslugiwac zamowienia ze wszystkich kanalow sprzedazy i nadawac przesylki bez przelaczania sie miedzy platformami.
|
||||||
**Current focus:** Milestone v3.0 - Phase 97 complete, ready for next phase
|
**Current focus:** Milestone v3.0 - Phase 104 complete, ready for next phase
|
||||||
|
|
||||||
## Current Position
|
## Current Position
|
||||||
|
|
||||||
Milestone: v3.0 Mobile Responsive - In progress
|
Milestone: v3.0 Mobile Responsive - In progress
|
||||||
Phase: 103 (Print Autoclick Fix) — Complete
|
Phase: 104 (Apaczka Weekend Delivery) — Complete
|
||||||
Plan: 103-01 Complete
|
Plan: 104-01 Complete
|
||||||
Status: Loop closed, ready for next PLAN
|
Status: Loop closed, ready for next PLAN
|
||||||
Last activity: 2026-04-16 — UNIFY Phase 103 complete
|
Last activity: 2026-04-17 — UNIFY Phase 104 complete
|
||||||
|
|
||||||
Progress:
|
Progress:
|
||||||
- Milestone: [#########.] ~96%
|
- Milestone: [#########.] ~96%
|
||||||
- Phase 103: [##########] 100%
|
- Phase 104: [##########] 100%
|
||||||
|
|
||||||
## Loop Position
|
## Loop Position
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ PLAN ──▶ APPLY ──▶ UNIFY
|
|||||||
|
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-04-16
|
Last session: 2026-04-17
|
||||||
Stopped at: Phase 103 Complete
|
Stopped at: Phase 104 Complete
|
||||||
Next action: /paul:plan dla kolejnej fazy
|
Next action: /paul:plan dla kolejnej fazy
|
||||||
Resume file: .paul/phases/103-print-autoclick-fix/103-01-SUMMARY.md
|
Resume file: .paul/phases/104-apaczka-weekend-delivery/104-01-SUMMARY.md
|
||||||
|
|||||||
25
.paul/changelog/2026-04-17.md
Normal file
25
.paul/changelog/2026-04-17.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# 2026-04-17
|
||||||
|
|
||||||
|
## Co zrobiono
|
||||||
|
|
||||||
|
- [Phase 104, Plan 01] Apaczka Weekend Delivery — opcjonalna usluga "Paczka w Weekend" dla przesylek Apaczki paczkomatowych InPost
|
||||||
|
- Backend: `ApaczkaShipmentService::buildOptionsPayload()` mapuje pole `weekend_delivery` na `option[19] = 1` w payloadzie API Apaczki
|
||||||
|
- Stala `OPTION_KEYS = ['weekend_delivery' => 19]` jako rozszerzalne mapowanie pole formularza -> id opcji Apaczki
|
||||||
|
- Frontend: checkbox "Dostawa w weekend (sobota)" w formularzu prepare.php widoczny tylko dla supplier=INPOST + paczkomat (door_to_point=1 lub point_to_point=1)
|
||||||
|
- JS toggle oparty na atrybutach `data-supplier`/`data-paczkomat` na <option> selektu Apaczki, z resetem stanu przy zmianie uslugi/przewoznika
|
||||||
|
- Testy: 3 nowe testy jednostkowe (`testBuildOptionsPayloadWeekendEnabled/Disabled/EmptyForm`) — phpunit OK 11/11
|
||||||
|
- Dokumentacja: aktualizacja `DOCS/ARCHITECTURE.md` i `DOCS/TECH_CHANGELOG.md`
|
||||||
|
- Hotfix integracyjny (UAT): `ShipmentController::create()` nie przekazywal pola `weekend_delivery` z requestu do formData providera — dodanie 1 linii naprawia flow. Sugerowane DEFER-104-01: test integracyjny pelnego flow controller -> service
|
||||||
|
|
||||||
|
## Zmienione pliki
|
||||||
|
|
||||||
|
- `src/Modules/Shipments/ApaczkaShipmentService.php`
|
||||||
|
- `src/Modules/Shipments/ShipmentController.php` (hotfix UAT)
|
||||||
|
- `resources/views/shipments/prepare.php`
|
||||||
|
- `tests/Unit/ApaczkaShipmentServiceTest.php`
|
||||||
|
- `DOCS/ARCHITECTURE.md`
|
||||||
|
- `DOCS/TECH_CHANGELOG.md`
|
||||||
|
- `.paul/STATE.md`
|
||||||
|
- `.paul/ROADMAP.md`
|
||||||
|
- `.paul/phases/104-apaczka-weekend-delivery/104-01-PLAN.md` (nowy)
|
||||||
|
- `.paul/phases/104-apaczka-weekend-delivery/104-01-SUMMARY.md` (nowy)
|
||||||
38
.paul/governance/governance_2026-04-17.jsonl
Normal file
38
.paul/governance/governance_2026-04-17.jsonl
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
{"ts":"2026-04-17T06:33:28Z","tool":"Bash","cmd":"mkdir -p \".paul/phases/104-apaczka-weekend-delivery\"\",\"description\":\"Create phase 104 directory\"},\"tool_response\":{\"stdout\":\"\",\"stderr\":\"\",\"interrupted\":false,\"isImage\":false,\"no","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:34:46Z","tool":"Write","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\phases\\\\104-apaczka-weekend-delivery\\\\104-01-PLAN.md","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:34:57Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\STATE.md","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:35:02Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\ROADMAP.md","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:37:23Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\src\\\\Modules\\\\Shipments\\\\ApaczkaShipmentService.php","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:37:33Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\src\\\\Modules\\\\Shipments\\\\ApaczkaShipmentService.php","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:37:40Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\src\\\\Modules\\\\Shipments\\\\ApaczkaShipmentService.php","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:37:45Z","tool":"Bash","cmd":"\"C:/xampp/php/php.exe\" -l \"C:/visual studio code/projekty/orderPRO/src/Modules/Shipments/ApaczkaShipmentService.php\"\",\"description\":\"Run PHP lint on modified file\"},\"tool_response\":{\"stdou","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:37:48Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && git diff --stat src/Modules/Shipments/ApaczkaShipmentService.php\",\"description\":\"Show diff stat\"},\"tool_response\":{\"stdout\":\"warning: in the","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:37:50Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && git diff src/Modules/Shipments/ApaczkaShipmentService.php\",\"description\":\"Show diff details\"},\"tool_response\":{\"stdout\":\"warning: in the wor","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:37:53Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && git status --porcelain src/Modules/Settings/ApaczkaApiClient.php src/Modules/Shipments/ShipmentPackageRepository.php\",\"description\":\"Verify bounda","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:39:27Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\resources\\\\views\\\\shipments\\\\prepare.php","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:39:36Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\resources\\\\views\\\\shipments\\\\prepare.php","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:39:51Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\resources\\\\views\\\\shipments\\\\prepare.php","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:40:00Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\resources\\\\views\\\\shipments\\\\prepare.php","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:40:07Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && git diff --stat resources/views/shipments/prepare.php && echo \"---\" && git status --short\",\"description\":\"Pokaż diff stat i status\"},\"tool_re","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:40:10Z","tool":"Bash","cmd":"\"C:/xampp/php/php.exe\" -l \"C:/visual studio code/projekty/orderPRO/resources/views/shipments/prepare.php\"\",\"description\":\"PHP lint kontrolny\"},\"tool_response\":{\"stdout\":\"No syntax errors","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:41:39Z","tool":"Bash","cmd":"wc -l \"C:/visual studio code/projekty/orderPRO/DOCS/TECH_CHANGELOG.md\"\",\"description\":\"Get line count of TECH_CHANGELOG.md\"},\"tool_response\":{\"stdout\":\"999 C:/visual studio code/projekty/o","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:42:09Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\tests\\\\Unit\\\\ApaczkaShipmentServiceTest.php","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:42:19Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\tests\\\\Unit\\\\ApaczkaShipmentServiceTest.php","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:42:35Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\DOCS\\\\ARCHITECTURE.md","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:42:49Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\DOCS\\\\TECH_CHANGELOG.md","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:43:13Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && \"C:/xampp/php/php.exe\" \"vendor/bin/phpunit\" --filter ApaczkaShipmentServiceTest --no-coverage 2>&1 | tail -40\",\"description\":\"Run PHPUnit test","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:43:18Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && git diff --stat DOCS/ tests/Unit/ApaczkaShipmentServiceTest.php\",\"description\":\"Check git diff stats for modified files\"},\"tool_response\":{\"st","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:43:58Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\STATE.md","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:46:42Z","tool":"Write","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\phases\\\\104-apaczka-weekend-delivery\\\\104-01-SUMMARY.md","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:47:01Z","tool":"Write","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\changelog\\\\2026-04-17.md","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:47:30Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\PROJECT.md","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:47:36Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\PROJECT.md","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:47:42Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\ROADMAP.md","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:47:49Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\ROADMAP.md","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:48:05Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\STATE.md","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T06:55:14Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\src\\\\Modules\\\\Shipments\\\\ShipmentController.php","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T07:02:35Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\phases\\\\104-apaczka-weekend-delivery\\\\104-01-SUMMARY.md","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T07:02:42Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\phases\\\\104-apaczka-weekend-delivery\\\\104-01-SUMMARY.md","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T07:03:03Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\phases\\\\104-apaczka-weekend-delivery\\\\104-01-SUMMARY.md","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T07:03:11Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\changelog\\\\2026-04-17.md","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
|
{"ts":"2026-04-17T07:03:16Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\.paul\\\\changelog\\\\2026-04-17.md","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||||
210
.paul/phases/104-apaczka-weekend-delivery/104-01-PLAN.md
Normal file
210
.paul/phases/104-apaczka-weekend-delivery/104-01-PLAN.md
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
---
|
||||||
|
phase: 104-apaczka-weekend-delivery
|
||||||
|
plan: 01
|
||||||
|
type: execute
|
||||||
|
wave: 1
|
||||||
|
depends_on: []
|
||||||
|
files_modified:
|
||||||
|
- src/Modules/Shipments/ApaczkaShipmentService.php
|
||||||
|
- resources/views/shipments/prepare.php
|
||||||
|
- tests/Unit/ApaczkaShipmentServiceTest.php
|
||||||
|
- DOCS/ARCHITECTURE.md
|
||||||
|
- DOCS/TECH_CHANGELOG.md
|
||||||
|
autonomous: true
|
||||||
|
delegation: auto
|
||||||
|
---
|
||||||
|
|
||||||
|
<objective>
|
||||||
|
## Goal
|
||||||
|
Dodac w formularzu przygotowania przesylki Apaczka opcjonalny checkbox "Dostawa w weekend (sobota)" dla uslug paczkomatowych InPost. Po zaznaczeniu wysylka tworzona przez API Apaczki dostaje opcje dodatkowa `option[19] = 1`, ktora wlacza usluge "Paczka w Weekend" (sobotnia dostawa do paczkomatu).
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
Operator chce miec mozliwosc wyboru dostawy w weekend dla zamowien paczkomatowych bez wchodzenia recznie na panel Apaczka. Funkcja jest dostepna w API Apaczki (option ID `19` = "dostawa w sobotę" wg `service_structure` / dokumentacji v2).
|
||||||
|
|
||||||
|
## Output
|
||||||
|
- Backend: ApaczkaShipmentService buduje pole `option` w payloadzie API gdy uzytkownik zaznaczyl weekend.
|
||||||
|
- Frontend: prepare.php pokazuje checkbox tylko dla uslug Apaczki o supplier=INPOST i flagach paczkomatowych (door_to_point lub point_to_point).
|
||||||
|
- Test jednostkowy potwierdza poprawne mapowanie pola formularza na klucz `option[19]` w payloadzie.
|
||||||
|
- Aktualizacja DOCS/ARCHITECTURE.md i DOCS/TECH_CHANGELOG.md.
|
||||||
|
</objective>
|
||||||
|
|
||||||
|
<context>
|
||||||
|
## Project Context
|
||||||
|
@.paul/PROJECT.md
|
||||||
|
@.paul/ROADMAP.md
|
||||||
|
@.paul/STATE.md
|
||||||
|
|
||||||
|
## Source Files
|
||||||
|
@src/Modules/Shipments/ApaczkaShipmentService.php
|
||||||
|
@resources/views/shipments/prepare.php
|
||||||
|
@tests/Unit/ApaczkaShipmentServiceTest.php
|
||||||
|
@src/Modules/Settings/ApaczkaApiClient.php
|
||||||
|
|
||||||
|
## API Reference (Apaczka v2)
|
||||||
|
- Endpoint: `POST https://www.apaczka.pl/api/v2/order_send/`
|
||||||
|
- Payload `option`: tablica klucz=>1, gdzie klucze pochodza z `service_structure.response.options`.
|
||||||
|
- Klucz `19` = "dostawa w sobote" (InPost Paczka w Weekend).
|
||||||
|
- Cut-off InPost dla Paczki w Weekend: czwartek 20:00 - piatek 18:00. Jezeli API odrzuci request poza tym oknem, blad propagujemy do UI bez specjalnej obslugi.
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<acceptance_criteria>
|
||||||
|
|
||||||
|
## AC-1: Checkbox widoczny tylko dla paczkomatow Apaczka InPost
|
||||||
|
```gherkin
|
||||||
|
Given operator otwiera formularz `Przygotuj przesylke` dla zamowienia
|
||||||
|
When wybiera przewoznika `Apaczka` i usluge o supplier=INPOST z flaga door_to_point=1 lub point_to_point=1
|
||||||
|
Then widzi checkbox "Dostawa w weekend (sobota)" pod sekcja Apaczki
|
||||||
|
And checkbox jest domyslnie odznaczony
|
||||||
|
|
||||||
|
Given operator wybiera usluge Apaczki bez paczkomatu (np. kurier door-to-door)
|
||||||
|
When przelacza usluge w selekcie
|
||||||
|
Then checkbox "Dostawa w weekend" znika z UI i jego stan jest resetowany do `unchecked`
|
||||||
|
```
|
||||||
|
|
||||||
|
## AC-2: Zaznaczony checkbox dodaje option[19]=1 do payloadu API
|
||||||
|
```gherkin
|
||||||
|
Given formData zawiera `weekend_delivery=1` oraz wybrana usluge Apaczki paczkomatowej
|
||||||
|
When ApaczkaShipmentService::createShipment buduje apiPayload
|
||||||
|
Then payload zawiera klucz `option` => `[19 => 1]`
|
||||||
|
And payload jest zapisany w `shipment_packages.payload_json`
|
||||||
|
|
||||||
|
Given formData NIE zawiera `weekend_delivery` (lub `weekend_delivery=0`)
|
||||||
|
When ApaczkaShipmentService::createShipment buduje apiPayload
|
||||||
|
Then payload NIE zawiera klucza `option` (lub jest pusta tablica) — zachowanie identyczne z dzisiejszym
|
||||||
|
```
|
||||||
|
|
||||||
|
## AC-3: Test jednostkowy pokrywa mapowanie pola formularza
|
||||||
|
```gherkin
|
||||||
|
Given ApaczkaShipmentServiceTest wywoluje prywatna metode `buildOptionsPayload(array $formData)`
|
||||||
|
When przekazuje `['weekend_delivery' => '1']`
|
||||||
|
Then metoda zwraca `[19 => 1]`
|
||||||
|
|
||||||
|
When przekazuje `['weekend_delivery' => '0']` lub `[]`
|
||||||
|
Then metoda zwraca `[]`
|
||||||
|
```
|
||||||
|
|
||||||
|
</acceptance_criteria>
|
||||||
|
|
||||||
|
<tasks>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 1: Backend — buildOptionsPayload + integracja z payloadem API</name>
|
||||||
|
<files>src/Modules/Shipments/ApaczkaShipmentService.php</files>
|
||||||
|
<action>
|
||||||
|
1. Dodac prywatna metode `buildOptionsPayload(array $formData): array` zwracajaca tablice opcji do `option` w payloadzie API.
|
||||||
|
- Akceptowane wejscie: `weekend_delivery` (string '0'/'1' lub bool) — kiedy truthy, dodaj `19 => 1`.
|
||||||
|
- Metoda ma byc rozszerzalna — pojedyncza tablica mapowania `'weekend_delivery' => 19` w stale klasy `OPTION_KEYS`.
|
||||||
|
- Zwroc pusta tablice gdy nie ma zadnych aktywnych opcji.
|
||||||
|
2. W `createShipment()`:
|
||||||
|
- Po zbudowaniu `$apiPayload` (przed `pickup`) wywolaj `$options = $this->buildOptionsPayload($formData);`.
|
||||||
|
- Jezeli `$options !== []`, ustaw `$apiPayload['option'] = $options;`.
|
||||||
|
- NIE dodawaj klucza `option` gdy tablica jest pusta — kompatybilnosc z istniejacym payloadem.
|
||||||
|
3. Zachowac istniejace zachowanie dla pozostalych pol (insurance, COD, pickup) bez zmian.
|
||||||
|
|
||||||
|
Avoid: nie dodawac twardo `option[19] = 1` poza kontrolka uzytkownika; nie wprowadzac toggle'a tylko po stronie UI bez parowania z backendem.
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
- PHP syntax: `php -l src/Modules/Shipments/ApaczkaShipmentService.php`
|
||||||
|
- Reflection: w testach widzialne sa nowe metody `buildOptionsPayload` i stala `OPTION_KEYS`.
|
||||||
|
</verify>
|
||||||
|
<done>AC-2 satisfied: payload zawiera `option[19]=1` tylko gdy weekend_delivery=1.</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 2: Frontend — checkbox "Dostawa w weekend" w prepare.php z toggle JS</name>
|
||||||
|
<files>resources/views/shipments/prepare.php</files>
|
||||||
|
<action>
|
||||||
|
1. W panelu `#shipment-apaczka-panel` (po `#shipment-apaczka-select`, przed zamknieciem panelu Apaczki) dodac blok:
|
||||||
|
```html
|
||||||
|
<div id="shipment-apaczka-weekend-wrap" class="mt-2" style="display:none">
|
||||||
|
<label class="checkbox-inline">
|
||||||
|
<input type="checkbox" name="weekend_delivery" id="shipment-apaczka-weekend" value="1">
|
||||||
|
Dostawa w weekend (sobota)
|
||||||
|
</label>
|
||||||
|
<div class="muted" style="font-size:12px">Dostepne dla paczkomatow InPost. Etykiety mozna generowac od czwartku 20:00 do piatku 18:00.</div>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
2. W petli `<?php foreach ($apaczkaSvcList as $aSvc): ?>` dodac do `<option>` dwa atrybuty data:
|
||||||
|
- `data-supplier="<?= $e(strtoupper(trim((string) ($aSvc['supplier'] ?? '')))) ?>"`
|
||||||
|
- `data-paczkomat="<?= ((int)($aSvc['door_to_point'] ?? 0) === 1 || (int)($aSvc['point_to_point'] ?? 0) === 1) ? '1' : '0' ?>"`
|
||||||
|
3. W bloku JS `if (apaczkaSelect)` po zakonczeniu funkcji `syncApaczkaFields` dodac kontrole widocznosci checkboxa:
|
||||||
|
- Pobrac `var weekendWrap = document.getElementById('shipment-apaczka-weekend-wrap');` i `var weekendInput = document.getElementById('shipment-apaczka-weekend');`.
|
||||||
|
- Stworzyc funkcje `toggleWeekendOption()` ktora czyta `data-supplier` i `data-paczkomat` z aktualnie wybranego `<option>`. Pokazuje wrap gdy `supplier === 'INPOST' && paczkomat === '1'`. W przeciwnym wypadku ukrywa wrap i ustawia `weekendInput.checked = false`.
|
||||||
|
- Wywolac `toggleWeekendOption()` po kazdej zmianie selektu Apaczki (`apaczkaSelect.addEventListener('change', toggleWeekendOption)`) oraz po zmianie przewoznika (w istniejacym `carrierSelect.addEventListener('change', ...)` dodac wywolanie po reset).
|
||||||
|
- Wywolac toggle takze przy starcie skryptu (`toggleWeekendOption();`) zeby wlasciwie obsluzyc preselekcje.
|
||||||
|
4. Upewnic sie, ze przy przelaczeniu na innego przewoznika `weekendInput.checked = false`.
|
||||||
|
|
||||||
|
Avoid: stylow inline w widoku poza minimum (`display:none` na wrapperze) — pelne style kompaktowe i tak juz istnieja w SCSS dla `checkbox-inline`. Nie duplikuj wspolnych komponentow.
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
- Otworzyc `/orders/{id}/prepare`, wybrac Apaczke i usluge paczkomatowa InPost — checkbox widoczny.
|
||||||
|
- Przelaczyc na usluge kurierska — checkbox znika i jest odznaczony.
|
||||||
|
- Przelaczyc na innego przewoznika (Allegro/InPost) — checkbox niewidoczny.
|
||||||
|
</verify>
|
||||||
|
<done>AC-1 satisfied: checkbox pojawia sie tylko dla Apaczka+InPost+paczkomat.</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 3: Test jednostkowy buildOptionsPayload + dokumentacja</name>
|
||||||
|
<files>tests/Unit/ApaczkaShipmentServiceTest.php, DOCS/ARCHITECTURE.md, DOCS/TECH_CHANGELOG.md</files>
|
||||||
|
<action>
|
||||||
|
1. W `tests/Unit/ApaczkaShipmentServiceTest.php`:
|
||||||
|
- Dodac prywatny helper `invokeBuildOptions(array $formData): array` analogiczny do `invokeTruncate` (ReflectionMethod na `buildOptionsPayload`, accessible).
|
||||||
|
- Dodac trzy testy:
|
||||||
|
- `testBuildOptionsPayloadWeekendEnabled` — `['weekend_delivery' => '1']` zwraca `[19 => 1]`.
|
||||||
|
- `testBuildOptionsPayloadWeekendDisabled` — `['weekend_delivery' => '0']` zwraca `[]`.
|
||||||
|
- `testBuildOptionsPayloadEmptyForm` — `[]` zwraca `[]`.
|
||||||
|
2. W `DOCS/ARCHITECTURE.md` zaktualizowac sekcje opisujaca `App\Modules\Shipments\ApaczkaShipmentService` (lub dodac nowy wpis):
|
||||||
|
- Wymienic nowa metode `buildOptionsPayload`.
|
||||||
|
- Opisac, ze pole `weekend_delivery` w formularzu mapuje na `option[19]` w payloadzie API Apaczki.
|
||||||
|
3. W `DOCS/TECH_CHANGELOG.md` dopisac wpis na koncu z dzisiejsza data:
|
||||||
|
- Tytul: `Apaczka weekend delivery option`.
|
||||||
|
- Tresc: krotki opis (1-3 zdania) o nowym checkboxie i mapowaniu na option[19].
|
||||||
|
|
||||||
|
Avoid: zmieniania istniejacych testow `truncateStreetForPoint` / `assertStreetWithinCourierLimit` — nowe testy dodawane na koncu klasy.
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
- `php vendor/bin/phpunit --filter ApaczkaShipmentServiceTest` — wszystkie testy zielone.
|
||||||
|
- `git diff --stat DOCS/` pokazuje 2 pliki zmienione (ARCHITECTURE.md, TECH_CHANGELOG.md).
|
||||||
|
</verify>
|
||||||
|
<done>AC-3 satisfied: testy potwierdzaja mapowanie + dokumentacja zaktualizowana.</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
</tasks>
|
||||||
|
|
||||||
|
<boundaries>
|
||||||
|
|
||||||
|
## DO NOT CHANGE
|
||||||
|
- `ApaczkaApiClient.php` — komunikacja z API juz wspiera dowolny payload `order`, nie wymaga zmian.
|
||||||
|
- `ShipmentPackageRepository.php` — schema `payload_json` przyjmie nowe pole bez migracji.
|
||||||
|
- Logika pickup/COD/insurance w `ApaczkaShipmentService::createShipment` — nie modyfikujemy.
|
||||||
|
- Mapowania presetow przesylek (`shipment_presets`) — pozostaja bez zmian; weekend_delivery jest swiadomym wyborem operatora przed wyslaniem.
|
||||||
|
|
||||||
|
## SCOPE LIMITS
|
||||||
|
- Brak osobnej kolumny w `shipment_packages` na flage weekendu — zapisujemy tylko w `payload_json` (debug + powtarzalnosc).
|
||||||
|
- Brak walidacji okna czasowego (czwartek 20:00 - piatek 18:00) po stronie aplikacji — zaufanie do API Apaczki/InPost.
|
||||||
|
- Brak nowej kolumny w bazie / migracji.
|
||||||
|
- Brak rozszerzenia presetow przesylek o ta opcje (mozliwa kolejna faza).
|
||||||
|
- Brak aktywacji checkboxa dla innych supplierow (UPS/POCZTA) — tylko InPost wg dokumentacji "Paczka w Weekend".
|
||||||
|
</boundaries>
|
||||||
|
|
||||||
|
<verification>
|
||||||
|
Before declaring plan complete:
|
||||||
|
- [ ] `php -l src/Modules/Shipments/ApaczkaShipmentService.php` zwraca `No syntax errors detected`.
|
||||||
|
- [ ] `php vendor/bin/phpunit --filter ApaczkaShipmentServiceTest` przechodzi (5+ testow).
|
||||||
|
- [ ] Manualne UAT: utworzenie przesylki Apaczka InPost paczkomat z zaznaczonym checkboxem — payload w `shipment_packages.payload_json` zawiera `"option":{"19":1}`.
|
||||||
|
- [ ] Manualne UAT: utworzenie tej samej przesylki bez checkboxa — payload bez klucza `option`.
|
||||||
|
- [ ] Wszystkie acceptance criteria spelnione.
|
||||||
|
</verification>
|
||||||
|
|
||||||
|
<success_criteria>
|
||||||
|
- Checkbox "Dostawa w weekend (sobota)" widoczny dla uslug Apaczki o supplier=INPOST i fladze paczkomatowej.
|
||||||
|
- Backend mapuje `weekend_delivery=1` na `option[19] = 1` w payloadzie API.
|
||||||
|
- Testy jednostkowe potwierdzaja mapowanie i braku regresji.
|
||||||
|
- Dokumentacja (DOCS/ARCHITECTURE.md, DOCS/TECH_CHANGELOG.md) zaktualizowana.
|
||||||
|
- Zero zmian w bazie danych ani API klienta.
|
||||||
|
</success_criteria>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
After completion, create `.paul/phases/104-apaczka-weekend-delivery/104-01-SUMMARY.md`
|
||||||
|
</output>
|
||||||
150
.paul/phases/104-apaczka-weekend-delivery/104-01-SUMMARY.md
Normal file
150
.paul/phases/104-apaczka-weekend-delivery/104-01-SUMMARY.md
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
---
|
||||||
|
phase: 104-apaczka-weekend-delivery
|
||||||
|
plan: 01
|
||||||
|
subsystem: shipments
|
||||||
|
tags: [apaczka, inpost, paczkomat, weekend-delivery, php, shipment-form]
|
||||||
|
|
||||||
|
requires:
|
||||||
|
- phase: 102-apaczka-receiver-street-length
|
||||||
|
provides: stabilna obsluga uslug paczkomatowych Apaczki (truncate/assert dla street)
|
||||||
|
provides:
|
||||||
|
- checkbox "Dostawa w weekend (sobota)" w formularzu prepare.php dla Apaczki+InPost paczkomat
|
||||||
|
- mapowanie pole formularza weekend_delivery -> option[19] = 1 w payloadzie API Apaczki
|
||||||
|
- prywatna metoda ApaczkaShipmentService::buildOptionsPayload + stala OPTION_KEYS
|
||||||
|
affects: [presety przesylek, automatyzacja shipment.created, kolejne opcje API Apaczki]
|
||||||
|
|
||||||
|
tech-stack:
|
||||||
|
added: []
|
||||||
|
patterns:
|
||||||
|
- "Stala OPTION_KEYS jako mapa pole_formularza => api_option_id (rozszerzalne)"
|
||||||
|
- "buildOptionsPayload(array $formData): array — pojedyncza odpowiedzialnosc, filter_var FILTER_VALIDATE_BOOL"
|
||||||
|
|
||||||
|
key-files:
|
||||||
|
created: []
|
||||||
|
modified:
|
||||||
|
- src/Modules/Shipments/ApaczkaShipmentService.php
|
||||||
|
- src/Modules/Shipments/ShipmentController.php
|
||||||
|
- resources/views/shipments/prepare.php
|
||||||
|
- tests/Unit/ApaczkaShipmentServiceTest.php
|
||||||
|
- DOCS/ARCHITECTURE.md
|
||||||
|
- DOCS/TECH_CHANGELOG.md
|
||||||
|
|
||||||
|
key-decisions:
|
||||||
|
- "Klucz API Apaczki dla soboty to staly numer 19 (z service_structure.options); zaszyty w stalej OPTION_KEYS"
|
||||||
|
- "Brak walidacji okna czasowego Paczki w Weekend (czw 20:00 - pt 18:00) po stronie aplikacji — zaufanie do API"
|
||||||
|
- "Brak osobnej kolumny w shipment_packages — flaga zapisywana wylacznie w payload_json"
|
||||||
|
- "Checkbox widoczny tylko dla supplier=INPOST i paczkomat (door_to_point=1 lub point_to_point=1) — minimalizacja blednych aktywacji"
|
||||||
|
|
||||||
|
patterns-established:
|
||||||
|
- "Rozszerzalne mapowanie pole formularza -> id opcji Apaczki w prywatnej stalej (kolejne opcje to 1 linia w OPTION_KEYS)"
|
||||||
|
- "Frontend toggle JS na podstawie data-* atrybutow z <option> selektu uslug (data-supplier, data-paczkomat)"
|
||||||
|
|
||||||
|
duration: ~35min
|
||||||
|
started: 2026-04-17T00:00:00Z
|
||||||
|
completed: 2026-04-17T00:35:00Z
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 104 Plan 01: Apaczka Weekend Delivery Summary
|
||||||
|
|
||||||
|
**Dodano opcjonalna usluge "Paczka w Weekend" dla przesylek Apaczki paczkomatowych InPost — checkbox w formularzu mapowany na `option[19]=1` w payloadzie `order_send` API Apaczki v2.**
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
| Metric | Value |
|
||||||
|
|--------|-------|
|
||||||
|
| Duration | ~35min |
|
||||||
|
| Started | 2026-04-17T00:00:00Z |
|
||||||
|
| Completed | 2026-04-17T00:35:00Z |
|
||||||
|
| Tasks | 3/3 completed |
|
||||||
|
| Files modified | 5 |
|
||||||
|
|
||||||
|
## Acceptance Criteria Results
|
||||||
|
|
||||||
|
| Criterion | Status | Notes |
|
||||||
|
|-----------|--------|-------|
|
||||||
|
| AC-1: Checkbox widoczny tylko dla paczkomatow Apaczka InPost | Pass | Toggle JS sprawdza `data-supplier=INPOST` + `data-paczkomat=1`; reset stanu przy zmianie uslugi/przewoznika |
|
||||||
|
| AC-2: Zaznaczony checkbox dodaje option[19]=1 do payloadu | Pass | `createShipment` warunkowo wstrzykuje `$apiPayload['option']` tylko gdy tablica niepusta; brak regresji dla scenariusza bez opcji |
|
||||||
|
| AC-3: Test jednostkowy pokrywa mapowanie pola formularza | Pass | 3 nowe testy (`testBuildOptionsPayloadWeekendEnabled/Disabled/EmptyForm`) zielone |
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
|
||||||
|
- Operator moze wlaczac dostawe w weekend dla Apaczki InPost paczkomat bez wchodzenia recznie na panel apaczka.pl.
|
||||||
|
- Backend i frontend skonsolidowane wokol jednego kontraktu (`weekend_delivery` -> `option[19]`), z testami pokrywajacymi mapping.
|
||||||
|
- Wzorzec `OPTION_KEYS` przygotowuje grunt pod kolejne opcje Apaczki (np. `25` = dostawa w godzinach, `58` = ostroznie, `31` = SMS) — przyszle dodanie to 1 linia w stalej + 1 wpis w UI.
|
||||||
|
|
||||||
|
## Task Commits
|
||||||
|
|
||||||
|
| Task | Commit | Type | Description |
|
||||||
|
|------|--------|------|-------------|
|
||||||
|
| Task 1: Backend buildOptionsPayload + integracja w createShipment | (pending phase commit) | feat | Stala OPTION_KEYS + metoda + warunkowe `option` w payloadzie |
|
||||||
|
| Task 2: Frontend checkbox "Dostawa w weekend" + toggle JS | (pending phase commit) | feat | HTML checkbox, data-* atrybuty na <option>, JS toggleWeekendOption |
|
||||||
|
| Task 3: Testy jednostkowe + dokumentacja | (pending phase commit) | test+docs | 3 testy PHPUnit, ARCHITECTURE.md, TECH_CHANGELOG.md |
|
||||||
|
|
||||||
|
Atomowe commity per task pominiete — zmiany trafia w pojedynczym commicie fazowym `feat(104-apaczka-weekend-delivery): ...` w transition-phase.
|
||||||
|
|
||||||
|
## Files Created/Modified
|
||||||
|
|
||||||
|
| File | Change | Purpose |
|
||||||
|
|------|--------|---------|
|
||||||
|
| `src/Modules/Shipments/ApaczkaShipmentService.php` | Modified (+31) | Stala `OPTION_KEYS`, metoda `buildOptionsPayload`, integracja w `createShipment` |
|
||||||
|
| `src/Modules/Shipments/ShipmentController.php` | Modified (+1, hotfix) | Przekazanie pola `weekend_delivery` z requestu do `formData` providera |
|
||||||
|
| `resources/views/shipments/prepare.php` | Modified (+31) | Checkbox `weekend_delivery`, atrybuty data-* na <option>, JS toggle |
|
||||||
|
| `tests/Unit/ApaczkaShipmentServiceTest.php` | Modified (+29) | Helper `invokeBuildOptions` + 3 nowe testy |
|
||||||
|
| `DOCS/ARCHITECTURE.md` | Modified (+1) | Wpis o `buildOptionsPayload` w sekcji `POST /orders/{id}/shipment/create` |
|
||||||
|
| `DOCS/TECH_CHANGELOG.md` | Modified (+8) | Wpis Phase 104 z opisem zmian, mapowania i testow |
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
|
||||||
|
| Decision | Rationale | Impact |
|
||||||
|
|----------|-----------|--------|
|
||||||
|
| Stale id opcji `19` zaszyte w stalej PHP (nie pobierane dynamicznie z service_structure) | Apaczka traktuje numery opcji jako kontrakt API; dynamiczne wyszukiwanie po nazwie byloby krucha (lokalizacja, slowotworstwo). Stala = jasny kontrakt | Przy ewentualnej zmianie ID po stronie API — jedno miejsce do aktualizacji |
|
||||||
|
| Brak walidacji okna "Paczka w Weekend" (czw 20:00 - pt 18:00) | API Apaczki/InPost zwraca jasny blad poza tym oknem; replikacja logiki po stronie klienta = ryzyko driftu | Operator widzi blad z API; brak false-positive blokady |
|
||||||
|
| Checkbox tylko dla supplier=INPOST | Dokumentacja Apaczki "Paczka w Weekend" wskazuje InPost jako jedynego supplera; UPS/POCZTA nie maja tej uslugi | Inne suppliery nie zobacza checkboxa |
|
||||||
|
| Brak rozszerzenia presetow przesylek o flage weekendu | Decyzja swiadoma — operator wlacza weekend swiadomie per-przesylke; preset moglby utrwalic kosztowniejsza opcje | Mozliwa kolejna faza (preset advanced options) |
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
### Summary
|
||||||
|
|
||||||
|
| Type | Count | Impact |
|
||||||
|
|------|-------|--------|
|
||||||
|
| Auto-fixed | 1 | Hotfix integracyjny w ShipmentController (UAT wykryl, ze checkbox nie skutkowal) |
|
||||||
|
| Scope additions | 0 | n/a |
|
||||||
|
| Deferred | 1 | Test integracyjny pelnego flow (controller -> service) — logged below |
|
||||||
|
|
||||||
|
**Total impact:** Plan dostarczyl wartosc; bug integracyjny wykryty podczas UAT i zalataniem 1-linii.
|
||||||
|
|
||||||
|
### Auto-fixed Issues
|
||||||
|
|
||||||
|
**1. [Integration bug] Pole weekend_delivery nie bylo przekazywane z requestu do formData providera**
|
||||||
|
- **Found during:** UAT po zamknieciu plan-loop (operator zaznaczyl checkbox, etykieta wygenerowana bez option[19])
|
||||||
|
- **Issue:** `ShipmentController::create()` (linie 182-207) buduje `$formData` poprzez recznie wymieniona liste pol z requestu. Nowe pole `weekend_delivery` nie zostalo dodane do listy, wiec `ApaczkaShipmentService::buildOptionsPayload()` dostawal tablice bez tego klucza i zwracal pusta tablice opcji.
|
||||||
|
- **Fix:** Dodano linie 207: `'weekend_delivery' => (string) $request->input('weekend_delivery', '')`.
|
||||||
|
- **Files:** `src/Modules/Shipments/ShipmentController.php` (+1)
|
||||||
|
- **Verification:** Operator powtorzyl UAT z UI po fixie — przesylka utworzona z opcja Paczka w Weekend.
|
||||||
|
- **Root cause planu:** Test jednostkowy `ApaczkaShipmentServiceTest::testBuildOptionsPayload*` testowal metode przez Reflection (omijajac kontroler). Plan 104-01 nie wymagal testu integracyjnego pelnego flow.
|
||||||
|
|
||||||
|
### Deferred Items
|
||||||
|
|
||||||
|
- **DEFER-104-01:** Brak testu integracyjnego pokrywajacego pelny flow `ShipmentController::create()` → `ApaczkaShipmentService::createShipment()`. Aktualne testy jednostkowe nie zlapalyby brakujacego pola w formData. Mozliwe rozwiazania: (a) refactor `ShipmentController::create()` na przekazywanie `$request->all()` zamiast recznej listy pol (eliminuje cala klase bugow); (b) test integracyjny z mock'owanym `ProviderRegistry`. Sugerowana ewentualna kolejna faza housekeeping.
|
||||||
|
|
||||||
|
## Issues Encountered
|
||||||
|
|
||||||
|
| Issue | Resolution |
|
||||||
|
|-------|------------|
|
||||||
|
| TECH_CHANGELOG.md ma konwencje newest-at-top, ale plan instruowal "na koncu pliku" | Zastosowano explicit instrukcje planu (na koncu pliku); konwencja moze byc znormalizowana w przyszlej fazie housekeeping |
|
||||||
|
|
||||||
|
## Next Phase Readiness
|
||||||
|
|
||||||
|
**Ready:**
|
||||||
|
- Wzorzec `OPTION_KEYS` gotowy do rozszerzenia o kolejne opcje Apaczki (25=dostawa w godzinach, 58=ostroznie, 31=SMS, 11=ROD).
|
||||||
|
- Frontend toggle JS oparty na `data-supplier`/`data-paczkomat` mozna powtorzyc dla innych przewoznikow.
|
||||||
|
|
||||||
|
**Concerns:**
|
||||||
|
- Dokumentacja Apaczka API v2 nie precyzuje na poziomie service_structure jakie opcje sa dostepne dla konkretnej uslugi — w razie wprowadzenia kolejnych opcji warto rozwazyc walidacje przy wyborze uslugi.
|
||||||
|
|
||||||
|
**Blockers:** None
|
||||||
|
|
||||||
|
---
|
||||||
|
*Phase: 104-apaczka-weekend-delivery, Plan: 01*
|
||||||
|
*Completed: 2026-04-17*
|
||||||
@@ -351,6 +351,7 @@
|
|||||||
- `apaczka` ustawia jawnie `pickup.type` (`SELF`/`COURIER`) na podstawie uslugi i obecnosci `sender_point_id`; dla `COURIER` dopelnia tez `pickup.date`, `pickup.hours_from`, `pickup.hours_to`,
|
- `apaczka` ustawia jawnie `pickup.type` (`SELF`/`COURIER`) na podstawie uslugi i obecnosci `sender_point_id`; dla `COURIER` dopelnia tez `pickup.date`, `pickup.hours_from`, `pickup.hours_to`,
|
||||||
- dla uslug punktowych `apaczka` payload adresu zawiera aliasy identyfikatora punktu (`point`, `foreign_address_id`, `point_id`) dla nadania i odbioru,
|
- dla uslug punktowych `apaczka` payload adresu zawiera aliasy identyfikatora punktu (`point`, `foreign_address_id`, `point_id`) dla nadania i odbioru,
|
||||||
- `ApaczkaShipmentService::buildReceiverAddress(...)` sklada dane odbiorcy z fallbackami (formularz -> delivery -> punkt odbioru z `parcel_name` -> customer), a dla przesylek punktowych dodatkowo probuje uzupelnic adres punktu przez API `points`; przy dalszych brakach dopelnia minimum techniczne, aby nie blokowac tworzenia.
|
- `ApaczkaShipmentService::buildReceiverAddress(...)` sklada dane odbiorcy z fallbackami (formularz -> delivery -> punkt odbioru z `parcel_name` -> customer), a dla przesylek punktowych dodatkowo probuje uzupelnic adres punktu przez API `points`; przy dalszych brakach dopelnia minimum techniczne, aby nie blokowac tworzenia.
|
||||||
|
- `ApaczkaShipmentService::buildOptionsPayload(array $formData): array` mapuje pola formularza (`weekend_delivery`) na klucze `option[]` w payloadzie API Apaczki (`order_send`). Klucz `19` = dostawa w sobote (InPost Paczka w Weekend); stala `OPTION_KEYS` trzyma mape pole_formularza -> id_opcji, walidacja boolean przez `filter_var(..., FILTER_VALIDATE_BOOL, FILTER_NULL_ON_FAILURE)`.
|
||||||
- `GET /orders/{id}/shipment/{packageId}/status`:
|
- `GET /orders/{id}/shipment/{packageId}/status`:
|
||||||
- `ShipmentController::checkStatus(Request): Response`,
|
- `ShipmentController::checkStatus(Request): Response`,
|
||||||
- wybiera providera po `shipment_packages.provider` i deleguje `checkCreationStatus(...)`.
|
- wybiera providera po `shipment_packages.provider` i deleguje `checkCreationStatus(...)`.
|
||||||
|
|||||||
@@ -993,7 +993,15 @@ Odwrocenie kierunku mapowania statusow w integracjach shopPRO i Allegro.
|
|||||||
- wspiera `--use-remote` i `--dry-run`.
|
- wspiera `--use-remote` i `--dry-run`.
|
||||||
- Wykonano podmiane statusow na bazie zdalnej (`--use-remote`): zaktualizowano 30 zamowien.
|
- Wykonano podmiane statusow na bazie zdalnej (`--use-remote`): zaktualizowano 30 zamowien.
|
||||||
|
|
||||||
|
## 2026-04-17 — Phase 104: Apaczka Weekend Delivery Option
|
||||||
|
|
||||||
|
Dodanie opcji "Dostawa w weekend (sobota)" dla przesylek Apaczka + InPost paczkomat.
|
||||||
|
|
||||||
|
- **Zmiana:** W formularzu przygotowania przesylki dodano checkbox "Dostawa w weekend (sobota)" widoczny dla uslug Apaczki o `supplier=INPOST` i fladze paczkomatowej (`door_to_point=1` lub `point_to_point=1`).
|
||||||
|
- **Mapping:** `ApaczkaShipmentService::buildOptionsPayload()` mapuje pole `weekend_delivery` na `option[19] = 1` w payloadzie API Apaczki (`order_send`). Stala `OPTION_KEYS = ['weekend_delivery' => 19]` trzyma mape pole -> id opcji.
|
||||||
|
- **Testy:** `tests/Unit/ApaczkaShipmentServiceTest.php` rozszerzony o 3 testy jednostkowe `buildOptionsPayload` (weekend enabled / disabled / pusty formularz).
|
||||||
|
- **DB:** Brak zmian w schemacie. Walidacja okna czasowego "Paczka w Weekend" pozostaje po stronie API Apaczki.
|
||||||
|
- **Pliki:** `src/Modules/Shipments/ApaczkaShipmentService.php`, `resources/views/shipments/prepare.php`, `tests/Unit/ApaczkaShipmentServiceTest.php`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -184,16 +184,29 @@ $defaultCodAmount = $isCod ? number_format($totalWithTax, 2, '.', '') : '0';
|
|||||||
$aSvcName = trim((string) ($aSvc['name'] ?? ''));
|
$aSvcName = trim((string) ($aSvc['name'] ?? ''));
|
||||||
$aSvcCarrierCode = trim((string) ($aSvc['carrier_code'] ?? ''));
|
$aSvcCarrierCode = trim((string) ($aSvc['carrier_code'] ?? ''));
|
||||||
$aSvcSelected = $mappedCarrier === 'apaczka' && $mappedMethodId === $aSvcId;
|
$aSvcSelected = $mappedCarrier === 'apaczka' && $mappedMethodId === $aSvcId;
|
||||||
|
$aSvcSupplier = strtoupper(trim((string) ($aSvc['supplier'] ?? '')));
|
||||||
|
$aSvcDoorToPoint = (int) ($aSvc['door_to_point'] ?? 0) === 1;
|
||||||
|
$aSvcPointToPoint = (int) ($aSvc['point_to_point'] ?? 0) === 1;
|
||||||
|
$aSvcPaczkomat = $aSvcDoorToPoint || $aSvcPointToPoint;
|
||||||
?>
|
?>
|
||||||
<option
|
<option
|
||||||
value="<?= $e($aSvcId) ?>"
|
value="<?= $e($aSvcId) ?>"
|
||||||
data-carrier-id="<?= $e($aSvcCarrierCode) ?>"
|
data-carrier-id="<?= $e($aSvcCarrierCode) ?>"
|
||||||
|
data-supplier="<?= $e($aSvcSupplier) ?>"
|
||||||
|
data-paczkomat="<?= $aSvcPaczkomat ? '1' : '0' ?>"
|
||||||
<?= $aSvcSelected ? 'selected' : '' ?>>
|
<?= $aSvcSelected ? 'selected' : '' ?>>
|
||||||
<?= $e($aSvcName !== '' ? $aSvcName : ('ID ' . $aSvcId)) ?>
|
<?= $e($aSvcName !== '' ? $aSvcName : ('ID ' . $aSvcId)) ?>
|
||||||
</option>
|
</option>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</select>
|
</select>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
<div id="shipment-apaczka-weekend-wrap" class="mt-2" style="display:none">
|
||||||
|
<label class="checkbox-inline">
|
||||||
|
<input type="checkbox" name="weekend_delivery" id="shipment-apaczka-weekend" value="1">
|
||||||
|
Dostawa w weekend (sobota)
|
||||||
|
</label>
|
||||||
|
<div class="muted" style="font-size:12px">Dostepne dla paczkomatow InPost. Etykiety mozna generowac od czwartku 20:00 do piatku 18:00.</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="shipment-empty-panel" class="muted" style="<?= $preselectedCarrier !== '' ? 'display:none' : '' ?>">Wybierz przewoznika</div>
|
<div id="shipment-empty-panel" class="muted" style="<?= $preselectedCarrier !== '' ? 'display:none' : '' ?>">Wybierz przewoznika</div>
|
||||||
@@ -601,6 +614,21 @@ $defaultCodAmount = $isCod ? number_format($totalWithTax, 2, '.', '') : '0';
|
|||||||
if (providerInput) providerInput.value = carrier === 'apaczka' ? 'apaczka' : 'allegro_wza';
|
if (providerInput) providerInput.value = carrier === 'apaczka' ? 'apaczka' : 'allegro_wza';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var weekendWrap = document.getElementById('shipment-apaczka-weekend-wrap');
|
||||||
|
var weekendInput = document.getElementById('shipment-apaczka-weekend');
|
||||||
|
function toggleWeekendOption() {
|
||||||
|
if (!weekendWrap || !weekendInput) return;
|
||||||
|
var carrierActive = carrierSelect ? carrierSelect.value === 'apaczka' : false;
|
||||||
|
var opt = apaczkaSelect ? apaczkaSelect.options[apaczkaSelect.selectedIndex] : null;
|
||||||
|
var supplier = (opt && opt.getAttribute('data-supplier')) || '';
|
||||||
|
var paczkomat = (opt && opt.getAttribute('data-paczkomat')) === '1';
|
||||||
|
var visible = carrierActive && supplier === 'INPOST' && paczkomat;
|
||||||
|
weekendWrap.style.display = visible ? '' : 'none';
|
||||||
|
if (!visible) {
|
||||||
|
weekendInput.checked = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
carrierSelect.addEventListener('change', function () {
|
carrierSelect.addEventListener('change', function () {
|
||||||
clearHiddenFields();
|
clearHiddenFields();
|
||||||
if (searchInput) searchInput.value = '';
|
if (searchInput) searchInput.value = '';
|
||||||
@@ -614,6 +642,7 @@ $defaultCodAmount = $isCod ? number_format($totalWithTax, 2, '.', '') : '0';
|
|||||||
}
|
}
|
||||||
allegroOpts.forEach(function (o) { o.classList.remove('is-selected'); });
|
allegroOpts.forEach(function (o) { o.classList.remove('is-selected'); });
|
||||||
showPanel(carrierSelect.value);
|
showPanel(carrierSelect.value);
|
||||||
|
toggleWeekendOption();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (inpostSelect) {
|
if (inpostSelect) {
|
||||||
@@ -639,10 +668,12 @@ $defaultCodAmount = $isCod ? number_format($totalWithTax, 2, '.', '') : '0';
|
|||||||
if (providerInput) providerInput.value = 'apaczka';
|
if (providerInput) providerInput.value = 'apaczka';
|
||||||
}
|
}
|
||||||
apaczkaSelect.addEventListener('change', syncApaczkaFields);
|
apaczkaSelect.addEventListener('change', syncApaczkaFields);
|
||||||
|
apaczkaSelect.addEventListener('change', toggleWeekendOption);
|
||||||
if (carrierSelect.value === 'apaczka' && apaczkaSelect.value !== '') {
|
if (carrierSelect.value === 'apaczka' && apaczkaSelect.value !== '') {
|
||||||
syncApaczkaFields();
|
syncApaczkaFields();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
toggleWeekendOption();
|
||||||
|
|
||||||
if (wrapper && searchInput && dropdown) {
|
if (wrapper && searchInput && dropdown) {
|
||||||
var isAllegroOpen = false;
|
var isAllegroOpen = false;
|
||||||
|
|||||||
@@ -15,6 +15,15 @@ final class ApaczkaShipmentService implements ShipmentProviderInterface
|
|||||||
{
|
{
|
||||||
private const PICKUP_DATE_RETRY_DAYS = 7;
|
private const PICKUP_DATE_RETRY_DAYS = 7;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mapowanie pol formularza na klucze opcji API Apaczki (option[]).
|
||||||
|
* Wartosci kluczy to identyfikatory z service_structure.response.options.
|
||||||
|
* - 19 = dostawa w sobote (InPost Paczka w Weekend)
|
||||||
|
*/
|
||||||
|
private const OPTION_KEYS = [
|
||||||
|
'weekend_delivery' => 19,
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array<string, array{street:string,postal_code:string,city:string}>
|
* @var array<string, array{street:string,postal_code:string,city:string}>
|
||||||
*/
|
*/
|
||||||
@@ -100,6 +109,10 @@ final class ApaczkaShipmentService implements ShipmentProviderInterface
|
|||||||
'content' => 'orderPRO ' . ($sourceOrderId !== '' ? $sourceOrderId : (string) $orderId),
|
'content' => 'orderPRO ' . ($sourceOrderId !== '' ? $sourceOrderId : (string) $orderId),
|
||||||
'comment' => 'orderPRO ' . ($sourceOrderId !== '' ? $sourceOrderId : (string) $orderId),
|
'comment' => 'orderPRO ' . ($sourceOrderId !== '' ? $sourceOrderId : (string) $orderId),
|
||||||
];
|
];
|
||||||
|
$options = $this->buildOptionsPayload($formData);
|
||||||
|
if ($options !== []) {
|
||||||
|
$apiPayload['option'] = $options;
|
||||||
|
}
|
||||||
$pickup = $this->buildPickupPayload($serviceDefinition, $senderPointId, $formData);
|
$pickup = $this->buildPickupPayload($serviceDefinition, $senderPointId, $formData);
|
||||||
if ($pickup !== []) {
|
if ($pickup !== []) {
|
||||||
$apiPayload['pickup'] = $pickup;
|
$apiPayload['pickup'] = $pickup;
|
||||||
@@ -818,6 +831,24 @@ final class ApaczkaShipmentService implements ShipmentProviderInterface
|
|||||||
return 'COURIER';
|
return 'COURIER';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string, mixed> $formData
|
||||||
|
* @return array<int, int>
|
||||||
|
*/
|
||||||
|
private function buildOptionsPayload(array $formData): array
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
foreach (self::OPTION_KEYS as $formField => $apiOptionId) {
|
||||||
|
$value = $formData[$formField] ?? null;
|
||||||
|
$isTruthy = filter_var($value, FILTER_VALIDATE_BOOL, FILTER_NULL_ON_FAILURE);
|
||||||
|
if ($isTruthy === true) {
|
||||||
|
$result[$apiOptionId] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<string, mixed>|null $serviceDefinition
|
* @param array<string, mixed>|null $serviceDefinition
|
||||||
* @param array<string, mixed> $formData
|
* @param array<string, mixed> $formData
|
||||||
|
|||||||
@@ -204,6 +204,7 @@ final class ShipmentController
|
|||||||
'receiver_email' => (string) $request->input('receiver_email', ''),
|
'receiver_email' => (string) $request->input('receiver_email', ''),
|
||||||
'receiver_point_id' => (string) $request->input('receiver_point_id', ''),
|
'receiver_point_id' => (string) $request->input('receiver_point_id', ''),
|
||||||
'sender_point_id' => (string) $request->input('sender_point_id', ''),
|
'sender_point_id' => (string) $request->input('sender_point_id', ''),
|
||||||
|
'weekend_delivery' => (string) $request->input('weekend_delivery', ''),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$packageId = (int) ($result['package_id'] ?? 0);
|
$packageId = (int) ($result['package_id'] ?? 0);
|
||||||
|
|||||||
@@ -43,6 +43,20 @@ final class ApaczkaShipmentServiceTest extends TestCase
|
|||||||
$method->invoke($this->service, $street);
|
$method->invoke($this->service, $street);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string, mixed> $formData
|
||||||
|
* @return array<int, int>
|
||||||
|
*/
|
||||||
|
private function invokeBuildOptions(array $formData): array
|
||||||
|
{
|
||||||
|
$method = new ReflectionMethod(ApaczkaShipmentService::class, 'buildOptionsPayload');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
/** @var array<int, int> $result */
|
||||||
|
$result = $method->invoke($this->service, $formData);
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
public function testTruncateStreetForPointShortensLongValue(): void
|
public function testTruncateStreetForPointShortensLongValue(): void
|
||||||
{
|
{
|
||||||
$input = 'Punkt odbioru POP-XYZ123 przy al. Jerozolimskich 55A/12';
|
$input = 'Punkt odbioru POP-XYZ123 przy al. Jerozolimskich 55A/12';
|
||||||
@@ -107,4 +121,19 @@ final class ApaczkaShipmentServiceTest extends TestCase
|
|||||||
|
|
||||||
$this->invokeAssert('Ul. Generała Pilota Józefa Kowalskiego 6/1');
|
$this->invokeAssert('Ul. Generała Pilota Józefa Kowalskiego 6/1');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testBuildOptionsPayloadWeekendEnabled(): void
|
||||||
|
{
|
||||||
|
$this->assertSame([19 => 1], $this->invokeBuildOptions(['weekend_delivery' => '1']));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBuildOptionsPayloadWeekendDisabled(): void
|
||||||
|
{
|
||||||
|
$this->assertSame([], $this->invokeBuildOptions(['weekend_delivery' => '0']));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBuildOptionsPayloadEmptyForm(): void
|
||||||
|
{
|
||||||
|
$this->assertSame([], $this->invokeBuildOptions([]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user