fix(142): preselect polkurier shipment mapping

Phase 142 complete:

- preselect Polkurier carrier and service in shipment prepare

- add render regression test for Polkurier mapping

- document hotfix and verification gaps
This commit is contained in:
2026-05-18 10:35:47 +02:00
parent ca0b37a86f
commit 2f89901ebf
10 changed files with 515 additions and 21 deletions

View File

@@ -13,8 +13,8 @@ Sprzedawca moĹĽe obsĹugiwać zamĂłwienia ze wszystkich kanaĹĂłw
| Attribute | Value | | Attribute | Value |
|-----------|-------| |-----------|-------|
| Version | 3.9.0-dev | | Version | 3.9.0-dev |
| Status | v3.10 Integrations UI Polish complete - Phase 141 closed | | Status | v3.11 Polkurier shipment prepare hotfix complete - Phase 142 closed |
| Last Updated | 2026-05-18 (Phase 141 unified) | | Last Updated | 2026-05-18 (Phase 142 unified) |
## Requirements ## Requirements
@@ -141,6 +141,7 @@ Sprzedawca moĹĽe obsĹugiwać zamĂłwienia ze wszystkich kanaĹĂłw
- [x] Sonar Critical/Major Cleanup: Phase 139 odswiezyla baseline Sonar i zmniejszyla OPEN BLOCKER/CRITICAL/MAJOR z 648 do 495 przez delivery-status/statistics cleanup, typowane wyjatki oraz szeroka migracje alert include/import patterns — Phase 139 - [x] Sonar Critical/Major Cleanup: Phase 139 odswiezyla baseline Sonar i zmniejszyla OPEN BLOCKER/CRITICAL/MAJOR z 648 do 495 przez delivery-status/statistics cleanup, typowane wyjatki oraz szeroka migracje alert include/import patterns — Phase 139
- [x] shopPRO Polkurier Delivery Mapping: zakladka `Dostawy` integracji shopPRO pozwala mapowac forme dostawy na Polkurier, laduje uslugi z `PolkurierShipmentService::getDeliveryServices()` i zapisuje `provider='polkurier'` w `carrier_delivery_method_mappings` bez migracji DB — Phase 140 - [x] shopPRO Polkurier Delivery Mapping: zakladka `Dostawy` integracji shopPRO pozwala mapowac forme dostawy na Polkurier, laduje uslugi z `PolkurierShipmentService::getDeliveryServices()` i zapisuje `provider='polkurier'` w `carrier_delivery_method_mappings` bez migracji DB — Phase 140
- [x] Integrations Hub Grouped Sections: `/settings/integrations` pokazuje lekkie sekcje dla marketplace, kurierow i pozostalych integracji, bez starego naglowka/opisu wspolnego panelu — Phase 141 - [x] Integrations Hub Grouped Sections: `/settings/integrations` pokazuje lekkie sekcje dla marketplace, kurierow i pozostalych integracji, bez starego naglowka/opisu wspolnego panelu — Phase 141
- [x] Polkurier Shipment Prepare Prefill: `/orders/{id}/shipment/prepare` rozpoznaje mapowania shopPRO z `provider='polkurier'`, preselectuje przewoznika i usluge oraz nie fallbackuje do Allegro — Phase 142
- [x] Integracja polkurier.pl (fundament): pojedyncza globalna konfiguracja w `/settings/integrations/polkurier`, szyfrowany Token API + login, karta w hubie integracji obok Apaczki i realny test polaczenia przez `apimetod=test_auth_api` zweryfikowany na zywym koncie operatora; `ShipmentProviderRegistry` netkniety — `PolkurierShipmentService/TrackingService` w kolejnych fazach — Phase 127 - [x] Integracja polkurier.pl (fundament): pojedyncza globalna konfiguracja w `/settings/integrations/polkurier`, szyfrowany Token API + login, karta w hubie integracji obok Apaczki i realny test polaczenia przez `apimetod=test_auth_api` zweryfikowany na zywym koncie operatora; `ShipmentProviderRegistry` netkniety — `PolkurierShipmentService/TrackingService` w kolejnych fazach — Phase 127
- [x] polkurier ShipmentService + TrackingService + UI prepare panel: pelen kontrakt API (createShipment/getLabel/getStatus/cancelOrder/getAvailableCarriers), `PolkurierShipmentService` implementujacy `ShipmentProviderInterface` z normalizacja shipmenttype (lowercase) i splitem ulicy na street/housenumber/flatnumber, `PolkurierTrackingService` mapujacy statusy O/P/A/WP/D/Z/W na znormalizowane, panel "polkurier" w `prepare.php` z dynamiczna lista uslug z `available_carriers`, seed migracja `delivery_status_mappings(provider='polkurier')` z 7 wpisami z PDF v1.11; live test na #114/#115 zakonczony sukcesem po 4 iteracjach (ReferenceError → uppercase shipmenttype → orderno parsing → A4/A6); rozmiar etykiety sterowany w panelu klienta polkurier.pl (Ustawienia konta → Preferencje etykiet), NIE przez API — Phase 128 - [x] polkurier ShipmentService + TrackingService + UI prepare panel: pelen kontrakt API (createShipment/getLabel/getStatus/cancelOrder/getAvailableCarriers), `PolkurierShipmentService` implementujacy `ShipmentProviderInterface` z normalizacja shipmenttype (lowercase) i splitem ulicy na street/housenumber/flatnumber, `PolkurierTrackingService` mapujacy statusy O/P/A/WP/D/Z/W na znormalizowane, panel "polkurier" w `prepare.php` z dynamiczna lista uslug z `available_carriers`, seed migracja `delivery_status_mappings(provider='polkurier')` z 7 wpisami z PDF v1.11; live test na #114/#115 zakonczony sukcesem po 4 iteracjach (ReferenceError → uppercase shipmenttype → orderno parsing → A4/A6); rozmiar etykiety sterowany w panelu klienta polkurier.pl (Ustawienia konta → Preferencje etykiet), NIE przez API — Phase 128
- [x] Order User Notes module (Phase 129): pelen CRUD notatek autorskich operatora per zamowienie. Reuse `order_notes` przez nowy `note_type='user'` z `user_id` (FK→users SET NULL) + `author_name` (snapshot) + indeks `idx_order_notes_type_order`. `OrderNotesService` z autoryzacja DB-level (`WHERE user_id = :user_id`, rowCount=0 ⇒ 403). Sekcja `#notes` w "Wiadomosci i zalaczniki" w `/orders/{id}` z inline edit form + delete przez `OrderProAlerts.confirm`. Badge `[N]` (indigo neutralny) przy nr zamowienia na `/orders/list` (subquery `user_notes_count` w paginate). Brak admin override (brak systemu rol w aplikacji) — edit/delete tylko dla autora — Phase 129 - [x] Order User Notes module (Phase 129): pelen CRUD notatek autorskich operatora per zamowienie. Reuse `order_notes` przez nowy `note_type='user'` z `user_id` (FK→users SET NULL) + `author_name` (snapshot) + indeks `idx_order_notes_type_order`. `OrderNotesService` z autoryzacja DB-level (`WHERE user_id = :user_id`, rowCount=0 ⇒ 403). Sekcja `#notes` w "Wiadomosci i zalaczniki" w `/orders/{id}` z inline edit form + delete przez `OrderProAlerts.confirm`. Badge `[N]` (indigo neutralny) przy nr zamowienia na `/orders/list` (subquery `user_notes_count` w paginate). Brak admin override (brak systemu rol w aplikacji) — edit/delete tylko dla autora — Phase 129
@@ -323,6 +324,6 @@ Quick Reference:
--- ---
*PROJECT.md — Updated when requirements or context change* *PROJECT.md — Updated when requirements or context change*
*Last updated: 2026-05-18 after Phase 141 closure* *Last updated: 2026-05-18 after Phase 142 closure*

View File

@@ -6,6 +6,23 @@ orderPRO to narzedzie do wielokanalowego zarzadzania sprzedaza. Projekt przechod
## Current Milestone ## Current Milestone
v3.11 Polkurier Shipment Prepare Hotfix - Complete
Pilny hotfix po Phase 140: mapowanie shopPRO -> Polkurier zapisuje sie poprawnie, ale formularz `/orders/{id}/shipment/prepare` nie podstawia providera i uslugi Polkuriera.
Progress: 1 of 1 phases complete (100%).
| Phase | Name | Plans | Status |
|-------|------|-------|--------|
| 142 | Polkurier Shipment Prepare Prefill | 1/1 | Complete (2026-05-18; PHPUnit/Sonar/manual live smoke follow-up pending) |
### Phase 142: Polkurier Shipment Prepare Prefill
Focus: Naprawic preselect w formularzu przygotowania przesylki, aby `carrier_delivery_method_mappings.provider='polkurier'` wybieral przewoznika Polkurier, zaznaczal zapisana usluge i ustawial hidden fields wymagane przez `PolkurierShipmentService`.
Plans: 142-01 (complete; `.paul/phases/142-polkurier-shipment-prepare-prefill/142-01-SUMMARY.md`)
## Previous Milestone
v3.10 Integrations UI Polish - Complete v3.10 Integrations UI Polish - Complete
Maly milestone porzadkujacy ekran `/settings/integrations`, aby rosnaca liczba integracji byla latwiejsza do skanowania bez zmiany backendowych kontraktow providerow. Maly milestone porzadkujacy ekran `/settings/integrations`, aby rosnaca liczba integracji byla latwiejsza do skanowania bez zmiany backendowych kontraktow providerow.
@@ -21,7 +38,7 @@ Progress: 1 of 1 phases complete (100%).
Focus: Podzielic `/settings/integrations` na lekkie sekcje/kafelki: marketplace (Allegro Sandbox, Allegro Production, shopPRO, Erli), kurierzy (InPost, Apaczka, polkurier.pl) i pozostale (Fakturownia, HostedSMS, SMSPLANET), usuwajac niepotrzebny naglowek/opis "Wspolny panel konfiguracji wszystkich providerow." Focus: Podzielic `/settings/integrations` na lekkie sekcje/kafelki: marketplace (Allegro Sandbox, Allegro Production, shopPRO, Erli), kurierzy (InPost, Apaczka, polkurier.pl) i pozostale (Fakturownia, HostedSMS, SMSPLANET), usuwajac niepotrzebny naglowek/opis "Wspolny panel konfiguracji wszystkich providerow."
Plans: 141-01 (complete; `.paul/phases/141-integrations-hub-grouped-sections/141-01-SUMMARY.md`) Plans: 141-01 (complete; `.paul/phases/141-integrations-hub-grouped-sections/141-01-SUMMARY.md`)
## Previous Milestone ## Earlier Milestone
v3.9 Stabilizacja i splata dlugu technicznego - Complete v3.9 Stabilizacja i splata dlugu technicznego - Complete

View File

@@ -5,19 +5,19 @@
See: .paul/PROJECT.md (updated 2026-05-18) See: .paul/PROJECT.md (updated 2026-05-18)
**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:** v3.10 Integrations UI Polish complete; Phase 141 Integrations Hub Grouped Sections unified. **Current focus:** v3.11 Polkurier Shipment Prepare Hotfix complete; Phase 142 unified.
## Current Position ## Current Position
Milestone: v3.10 Integrations UI Polish Milestone: v3.11 Polkurier Shipment Prepare Hotfix
Phase: 141 of 141 (Integrations Hub Grouped Sections) - Complete Phase: 142 of 142 (Polkurier Shipment Prepare Prefill) - Complete
Plan: 141-01 complete Plan: 142-01 complete
Status: Milestone complete, ready for next milestone or release decision Status: Milestone complete, ready for next milestone or release decision
Last activity: 2026-05-18 00:00 - Unified .paul/phases/141-integrations-hub-grouped-sections/141-01-PLAN.md Last activity: 2026-05-18 10:34 - Unified .paul/phases/142-polkurier-shipment-prepare-prefill/142-01-PLAN.md
Progress: Progress:
- Milestone v3.10: [##########] 100% (1 of 1 phases complete) - Milestone v3.11: [##########] 100% (1 of 1 phases complete)
- Phase 141: [##########] 100% (complete) - Phase 142: [##########] 100% (complete)
## Loop Position ## Loop Position
@@ -29,19 +29,19 @@ PLAN -> APPLY -> UNIFY
## Session Continuity ## Session Continuity
Last session: 2026-05-18 00:00 Last session: 2026-05-18 10:34
Stopped at: Phase 141 complete; v3.10 milestone complete Stopped at: Phase 142 complete; v3.11 milestone complete
Next action: Run $paul-complete-milestone or start next milestone planning Next action: Run $paul-complete-milestone or start next milestone planning
Resume file: .paul/phases/141-integrations-hub-grouped-sections/141-01-SUMMARY.md Resume file: .paul/phases/142-polkurier-shipment-prepare-prefill/142-01-SUMMARY.md
## Pending parallel work ## Pending parallel work
- None — Phase 118, 121, 122 wszystkie zacommitowane (8f14851, 360eef1). - None — Phase 118, 121, 122 wszystkie zacommitowane (8f14851, 360eef1).
## Git State ## Git State
Last commit: HEAD feat(141): group integrations hub sections Last commit: HEAD fix(142): preselect polkurier shipment mapping
Last phase commit: HEAD feat(141): group integrations hub sections Last phase commit: HEAD fix(142): preselect polkurier shipment mapping
Previous: feat(140): shoppro polkurier delivery mapping Previous: feat(141): group integrations hub sections
Branch: main Branch: main
### Skill Audit (Phase 139) ### Skill Audit (Phase 139)
@@ -63,6 +63,12 @@ Branch: main
|----------|---------|-------| |----------|---------|-------|
| `sonar-scanner` | gap documented | Attempted after APPLY with `sonar-scanner --version`; CLI is not available in PATH. | | `sonar-scanner` | gap documented | Attempted after APPLY with `sonar-scanner --version`; CLI is not available in PATH. |
### Skill Audit (Phase 142)
| Expected | Invoked | Notes |
|----------|---------|-------|
| `sonar-scanner` | gap documented | Attempted after APPLY with `sonar-scanner --version`; CLI is not available in PATH. |
### Skill Audit (Phase 129) ### Skill Audit (Phase 129)
| Expected | Invoked | Notes | | Expected | Invoked | Notes |
@@ -162,6 +168,9 @@ Branch: main
- Phase 140 follow-up: uruchom SonarQube scan po przywroceniu `sonar-scanner` w PATH albo ponownym pobraniu oficjalnego scanner fallback. - Phase 140 follow-up: uruchom SonarQube scan po przywroceniu `sonar-scanner` w PATH albo ponownym pobraniu oficjalnego scanner fallback.
- Phase 141 follow-up: manual smoke `/settings/integrations` -> potwierdz sekcje marketplace/kurierzy/pozostale, osobne wiersze Allegro Sandbox/Production i poprawne linki Ustawienia. - Phase 141 follow-up: manual smoke `/settings/integrations` -> potwierdz sekcje marketplace/kurierzy/pozostale, osobne wiersze Allegro Sandbox/Production i poprawne linki Ustawienia.
- Phase 141 follow-up: uruchom SonarQube scan po przywroceniu `sonar-scanner` w PATH albo ponownym pobraniu oficjalnego scanner fallback. - Phase 141 follow-up: uruchom SonarQube scan po przywroceniu `sonar-scanner` w PATH albo ponownym pobraniu oficjalnego scanner fallback.
- Phase 142 follow-up: manual smoke `/orders/1164/shipment/prepare` -> potwierdz, ze mapowanie shopPRO -> Polkurier preselectuje przewoznika i usluge.
- Phase 142 follow-up: `composer install` / przywroc `vendor/`, potem uruchom `vendor/bin/phpunit tests/Unit/ShipmentPreparePolkurierMappingTest.php`.
- Phase 142 follow-up: uruchom SonarQube scan po przywroceniu `sonar-scanner` w PATH albo ponownym pobraniu oficjalnego scanner fallback.
- Phase 138 manual smoke: test a real SMTP SSL/STARTTLS mailbox in strict mode; test invalid and valid e-mail/SMS template saves in UI. - Phase 138 manual smoke: test a real SMTP SSL/STARTTLS mailbox in strict mode; test invalid and valid e-mail/SMS template saves in UI.
- Manualne testy AC-1..AC-7 dla Phase 112 na zywej bazie (XAMPP online). - Manualne testy AC-1..AC-7 dla Phase 112 na zywej bazie (XAMPP online).
- Backfill zamowienia #882 - operator robi recznie po wdrozeniu (poza zakresem planu). - Backfill zamowienia #882 - operator robi recznie po wdrozeniu (poza zakresem planu).

View File

@@ -12,6 +12,10 @@
- Zachowano osobne wiersze Allegro Sandbox i Allegro Production oraz dotychczasowe linki konfiguracji providerow. - Zachowano osobne wiersze Allegro Sandbox i Allegro Production oraz dotychczasowe linki konfiguracji providerow.
- Dodano kompaktowe style SCSS dla huba integracji i przebudowano `public/assets/css/app.css`. - Dodano kompaktowe style SCSS dla huba integracji i przebudowano `public/assets/css/app.css`.
- Gap: manualny smoke UI i SonarQube scan Phase 141 pozostaja do wykonania po uruchomieniu app/DB i przywroceniu `sonar-scanner`. - Gap: manualny smoke UI i SonarQube scan Phase 141 pozostaja do wykonania po uruchomieniu app/DB i przywroceniu `sonar-scanner`.
- [Phase 142, Plan 01] Naprawiono preselect Polkuriera w `/orders/{id}/shipment/prepare` dla mapowan shopPRO -> Polkurier.
- Formularz przygotowania przesylki rozpoznaje `provider='polkurier'`, pokazuje panel Polkuriera i zaznacza zapisana usluge.
- Dodano test regresyjny renderowania widoku dla mapowania Polkuriera.
- Gap: PHPUnit i SonarQube scan Phase 142 pozostaja do wykonania po przywroceniu `vendor/` i `sonar-scanner`.
## Zmienione pliki ## Zmienione pliki
@@ -33,3 +37,7 @@
- `src/Modules/Settings/ShopproIntegrationsController.php` - `src/Modules/Settings/ShopproIntegrationsController.php`
- `.paul/phases/141-integrations-hub-grouped-sections/141-01-PLAN.md` - `.paul/phases/141-integrations-hub-grouped-sections/141-01-PLAN.md`
- `.paul/phases/141-integrations-hub-grouped-sections/141-01-SUMMARY.md` - `.paul/phases/141-integrations-hub-grouped-sections/141-01-SUMMARY.md`
- `.paul/phases/142-polkurier-shipment-prepare-prefill/142-01-PLAN.md`
- `.paul/phases/142-polkurier-shipment-prepare-prefill/142-01-SUMMARY.md`
- `resources/views/shipments/prepare.php`
- `tests/Unit/ShipmentPreparePolkurierMappingTest.php`

View File

@@ -0,0 +1,174 @@
---
phase: 142-polkurier-shipment-prepare-prefill
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
- resources/views/shipments/prepare.php
- tests/Unit/ShipmentPreparePolkurierMappingTest.php
- DOCS/ARCHITECTURE.md
- DOCS/TECH_CHANGELOG.md
autonomous: true
delegation: off
---
<objective>
## Goal
Naprawic przygotowanie przesylki dla zamowien shopPRO z mapowaniem na Polkurier, tak aby formularz automatycznie wybieral przewoznika Polkurier i zapisana usluge.
## Purpose
Phase 140 dodala zapis mapowan shopPRO -> Polkurier, ale formularz `/orders/{id}/shipment/prepare` nadal traktuje nieznanego providera jako Allegro. Operator musi recznie poprawiac dane mimo istniejacego mapowania.
## Output
Poprawiony widok formularza przygotowania przesylki, test regresyjny renderowania preselectu oraz aktualizacja dokumentacji technicznej.
</objective>
<context>
<clarifications>
- **Brak pytan** - Problem jest jednoznaczny po analizie kodu: `resources/views/shipments/prepare.php` nie rozpoznaje `provider='polkurier'` w `match`, nie ustawia `selected` dla uslugi Polkuriera i opis mapowania pokazuje fallback "Allegro".
-> Odpowiedz: No clarifications needed - proceeding.
</clarifications>
## Project Context
@AGENTS.md
@.paul/PROJECT.md
@.paul/ROADMAP.md
@.paul/STATE.md
@DOCS/ARCHITECTURE.md
@DOCS/DB_SCHEMA.md
## Prior Work
@.paul/phases/140-shoppro-polkurier-delivery-mapping/140-01-PLAN.md
@.paul/phases/140-shoppro-polkurier-delivery-mapping/140-01-SUMMARY.md
## Source Files
@src/Modules/Shipments/ShipmentController.php
@src/Modules/Settings/CarrierDeliveryMethodMappingRepository.php
@src/Modules/Settings/ShopproIntegrationsController.php
@resources/views/shipments/prepare.php
@resources/views/settings/shoppro.php
</context>
<skills>
## Required Skills (from SPECIAL-FLOWS.md)
| Skill | Priority | When to Invoke | Loaded? |
|-------|----------|----------------|---------|
| `sonar-scanner` | required | Po APPLY, przed UNIFY | ○ |
</skills>
<acceptance_criteria>
## AC-1: Polkurier Jest Preselectowany
```gherkin
Given zamowienie shopPRO ma `external_carrier_id` zgodne z rekordem `carrier_delivery_method_mappings`
And rekord mapowania ma `provider='polkurier'` i `provider_service_id`
When operator otwiera `/orders/{id}/shipment/prepare`
Then select przewoznika ma wybrane `polkurier`
And panel uslug Polkuriera jest widoczny
```
## AC-2: Usluga Polkuriera Jest Podstawiona Do Formularza
```gherkin
Given lista uslug Polkuriera zawiera usluge o id rownym `provider_service_id` z mapowania
When formularz przygotowania przesylki sie laduje
Then ta usluga jest zaznaczona
And ukryte pola `delivery_method_id`, `service_code`, `provider_code` synchronizuja sie na `polkurier`
```
## AC-3: Czytelny Opis Mapowania
```gherkin
Given mapowanie wskazuje provider Polkurier
When formularz pokazuje "Metoda z zamowienia"
Then opis pokazuje "Polkurier: <nazwa uslugi>" zamiast fallbacku "Allegro"
```
## AC-4: Brak Zmian Schematu
```gherkin
Given naprawa dotyczy tylko odczytu istniejacego mapowania
When plan zostanie wdrozony
Then nie powstaje migracja ani zmiana struktury tabel
```
</acceptance_criteria>
<tasks>
<task type="auto">
<name>Task 1: Poprawic rozpoznawanie Polkuriera w formularzu prepare</name>
<files>resources/views/shipments/prepare.php</files>
<action>
- Dodaj `polkurier` do mapowania providera na carrier w poczatkowym bloku PHP.
- Ustaw `deliveryMethodId` dla Polkuriera z `provider_service_id`, analogicznie do InPost/Apaczka.
- Popraw etykiete diagnostyczna mapowania, aby provider `polkurier` pokazywal "Polkurier", a nie fallback "Allegro".
- W opcjach selecta Polkuriera dodaj `selected`, gdy `mappedCarrier === 'polkurier'` i id uslugi zgadza sie z `provider_service_id`.
- Zachowaj obecny kontrakt pól hidden i JS: `delivery_method_id`, `service_code`, `provider_code`.
</action>
<verify>C:\xampp\php\php.exe -l resources/views/shipments/prepare.php</verify>
<done>AC-1, AC-2 i AC-3 spelnione dla mapowania `provider='polkurier'`.</done>
</task>
<task type="auto">
<name>Task 2: Dodac test regresyjny renderowania mapowania Polkuriera</name>
<files>tests/Unit/ShipmentPreparePolkurierMappingTest.php</files>
<action>
- Dodaj maly test jednostkowy renderujacy `resources/views/shipments/prepare.php` z minimalnymi danymi: `deliveryMapping.provider='polkurier'`, `provider_service_id` i lista `polkurierServices`.
- Assert: option przewoznika `value="polkurier"` ma `selected`, panel Polkuriera nie ma `display:none`, usluga z mapowania ma `selected`, hidden `provider_code` startuje jako `polkurier`, a opis zawiera "Polkurier".
- Test ma uzywac prostych closure dla `$e`, `$t` i `$component`, bez uruchamiania aplikacji ani DB.
</action>
<verify>C:\xampp\php\php.exe -l tests/Unit/ShipmentPreparePolkurierMappingTest.php; vendor/bin/phpunit tests/Unit/ShipmentPreparePolkurierMappingTest.php jezeli vendor/bin/phpunit jest dostepny</verify>
<done>AC-1, AC-2 i AC-3 zabezpieczone testem regresyjnym albo jasno udokumentowany gap srodowiskowy PHPUnit.</done>
</task>
<task type="auto">
<name>Task 3: Zaktualizowac dokumentacje techniczna</name>
<files>DOCS/ARCHITECTURE.md, DOCS/TECH_CHANGELOG.md</files>
<action>
- W `DOCS/ARCHITECTURE.md` doprecyzuj, ze prepare flow obsluguje `provider='polkurier'` bez fallbacku na Allegro.
- W `DOCS/TECH_CHANGELOG.md` dodaj wpis 2026-05-18 opisujacy hotfix prefillu Polkuriera.
- Nie aktualizuj `DOCS/DB_SCHEMA.md`, bo plan nie zmienia bazy danych.
</action>
<verify>rg -n "Polkurier|polkurier|2026-05-18" DOCS/ARCHITECTURE.md DOCS/TECH_CHANGELOG.md</verify>
<done>AC-4 spelnione i dokumentacja opisuje realny kontrakt formularza.</done>
</task>
</tasks>
<boundaries>
## DO NOT CHANGE
- `database/migrations/*` - brak zmiany schematu.
- `src/Modules/Settings/ShopproIntegrationsController.php` - zapis mapowan zostaje poza zakresem, chyba ze test dowiedzie blednego payloadu.
- `src/Modules/Shipments/PolkurierShipmentService.php` - tworzenie paczki/API Polkuriera nie jest czescia tej naprawy.
- `resources/views/settings/shoppro.php` - UI mapowan bylo dodane w Phase 140; nie zmieniac bez nowego dowodu.
## SCOPE LIMITS
- Naprawa dotyczy prefillu formularza przygotowania przesylki, nie odkrywania nowych metod dostawy.
- Nie dodawac nowych providerow ani nowych pol w tabeli mapowan.
- Manualny smoke na produkcyjnym URL moze zostac wykonany przez operatora po wdrozeniu; plan ma dostarczyc kod i test regresyjny lokalnie.
</boundaries>
<verification>
Before declaring plan complete:
- [ ] `C:\xampp\php\php.exe -l resources/views/shipments/prepare.php`
- [ ] `C:\xampp\php\php.exe -l tests/Unit/ShipmentPreparePolkurierMappingTest.php`
- [ ] `vendor/bin/phpunit tests/Unit/ShipmentPreparePolkurierMappingTest.php` jezeli zaleznosci sa dostepne
- [ ] `rg -n "Polkurier|polkurier|2026-05-18" DOCS/ARCHITECTURE.md DOCS/TECH_CHANGELOG.md`
- [ ] `git diff --check`
- [ ] `sonar-scanner` jezeli CLI jest dostepny; w przeciwnym razie udokumentowac gap
</verification>
<success_criteria>
- Formularz prepare nie fallbackuje mapowania Polkuriera do Allegro.
- Zmapowana usluga Polkuriera jest widoczna i wybrana po zaladowaniu.
- Ukryte pola wysylane przy tworzeniu przesylki wskazuja Polkurier.
- Dokumentacja techniczna odzwierciedla naprawe.
- Brak migracji DB i brak zmian w runtime konfiguracji.
</success_criteria>
<output>
After completion, create `.paul/phases/142-polkurier-shipment-prepare-prefill/142-01-SUMMARY.md`
</output>

View File

@@ -0,0 +1,160 @@
---
phase: 142-polkurier-shipment-prepare-prefill
plan: 01
subsystem: shipments
tags: [shoppro, polkurier, delivery-mapping, shipment-prepare, regression-test]
requires:
- phase: 140-shoppro-polkurier-delivery-mapping
provides: shopPRO delivery mappings can store provider='polkurier'
provides:
- shipment prepare form preselects Polkurier from shopPRO delivery mappings
- regression coverage for Polkurier mapping render
affects: [shipments, shoppro, polkurier, carrier_delivery_method_mappings]
tech-stack:
added: []
patterns: [view render regression test for shipment prepare prefill]
key-files:
created:
- tests/Unit/ShipmentPreparePolkurierMappingTest.php
- .paul/phases/142-polkurier-shipment-prepare-prefill/142-01-SUMMARY.md
modified:
- resources/views/shipments/prepare.php
- DOCS/ARCHITECTURE.md
- DOCS/TECH_CHANGELOG.md
- .paul/PROJECT.md
- .paul/ROADMAP.md
- .paul/STATE.md
key-decisions:
- "Fix prepare prefill in the existing view; do not change mapping persistence or DB schema."
patterns-established:
- "Provider-specific prepare prefill must explicitly map local provider keys, including polkurier."
duration: 8min
started: 2026-05-18T10:28:00+02:00
completed: 2026-05-18T10:34:02+02:00
---
# Phase 142 Plan 01 Summary: Polkurier Shipment Prepare Prefill
shopPRO delivery mappings to Polkurier now preselect the Polkurier carrier, mapped service and hidden shipment fields in `/orders/{id}/shipment/prepare`.
## Performance
| Metric | Value |
|--------|-------|
| Duration | ~8 min |
| Started | 2026-05-18T10:28:00+02:00 |
| Completed | 2026-05-18T10:34:02+02:00 |
| Tasks | 3 completed |
| Files modified | 8 |
## Acceptance Criteria Results
| Criterion | Status | Notes |
|-----------|--------|-------|
| AC-1: Polkurier Jest Preselectowany | Pass | `provider='polkurier'` maps to carrier `polkurier`; render smoke confirmed selected carrier and visible panel. |
| AC-2: Usluga Polkuriera Jest Podstawiona Do Formularza | Pass | Polkurier option receives `selected`; render smoke confirmed mapped `DHL_TEST` service and provider hidden field. |
| AC-3: Czytelny Opis Mapowania | Pass | Mapping label now uses `Polkurier: <service name>` instead of Allegro fallback. |
| AC-4: Brak Zmian Schematu | Pass | No migrations or DB schema files changed. Existing `carrier_delivery_method_mappings` contract remains unchanged. |
## Accomplishments
- Fixed `resources/views/shipments/prepare.php` so Polkurier mappings are not treated as Allegro.
- Added `tests/Unit/ShipmentPreparePolkurierMappingTest.php` to cover the Polkurier render prefill case.
- Updated technical docs to reflect the real prepare-flow contract.
## Task Commits
Commits are created at phase transition rather than per task in this repository workflow.
| Task | Commit | Type | Description |
|------|--------|------|-------------|
| Task 1: Poprawic rozpoznawanie Polkuriera w formularzu prepare | phase commit | fix | Polkurier carrier/service preselect and mapping label fixed. |
| Task 2: Dodac test regresyjny renderowania mapowania Polkuriera | phase commit | test | View render regression test added. |
| Task 3: Zaktualizowac dokumentacje techniczna | phase commit | docs | Architecture and technical changelog updated. |
## Files Created/Modified
| File | Change | Purpose |
|------|--------|---------|
| `resources/views/shipments/prepare.php` | Modified | Recognizes `polkurier`, selects the mapped service and shows the correct provider label. |
| `tests/Unit/ShipmentPreparePolkurierMappingTest.php` | Created | Regression test for Polkurier mapping render. |
| `DOCS/ARCHITECTURE.md` | Modified | Documents that prepare flow preselects Polkurier without Allegro fallback. |
| `DOCS/TECH_CHANGELOG.md` | Modified | Records Phase 142 hotfix. |
| `.paul/phases/142-polkurier-shipment-prepare-prefill/142-01-PLAN.md` | Created | Executable plan for the hotfix. |
| `.paul/phases/142-polkurier-shipment-prepare-prefill/142-01-SUMMARY.md` | Created | Completion summary. |
| `.paul/PROJECT.md` | Modified | Phase status evolved. |
| `.paul/ROADMAP.md` | Modified | Phase/milestone marked complete. |
| `.paul/STATE.md` | Modified | Loop and session state closed. |
| `.paul/changelog/2026-05-18.md` | Modified | Daily PAUL changelog updated. |
## Decisions Made
| Decision | Rationale | Impact |
|----------|-----------|--------|
| Keep persistence unchanged | Phase 140 mapping save path already writes `provider='polkurier'`; bug was in render-time interpretation. | Smaller fix with no DB or settings UI risk. |
| Add a view render test | The regression lives in template prefill logic, not in a service. | Future provider additions can follow this test shape. |
## Deviations from Plan
### Summary
| Type | Count | Impact |
|------|-------|--------|
| Environment gaps | 2 | PHPUnit and Sonar could not run because local tooling is missing. |
| Scope additions | 1 | Added ad-hoc PHP render smoke to compensate for missing PHPUnit execution. |
| Deferred | 1 | Manual production smoke for order #1164 remains operator-side after deploy. |
**Total impact:** Planned code and docs completed; verification gap is environment-only.
### Auto-fixed Issues
None.
### Deferred Items
- Manual smoke: open `/orders/1164/shipment/prepare` after deployment and confirm Polkurier service is preselected on live data.
- Run `vendor/bin/phpunit tests/Unit/ShipmentPreparePolkurierMappingTest.php` once `vendor/` is installed.
- Run SonarQube scan once `sonar-scanner` is available in PATH.
## Issues Encountered
| Issue | Resolution |
|-------|------------|
| `vendor/bin/phpunit` missing | Test file was linted and the same scenario was verified with an ad-hoc PHP render smoke. |
| `sonar-scanner` missing from PATH | Gap documented in STATE and summary, matching previous project environment gaps. |
## Verification Results
| Check | Result |
|-------|--------|
| `C:\xampp\php\php.exe -l resources\views\shipments\prepare.php` | Pass |
| `C:\xampp\php\php.exe -l tests\Unit\ShipmentPreparePolkurierMappingTest.php` | Pass |
| `vendor/bin/phpunit tests/Unit/ShipmentPreparePolkurierMappingTest.php` | Not run - `vendor/bin/phpunit` missing |
| Ad-hoc PHP render smoke for Polkurier mapping | Pass: carrier selected, panel visible, service selected, provider hidden field present, label correct |
| `rg -n "Polkurier|polkurier|2026-05-18" DOCS/ARCHITECTURE.md DOCS/TECH_CHANGELOG.md` | Pass |
| `git diff --check` | Pass with Git CRLF warnings only |
| `sonar-scanner --version` | Not run - command not found |
## Skill Audit
| Expected | Invoked | Notes |
|----------|---------|-------|
| `sonar-scanner` | gap documented | CLI is not available in PATH. |
## Next Phase Readiness
**Ready:**
- Polkurier prepare prefill is fixed in code.
- Regression coverage exists for the template case.
- No DB migration or settings contract change is needed.
**Concerns:**
- PHPUnit and Sonar remain unavailable in the local checkout.
- Live order #1164 should still be smoke-tested after deployment.
**Blockers:**
- None.
---
*Phase: 142-polkurier-shipment-prepare-prefill, Plan: 01*
*Completed: 2026-05-18*

View File

@@ -148,7 +148,7 @@ Phase 135 fixes daily net totals: `OrdersStatisticsRepository::netAmountSql()` p
### Shipment Flow ### Shipment Flow
Phase 130 adds an Erli-specific post-label step: for `orders.source='erli'`, `ShipmentController` calls `ErliExternalShipmentService::syncPackage()` after a local provider has a tracking number. Phase 131 extends the same Allegro-like contract into cron tracking: `ShipmentTrackingHandler` retries the Erli external parcel sync after a provider returns tracking status, but the retry is non-critical and never blocks local `delivery_status` updates. The service posts `vendor/status/trackingNumber/orderId` to Erli `POST /shipping/external` and stores the response in `shipment_packages.payload_json.erli_external_parcel`; failures are activity-log warnings. Phase 130 adds an Erli-specific post-label step: for `orders.source='erli'`, `ShipmentController` calls `ErliExternalShipmentService::syncPackage()` after a local provider has a tracking number. Phase 131 extends the same Allegro-like contract into cron tracking: `ShipmentTrackingHandler` retries the Erli external parcel sync after a provider returns tracking status, but the retry is non-critical and never blocks local `delivery_status` updates. The service posts `vendor/status/trackingNumber/orderId` to Erli `POST /shipping/external` and stores the response in `shipment_packages.payload_json.erli_external_parcel`; failures are activity-log warnings.
Phase 140 extends shopPRO delivery mapping with Polkurier. `/settings/integrations/shoppro?tab=delivery` now lists Polkurier services from `PolkurierShipmentService::getDeliveryServices()` and stores selected rows in `carrier_delivery_method_mappings` as `source_system='shoppro'`, `provider='polkurier'`, `provider_service_id=<servicecode>`, and `provider_service_name=<name>`. No schema change is required; the existing shipment prepare flow already reads the shared mapping and preselects `provider='polkurier'` with the stored delivery method id. Phase 140 extends shopPRO delivery mapping with Polkurier. `/settings/integrations/shoppro?tab=delivery` now lists Polkurier services from `PolkurierShipmentService::getDeliveryServices()` and stores selected rows in `carrier_delivery_method_mappings` as `source_system='shoppro'`, `provider='polkurier'`, `provider_service_id=<servicecode>`, and `provider_service_name=<name>`. No schema change is required; the shipment prepare flow reads the shared mapping and preselects `provider='polkurier'` with the stored delivery method id instead of falling back to Allegro.
1. **Create**`ShipmentController::create()``ShipmentProviderRegistry` → carrier `ShipmentService::createShipment()``ShipmentPackageRepository::insert()` 1. **Create**`ShipmentController::create()``ShipmentProviderRegistry` → carrier `ShipmentService::createShipment()``ShipmentPackageRepository::insert()`
2. **Track** — Cron `ShipmentTrackingHandler``ShipmentTrackingRegistry` → carrier tracking API → optional Erli external parcel retry → `ShipmentPackageRepository::updateDeliveryStatus()` → shared `shipment.status_changed` automation event when normalized status really changes. 2. **Track** — Cron `ShipmentTrackingHandler``ShipmentTrackingRegistry` → carrier tracking API → optional Erli external parcel retry → `ShipmentPackageRepository::updateDeliveryStatus()` → shared `shipment.status_changed` automation event when normalized status really changes.

View File

@@ -1,5 +1,19 @@
# Technical Changelog # Technical Changelog
## 2026-05-18 - Phase 142 Plan 01: Polkurier Shipment Prepare Prefill
**Co zrobiono:**
- Naprawiono preselect w `/orders/{id}/shipment/prepare` dla mapowan shopPRO -> Polkurier.
- Widok przygotowania przesylki rozpoznaje `carrier_delivery_method_mappings.provider='polkurier'`, wybiera panel Polkuriera i zaznacza usluge z `provider_service_id`.
- Opis "Metoda z zamowienia" pokazuje teraz "Polkurier: <nazwa uslugi>" zamiast fallbacku "Allegro".
- Dodano test regresyjny renderowania formularza dla mapowania Polkuriera.
**Dlaczego:**
- Po Phase 140 mapowanie moglo byc zapisane poprawnie, ale formularz przygotowania przesylki nadal traktowal nieznanego providera jak Allegro, przez co operator musial recznie podstawiać dane.
**BREAKING / migracja:**
- Brak migracji DB i brak zmian breaking. Naprawa dotyczy tylko odczytu istniejacego mapowania w UI przygotowania przesylki.
## 2026-05-18 - Phase 141 Plan 01: Integrations Hub Grouped Sections ## 2026-05-18 - Phase 141 Plan 01: Integrations Hub Grouped Sections
**Co zrobiono:** **Co zrobiono:**

View File

@@ -26,13 +26,14 @@ $mappedServiceName = trim((string) ($mapping['provider_service_name'] ?? ''));
$mappedCarrier = match ($mappedProvider) { $mappedCarrier = match ($mappedProvider) {
'apaczka' => 'apaczka', 'apaczka' => 'apaczka',
'inpost' => 'inpost', 'inpost' => 'inpost',
'polkurier' => 'polkurier',
default => 'allegro', default => 'allegro',
}; };
if ($mappedCarrier !== 'apaczka' && stripos($mappedCarrierId, 'inpost') !== false) { if ($mappedCarrier !== 'apaczka' && stripos($mappedCarrierId, 'inpost') !== false) {
$mappedCarrier = 'inpost'; $mappedCarrier = 'inpost';
} }
$deliveryMethodId = ''; $deliveryMethodId = '';
if ($mappedCarrier === 'apaczka' && $mappedMethodId !== '') { if (($mappedCarrier === 'apaczka' || $mappedCarrier === 'polkurier') && $mappedMethodId !== '') {
$deliveryMethodId = $mappedMethodId; $deliveryMethodId = $mappedMethodId;
} elseif (($mappedCarrier === 'allegro' || $mappedCarrier === 'inpost') && $mappedMethodId !== '') { } elseif (($mappedCarrier === 'allegro' || $mappedCarrier === 'inpost') && $mappedMethodId !== '') {
$deliveryMethodId = $mappedMethodId; $deliveryMethodId = $mappedMethodId;
@@ -42,6 +43,12 @@ if ($mappedCarrier === 'apaczka' && $mappedMethodId !== '') {
$deliveryMethodName = trim((string) ($orderRow['external_carrier_id'] ?? '')); $deliveryMethodName = trim((string) ($orderRow['external_carrier_id'] ?? ''));
$inpostSvcList = is_array($inpostServices ?? null) ? $inpostServices : []; $inpostSvcList = is_array($inpostServices ?? null) ? $inpostServices : [];
$preselectedCarrier = $mappedCarrier !== '' ? $mappedCarrier : ($mappedMethodId !== '' ? 'allegro' : ''); $preselectedCarrier = $mappedCarrier !== '' ? $mappedCarrier : ($mappedMethodId !== '' ? 'allegro' : '');
$mappedCarrierLabel = match ($mappedCarrier) {
'inpost' => 'InPost',
'apaczka' => 'Apaczka',
'polkurier' => 'Polkurier',
default => 'Allegro',
};
$pointId = trim((string) ($receiver['parcel_external_id'] ?? '')); $pointId = trim((string) ($receiver['parcel_external_id'] ?? ''));
$pointName = trim((string) ($receiver['parcel_name'] ?? '')); $pointName = trim((string) ($receiver['parcel_name'] ?? ''));
$totalWithTax = (float) ($orderRow['total_with_tax'] ?? 0); $totalWithTax = (float) ($orderRow['total_with_tax'] ?? 0);
@@ -112,7 +119,7 @@ $defaultCodAmount = $isCod ? number_format($totalWithTax, 2, '.', '') : '0';
<option value="polkurier"<?= $preselectedCarrier === 'polkurier' ? ' selected' : '' ?>>polkurier</option> <option value="polkurier"<?= $preselectedCarrier === 'polkurier' ? ' selected' : '' ?>>polkurier</option>
</select> </select>
<?php if ($deliveryMethodName !== ''): ?> <?php if ($deliveryMethodName !== ''): ?>
<div class="muted mt-4" style="font-size:12px">Metoda z zamowienia: <strong><?= $e($deliveryMethodName) ?></strong><?php if ($mappedServiceName !== ''): ?> &rarr; <?= $e($mappedCarrier === 'inpost' ? 'InPost' : ($mappedCarrier === 'apaczka' ? 'Apaczka' : 'Allegro')) ?>: <?= $e($mappedServiceName) ?><?php endif; ?></div> <div class="muted mt-4" style="font-size:12px">Metoda z zamowienia: <strong><?= $e($deliveryMethodName) ?></strong><?php if ($mappedServiceName !== ''): ?> &rarr; <?= $e($mappedCarrierLabel) ?>: <?= $e($mappedServiceName) ?><?php endif; ?></div>
<?php endif; ?> <?php endif; ?>
<?php if ($deliveryMappingDiagnostic !== ''): ?> <?php if ($deliveryMappingDiagnostic !== ''): ?>
<div class="mt-8"><?php $component('components/alert', ['type' => 'danger', 'message' => (string) $deliveryMappingDiagnostic, 'dismissible' => true]); ?></div> <div class="mt-8"><?php $component('components/alert', ['type' => 'danger', 'message' => (string) $deliveryMappingDiagnostic, 'dismissible' => true]); ?></div>
@@ -234,10 +241,12 @@ $defaultCodAmount = $isCod ? number_format($totalWithTax, 2, '.', '') : '0';
if ($pSvcId === '') { if ($pSvcId === '') {
continue; continue;
} }
$pSvcSelected = $mappedCarrier === 'polkurier' && $mappedMethodId === $pSvcId;
?> ?>
<option <option
value="<?= $e($pSvcId) ?>" value="<?= $e($pSvcId) ?>"
data-carrier-id="<?= $e($pSvcId) ?>"> data-carrier-id="<?= $e($pSvcId) ?>"
<?= $pSvcSelected ? 'selected' : '' ?>>
<?= $e($pSvcName) ?> <?= $e($pSvcName) ?>
</option> </option>
<?php endforeach; ?> <?php endforeach; ?>

View File

@@ -0,0 +1,102 @@
<?php
declare(strict_types=1);
namespace Tests\Unit;
use PHPUnit\Framework\TestCase;
final class ShipmentPreparePolkurierMappingTest extends TestCase
{
public function testPolkurierDeliveryMappingPreselectsCarrierAndService(): void
{
$html = $this->renderPrepareView([
'orderId' => 1164,
'csrfToken' => 'csrf-token',
'order' => [
'source' => 'shoppro',
'external_order_id' => 'SHOPPRO-1164',
'external_carrier_id' => 'Kurier Polkurier',
'total_with_tax' => '123.45',
'currency' => 'PLN',
'external_payment_type_id' => 'prepaid',
],
'receiverAddr' => [
'name' => 'Jan Kowalski',
'street_name' => 'Testowa 1',
'zip_code' => '35-001',
'city' => 'Rzeszow',
'country' => 'PL',
'phone' => '500600700',
'email' => 'jan@example.test',
],
'company' => [
'default_package_length_cm' => '25',
'default_package_width_cm' => '20',
'default_package_height_cm' => '8',
'default_package_weight_kg' => '1',
'default_label_format' => 'PDF',
],
'deliveryMapping' => [
'provider' => 'polkurier',
'provider_service_id' => 'DHL_TEST',
'provider_service_name' => 'Polkurier DHL Test',
],
'polkurierServices' => [
['id' => 'DHL_TEST', 'name' => 'Polkurier DHL Test'],
['id' => 'DPD_TEST', 'name' => 'Polkurier DPD Test'],
],
]);
self::assertMatchesRegularExpression(
'/<option value="polkurier"[^>]*selected[^>]*>polkurier<\/option>/',
$html
);
self::assertStringContainsString('id="shipment-polkurier-panel" style=""', $html);
self::assertMatchesRegularExpression(
'/<option\s+value="DHL_TEST"\s+data-carrier-id="DHL_TEST"\s+selected>/',
$html
);
self::assertStringContainsString('value="polkurier"', $html);
self::assertStringContainsString('Polkurier: Polkurier DHL Test', $html);
}
/**
* @param array<string, mixed> $overrides
*/
private function renderPrepareView(array $overrides): string
{
$defaults = [
'orderId' => 1,
'csrfToken' => 'csrf',
'order' => [],
'items' => [],
'receiverAddr' => [],
'preferences' => [],
'company' => [],
'deliveryServices' => [],
'apaczkaServices' => [],
'polkurierServices' => [],
'deliveryServicesError' => '',
'existingPackages' => [],
'flashSuccess' => '',
'flashError' => '',
'deliveryMapping' => null,
'deliveryMappingDiagnostic' => '',
'inpostServices' => [],
'pendingPrintPackageIds' => [],
];
extract(array_merge($defaults, $overrides), EXTR_SKIP);
$e = static fn (string $value): string => htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
$component = static function (string $view, array $params = []): void {
$message = isset($params['message']) ? (string) $params['message'] : '';
echo '<div class="alert">' . htmlspecialchars($message, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') . '</div>';
};
ob_start();
require dirname(__DIR__, 2) . '/resources/views/shipments/prepare.php';
return (string) ob_get_clean();
}
}