Files
orderPRO/.paul/phases/90-delivery-price-import-fix/90-01-PLAN.md
2026-04-08 23:22:48 +02:00

8.3 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, delegation
phase plan type wave depends_on files_modified autonomous delegation
90-delivery-price-import-fix 01 execute 1
src/Modules/Orders/OrderImportRepository.php
src/Modules/Settings/AllegroOrderImportService.php
src/Modules/Settings/ShopproOrderMapper.php
database/migrations/20260408_000090_backfill_delivery_price.sql
true off
## Goal Naprawic brak zapisu `delivery_price` przy imporcie zamowien — kolumna istnieje w tabeli `orders` ale nigdy nie jest wypelniana, przez co paragony nie zawieraja kosztu wysylki.

Purpose

Phase 70 naprawil ReceiptService (odczyt delivery_price), ale zrodlo danych (import) nigdy nie zapisuje wartosci. Paragon #53 dla zamowienia #165 pokazuje 17 zl zamiast 30,50 zl — brakuje kosztu wysylki.

Output

  • Import Allegro i shopPRO zapisuje delivery_price do tabeli orders
  • Istniejace zamowienia maja backfill z preferences_json / payload_json
  • Nowe paragony prawidlowo uwzgledniaja koszt wysylki
## Project Context @.paul/PROJECT.md @.paul/ROADMAP.md @.paul/STATE.md

Prior Work

@.paul/phases/70-receipt-shipping-cost/70-01-SUMMARY.md (ReceiptService juz poprawnie odczytuje delivery_price)

Source Files

@src/Modules/Orders/OrderImportRepository.php (insertOrder/updateOrder/orderParams — brak delivery_price) @src/Modules/Settings/AllegroOrderImportService.php (linia 232: delivery_cost idzie do preferences_json, nie do delivery_price) @src/Modules/Settings/ShopproOrderMapper.php (linia 94: $transportCost uzywany do totalGross, nie mapowany do delivery_price) @database/migrations/20260302_000018_create_orders_tables_and_schedule.sql (linia 16: kolumna delivery_price DECIMAL(12,2) NULL)

<acceptance_criteria>

AC-1: Import Allegro zapisuje delivery_price

Given zamowienie Allegro z delivery.cost w danych API
When zamowienie jest importowane/aktualizowane przez AllegroOrderImportService
Then kolumna orders.delivery_price zawiera wartosc delivery.cost

AC-2: Import shopPRO zapisuje delivery_price

Given zamowienie shopPRO z transport_cost/delivery_cost w payload
When zamowienie jest importowane przez ShopproOrderMapper
Then kolumna orders.delivery_price zawiera wartosc kosztu dostawy

AC-3: Backfill istniejacych zamowien

Given istniejace zamowienia z delivery_price = NULL
When migracja backfill zostanie uruchomiona
Then zamowienia Allegro maja delivery_price z preferences_json->delivery_cost
And zamowienia shopPRO maja delivery_price z payload_json (transport_cost/delivery_cost/shipping.cost)

AC-4: Paragon zawiera koszt wysylki

Given zamowienie z delivery_price > 0 (po backfill lub nowym imporcie)
When wystawiany jest paragon
Then paragon zawiera pozycje "Koszt wysylki" z prawidlowa kwota
And suma paragonu = suma produktow + koszt wysylki

</acceptance_criteria>

Task 1: Dodac delivery_price do OrderImportRepository + mapowania importerow src/Modules/Orders/OrderImportRepository.php, src/Modules/Settings/AllegroOrderImportService.php, src/Modules/Settings/ShopproOrderMapper.php 1. **OrderImportRepository.php** — dodac `delivery_price` do: - `insertOrder()` SQL INSERT (linia ~122): dodac kolumne `delivery_price` i placeholder `:delivery_price` - `updateOrder()` SQL UPDATE (linia ~150): dodac `delivery_price = :delivery_price` - `orderParams()` (linia ~196): dodac `'delivery_price' => $orderData['delivery_price'] ?? null`
2. **AllegroOrderImportService.php** — dodac `delivery_price` do tablicy danych zamowienia:
   - Okolo linii 232, obok `preferences_json`, dodac:
     `'delivery_price' => isset($delivery['cost']) ? (float) ($delivery['cost']['amount'] ?? $delivery['cost']) : null,`
   - Allegro API zwraca delivery.cost jako obiekt {amount, currency} lub float — obsluzyc oba formaty
   - Sprawdzic dokladna strukture Allegro API response dla delivery.cost

3. **ShopproOrderMapper.php** — dodac `delivery_price` do tablicy `$order` (linia ~131):
   - Wartosc `$transportCost` jest juz obliczona w linii 94
   - Dodac do tablicy `$order`: `'delivery_price' => $transportCost,`

Avoid: Nie zmieniac logiki preferences_json — delivery_cost w preferences nadal powinien byc zapisywany (backward compat).
- grep -n "delivery_price" src/Modules/Orders/OrderImportRepository.php — powinno byc w INSERT, UPDATE i orderParams - grep -n "delivery_price" src/Modules/Settings/AllegroOrderImportService.php — powinno byc w tablicy danych zamowienia - grep -n "delivery_price" src/Modules/Settings/ShopproOrderMapper.php — powinno byc w tablicy $order AC-1 i AC-2 satisfied: oba importery zapisuja delivery_price do tabeli orders Task 2: Migracja backfill delivery_price dla istniejacych zamowien database/migrations/20260408_000090_backfill_delivery_price.sql Utworzyc migracje SQL ktora wypelni delivery_price dla istniejacych zamowien:
1. **Allegro** — wyciagnac z preferences_json:
   ```sql
   UPDATE orders
   SET delivery_price = JSON_UNQUOTE(JSON_EXTRACT(preferences_json, '$.delivery_cost.amount'))
   WHERE source = 'allegro'
     AND delivery_price IS NULL
     AND preferences_json IS NOT NULL
     AND JSON_EXTRACT(preferences_json, '$.delivery_cost') IS NOT NULL;
   ```
   Plus fallback dla przypadku gdy delivery_cost jest plain number (nie obiekt):
   ```sql
   UPDATE orders
   SET delivery_price = CAST(JSON_UNQUOTE(JSON_EXTRACT(preferences_json, '$.delivery_cost')) AS DECIMAL(12,2))
   WHERE source = 'allegro'
     AND delivery_price IS NULL
     AND preferences_json IS NOT NULL
     AND JSON_EXTRACT(preferences_json, '$.delivery_cost') IS NOT NULL
     AND JSON_TYPE(JSON_EXTRACT(preferences_json, '$.delivery_cost')) != 'OBJECT';
   ```

2. **shopPRO** — wyciagnac z payload_json:
   ```sql
   UPDATE orders
   SET delivery_price = COALESCE(
       CAST(JSON_UNQUOTE(JSON_EXTRACT(payload_json, '$.transport_cost')) AS DECIMAL(12,2)),
       CAST(JSON_UNQUOTE(JSON_EXTRACT(payload_json, '$.delivery_cost')) AS DECIMAL(12,2)),
       CAST(JSON_UNQUOTE(JSON_EXTRACT(payload_json, '$.shipping.cost')) AS DECIMAL(12,2))
   )
   WHERE source = 'shoppro'
     AND delivery_price IS NULL
     AND payload_json IS NOT NULL;
   ```

Avoid: Nie nadpisywac juz ustawionych wartosci (warunek `delivery_price IS NULL`).
- Plik migracji istnieje w database/migrations/ - SQL jest poprawny skladniowo (sprawdzic JSON_EXTRACT syntax) AC-3 satisfied: istniejace zamowienia maja delivery_price z JSON

DO NOT CHANGE

  • src/Modules/Accounting/ReceiptService.php (juz poprawnie odczytuje delivery_price — Phase 70)
  • src/Modules/Accounting/ReceiptController.php (juz poprawnie odczytuje delivery_price)
  • resources/views/orders/receipt-create.php (juz wyswietla koszt wysylki)
  • resources/views/receipts/show.php (renderuje items_json ktory juz zawiera "Koszt wysylki")
  • resources/views/receipts/print.php (jak wyzej)

SCOPE LIMITS

  • Nie zmieniac struktury preferences_json — delivery_cost nadal tam zostaje
  • Nie zmieniac formatu items_json w paragonach
  • Nie przeliczac istniejacych juz wystawionych paragonow (snapshot jest zamrozony)
Before declaring plan complete: - [ ] `delivery_price` jest w INSERT, UPDATE i orderParams w OrderImportRepository - [ ] AllegroOrderImportService przekazuje delivery_price w danych zamowienia - [ ] ShopproOrderMapper przekazuje delivery_price w danych zamowienia - [ ] Migracja backfill istnieje i ma poprawny SQL - [ ] Brak bledow skladniowych PHP (php -l na zmienionych plikach) - [ ] AC-4: Nowy paragon dla zamowienia z delivery_price > 0 zawiera "Koszt wysylki"

<success_criteria>

  • Wszystkie taski ukonczone
  • Nowe zamowienia importowane z Allegro/shopPRO maja delivery_price w tabeli orders
  • Istniejace zamowienia maja delivery_price po backfill
  • Paragony prawidlowo pokazuja koszt wysylki </success_criteria>
After completion, create `.paul/phases/90-delivery-price-import-fix/90-01-SUMMARY.md`