# 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.3.0 | | Status | v3.3 shipped - UI Filters complete | | Last Updated | 2026-04-28 | ## 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 52–105 - [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; `
` 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 ### 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) - [ ] (brak — v3.3 zakonczony, oczekiwanie na kolejny milestone) ### 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 | | 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 | ## 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-04-28 after v3.3 UI Filters milestone completion (Phase 109)*