14 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, delegation
| phase | plan | type | wave | depends_on | files_modified | autonomous | delegation | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 130-erli-shipments-labels | 01 | execute | 1 |
|
true | auto |
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.
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/priceListsDetailsexpose Erli shipping/delivery dictionaries and cenniki.POST /shipping/externalcreates external parcels withorderId,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
## 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-scannerattempted after APPLY- Optional flows considered if implementation risk warrants them
<acceptance_criteria>
AC-1: Erli Shipping Contract Is Used Where Safe
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
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
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
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
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
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>
Task 1: Extend Erli API and mapping repository for shipping src/Core/Constants/IntegrationSources.php, src/Modules/Settings/ErliApiClient.php, src/Modules/Settings/CarrierDeliveryMethodMappingRepository.php, DOCS/DB_SCHEMA.md, DOCS/ARCHITECTURE.md 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. `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. AC-1 foundation complete and AC-2 persistence ready. Task 2: Add Erli delivery mapping tab 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 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()`. `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. AC-2 satisfied; UI is consistent with Phase 129 tab pattern. Task 3: Use mappings during shipment creation and sync external parcel to Erli 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 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. `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. AC-3, AC-4, AC-5 and AC-6 satisfied.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.
<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>