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>
211 lines
11 KiB
Markdown
211 lines
11 KiB
Markdown
---
|
|
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>
|