# TODO — odlozone zadania techniczne

> Lista nieformalnych zadan do zrobienia pozniej. Kazdy wpis ma wlasny tag (np. `STAT-NET`) zeby mozna go bylo zlinkowac z komentarzy w kodzie.

## RECEIPT-NET-FIX — `receipts.total_net` powinno byc realnym netto (data: 2026-05-12)

### Kontekst
- Phase 123-01 — eksport paragonow XLSX z VAT breakdown.
- `ReceiptService::issue()` (linie 81-82) zapisuje `total_net = total_gross` (kopia, nie realne netto). To znany bug, ale nie poprawiany w 123 (poza zakresem).
- Phase 123 fallback dla legacy paragonow musi liczyc `net = brutto/1.23` zamiast brac z `total_net`, bo inaczej VAT = 0.

### Zadania
1. W `ReceiptService::buildItemsSnapshot()` agreguj `total_net` z pozycji (per stawka) — `lineTotal / (1 + vat/100)`.
2. Zwroc oba: `total_net` (suma netto per pozycja) i `total_gross` (suma brutto). Uzyj `total_net` w INSERT zamiast kopii brutto.
3. Po deploy mozna uproscic legacy fallback w `AccountingController::buildVatBreakdown()` zeby brak `vat` -> uzywal `total_net` z bazy.
4. Backfill historycznych paragonow opcjonalny (eksport teraz dziala bez tego).


## INVOICE-IDEMP-115 — idempotencja podwojnego POST do Fakturowni (data: 2026-05-10)

### Kontekst
- Phase 115-01 — wystawianie faktury z zamowienia (delegacja Fakturownia).
- Flow: `InvoiceService::issueDelegated()` -> POST do Fakturowni -> on success INSERT do `invoices`.
- Edge case: faktura zostala utworzona w Fakturowni, ale odpowiedz nie dotarla (timeout, network). Operator widzi blad, klika "Wystaw fakture" ponownie -> drugi POST -> Fakturownia tworzy DRUGA fakture.

### Zadania
1. Dorzucic idempotency-key (np. UUID per attempt zachowany w sesji albo w `invoices` ze statusem `pending_external`).
2. Sprawdzic czy Fakturownia API wspiera nag/lowek `Idempotency-Key` lub deduplikacje po referencji.
3. Alternatywa: po bledzie API, przed kolejnym POST, query Fakturowni `GET /invoices.json?q=<order_reference>` zeby sprawdzic czy faktura juz istnieje.

### Status
- Odlozone — operator musi recznie zweryfikowac w panelu Fakturowni przy bledach API.

---

## STAT-NET — netto zamowien w statystykach (data: 2026-04-19)

### Kontekst
- Statystyki `/statistics/orders` pokazuja `Netto` per dzien/kanal.
- shopPRO nie wysyla kwoty netto ani na poziomie zamowienia (`orders.total_without_tax`), ani produktow (`order_items.original_price_without_tax` — rowniez puste).
- Allegro: `orders.total_without_tax` rowniez moze byc puste.
- Obecnie dziala fallback: netto = `ROUND(total_with_tax / 1.23, 2)` gdy kolumna netto jest pusta/zerowa. Zaklada 23% VAT dla wszystkich.

### Zadania
1. **Ustalic zrodlo prawdy dla netto**:
   - Sprawdzic, czy API shopPRO udostepnia `price_netto` lub `total_netto` (payload zawiera tylko `price_brutto` + `vat`).
   - Jesli TAK → rozszerzyc mapping importu (`src/Modules/ShopPro/...`) i backfill migracja dla historycznych rekordow.
   - Jesli NIE → liczyc netto deterministycznie z `order_items.original_price_with_tax` i `order_items.tax_rate` (wtedy nie zakladamy sztywno 23%).
2. **Backfill historycznych zamowien** po wdrozeniu zrodla netto (migracja SQL + idempotentny skrypt).
3. **Zastapic fallback /1.23** w `OrdersStatisticsRepository::netAmountSql()`:
   - Preferuj `orders.total_without_tax`.
   - Jesli brak — `SUM(order_items.original_price_with_tax / (1 + order_items.tax_rate / 100) * order_items.quantity)`.
   - Stala 1.23 tylko jako ostateczny fallback przy braku item-levelu.

### Linki w kodzie
- `src/Modules/Statistics/OrdersStatisticsRepository.php` - metoda `netAmountSql()` (komentarz `TODO(STAT-NET)`).

## DELIVERY-STATUS-MGMT — zarzadzanie statusami znormalizowanymi z panelu (data: 2026-04-26)

### Kontekst
- Aktualnie statusy znormalizowane (`created`, `confirmed`, `picked_up`, `in_transit`, itd.) sa stalymi w kodzie (`DeliveryStatus.php`).
- Dodanie nowego statusu wymaga zmiany kodu + deploymentu.
- Panel ustawien pozwala tylko mapowac surowe statusy kurierow na istniejace statusy znormalizowane - nie mozna dodac nowego znormalizowanego statusu z UI.

### Zadania
1. Wyniesc liste statusow znormalizowanych do tabeli DB (np. `delivery_statuses`) z kolumnami: `key`, `label_pl`, `color`, `sort_order`, `is_terminal`, `is_system`.
2. Statusy systemowe (`delivered`, `returned`, `cancelled`) oznaczac flaga `is_system = true` - nieedytowalne z UI (maja specjalne znaczenie w kodzie).
3. Panel `/settings/delivery-statuses` - CRUD dla statusow niebedacych systemowymi (dodaj, zmien etykiete/kolor, usun jesli nieuzywany).
4. `DeliveryStatus::ALL_STATUSES`, `LABEL_PL` i badge CSS zastapic dynamicznym ladowaniem z DB (cache per-request).
5. Automatyzacje i mapowania kurierow - dropdown statusow znormalizowanych pobierany z DB zamiast hardcoded.

### Uwagi
- `TERMINAL_STATUSES` musi zostac zachowane jako lista systemowych statusow koncowych - te nie powinny byc usuwalne.
- Przy usuwaniu statusu znormalizowanego - blokada jesli uzywany w `delivery_status_mappings` lub `shipment_packages.delivery_status`.
