feat(130): erli shipments and labels
This commit is contained in:
@@ -13,8 +13,8 @@ Sprzedawca może obsługiwać zamówienia ze wszystkich kanałów
|
||||
| Attribute | Value |
|
||||
|-----------|-------|
|
||||
| Version | 3.8.0-dev |
|
||||
| Status | v3.8 Erli Marketplace Integration in progress — Phase 129 shipped (Erli status mappings/sync); Phase 130 next |
|
||||
| Last Updated | 2026-05-16 (Phase 129 closed) |
|
||||
| Status | v3.8 Erli Marketplace Integration in progress — Phase 130 shipped (Erli shipments + labels/external parcel sync); Phase 131 next |
|
||||
| Last Updated | 2026-05-16 (Phase 130 closed) |
|
||||
|
||||
## Requirements
|
||||
|
||||
@@ -129,6 +129,7 @@ Sprzedawca może obsługiwać zamówienia ze wszystkich kanałów
|
||||
- [x] Fundament integracji Erli: pojedyncza globalna konfiguracja `/settings/integrations/erli`, szyfrowany Bearer API key, realny test `GET /svc/shop-api/inbox`, karta w hubie integracji oraz dokumentacja schematu/architektury — Phase 127
|
||||
- [x] Import zamowien Erli: pobieranie `/inbox` przez cron i recznie, mapper do orderPRO, delta-only re-import, `invoice_requested` z danych firmowych/NIP, bezpieczny ACK `/inbox/mark-read` po bezblednym batchu — Phase 128
|
||||
- [x] Mapowanie i synchronizacja statusow Erli: osobne pull/push mappings, discovery statusow z inboxa, reczny-only push `PATCH /orders/{id}/status`, cron `erli_status_sync` i zakladki w ustawieniach Erli — Phase 129
|
||||
- [x] Przesylki Erli: zakladka mapowania dostaw, etykiety przez lokalne providery InPost/Apaczka i rejestracja paczek zewnetrznych w Erli przez `POST /shipping/external` — Phase 130
|
||||
|
||||
### Deferred
|
||||
|
||||
@@ -137,11 +138,10 @@ Sprzedawca może obsługiwać zamówienia ze wszystkich kanałów
|
||||
|
||||
### Active (In Progress)
|
||||
|
||||
- [ ] v3.8 Erli Marketplace Integration — Phase 130 next: generowanie etykiet i obsluga przesylek Erli.
|
||||
- [ ] v3.8 Erli Marketplace Integration — Phase 131 next: tracking przesylek Erli i hooki automatyzacji.
|
||||
|
||||
### Planned (Next)
|
||||
|
||||
- [ ] Erli shipments + labels — Phase 130
|
||||
- [ ] Erli tracking + automation hooks — Phase 131
|
||||
- [ ] Erli hardening, observability + docs — Phase 132
|
||||
- [ ] ZarzÄ…dzanie produktami
|
||||
@@ -251,13 +251,15 @@ PHP (XAMPP/Laravel), integracje z API marketplace'Ăłw (Allegro, Erli) oraz API
|
||||
| Push statusow Erli obejmuje tylko reczne zmiany orderPRO (`change_source='manual'`) | Chroni przed petlami po imporcie, automatyzacjach i systemowych zmianach statusu | 2026-05-16 | Active |
|
||||
| Erli -> orderPRO status pull uzywa tego samego inbox + ACK flow co import zamowien | Jedno bezpieczne zrodlo zdarzen Erli; brak osobnego status endpointu do utrzymania | 2026-05-16 | Active |
|
||||
| Erli settings korzysta z zakladek Integracja/Statusy/Ustawienia | Po dodaniu mapowan strona wymagala parytetu UX z Allegro/shopPRO | 2026-05-16 | Active |
|
||||
| Erli etykiety uzywaja lokalnych providerow, a Erli dostaje paczke zewnetrzna przez `POST /shipping/external` | Operator nie chce nadawac na umowie Erli; API wspiera zewnetrzne paczki/tracking | 2026-05-16 | Active |
|
||||
| `carrier_delivery_method_mappings` przechowuje `source_vendor_code`/`source_service_id` dla Erli | Vendor Erli i lokalny provider to osobne kontrakty, nie nalezy ich mieszac w polach Apaczki/InPost | 2026-05-16 | Active |
|
||||
|
||||
## Success Metrics
|
||||
|
||||
| Metric | Target | Current | Status |
|
||||
|--------|--------|---------|--------|
|
||||
| Liczba zintegrowanych źródeł zamówień | ≥3 | 3 zrodla importu (Allegro, shopPRO, Erli); Erli wymaga manualnego smoke po migracji | In progress |
|
||||
| Generowanie etykiet | Działa | InPost | In progress |
|
||||
| Generowanie etykiet | Działa | InPost + Erli przez lokalne providery po mapowaniu; Erli wymaga manualnego smoke po migracji | In progress |
|
||||
|
||||
## Tech Stack
|
||||
|
||||
@@ -282,6 +284,6 @@ Quick Reference:
|
||||
|
||||
---
|
||||
*PROJECT.md — Updated when requirements or context change*
|
||||
*Last updated: 2026-05-16 after Phase 129 (Erli Status Mapping + Sync) closure; v3.8 milestone in progress*
|
||||
*Last updated: 2026-05-16 after Phase 130 (Erli Shipments + Labels) closure; v3.8 milestone in progress*
|
||||
|
||||
|
||||
|
||||
@@ -10,14 +10,14 @@ v3.8 Erli Marketplace Integration — In progress
|
||||
|
||||
Pelna integracja z erli.pl wzorowana na istniejacej integracji Allegro: konfiguracja konta/API, pobieranie zamowien, mapowanie i synchronizacja statusow, generowanie etykiet, tracking oraz wlaczenie Erli w istniejace przeplywy automatyzacji, statystyk i obslugi zamowien.
|
||||
|
||||
Progress: 3 of 6 phases complete (50%).
|
||||
Progress: 4 of 6 phases complete (67%).
|
||||
|
||||
| Phase | Name | Plans | Status |
|
||||
|-------|------|-------|--------|
|
||||
| 127 | Erli Integration Foundation | 1/1 | Complete (2026-05-15; migration/manual Erli API smoke pending operator) |
|
||||
| 128 | Erli Orders Import | 1/1 | Complete (2026-05-15; migration/manual Erli import smoke pending operator) |
|
||||
| 129 | Erli Status Mapping + Sync | 1/1 | Complete (2026-05-16; migration/manual Erli status smoke pending operator) |
|
||||
| 130 | Erli Shipments + Labels | TBD | Not started |
|
||||
| 130 | Erli Shipments + Labels | 1/1 | Complete (2026-05-16; migration/manual Erli shipping smoke pending operator) |
|
||||
| 131 | Erli Tracking + Automation Hooks | TBD | Not started |
|
||||
| 132 | Erli Hardening, Observability + Docs | TBD | Not started |
|
||||
|
||||
@@ -39,7 +39,7 @@ Plans: 129-01 (complete)
|
||||
### Phase 130: Erli Shipments + Labels
|
||||
|
||||
Focus: Generowanie etykiet dla zamowien Erli, mapowanie metod dostawy Erli na dostepne providery, zapis paczek w `shipment_packages`, pobieranie labeli i integracja z kolejka zdalnego druku.
|
||||
Plans: TBD (defined during $paul-plan)
|
||||
Plans: 130-01 (complete)
|
||||
|
||||
### Phase 131: Erli Tracking + Automation Hooks
|
||||
|
||||
@@ -555,4 +555,4 @@ Archive: `.paul/milestones/v0.1-ROADMAP.md`
|
||||
|
||||
---
|
||||
*Roadmap created: 2026-03-12*
|
||||
*Last updated: 2026-05-16 - Phase 129 complete, ready for Phase 130 planning*
|
||||
*Last updated: 2026-05-16 - Phase 130 complete, ready for Phase 131 planning*
|
||||
|
||||
@@ -5,33 +5,33 @@
|
||||
See: .paul/PROJECT.md (updated 2026-05-16)
|
||||
|
||||
**Core value:** Sprzedawca moze obslugiwac zamowienia ze wszystkich kanalow sprzedazy i nadawac przesylki bez przelaczania sie miedzy platformami.
|
||||
**Current focus:** v3.8 Erli Marketplace Integration - Phase 130 ready to plan.
|
||||
**Current focus:** v3.8 Erli Marketplace Integration - Phase 131 ready to plan.
|
||||
|
||||
## Current Position
|
||||
|
||||
Milestone: v3.8 Erli Marketplace Integration
|
||||
Phase: 130 of 132 (Erli Shipments + Labels) - Not started
|
||||
Phase: 131 of 132 (Erli Tracking + Automation Hooks) - Not started
|
||||
Plan: Not started
|
||||
Status: Ready to plan
|
||||
Last activity: 2026-05-16 00:23 - Phase 129 complete, transitioned to Phase 130
|
||||
Last activity: 2026-05-16 00:51 - Phase 130 complete, transitioned to Phase 131
|
||||
|
||||
Progress:
|
||||
- Milestone v3.8: [#####-----] 50% (Phases 127-129 complete; Phase 130 next)
|
||||
- Phase 130: [----------] 0% (not planned)
|
||||
- Milestone v3.8: [#######---] 67% (Phases 127-130 complete; Phase 131 next)
|
||||
- Phase 131: [----------] 0% (not planned)
|
||||
|
||||
## Loop Position
|
||||
|
||||
Current loop state:
|
||||
```
|
||||
PLAN -> APPLY -> UNIFY
|
||||
done done done [Loop complete - ready for next PLAN]
|
||||
done done done [Loop complete, ready for next PLAN]
|
||||
```
|
||||
|
||||
## Session Continuity
|
||||
|
||||
Last session: 2026-05-16 00:23
|
||||
Stopped at: Phase 129 complete, ready to plan Phase 130
|
||||
Next action: $paul-plan for Phase 130 (Erli Shipments + Labels)
|
||||
Last session: 2026-05-16 00:51
|
||||
Stopped at: Phase 130 complete, ready to plan Phase 131
|
||||
Next action: $paul-plan for Phase 131 (Erli Tracking + Automation Hooks)
|
||||
Resume file: .paul/ROADMAP.md
|
||||
|
||||
## Pending parallel work
|
||||
@@ -39,8 +39,8 @@ Resume file: .paul/ROADMAP.md
|
||||
|
||||
## Git State
|
||||
|
||||
Last phase commit: 7972bb9 feat(129): erli status mapping sync
|
||||
Previous: 2565d9b feat(128): erli orders import
|
||||
Last phase commit: a73bd7f feat(130): erli shipments and labels
|
||||
Previous: 7972bb9 feat(129): erli status mapping sync
|
||||
Branch: main
|
||||
|
||||
### Skill Audit (Phase 129)
|
||||
@@ -49,6 +49,12 @@ Branch: main
|
||||
|----------|---------|-------|
|
||||
| `sonar-scanner` | gap documented | Attempted before UNIFY; CLI is not available in PATH. |
|
||||
|
||||
### Skill Audit (Phase 130)
|
||||
|
||||
| Expected | Invoked | Notes |
|
||||
|----------|---------|-------|
|
||||
| `sonar-scanner` | gap documented | Attempted after APPLY; CLI is not available in PATH. |
|
||||
|
||||
## Pending Actions
|
||||
|
||||
- Manualne testy AC-1..AC-7 dla Phase 112 na zywej bazie (XAMPP online).
|
||||
@@ -76,6 +82,9 @@ Branch: main
|
||||
- Phase 128 verification gap: `vendor/bin/phpunit` nie istnieje w checkoutcie, wiec test `tests/Unit/ErliOrderMapperTest.php` nie zostal uruchomiony przez PHPUnit; wykonano `php -l` i runtime smoke mappera.
|
||||
- Phase 129 follow-up: uruchom `php bin/migrate.php`, sprawdz `/settings/integrations/erli` mapowania pull/push i zakladki, zapisz mapowania, ustaw `orderPRO -> Erli`, zmien recznie status zamowienia Erli i uruchom cron `erli_status_sync`.
|
||||
- Phase 129 verification gap: `vendor/bin/phpunit` nie istnieje w checkoutcie, a globalny XAMPP PHPUnit jest niekompatybilny z PHP (`each()` removed), wiec testy `ErliOrderMapperTest` i `ErliStatusSyncServiceTest` nie zostaly uruchomione przez PHPUnit; wykonano `php -l`, runtime smoke mappera i `git diff --check`.
|
||||
- Phase 130 follow-up: uruchom `php bin/migrate.php` (dodaje `carrier_delivery_method_mappings.source_service_id/source_vendor_code`), otworz `/settings/integrations/erli?tab=delivery`, zapisz mapowanie metody Erli na InPost/Apaczka oraz vendor Erli, a potem utworz etykiete dla zamowienia Erli i potwierdz `POST /shipping/external`.
|
||||
- Phase 130 verification gap: `vendor/bin/phpunit` nie istnieje w checkoutcie, wiec test `tests/Unit/ErliExternalShipmentServiceTest.php` nie zostal uruchomiony przez PHPUnit; wykonano `php -l` i `git diff --check`.
|
||||
- Phase 130 skill gap: `sonar-scanner` nie jest dostepny w PATH, wiec skan SonarQube nie zostal uruchomiony.
|
||||
|
||||
## Deferred to Next Milestones
|
||||
|
||||
|
||||
@@ -7,6 +7,11 @@
|
||||
- Dodano repozytoria mapowan, `ErliStatusSyncService`, `ErliStatusSyncHandler`, discovery nieznanych statusow Erli i testy jednostkowe dla mappera/status sync.
|
||||
- Ujednolicono `/settings/integrations/erli` z innymi integracjami przez zakladki Integracja, Statusy i Ustawienia.
|
||||
- Udokumentowano gapy srodowiskowe: brak `vendor/bin/phpunit`, globalny XAMPP PHPUnit niekompatybilny z PHP, brak `sonar-scanner` w PATH.
|
||||
- [Phase 130, Plan 01] Wdrozono obsluge przesylek Erli: zakladke mapowan dostaw, lokalne generowanie etykiet przez zmapowanych providerow i rejestracje paczki zewnetrznej w Erli.
|
||||
- Rozszerzono klienta Erli o slowniki shipping/delivery, vendorow, cenniki oraz `POST /shipping/external`.
|
||||
- Rozszerzono mapowania dostaw o `source_service_id` i `source_vendor_code`, zeby oddzielic Erli vendor od lokalnego providera etykiety.
|
||||
- Dodano niekrytyczna synchronizacje tracking number do Erli po utworzeniu lokalnej paczki.
|
||||
- Udokumentowano gapy srodowiskowe Phase 130: brak `vendor/bin/phpunit`, brak `sonar-scanner` w PATH, smoke testy Erli po migracji do wykonania przez operatora.
|
||||
|
||||
## Zmienione pliki
|
||||
|
||||
@@ -35,6 +40,15 @@
|
||||
- `resources/lang/pl.php`
|
||||
- `tests/Unit/ErliOrderMapperTest.php`
|
||||
- `tests/Unit/ErliStatusSyncServiceTest.php`
|
||||
- `.paul/phases/130-erli-shipments-labels/130-01-PLAN.md`
|
||||
- `.paul/phases/130-erli-shipments-labels/130-01-SUMMARY.md`
|
||||
- `database/migrations/20260516_000117_extend_delivery_mappings_for_erli_shipping.sql`
|
||||
- `src/Modules/Settings/CarrierDeliveryMethodMappingRepository.php`
|
||||
- `src/Modules/Settings/ErliDeliveryMappingController.php`
|
||||
- `src/Modules/Settings/ErliExternalShipmentService.php`
|
||||
- `src/Modules/Shipments/ShipmentController.php`
|
||||
- `resources/views/shipments/prepare.php`
|
||||
- `tests/Unit/ErliExternalShipmentServiceTest.php`
|
||||
- `DOCS/DB_SCHEMA.md`
|
||||
- `DOCS/ARCHITECTURE.md`
|
||||
- `DOCS/TECH_CHANGELOG.md`
|
||||
|
||||
255
.paul/phases/130-erli-shipments-labels/130-01-PLAN.md
Normal file
255
.paul/phases/130-erli-shipments-labels/130-01-PLAN.md
Normal file
@@ -0,0 +1,255 @@
|
||||
---
|
||||
phase: 130-erli-shipments-labels
|
||||
plan: 01
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: []
|
||||
files_modified:
|
||||
- src/Core/Constants/IntegrationSources.php
|
||||
- src/Modules/Settings/ErliApiClient.php
|
||||
- src/Modules/Settings/ErliDeliveryMappingController.php
|
||||
- src/Modules/Settings/ErliIntegrationController.php
|
||||
- src/Modules/Settings/CarrierDeliveryMethodMappingRepository.php
|
||||
- src/Modules/Settings/ErliExternalShipmentService.php
|
||||
- src/Modules/Shipments/ShipmentController.php
|
||||
- routes/web.php
|
||||
- resources/views/settings/erli.php
|
||||
- resources/views/shipments/prepare.php
|
||||
- resources/lang/pl.php
|
||||
- tests/Unit/ErliExternalShipmentServiceTest.php
|
||||
- DOCS/DB_SCHEMA.md
|
||||
- DOCS/ARCHITECTURE.md
|
||||
- DOCS/TECH_CHANGELOG.md
|
||||
autonomous: true
|
||||
delegation: auto
|
||||
---
|
||||
|
||||
<objective>
|
||||
## Goal
|
||||
Dodac obsluge przesylek dla zamowien Erli: mapowanie metod dostawy w osobnej zakladce ustawien, uzycie istniejacych providerow etykiet (InPost/Apaczka tam, gdzie sa dostepne), zapis paczek w `shipment_packages` oraz rejestracje numeru nadania w Erli przez natywny endpoint przesylek zewnetrznych.
|
||||
|
||||
## Purpose
|
||||
Sprzedawca ma nadawac zamowienia Erli z orderPRO bez przelaczania sie do panelu marketplace, ale bez wymuszania nadawania "na umowie Erli". Natywne Erli w tym planie oznacza wykorzystanie oficjalnych slownikow/cennikow/shipping API tam, gdzie pasuja do wlasnych umow operatora.
|
||||
|
||||
## Output
|
||||
Nowa zakladka dostaw w `/settings/integrations/erli`, rozszerzony Erli API client, flow tworzenia etykiety dla zmapowanych zamowien Erli oraz synchronizacja paczki zewnetrznej do Erli po uzyskaniu numeru przesylki.
|
||||
</objective>
|
||||
|
||||
<context>
|
||||
<clarifications>
|
||||
- **Natywne Erli** - Czy probujemy najpierw API shipping Erli, czy od razu tylko istniejacy provider etykiet?
|
||||
-> Odpowiedz: Trzeba sprobowac natywnego z erli.
|
||||
- **Konfiguracja** - Gdzie operator ma mapowac metody dostawy Erli?
|
||||
-> Odpowiedz: zakladka.
|
||||
- **Umowa/cenniki** - Czy nadawac przez Erli na ich umowie, czy tylko to, co da sie spiac z wlasnymi providerami/cennikami?
|
||||
-> Odpowiedz: Nie chce nadawac przez Erli na ich umowie, to co sie da. Tak jak allegro ma swoje cenniki.
|
||||
</clarifications>
|
||||
|
||||
## Project Context
|
||||
@.paul/PROJECT.md
|
||||
@.paul/ROADMAP.md
|
||||
@.paul/STATE.md
|
||||
@.paul/codebase/architecture.md
|
||||
@.paul/codebase/db_schema.md
|
||||
@AGENTS.md
|
||||
|
||||
## Prior Work
|
||||
@.paul/phases/127-erli-integration-foundation/127-01-SUMMARY.md
|
||||
@.paul/phases/128-erli-orders-import/128-01-SUMMARY.md
|
||||
@.paul/phases/129-erli-status-mapping-sync/129-01-SUMMARY.md
|
||||
|
||||
## External Contract
|
||||
@https://erli.pl/svc/shop-api/doc/swagger.json
|
||||
|
||||
Notes from official swagger checked during planning:
|
||||
- `GET /dictionaries/shippingMethods`, `GET /dictionaries/deliveryMethods`, `GET /dictionaries/deliveryVendors`, `GET /delivery/priceLists`, `GET /delivery/priceListsDetails` expose Erli shipping/delivery dictionaries and cenniki.
|
||||
- `POST /shipping/external` creates external parcels with `orderId`, `vendor`, `status`, `trackingNumber`.
|
||||
- `POST /shipping/parcels/` creates Erli parcels, but this path is treated as optional/discovery only because the user does not want to ship on Erli's carrier agreement.
|
||||
- No label-download endpoint was found in the swagger path list; local label generation must continue through existing provider services unless APPLY finds a documented endpoint with compatible contract.
|
||||
|
||||
## Source Files
|
||||
@src/Modules/Settings/ErliApiClient.php
|
||||
@src/Modules/Settings/ErliIntegrationController.php
|
||||
@src/Modules/Settings/CarrierDeliveryMethodMappingRepository.php
|
||||
@src/Modules/Settings/AllegroDeliveryMappingController.php
|
||||
@src/Modules/Shipments/ShipmentController.php
|
||||
@src/Modules/Shipments/ShipmentProviderInterface.php
|
||||
@src/Modules/Shipments/InpostShipmentService.php
|
||||
@src/Modules/Shipments/ApaczkaShipmentService.php
|
||||
@resources/views/settings/erli.php
|
||||
@resources/views/shipments/prepare.php
|
||||
@routes/web.php
|
||||
@DOCS/DB_SCHEMA.md
|
||||
@DOCS/ARCHITECTURE.md
|
||||
</context>
|
||||
|
||||
<skills>
|
||||
## Required Skills (from SPECIAL-FLOWS.md)
|
||||
|
||||
| Skill | Priority | When to Invoke | Loaded? |
|
||||
|-------|----------|----------------|---------|
|
||||
| `sonar-scanner` | required | Po APPLY, przed UNIFY | ○ |
|
||||
| /feature-dev | optional | Przed implementacja integracji marketplace/shipping | ○ |
|
||||
| /frontend-design | optional | Przy dodaniu zakladki UI w ustawieniach Erli | ○ |
|
||||
| /code-review | optional | Po implementacji, przed UNIFY | ○ |
|
||||
|
||||
**BLOCKING:** Required `sonar-scanner` must be attempted before UNIFY. If CLI is still unavailable in PATH, document the gap in SUMMARY and STATE like Phase 128/129.
|
||||
|
||||
## Skill Invocation Checklist
|
||||
- [ ] `sonar-scanner` attempted after APPLY
|
||||
- [ ] Optional flows considered if implementation risk warrants them
|
||||
</skills>
|
||||
|
||||
<acceptance_criteria>
|
||||
|
||||
## AC-1: Erli Shipping Contract Is Used Where Safe
|
||||
```gherkin
|
||||
Given Erli API credentials are configured
|
||||
When orderPRO loads shipment configuration for Erli
|
||||
Then it can fetch Erli shipping/delivery dictionaries, delivery vendors and price list data from the official Erli API
|
||||
And it does not assume native Erli label download exists unless a documented endpoint is confirmed during implementation.
|
||||
```
|
||||
|
||||
## AC-2: Erli Delivery Mapping Tab Exists
|
||||
```gherkin
|
||||
Given the operator opens /settings/integrations/erli
|
||||
When they select the delivery/shipping tab
|
||||
Then they see distinct Erli delivery methods from imported orders plus Erli dictionary context
|
||||
And they can map each method to an available local label provider/service and Erli vendor with a CSRF-protected save form.
|
||||
```
|
||||
|
||||
## AC-3: Erli Orders Preselect Shipment Provider
|
||||
```gherkin
|
||||
Given an Erli order has a saved delivery mapping
|
||||
When the operator opens the shipment prepare page for that order
|
||||
Then orderPRO preselects the mapped provider/service and shows a clear unmapped diagnostic if no mapping exists.
|
||||
```
|
||||
|
||||
## AC-4: Labels Are Generated Without Erli Carrier Agreement
|
||||
```gherkin
|
||||
Given an Erli order is mapped to an existing local provider such as InPost or Apaczka
|
||||
When the operator creates a shipment
|
||||
Then the existing provider creates the local shipment package, stores it in shipment_packages and makes the label available for download/print queue
|
||||
And the flow does not create Erli-contract parcels unless explicitly supported and selected in future work.
|
||||
```
|
||||
|
||||
## AC-5: External Parcel Is Registered In Erli
|
||||
```gherkin
|
||||
Given a local Erli shipment package has a tracking number and a mapped Erli vendor
|
||||
When the package creation/status check reaches a label-ready or sent state
|
||||
Then orderPRO calls POST /shipping/external with order id, vendor, status and tracking number
|
||||
And API failures are logged as non-critical local shipment warnings rather than losing the label.
|
||||
```
|
||||
|
||||
## AC-6: Documentation And Verification Cover The Flow
|
||||
```gherkin
|
||||
Given the implementation is complete
|
||||
When verification runs
|
||||
Then PHP syntax checks, focused tests or documented PHPUnit gap, diff checks and documentation updates cover the new Erli shipment behavior.
|
||||
```
|
||||
|
||||
</acceptance_criteria>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Extend Erli API and mapping repository for shipping</name>
|
||||
<files>src/Core/Constants/IntegrationSources.php, src/Modules/Settings/ErliApiClient.php, src/Modules/Settings/CarrierDeliveryMethodMappingRepository.php, DOCS/DB_SCHEMA.md, DOCS/ARCHITECTURE.md</files>
|
||||
<action>
|
||||
Add `erli` as an explicit integration source constant/path wherever current generic delivery mappings normalize only `allegro` and `shoppro`.
|
||||
Extend `CarrierDeliveryMethodMappingRepository` so `listMappings`, `findByOrderMethod`, `saveMappings`, `hasMappingsForSource` and `getDistinctOrderDeliveryMethods` work for `source_system='erli'` and global `source_integration_id=0`.
|
||||
Extend `ErliApiClient` with small focused methods for shipping dictionaries and external parcels:
|
||||
- `getShippingMethods()`
|
||||
- `getDeliveryMethods()`
|
||||
- `getDeliveryVendors()`
|
||||
- `getPriceLists()` / `getPriceListsDetails()` if the response is needed for operator context
|
||||
- `createExternalParcel(array $payload)`
|
||||
Keep request/response handling consistent with existing Erli client methods and keep runtime on `DB_HOST`, never `DB_HOST_REMOTE`.
|
||||
Do not add a new table unless APPLY proves existing `carrier_delivery_method_mappings` cannot represent the mapping. If a schema change becomes unavoidable, add a migration and update DB docs in the same task.
|
||||
</action>
|
||||
<verify>`C:\xampp\php\php.exe -l src/Modules/Settings/ErliApiClient.php` and `C:\xampp\php\php.exe -l src/Modules/Settings/CarrierDeliveryMethodMappingRepository.php`; repository can list/save/find Erli mappings without falling back to Allegro.</verify>
|
||||
<done>AC-1 foundation complete and AC-2 persistence ready.</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Add Erli delivery mapping tab</name>
|
||||
<files>src/Modules/Settings/ErliDeliveryMappingController.php, src/Modules/Settings/ErliIntegrationController.php, routes/web.php, resources/views/settings/erli.php, resources/lang/pl.php, DOCS/ARCHITECTURE.md</files>
|
||||
<action>
|
||||
Create or wire a focused Erli delivery mapping controller, following the clarity of `AllegroDeliveryMappingController` but without Allegro OAuth assumptions.
|
||||
Load:
|
||||
- distinct Erli delivery methods from imported orders,
|
||||
- current `carrier_delivery_method_mappings` rows for `erli`,
|
||||
- available local label provider services already supported by the shipment flow,
|
||||
- Erli vendors/dictionaries for choosing the vendor sent to `/shipping/external`.
|
||||
Add a new Erli settings tab (for example `delivery`) next to existing integration/status/settings tabs.
|
||||
Saving must use POST + `_token`, `Flash`, bounded validation and redirect back to `/settings/integrations/erli?tab=delivery`.
|
||||
Escape all view output with `$e()`, avoid inline CSS in the view, and do not add native `alert()`/`confirm()`.
|
||||
</action>
|
||||
<verify>`C:\xampp\php\php.exe -l src/Modules/Settings/ErliDeliveryMappingController.php`, `C:\xampp\php\php.exe -l resources/views/settings/erli.php`, and manual route smoke: opening `/settings/integrations/erli?tab=delivery` renders the tab even when Erli API metadata fetch fails.</verify>
|
||||
<done>AC-2 satisfied; UI is consistent with Phase 129 tab pattern.</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 3: Use mappings during shipment creation and sync external parcel to Erli</name>
|
||||
<files>src/Modules/Shipments/ShipmentController.php, src/Modules/Settings/ErliExternalShipmentService.php, resources/views/shipments/prepare.php, routes/web.php, tests/Unit/ErliExternalShipmentServiceTest.php, DOCS/ARCHITECTURE.md, DOCS/TECH_CHANGELOG.md</files>
|
||||
<action>
|
||||
Update shipment prepare flow so Erli orders are eligible for `CarrierDeliveryMethodMappingRepository::findByOrderMethod('erli', 0, ...)` just like Allegro/shopPRO.
|
||||
Ensure the mapped provider/service can preselect existing local provider forms. Preserve existing Allegro/shopPRO behavior.
|
||||
Add an `ErliExternalShipmentService` that reads the local package/order context and calls `ErliApiClient::createExternalParcel()` with:
|
||||
- Erli external order id,
|
||||
- mapped Erli vendor,
|
||||
- tracking number from `shipment_packages`,
|
||||
- status matching Erli's accepted external parcel status contract.
|
||||
Trigger this service after a local provider has produced a tracking number/label-ready package (for example from `checkStatus()` and/or label-ready creation path), and make the call idempotent enough for retries by treating duplicate/already-existing responses as non-fatal where Erli exposes that signal.
|
||||
Log or flash bounded warnings for Erli sync failure but never discard the local label.
|
||||
Add focused unit coverage for payload building and failure behavior. If PHPUnit remains unavailable, leave the test file and document the run gap.
|
||||
</action>
|
||||
<verify>`C:\xampp\php\php.exe -l src/Modules/Shipments/ShipmentController.php`; `C:\xampp\php\php.exe -l src/Modules/Settings/ErliExternalShipmentService.php`; if dependencies exist, run `vendor/bin/phpunit tests/Unit/ErliExternalShipmentServiceTest.php`; manual smoke on a mapped Erli order reaches local `shipment_packages` and attempts `/shipping/external` only after tracking exists.</verify>
|
||||
<done>AC-3, AC-4, AC-5 and AC-6 satisfied.</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<boundaries>
|
||||
|
||||
## DO NOT CHANGE
|
||||
- Do not change unrelated `.vscode/ftp-kr.sync.cache.json`.
|
||||
- Do not regress Allegro, shopPRO, InPost or Apaczka shipment behavior.
|
||||
- Do not connect runtime application code to `DB_HOST_REMOTE`.
|
||||
- Do not add inline CSS to `resources/views/...`.
|
||||
- Do not add native `alert()` / `confirm()` in views.
|
||||
|
||||
## SCOPE LIMITS
|
||||
- This plan does not implement Phase 131 carrier tracking polling, automation expansion or delivery-status cron beyond the immediate external parcel registration.
|
||||
- This plan does not force creating shipments through Erli's own carrier agreement. `POST /shipping/parcels/` may be inspected during APPLY, but shipping via Erli-contract parcels is out of scope unless it is clearly just external/seller-contract compatible.
|
||||
- This plan does not build product/stock sync or Erli offer management.
|
||||
- This plan keeps Erli as one global integration unless a future phase explicitly introduces multi-account support.
|
||||
- This plan should avoid new schema if existing generic mapping storage is enough.
|
||||
|
||||
</boundaries>
|
||||
|
||||
<verification>
|
||||
Before declaring plan complete:
|
||||
- [ ] `C:\xampp\php\php.exe -l` for every changed PHP/view/test file.
|
||||
- [ ] `git diff --check`.
|
||||
- [ ] `vendor/bin/phpunit tests/Unit/ErliExternalShipmentServiceTest.php` if PHPUnit dependencies are available; otherwise document the environment gap.
|
||||
- [ ] Attempt `sonar-scanner` after APPLY; if unavailable, document the gap in SUMMARY and STATE.
|
||||
- [ ] Manual smoke: `/settings/integrations/erli?tab=delivery` renders, saves mapping with `_token`, and survives Erli API metadata errors.
|
||||
- [ ] Manual smoke: a mapped Erli order preselects shipment provider/service on prepare page.
|
||||
- [ ] Manual smoke: local provider label creation still stores `shipment_packages` and the Erli external parcel sync is attempted only with a tracking number.
|
||||
- [ ] `DOCS/DB_SCHEMA.md`, `DOCS/ARCHITECTURE.md`, `DOCS/TECH_CHANGELOG.md` updated for changed behavior and any schema decision.
|
||||
- [ ] All acceptance criteria met.
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- Erli settings has a working delivery/shipping mapping tab.
|
||||
- Erli delivery mappings are stored and used by shipment prepare.
|
||||
- Erli orders can generate local labels through existing providers when mapped.
|
||||
- Erli receives external parcel/tracking data through native shipping API when tracking exists.
|
||||
- Native Erli-contract parcel creation is either explicitly not used or documented as future/manual decision.
|
||||
- Tests/lints/docs and required skill audit are completed or gaps documented.
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.paul/phases/130-erli-shipments-labels/130-01-SUMMARY.md`.
|
||||
</output>
|
||||
165
.paul/phases/130-erli-shipments-labels/130-01-SUMMARY.md
Normal file
165
.paul/phases/130-erli-shipments-labels/130-01-SUMMARY.md
Normal file
@@ -0,0 +1,165 @@
|
||||
---
|
||||
phase: 130-erli-shipments-labels
|
||||
plan: 01
|
||||
subsystem: settings, integrations, shipments, database
|
||||
tags: [erli, shipping, labels, delivery-mapping, external-parcels]
|
||||
requires:
|
||||
- phase: 127-erli-integration-foundation
|
||||
provides: global Erli credentials and API client
|
||||
- phase: 128-erli-orders-import
|
||||
provides: Erli orders in common order model
|
||||
- phase: 129-erli-status-mapping-sync
|
||||
provides: tabbed Erli settings UI and outbound API pattern
|
||||
provides:
|
||||
- Erli delivery mapping tab
|
||||
- Erli shipping dictionary and external parcel API methods
|
||||
- Local label provider preselection for Erli orders
|
||||
- External parcel registration in Erli after tracking number exists
|
||||
affects: [phase-131-erli-tracking-automation, erli-settings, shipment-flow]
|
||||
tech-stack:
|
||||
added: []
|
||||
patterns: [marketplace delivery mapping with source vendor, non-critical external parcel sync]
|
||||
key-files:
|
||||
created:
|
||||
- database/migrations/20260516_000117_extend_delivery_mappings_for_erli_shipping.sql
|
||||
- src/Modules/Settings/ErliDeliveryMappingController.php
|
||||
- src/Modules/Settings/ErliExternalShipmentService.php
|
||||
- tests/Unit/ErliExternalShipmentServiceTest.php
|
||||
modified:
|
||||
- src/Modules/Settings/ErliApiClient.php
|
||||
- src/Modules/Settings/CarrierDeliveryMethodMappingRepository.php
|
||||
- src/Modules/Settings/ErliIntegrationController.php
|
||||
- src/Modules/Shipments/ShipmentController.php
|
||||
- routes/web.php
|
||||
- resources/views/settings/erli.php
|
||||
- resources/views/shipments/prepare.php
|
||||
- resources/lang/pl.php
|
||||
- DOCS/DB_SCHEMA.md
|
||||
- DOCS/ARCHITECTURE.md
|
||||
- DOCS/TECH_CHANGELOG.md
|
||||
key-decisions:
|
||||
- "Erli labels stay on local providers; Erli receives external parcel/tracking through POST /shipping/external."
|
||||
- "Erli vendor code is stored separately from local provider service in carrier_delivery_method_mappings.source_vendor_code."
|
||||
patterns-established:
|
||||
- "External marketplace shipment sync is non-critical and must not block local labels."
|
||||
duration: ~20min
|
||||
started: 2026-05-16T00:37:00+02:00
|
||||
completed: 2026-05-16T00:51:00+02:00
|
||||
---
|
||||
|
||||
# Phase 130-01 Summary: Erli Shipments + Labels
|
||||
|
||||
Phase 130 adds Erli delivery mappings, local label provider preselection and external parcel registration through the native Erli shipping API without using Erli carrier-contract label flow.
|
||||
|
||||
## Performance
|
||||
|
||||
| Metric | Result |
|
||||
|--------|--------|
|
||||
| Duration | ~20min |
|
||||
| Started | 2026-05-16T00:37:00+02:00 |
|
||||
| Completed | 2026-05-16T00:51:00+02:00 |
|
||||
| Tasks | 3/3 completed |
|
||||
| Files changed | 18 phase files, excluding unrelated `.vscode/ftp-kr.sync.cache.json` |
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
| AC | Result | Notes |
|
||||
|----|--------|-------|
|
||||
| AC-1: Erli Shipping Contract Is Used Where Safe | Pass | `ErliApiClient` now supports shipping/delivery dictionaries, vendors, price lists and `POST /shipping/external`; no native label download endpoint is assumed. |
|
||||
| AC-2: Erli Delivery Mapping Tab Exists | Pass | `/settings/integrations/erli?tab=delivery` has a CSRF-protected mapping tab with imported delivery methods, Erli vendor context and local provider service choices. |
|
||||
| AC-3: Erli Orders Preselect Shipment Provider | Pass | Shipment prepare includes Erli in delivery mapping lookup and preselects mapped local provider/service. |
|
||||
| AC-4: Labels Are Generated Without Erli Carrier Agreement | Pass | Labels remain provider-driven through local InPost/Apaczka/Allegro WZA flow and keep writing `shipment_packages`. |
|
||||
| AC-5: External Parcel Is Registered In Erli | Pass with live smoke pending | `ErliExternalShipmentService` registers external parcels only after tracking exists and logs non-critical errors. |
|
||||
| AC-6: Documentation And Verification Cover The Flow | Pass with env gaps | PHP lint and diff checks passed; PHPUnit and Sonar are unavailable in this environment. |
|
||||
|
||||
## Accomplishments
|
||||
|
||||
- Extended generic carrier delivery mappings with Erli-specific source service/vendor metadata.
|
||||
- Added an Erli delivery tab that maps Erli delivery methods to local label providers and Erli vendor codes.
|
||||
- Added native Erli shipping dictionary and external parcel client methods.
|
||||
- Wired Erli shipment preparation into the existing local label flow.
|
||||
- Added non-blocking external parcel sync to Erli after local tracking numbers become available.
|
||||
- Updated database, architecture and technical changelog documentation.
|
||||
|
||||
## Task Results
|
||||
|
||||
| Task | Result | Commit |
|
||||
|------|--------|--------|
|
||||
| Task 1: Extend Erli API and mapping repository for shipping | Done | Phase commit |
|
||||
| Task 2: Add Erli delivery mapping tab | Done | Phase commit |
|
||||
| Task 3: Use mappings during shipment creation and sync external parcel to Erli | Done | Phase commit |
|
||||
|
||||
## Files Created
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `database/migrations/20260516_000117_extend_delivery_mappings_for_erli_shipping.sql` | Adds Erli source service/vendor metadata to delivery mappings. |
|
||||
| `src/Modules/Settings/ErliDeliveryMappingController.php` | Loads and saves Erli delivery mapping tab data. |
|
||||
| `src/Modules/Settings/ErliExternalShipmentService.php` | Registers local tracking numbers as Erli external parcels. |
|
||||
| `tests/Unit/ErliExternalShipmentServiceTest.php` | Focused unit coverage for Erli external parcel sync behavior. |
|
||||
|
||||
## Files Modified
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `src/Modules/Settings/ErliApiClient.php` | Added shipping dictionaries, price lists and external parcel API calls. |
|
||||
| `src/Modules/Settings/CarrierDeliveryMethodMappingRepository.php` | Added Erli source support and source vendor/service persistence. |
|
||||
| `src/Modules/Settings/ErliIntegrationController.php` | Added delivery tab data and tab routing. |
|
||||
| `src/Modules/Shipments/ShipmentController.php` | Uses Erli delivery mappings and triggers external parcel sync after tracking exists. |
|
||||
| `routes/web.php` | Wires Erli delivery save route and external shipment service dependencies. |
|
||||
| `resources/views/settings/erli.php` | Adds Erli delivery tab UI. |
|
||||
| `resources/views/shipments/prepare.php` | Preselects mapped local provider/service for Erli shipments. |
|
||||
| `resources/lang/pl.php` | Adds Polish labels for Erli delivery mapping UI. |
|
||||
| `DOCS/DB_SCHEMA.md` | Documents mapping columns. |
|
||||
| `DOCS/ARCHITECTURE.md` | Documents Erli shipment flow. |
|
||||
| `DOCS/TECH_CHANGELOG.md` | Records Phase 130 technical changes. |
|
||||
|
||||
## Decisions Made
|
||||
|
||||
| Decision | Rationale |
|
||||
|----------|-----------|
|
||||
| Use local label providers for Erli labels | Operator does not want to ship on Erli's carrier agreement; existing provider labels are the source of truth. |
|
||||
| Register Erli parcels through `POST /shipping/external` | Official Erli API supports external parcels with order id, vendor, status and tracking number. |
|
||||
| Store Erli vendor separately from local provider service | Erli vendor and local provider/service are different contracts and should not overload the same field. |
|
||||
| Make Erli external parcel sync non-critical | Local label generation must survive Erli API failures. |
|
||||
|
||||
## Deviations
|
||||
|
||||
| Type | Description | Impact |
|
||||
|------|-------------|--------|
|
||||
| Scope addition | Added a small migration because the existing mapping schema could not cleanly store Erli vendor separately from the local provider service. | Low risk, improves contract clarity. |
|
||||
| Implementation detail | Native InPost service data is preferred for Erli/InPost mappings where available, with existing Allegro WZA filtered service list as fallback. | Keeps Erli local-provider flow independent from Allegro where possible. |
|
||||
| Verification gap | PHPUnit binary is missing and `sonar-scanner` is not available in PATH. | Tests exist but could not be executed locally. |
|
||||
|
||||
## Issues Encountered
|
||||
|
||||
| Issue | Resolution |
|
||||
|-------|------------|
|
||||
| Erli `deliveryVendors` dictionary can return scalar rows | Normalization now preserves scalar values as both id and name. |
|
||||
| MySQL `CREATE INDEX IF NOT EXISTS` support is environment-sensitive | Migration avoids that syntax and only adds required columns. |
|
||||
| External parcel duplicate behavior could not be live-tested | Service stores successful sync payload and treats sync failures as non-critical activity entries. |
|
||||
|
||||
## Verification
|
||||
|
||||
| Check | Result |
|
||||
|-------|--------|
|
||||
| PHP syntax lint for changed PHP/view/test files | Passed |
|
||||
| `git diff --check -- . ':!.vscode/ftp-kr.sync.cache.json'` | Passed |
|
||||
| `vendor/bin/phpunit tests/Unit/ErliExternalShipmentServiceTest.php` | Not run: `vendor/bin/phpunit` missing |
|
||||
| `sonar-scanner --version` | Not run: command unavailable in PATH |
|
||||
| Manual Erli delivery tab smoke | Pending operator after migration/live configuration |
|
||||
| Manual Erli label + external parcel smoke | Pending operator after migration/live configuration |
|
||||
|
||||
## Next Phase Readiness
|
||||
|
||||
Phase 131 can build on:
|
||||
- Erli delivery mappings with local provider and Erli vendor metadata.
|
||||
- Local shipment packages with tracking numbers.
|
||||
- Non-critical Erli external parcel sync payloads stored in `shipment_packages.payload_json`.
|
||||
|
||||
Remaining concerns for Phase 131:
|
||||
- Live Erli credentials, migration execution and browser smoke are still pending operator environment.
|
||||
- Delivery tracking automation should decide how to poll/update delivery status after the external parcel exists.
|
||||
- Duplicate external parcel semantics should be confirmed against live Erli responses.
|
||||
|
||||
No blocker prevents planning Phase 131.
|
||||
Reference in New Issue
Block a user