Files
orderPRO/.paul/PROJECT.md
Jacek Pyziak 33ee1a1cf5 feat(115): wystawianie faktury z zamowienia (lokalne + delegowane Fakturownia)
Phase 115 complete (vertical slice "zamowienie z NIP -> faktura PDF"):
- Task 1: InvoiceRepository + InvoiceService (dual-flow orchestrator) +
  InvoiceIssueException + FakturowniaApiClient::createInvoice + buildPdfUrl
- Task 2: InvoiceController + OrdersController::toggleInvoiceRequested +
  OrdersRepository::setInvoiceRequested + auto-import invoice_requested z
  Allegro (invoice.required) i shopPRO (5-key flexible parser) + show.php
  (toggle w zakladce Platnosci + warunkowy przycisk Wystaw fakture)
- Task 3: Lista wystawionych /settings/accounting/invoices/issued z filtrami
  + invoice_preview + invoice_pdf Dompdf template + hub link
- Task 3b (dodany): NIP lookup przez MF Biala Lista (publiczne API, bez
  rejestracji) — MfWhitelistApiClient w src/Core/Http/ + /api/nip/lookup +
  przycisk "Pobierz z GUS" w formularzu

Auto-fixes podczas smoke testu (5):
- GUS endpoint Fakturowni nie istnial (HTML 404 -> "json is not valid");
  switch na MF Biala Liste
- PHP 8.5 curl_close() deprecation wycieka HTML przed JSON; usuniete z
  MfWhitelistApiClient i FakturowniaApiClient (3 miejsca)
- Fakturownia 422 payment_to_kind_days (nieistniejace pole) -> usuniete
- Generic "error" w 422 -> parser plaskuje errors: {pole: [...]} +
  error_log z 1000 znakow raw body
- Fakturownia security odrzuca seller_*/department_id jako "create new
  department"; usuniete z payloadu (Fakturownia uzywa danych konta)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 23:34:50 +02:00

258 lines
27 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# orderPRO
## What This Is
Aplikacja do zarzÄ…dzania zamĂłwieniami pobieranymi z wielu ĹşrĂłdeĹ sprzedaĹĽy (Allegro, Erli, wĹasne sklepy internetowe). UmoĹĽliwia generowanie etykiet przewozowych u kurierĂłw oraz docelowo zarzÄ…dzanie produktami i stanami magazynowymi w jednym miejscu.
## Core Value
Sprzedawca moĹĽe obsĹugiwać zamĂłwienia ze wszystkich kanaĹĂłw sprzedaĹĽy i nadawać przesyĹki bez przeĹÄ…czania siÄ™ miÄ™dzy platformami.
## Current State
| Attribute | Value |
|-----------|-------|
| Version | 3.7.0-dev |
| Status | v3.7 in progress — Phases 113 (Fakturownia Foundation) + 114 (Accounting Configs Refactor) + 115 (Wystawianie faktury z zamowienia) shipped |
| Last Updated | 2026-05-10 |
## Requirements
### Validated (Shipped)
- [x] Integracja z Allegro — pobieranie zamówień
- [x] Generowanie etykiet (InPost)
- [x] Performance: N+1 subqueries fix, DB indexes — Phase 7
- [x] Stability: SSL verification, cron throttle — Phase 7
- [x] UX: orderpro-to-allegro disable, lista zamówień poprawki — Phase 7
- [x] Unit tests: AllegroTokenManager, AllegroOrderImportService (12 testów) — Phase 7
- [x] InPost ShipX API: natywny provider niezależny od Allegro — Phase 7
- [x] DB Foundation: tabele receipts, receipt_configs, receipt_number_counters + company_settings extended — Phase 8
- [x] Konfiguracja paragonĂłw (CRUD w Ustawienia > KsiÄ™gowoĹć) — Phase 9
- [x] Wystawianie paragonów z zamówienia (formularz, snapshoty, atomowe numerowanie) — Phase 10
- [x] Podgląd i wydruk paragonu (HTML+PDF, dompdf) — Phase 11
- [x] Sekcja KsiÄ™gowoĹć — lista paragonĂłw z filtrami, paginacjÄ…, eksportem XLSX — Phase 12
- [x] DB Foundation: tabele email_mailboxes, email_templates, email_logs — Phase 13
- [x] Skrzynki pocztowe SMTP (CRUD + test poĹÄ…czenia) — Phase 13
- [x] Szablony wiadomoĹci e-mail (CRUD + Quill.js + system zmiennych + zaĹÄ…czniki) — Phase 14
- [x] WysyĹka e-mail z zamĂłwieĹ„ (resolwer zmiennych, zaĹÄ…czniki, log) — Phase 15
- [x] Zadania automatyczne — reguĹy zdarzenie/warunki/akcje (CRUD + watcher/executor) — Phase 16
- [x] Ostrzeżenie i potwierdzenie przy duplikacie paragonu — Phase 17
- [x] Print Queue Backend: REST API + API key auth + CRUD kluczy — Phase 18
- [x] UI Integration: przycisk Drukuj, bulk print, kolejka wydruku — Phase 19
- [x] Windows Client: C# WinForms tray app, polling API, druk etykiet PDF — Phase 20
- [x] WyĹwietlanie nazwy integracji zamiast generycznego "shopPRO" na liĹcie i szczegĂłĹach zamĂłwienia — Phase 21
- [x] Naprawa zapisu REGON, BDO, KRS i logo w ustawieniach firmy — Phase 22
- [x] Presety przesyĹek — customowe przyciski szybkiego wypeĹniania formularza (CRUD + autofill + zarzÄ…dzanie) — Phase 23-25
- [x] RÄ™czny numer przesyĹki — dodawanie tracking number bez API przewoĹşnika — Phase 26
- [x] Tracking backend — dwupoziomowe statusy dostawy, 3 implementacje providerów, cron handler — Phase 27
- [x] Tracking UI i ustawienia crona — statusy dostawy i konfiguracja harmonogramu — Phase 28-29
- [x] UI readability tweak - rozdzielenie koloru przyciskow akcji od naglowkow sekcji (button primary distinction) - Phase 30
- [x] Usuniecie bulk print "Drukuj etykiety" z listy zamowien (`/orders/list`) wraz z endpointem bulk - Phase 40
- [x] Ograniczenie szumu logow importu Allegro i deduplikacja wpisow activity log - Phase 41
- [x] Automatyzacja: event `shipment.status_changed` + warunki statusowe przesylki - Phase 42
- [x] Usuwanie wpisu z kolejki druku etykiet z panelu ustawien - Phase 43
- [x] Szybka zmiana statusu zamowienia z listy zamowien (inline dropdown + AJAX) - Phase 44
- [x] Synchronizacja statusow orderPRO -> shopPRO (cron push, reverse mapping, PUT API) — Phase 45
- [x] Synchronizacja statusow orderPRO -> Allegro (cron push, reverse mapping, fulfillment status update API) - Phase 46
- [x] Automatyzacja przesylek: natychmiastowy event `shipment.created` + akcja `update_shipment_status` - Phase 47
- [x] Szablony e-mail: zmienne `przesylka.numer` i `przesylka.link_sledzenia` z provider-aware linkiem sledzenia - Phase 48
- [x] Automatyzacja: tab Historia z filtrowaniem/paginacja + retencja 30 dni + akcja update_order_status - Phase 49
- [x] Allegro: automatyczne przekazywanie numeru przesylki do checkout form po utworzeniu paczki (tylko source=allegro) - Phase 50
- [x] Email HTML Layout: header/footer HTML per skrzynka pocztowa, dual-mode edytor (Quill + HTML source), kompozycja header+body+footer, podglad — Phase 51
- [x] Mobile Main Menu: hamburger, slide-in overlay sidebar, backdrop na mobile <=768px — Phase 52
- [x] Mobile Status Panel Toggle: zwijany/rozwijany panel statusow na /orders/list — Phase 53
- [x] Order Detail Image Hover: hover zoom na miniaturkach produktow w /orders/{id} — Phase 54
- [x] Desktop Collapsed Sidebar Fix: ukrycie etykiet, centrowanie ikon w zwiniętym sidebarze — Phase 55
- [x] Dodawanie płatności ręcznych + push set_paid do shopPRO — Phase 56
- [x] Automatyzacja: event `payment.status_changed` + warunek `payment_status` (0/1/2) — Phase 57
- [x] Zachowanie danych formularza automatyzacji po bledzie walidacji — Phase 58
- [x] Automatyzacja: event `order.status_changed` + warunek `order_status` — Phase 59
- [x] Automatyzacja: event `order.status_aged` (cron) + warunek `days_in_status` — Phase 60
- [x] Aktywacja przycisku Platnosc w headerze zamowienia + poprawa odstepu w formularzu platnosci — Phase 61
- [x] Ochrona danych lokalnych przy re-imporcie + rozroznienie import/aktualizacja w activity log shopPRO — Phase 62
- [x] Import i wyswietlanie personalizacji produktow z shopPRO (custom_fields) + naprawa daty zamowienia — Phase 63
- [x] Data wystawienia paragonu z dokladnoscia do godziny i minuty (DATE -> DATETIME) — Phase 64
- [x] Koszt wysylki jako pozycja paragonu (bugfix buildItemsSnapshot + delivery_price) — Phase 70
- [x] Import atrybutow produktow z shopPRO (attributes + custom_fields w personalizacji) — Phase 71
- [x] Zapamiętywanie wybranej liczby wierszy na stronie (per_page) w localStorage — Phase 72
- [x] Wyszukiwanie zamowien po nazwie produktu (EXISTS subquery) — Phase 73
- [x] Odwrocenie mapowania statusow: orderPRO po lewej, zewnetrzne po prawej (shopPRO + Allegro) — Phase 74
- [x] Rozdzielenie mapowania push/pull statusow shopPRO + ochrona statusu przy re-imporcie — Phase 75
- [x] Fallback danych odbiorcy z customer gdy delivery nie ma adresu (shopPRO) — Phase 76
- [x] Naprawa auto-fill kwoty pobrania (COD) dla zamowien shopPRO — Phase 77
- [x] Presety przesylek: auto-submit formularza po autofill — Phase 78
- [x] Import pola message z shopPRO do personalizacji pozycji i notatek zamowienia — Phase 79
- [x] Przeladowanie listy zamowien po zmianie statusu inline (location.reload) — Phase 80
- [x] Globalna wyszukiwarka zamowien w topbarze (AJAX search, dropdown, nawigacja klawiaturowa) — Phase 81
- [x] Tooltip z pelna nazwa produktu na liscie zamowien (natywny title attribute) — Phase 82
- [x] Dedykowane pull mapowanie statusow Allegro przy imporcie zamowien — Phase 83
- [x] Automatyzacja: zdarzenie `order.imported` przy pobraniu zamowienia (Allegro + shopPRO) — Phase 84
- [x] Filtrowanie zamowien po grupie statusow (klikalna nazwa grupy na panelu) — Phase 85
- [x] Naprawa tworzenia przesylek COD Apaczka — dodanie numeru konta bankowego do payloadu API — Phase 86
- [x] Usuwanie przesylek z zakladki Przesylki w szczegolach zamowienia (z potwierdzeniem) — Phase 87
- [x] Naglowek User-Agent w requestach Allegro API (art. 3.4.c Regulaminu, deadline 30.06.2026) — Phase 88
- [x] Publiczna strona /info dla Allegro User-Agent URL — Phase 89
- [x] Naprawa zapisu delivery_price przy imporcie zamowien (Allegro + shopPRO) + backfill — Phase 90
- [x] Resilient polling w OrderPROPrint — 3 warstwy timeout (HttpClient/CancellationToken/Watchdog) — Phase 91
- [x] Ikona kopiowania imienia i nazwiska kupujacego w szczegolach zamowienia (clipboard copy) — Phase 92
- [x] Checkbox "Zapamietaj mnie" z persistent cookie 30 dni + dzialajace komunikaty bledow logowania — Phase 93
- [x] Popup podgladu zamowienia na liscie zamowien (zdjecia, personalizacja, notatki, kopiowanie) — Phase 94
- [x] AJAX refresh tabeli i panelu statusow po zmianie statusu inline (bez reload strony) — Phase 95
- [x] Automatyzacja: warunek "Metoda platnosci" (COD/Przelew/Karta/Inna) oparty na external_payment_type_id — Phase 96
- [x] Polautomatyczne generowanie projektow graficznych PSD z zamowien (mapowania, komenda Claude, Photoshop API, flagi statusu) + rename external_status_id na status_code — Phase 97
- [x] Event automatyzacji `order.imported` ogranicza sie do pierwszego importu zamowienia + backfill statusow w_realizacji -> wyslane dla zamowien z istniejaca przesylka — Phase 98
- [x] Preset przesylek nadpisuje wylacznie wymiary+wage paczki + polling kolejki wydruku + auto-click ostatniej etykiety po utworzeniu przesylki + usuniecie placeholderow "-" — Phase 100
- [x] Wizualna flaga wiekowa na liscie zamowien: czerwona ramka o rosnacej intensywnosci dla zamowien 4-7+ dniowych — Phase 101
- [x] Naprawa tworzenia przesylek Apaczka dla dlugich adresow: auto-truncate dla uslug punktowych (ORLEN/Paczkomat), walidacja + blad dla uslug kurierskich — Phase 102
- [x] Naprawa auto-click etykiety po utworzeniu przesylki: klik na najnowsza paczke zamiast najstarszej (buttons[0] vs buttons[length-1]) — Phase 103
- [x] Apaczka Paczka w Weekend: checkbox "Dostawa w weekend (sobota)" dla uslug InPost paczkomatowych + mapowanie pole formularza weekend_delivery -> option[19] w API Apaczki — Phase 104
- [x] Statystyki zamowien: widok `/statistics/orders` z filtrami (daty, kanaly multiselect, grupy statusow multiselect) i raportem dziennym per kanal (Allegro, shopPRO per integracja); hotfix collation MySQL + fallback netto 23% VAT — Phase 105
- [x] Wersja mobilna — modul po module (v3.0) — shipped across phases 52105
- [x] Alert o kliencie z historia zwrotow: badge w liscie zamowien (kolumna buyer) + czerwony banner u gory szczegolow zamowienia; matching OR po email/phone/name; `<details>` z lista zwroconych zamowien — Phase 106
- [x] Idempotentna jednorazowa wysylka e-mail per zamowienie: tabela deduplikacji `automation_email_once_deliveries` (UNIQUE KEY rule_id+action_id+order_id), checkbox "Wyslij tylko raz" w konfiguracji akcji, markSent() tylko po sukcesie — Phase 107
- [x] Delivery Status Management: tabela `delivery_statuses` z CRUD panelem `/settings/delivery-statuses`, `DeliveryStatus::setRepository()` z DB fallbackiem, integracja DB-driven w dropdownach automatyzacji (warunek shipment_status + akcja update_shipment_status), osobna podstrona formularza CRUD (BREAKING: drop backward compat dla starych grupowych kluczy automatyzacji) — Phase 108
- [x] Checkbox dropdown multi-select filters: `/statistics/orders` korzysta z progresywnie ulepszanych selectow multiple z checkboxami, opcja "Wszystkie" i zachowanym kontraktem GET — Phase 109
- [x] Podsumowanie statystyk: `Statystyki -> Podsumowanie` z miesiecznymi wykresami liczby i wartosci zamowien per integracja plus `Razem`, Chart.js i fallback tabelaryczny — Phase 110
- [x] Re-import zamowienia (Allegro + shopPRO) wykrywa tranzycje payment_status 0/1->2 i emituje `payment.status_changed` (chain reguly #7 zmienia status na `w_realizacji`); naprawa luki dla zamowien zaimportowanych przed potwierdzeniem platnosci (case #864) + backfill CLI — Phase 111
- [x] Re-import istniejacego zamowienia jest delta-only: skip dla pozycji/adresow/notatek (stabilne `order_items.id`, ochrona `project_generated`), zawezony `updateOrderDelta()`, propagacja anulowania ze zrodla, identical-payload no-op guard (case #882) — Phase 112
- [x] Fundament v3.7 Invoices: tabele `invoices`, `invoice_configs`, `invoice_number_counters`, `fakturownia_integration_settings` + `orders.invoice_requested`; CRUD kont Fakturowni z testem polaczenia API (`/settings/integrations/fakturownia`); karta w hubie integracji — Phase 113
- [x] Ksiegowosc: refaktor `/settings/accounting` na hub-rozdroze + osobne podstrony `/receipts` i `/invoices` + edycja na osobnym widoku; pelen CRUD `invoice_configs` z opcja delegacji do Fakturowni (conditional integration_id, serwerowa walidacja); seed `Domyslny VAT`; globalny modul `confirm-delete.js` — Phase 114
- [x] Wystawianie faktury z zamowienia: toggle `orders.invoice_requested` w zakladce Platnosci + auto-set z importu (Allegro `invoice.required` / shopPRO 5-key parser); formularz z auto-fillem NIP przez MF Biala Liste (publiczne API); dual flow lokalny (Dompdf + atomowy `invoice_number_counters`) / delegowany (POST do Fakturowni przed INSERT, redirect 302 do natywnego PDF); lista `/settings/accounting/invoices/issued` z filtrami; snapshot pattern w `invoices` JSON; PHP 8.5-compatible (curl_close removed) — Phase 115
### Deferred
- [ ] Eliminacja zduplikowanego kodu: SslCertificateResolver, ToggleableRepositoryTrait, RedirectPathResolver, ReceiptService — Phase 68
- [ ] STAT-NET: pobieranie netto z shopPRO lub wyliczanie z `order_items.tax_rate` (unikniecie sztywnego 23% VAT) — `.paul/TODO.md`
### Active (In Progress)
- [ ] v3.7 Invoices — wystawianie faktur dla klientow z NIP przez integracje z Fakturownia (multi-account, lokalna numeracja z opcja delegacji, rozdzielenie przyciskow paragon/faktura, osobne podstrony edycji configs). Phases 113 + 114 + 115 shipped; ewentualne kolejne fazy (np. eksport XLSX, invoice.created event, idempotencja Fakturowni) w kolejce.
### Planned (Next)
- [ ] ZarzÄ…dzanie produktami
- [ ] ZarzÄ…dzanie stanami magazynowymi
- [ ] Mobile Orders List / Mobile Order Details / Mobile Settings — pelna wersja mobilna pozostalych ekranow
### Out of Scope
- [Do zdefiniowania podczas planowania]
## Target Users
**Primary:** Sprzedawcy wielokanaĹowi (Allegro, Erli, wĹasny sklep)
- ObsĹugujÄ… zamĂłwienia z wielu platform jednoczeĹnie
- PotrzebujÄ… szybkiego nadawania przesyĹek
- ChcÄ… jednego miejsca do zarzÄ…dzania sprzedaĹĽÄ…
## Context
**Business Context:**
Rynek narzÄ™dzi do zarzÄ…dzania sprzedaĹĽÄ… wielokanaĹowÄ… (podobne rozwiÄ…zania: base.com, apilo.com). Aplikacja budowana jako wĹasne rozwiÄ…zanie.
**Technical Context:**
PHP (XAMPP/Laravel), integracje z API marketplace'Ăłw (Allegro, Erli) oraz API przewoĹşnikĂłw (InPost i inne).
## Constraints
### Technical Constraints
- PHP/XAMPP — Ĺrodowisko Windows lokalne
- Medoo + prepared statements (bez sklejania SQL)
- Brak natywnych `alert()`/`confirm()` — używać `window.OrderProAlerts`
- Metody pomocnicze string/date/color → `App\Core\Support\StringHelper` (nie powielać w klasach)
- Zarządzanie tokenami OAuth Allegro → `App\Modules\Settings\AllegroTokenManager`
- Kompozycja obiektĂłw crona → `App\Modules\Cron\CronHandlerFactory` (jedyne miejsce `new AllegroIntegrationRepository` i in. w kontekĹcie crona)
- Pole CSRF w formularzach HTTP: zawsze `_token` (nie `_csrf_token`)
### Business Constraints
- [Do zdefiniowania podczas planowania]
## Key Decisions
| Decision | Rationale | Date | Status |
|----------|-----------|------|--------|
| WĹasne rozwiÄ…zanie zamiast gotowego SaaS | PeĹna kontrola nad funkcjonalnoĹciÄ… | 2026-03-12 | Active |
| AllegroTokenManager wydzielony z 4 klas OAuth | Eliminacja duplikacji logiki odĹwieĹĽania tokenĂłw | 2026-03-12 | Active |
| StringHelper jako final static class w Core/Support | Centralizacja 19 kopii helperĂłw string/date/color z 15+ klas | 2026-03-12 | Active |
| CronHandlerFactory jako jedyne miejsce kompozycji crona | Application.php i bin/cron.php byĹy rozsynchronizowane — 2 bugi w bin/cron.php | 2026-03-13 | Active |
| Pole CSRF w formularzach: `_token` (nie `_csrf_token`) | Standardyzacja na nazwÄ™ uĹĽywanÄ… przez wiÄ™kszoĹć kodu (10+ kontrolerĂłw); eliminacja ryzyka pomyĹki przy nowych formularzach | 2026-03-13 | Active |
| Flash messages: Flash::set('module.type') / Flash::get('module.type', '') | Jeden wzorzec w caĹej aplikacji; eliminacja bezpoĹrednich zapisĂłw $_SESSION | 2026-03-13 | Active |
| validateXxxInput(): ?string i validateXxxAccess(): ?Response jako wzorce helperów walidacji | Redukcja return statements do ≤3; spójny wzorzec kontrolerów | 2026-03-13 | Active |
| God class split via move-method bez zmiany logiki | ShopproOrdersSyncService 39â†9 metod; AllegroIntegrationController 35â†25 — czysty podziaĹ przez ekstrakcjÄ™ klas | 2026-03-13 | Active |
| AllegroIntegrationController pozostaje przy 25 metodach (nie ≤15) | PeĹny podziaĹ wymaga AllegroImportScheduleService — poza zakresem v0.1 | 2026-03-13 | Active |
| dg/bypass-finals do testów final classes | Wszystkie klasy final — mockowanie przez bypass-finals zamiast usuwania final | 2026-03-15 | Active |
| InPost ShipX API zamiast Allegro WZA remap | InpostIntegrationRepository jest pod ShipX; niezaleĹĽnoĹć od Allegro | 2026-03-15 | Active |
| vendor/ w ftp-kr ignore | Auto-upload dev deps na serwer powodowaĹ Fatal Error | 2026-03-15 | Active |
| Snapshot pattern: seller/buyer/items jako JSON w receipts | Dane zamroĹĽone w momencie wystawienia — niezaleĹĽne od przyszĹych zmian ĹşrĂłdĹa | 2026-03-15 | Active |
| Atomowe numerowanie paragonĂłw: INSERT ON DUPLICATE KEY UPDATE | Bezpieczne generowanie kolejnych numerĂłw bez race conditions | 2026-03-15 | Active |
| ModuŠAccounting w osobnym namespace | App\Modules\Accounting — separacja od Settings | 2026-03-15 | Active |
| ATTACHMENT_TYPES jako centralna mapa typĂłw zaĹÄ…cznikĂłw | RozszerzalnoĹć: nowy typ = 1 linia w tablicy PHP, bez zmian DB/widoku | 2026-03-16 | Active |
| Quill.js 2.0.3 CDN dla edytora szablonĂłw | Brak build pipeline w projekcie; CDN prostszy | 2026-03-16 | Active |
| Event automatyzacji `shipment.created` uruchamiany natychmiast po utworzeniu paczki | Reakcje automatyzacji nie czekaja na cron tracking; przeplyw jest natychmiastowy | 2026-03-28 | Active |
| Akcja `update_shipment_status` emituje `shipment.status_changed` tylko przy realnej zmianie | Brak petli automatyzacji i brak falszywych triggerow | 2026-03-28 | Active |
| Zmienne e-mail przesylki bazuja na najnowszej paczce `shipment_packages` i `DeliveryStatus::trackingUrl` | Jeden spojny kontrakt dla numeru i linku sledzenia w szablonach | 2026-03-28 | Active |
| Historia automatyzacji zapisywana per regula (success/failed) i czyszczona cronem po 30 dniach | Audyt wykonywania regul bez recznego utrzymania danych | 2026-03-28 | Active |
| Akcja update_order_status korzysta z OrdersRepository::updateOrderStatus | Spojnosc z historia statusow i activity log bez duplikowania logiki | 2026-03-28 | Active |
| Push waybilla do Allegro checkout forms wykonywany tylko dla zamowien source=allegro i jest niekrytyczny dla lokalnego tworzenia paczki | Eliminacja recznego kroku po stronie Allegro bez ryzyka utraty lokalnie utworzonej przesylki przy bledzie API | 2026-03-28 | Active |
| Event `order.imported` emitowany tylko przy pierwszym imporcie zamowienia | Unikniecie duplikatow reakcji automatyzacji przy kolejnych synchronizacjach | 2026-04-15 | Active |
| Preset przesylek nadpisuje wylacznie wymiary+wage + auto-submit po autofill | Single responsibility preseta + szybszy flow operatora | 2026-04-17 | Active |
| Re-import istniejacego zamowienia jest delta-only — `replaceAddresses/Items/Notes` tylko przy `created=true`; `updateOrderDelta()` zawezony do payment_status/total_paid/status_code/is_canceled_by_buyer/source_updated_at/payload_json/fetched_at | Zamowienia zarzadzane sa w orderPRO (nie w zrodle), wiec re-import nie powinien nadpisywac stanu lokalnego ani lamac stabilnosci `order_items.id` (case #882: znikajace `project_generated`) | 2026-05-07 | Active |
| Identical-payload no-op guard w re-imporcie via `normalizePayloadJson()` (decode->encode->compare) | Eliminacja niepotrzebnych write'ow do binloga/replikacji przy cyklicznym imporcie tych samych zamowien; fail-open gdy klucze JSON sa reorderowane miedzy syncami | 2026-05-07 | Active |
| Statistics channelSql: explicit `COLLATE utf8mb4_unicode_ci` na CASE z `CAST(integration_id AS CHAR)` | Unikniecie `1271 Illegal mix of collations` w `IN (...)` z parametrami bindowanymi; pattern dla przyszlych agregacji per-integration | 2026-04-19 | Active |
| Statistics netto fallback `ROUND(gross / 1.23, 2)` gdy `total_without_tax` puste | shopPRO nie wysyla netto ani w zamowieniu ani w `order_items`; tymczasowy fallback — docelowy fix w `.paul/TODO.md` (STAT-NET) | 2026-04-19 | Active |
| ON DUPLICATE KEY UPDATE created_at = created_at dla idempotentnego markSent() | Unikniece silent failure i race condition przy rownolegych cronach; thread-safe bez wyjatkow | 2026-04-25 | Active |
| send_once_per_order opt-in przez checkbox (domyslnie off) | Wsteczna zgodnosc — istniejace reguly nie zmieniaja zachowania; markSent() tylko po sukcesie wysylki | 2026-04-25 | Active |
| DeliveryStatus::setRepository() pattern: DB fallback dla static final class | Operator dodaje status w UI bez zmian kodu; `getAllOptions()`/`label()`/`getColor()` ladują z DB gdy repo ustawione, fallback na hardcoded ALL_STATUSES/LABEL_PL | 2026-04-27 | Active |
| Drop backward compat dla starych grupowych kluczy automatyzacji (Phase 108-02) | Kolizja semantyczna: stary `picked_up` mapował na `delivered`, nowy klucz DB `picked_up` to "Odebrana przez kuriera" — odwrotne końce cyklu. Hybrid evaluation by silently dawała wrong matches | 2026-04-27 | Active |
| Path params w controllerach via `$request->input('id')` (nie jako argumenty metody) | Konwencja routera projektu: handler wywoływany z jednym argumentem `$request`, params siedzą jako attributes — `ReceiptController::show()` jako wzorzec | 2026-04-27 | Active |
| Statistics Summary Chart.js CDN + start `2026-04-01` | Interaktywne wykresy bez zmiany build pipeline; historia podsumowania ma zaczynac sie od `04-2026` mimo starszych danych | 2026-04-28 | Active |
| Faktury: multi-account Fakturownia przez `integrations.type='fakturownia'` + `fakturownia_integration_settings(integration_id UNIQUE)` | Klient moze miec wiele kont (rozne marki/oddzialy); spojne z shopPRO; `invoice_configs.integration_id` wskazuje konkretne konto | 2026-05-10 | Active |
| Faktury: lokalna numeracja domyslna, delegacja przez `invoice_configs.is_delegated` | Pelna kontrola w default; opcja outsourcingu numeracji+PDF do Fakturowni gdy ksiegowy tak chce | 2026-05-10 | Active |
| Brak eventu automatyzacji `invoice.created` (na start v3.7) | `receipt.created` pozostaje czysty — regula wysylki paragonu mailem nie zostanie odpalona dla faktury; mozliwe rozszerzenie jako osobny plan w przyszlosci | 2026-05-10 | Active |
| Migracje no-op zawsze jako DDL (np. `ALTER TABLE COMMENT`), nigdy `SELECT 1;` | `SELECT` zwraca result set i pod PDO unbuffered blokuje kolejne migracje (SQLSTATE 2014) | 2026-05-10 | Active |
| Ksiegowosc: osobne podstrony `/settings/accounting/{receipts\|invoices}` zamiast tabow/jednej strony | Dlugie listy + rosnacy form faktury (conditional fields delegacji) nie mieszczace sie na jednej stronie | 2026-05-10 | Active |
| Legacy aliasy starych endpointow `/settings/accounting/save\|toggle\|delete` jako duplicate routes | Brak inwentaryzacji zewnetrznych referencji/bookmarkow - zero kosztu utrzymania, pelna wsteczna kompatybilnosc | 2026-05-10 | Active |
| `OrderProAlerts.confirm` to options-object API (`{title, message, onConfirm, danger, confirmLabel}`), nie pozycyjne argumenty | Pozycyjne wywolanie cicho fail'uje - callback ginie. Bug znaleziony w Phase 114-01 podczas smoke testu user. Pattern dla wszystkich przyszlych confirm dialogow | 2026-05-10 | Active |
| Globalny `confirm-delete.js` z `data-confirm-bound='1'` idempotent guard | Stare widoki maja inline scripts robiace to samo - guard zapobiega podwojnemu bindowi gdy modul globalny widzi juz-bound buttony. Mozna stopniowo migrowac stare widoki | 2026-05-10 | Active |
| Wystawianie faktury delegowanej do Fakturowni: POST PRZED INSERT lokalnym | Brak orphan rows w `invoices` gdy API padnie. On success zapis `external_invoice_id`/`external_pdf_url`/`invoice_number` z odpowiedzi Fakturowni. Trade-off: brak idempotencji przy double-POST -> INVOICE-IDEMP-115 w todo.md | 2026-05-10 | Active |
| NIP lookup przez MF Biala Liste (publiczne API) zamiast Fakturowni | Fakturownia API NIE MA endpointu GUS (sprawdzone w dokumentacji 2026-05-10). MF Biala Lista jest publiczna (bez rejestracji/klucza), zwraca nazwa+adres+REGON. Klient `MfWhitelistApiClient` w `src/Core/Http/` dostepny dla innych modulow | 2026-05-10 | Active |
| Fakturownia invoice payload: NIE wysylamy `seller_*` ani `department_id` | Konta z podwyzszonym security interpretuja roznice w seller_bank_account jako proba "utworz nowy dzial" -> HTTP 422. Fakturownia uzywa danych konta jako sprzedawca. Lokalny snapshot w `invoices.seller_data_json` zachowany dla audytu | 2026-05-10 | Active |
| PHP 8.5: zakaz `curl_close()` w nowym kodzie | Deprecated od 8.5 (no-op od 8.0). Wycieka HTML `<br/><b>Deprecated</b>...` przed JSON response -> "json is not valid" w fetch().json(). Pattern dla wszystkich httpGet/httpPost helperow w `src/Core/Http/` i `src/Modules/Settings/*ApiClient` | 2026-05-10 | Active |
| Auto-set `orders.invoice_requested` tylko przy `created=true` w imporcie | Delta-only re-import (Phase 112) zachowuje stabilnosc manualnej flagi operatora. Re-import nie nadpisuje stanu lokalnego, w tym manualnego "Klient prosi o fakture" | 2026-05-10 | Active |
| `OrderProAlerts.confirm` ZAWSZE options-object API (`{title, message, onConfirm, danger}`) | Phase 114 ustalil. Phase 115 uzyl w invoice_form.php. Pozycyjne wywolanie cicho fail'uje - callback ginie. Pattern obowiazuje dla wszystkich nowych confirm dialogow | 2026-05-10 | Active |
## Success Metrics
| Metric | Target | Current | Status |
|--------|--------|---------|--------|
| Liczba zintegrowanych źródeŠzamówień | ≥3 | 2 (Allegro, Erli) | In progress |
| Generowanie etykiet | DziaĹa | InPost | In progress |
## Tech Stack
| Layer | Technology | Notes |
|-------|------------|-------|
| Framework | PHP (custom/Laravel) | XAMPP lokalnie |
| Frontend | HTML/CSS/JS + SCSS | jQuery Alerts module |
| Database | MySQL (Medoo) | Prepared statements |
| Auth | Sesje PHP | |
| Integracje | Allegro API, Erli API | PrzewoĹşnicy: InPost (ShipX), Apaczka |
| Testing | PHPUnit 11.5 + dg/bypass-finals | Unit tests w tests/Unit/ |
## Specialized Flows
See: .paul/SPECIAL-FLOWS.md
Quick Reference:
- /feature-dev → Nowe funkcjonalnoĹci i integracje (optional)
- /code-review → Przegląd kodu przed UNIFY (optional)
- /frontend-design → Komponenty UI i widoki (optional)
- /simplify → Refaktoryzacja po implementacji (optional)
---
*PROJECT.md — Updated when requirements or context change*
*Last updated: 2026-05-10 after Phase 115 (Wystawianie faktury z zamowienia) completion; v3.7 Invoices milestone in progress*