--- phase: 114-accounting-configs-refactor plan: 01 subsystem: ui tags: [accounting, invoice_configs, receipt_configs, fakturownia, ui-refactor, js-module] requires: - phase: 113-fakturownia-integration provides: invoice_configs/invoices schema, FakturowniaIntegrationRepository (findAll dla selectu) provides: - InvoiceConfigRepository (CRUD invoice_configs z walidacja delegacji) - InvoiceConfigController (/settings/accounting/invoices) - ReceiptConfigController refactor (hub/list/edit rozdzielone) - Hub /settings/accounting (2 karty Paragony/Faktury) - 4 nowe widoki ksiegowosci (accounting-receipts, accounting-receipt-edit, accounting-invoices, accounting-invoice-edit) - invoice-config-form.js (JS toggle is_delegated -> integration_id) - confirm-delete.js (globalny modul OrderProAlerts.confirm dla js-delete-btn) - Seed migracji `Domyslny VAT` invoice config (idempotentny) - Legacy aliasy starych endpointow /settings/accounting/save|toggle|delete affects: [115-invoice-issuance (InvoiceService -> uzyje InvoiceConfigRepository), all-future-list-views (confirm-delete.js zastepuje inline scripts)] tech-stack: added: [] patterns: - "Hub-rozdroze view: `/settings/accounting` jako landing z linkami zamiast inline-listy" - "Conditional form fields przez `[data-*]` wrappery + dedykowany JS modul (toggle widocznosci + dynamiczny `required`)" - "Globalny modul `confirm-delete.js` z `data-confirm-bound='1'` markerem (idempotentny, koegzystuje z inline scripts w starych widokach)" - "Legacy route aliasy przez duplicate `$router->post()` registration (zero kosztu utrzymania, pelna kompatybilnosc)" - "Repozytorium z walidacja krzyzowa: `is_delegated=1` wymaga `integration_id` typu 'fakturownia' (serwerowa walidacja niezalezna od JS UI)" key-files: created: - database/migrations/20260511_000107_seed_default_invoice_config.sql - src/Modules/Settings/InvoiceConfigRepository.php - src/Modules/Settings/InvoiceConfigController.php - resources/views/settings/accounting-receipts.php - resources/views/settings/accounting-receipt-edit.php - resources/views/settings/accounting-invoices.php - resources/views/settings/accounting-invoice-edit.php - public/assets/js/modules/invoice-config-form.js - public/assets/js/modules/confirm-delete.js modified: - src/Modules/Settings/ReceiptConfigController.php - resources/views/settings/accounting.php - resources/views/layouts/app.php - routes/web.php - .paul/codebase/db_schema.md - .paul/codebase/architecture.md - .paul/codebase/tech_changelog.md key-decisions: - "Osobne podstrony `/settings/accounting/receipts` i `/.../invoices` zamiast tabow lub jednej strony — dlugie listy + rosnacy form faktury wymuszaja osobne ekrany" - "Seed `Domyslny VAT` przez idempotentny NOT EXISTS guard (name nie UNIQUE, wiec ON DUPLICATE KEY niemozliwe)" - "Legacy aliasy `/settings/accounting/save|toggle|delete` zachowane jako duplicate routes — zero ryzyka regresji" - "Walidacja `is_delegated=1` => `integration_id` typu 'fakturownia' jest serwerowa w Repo (JS toggle to tylko UX, nie security)" - "Globalny modul `confirm-delete.js` zamiast nowych inline scripts — `OrderProAlerts.confirm({onConfirm:...})` to obiekt-options API, nie pozycyjne (3-arg pozycyjne wywolanie cicho fail'owalo z bug case zglosznym przez usera)" patterns-established: - "Form action: ujednolicony `class='js-confirm-delete'` na form + `class='js-delete-btn'` na buttonie type=button (nie submit), submit wywolywany przez globalny confirm-delete.js po potwierdzeniu" - "Edycja konfiguracji ksiegowosci: `/settings/accounting/{receipts|invoices}/edit?id=N` + redirect po sukcesie na liste, po bledzie z powrotem na edycje (zachowanie kontekstu)" - "Conditional select w form: wrapper `[data-X]` + checkbox `[data-X-flag]` + JS modul ktory toggluje display i select.required" - "Hub-rozdroze: `section.card` z gridem 2-kolumnowym (border + padding 16px) jako landing dla submodulow" duration: 75min started: 2026-05-10T20:30:00Z completed: 2026-05-10T21:45:00Z --- # Phase 114 Plan 01: Accounting Configs Refactor Summary **`/settings/accounting` rozdzielone na osobne podstrony Paragony i Faktury z osobnym widokiem edycji konfiguracji; pelny CRUD `invoice_configs` z opcja delegacji do Fakturowni (warunkowy select integracji + serwerowa walidacja); seed `Domyslny VAT` config; globalny JS modul `confirm-delete.js` zastepuje rozsiane inline scripts.** ## Performance | Metric | Value | |--------|-------| | Duration | ~75min | | Started | 2026-05-10T20:30:00Z | | Completed | 2026-05-10T21:45:00Z | | Tasks | 3 completed (auto, inline) | | Files created | 9 | | Files modified | 7 | ## Acceptance Criteria Results | Criterion | Status | Notes | |-----------|--------|-------| | AC-1: Seed + Repository dla invoice_configs | Pass | Migracja seed idempotentna (NOT EXISTS guard). `InvoiceConfigRepository::listAll()` JOIN integrations zwraca `integration_name`. `save()` rzuca `IntegrationConfigException` gdy `is_delegated=1` bez `integration_id` typu 'fakturownia'. | | AC-2: CRUD invoice_configs na osobnej podstronie | Pass | `/settings/accounting/invoices` lista + `/new` + `/edit` + save/toggle/delete dziala. Conditional select Fakturowni dziala (po naprawie `OrderProAlerts.confirm` API). Delete blokuje gdy istnieja faktury (pre-check w Repo). | | AC-3: Refaktor receipt_configs + hub | Pass | `/settings/accounting` to hub-rozdroze (2 karty). `/settings/accounting/receipts` lista w stylu spojnym z fakturami. Edycja na osobnej podstronie. Legacy aliasy starych POST endpointow zachowane. | ## Accomplishments - Pelen CRUD `invoice_configs` z UI + serwerowa walidacja delegacji (krytyczna dla v3.7 - bez tego Phase 115 wystawiania faktur nie ma sensu). - Refaktor ksiegowosci na 3-poziomowa nawigacje (hub → lista → edycja) ujednolicony dla paragonow i faktur — eliminuje wczesniejszy problem dlugiego scrolla + brak miejsca na conditional fields w form faktury. - Globalny modul `confirm-delete.js` z idempotentnym bindingiem przez `data-confirm-bound` — usuwa potrzebe duplikowania inline scripts w przyszlych widokach list. - Seed `Domyslny VAT` invoice config — zerowy onboarding (operator moze wystawiac faktury natychmiast po deployment). - 3 nowe Key Decisions w PROJECT.md (osobne podstrony, walidacja delegacji, legacy aliasy). ## Task Commits Inline execution (delegation: off) - wszystko w jednym commicie na koniec. | Task | Status | Description | |------|--------|-------------| | Task 1: Migration seed + InvoiceConfigRepository | Done | 1 migracja SQL + repo z walidacja delegacji + db_schema.md notka | | Task 2: InvoiceConfigController + widoki + JS toggle + routy | Done | controller, 2 widoki (lista + edit), invoice-config-form.js, layouts/app.php script reg, 6 routes invoice | | Task 3: Refaktor ReceiptConfigController + hub + widoki + docs + legacy aliasy | Done | controller split (hub/list/edit), accounting.php hub view, 2 nowe widoki paragonow, 6 routes receipts + 3 legacy aliasy, architecture.md + tech_changelog.md | ## Files Created/Modified | File | Change | Purpose | |------|--------|---------| | `database/migrations/20260511_000107_seed_default_invoice_config.sql` | Created | Idempotentny seed `Domyslny VAT` | | `src/Modules/Settings/InvoiceConfigRepository.php` | Created | CRUD invoice_configs z walidacja delegacji | | `src/Modules/Settings/InvoiceConfigController.php` | Created | UI controller dla `/settings/accounting/invoices` | | `src/Modules/Settings/ReceiptConfigController.php` | Modified | Split `index()` na `hub()` + `list()` + nowa `edit()`. Save/toggle/delete redirect na `/receipts` | | `resources/views/settings/accounting.php` | Refactored | Z listy+formularza na hub-rozdroze z 2 kartami | | `resources/views/settings/accounting-receipts.php` | Created | Lista paragonow (table.table + badge, spojna z fakturami) | | `resources/views/settings/accounting-receipt-edit.php` | Created | Formularz paragonu na osobnej podstronie | | `resources/views/settings/accounting-invoices.php` | Created | Lista faktur (7 kolumn z Tryb + Konto Fakturowni) | | `resources/views/settings/accounting-invoice-edit.php` | Created | Formularz faktury z conditional integration_id select | | `public/assets/js/modules/invoice-config-form.js` | Created | Toggle widocznosci integration_id + dynamiczny `required` | | `public/assets/js/modules/confirm-delete.js` | Created | Globalny handler dla `.js-delete-btn` (OrderProAlerts.confirm) | | `resources/views/layouts/app.php` | Modified | Rejestracja 2 nowych modulow JS z cache-busting `?ver=mtime` | | `routes/web.php` | Modified | +use imports, +DI wiring, 12 nowych routes + 3 legacy aliasy | | `.paul/codebase/db_schema.md` | Modified | Notka o seed `Domyslny VAT` | | `.paul/codebase/architecture.md` | Modified | Nowa sekcja "Phase 114 — Accounting Configs Refactor" | | `.paul/codebase/tech_changelog.md` | Modified | Wpis 2026-05-10 dla Phase 114-01 | ## Decisions Made | Decision | Rationale | Impact | |----------|-----------|--------| | Osobne podstrony zamiast tabow | Dlugie listy + rosnacy form faktury (conditional fields) nie zmiescilyby sie na jednej stronie z tabami | Operator widzi sekcje paragonow i faktur osobno; przyszle rozszerzenia (np. lista wystawionych faktur Phase 116) maja naturalne miejsce | | Globalny `confirm-delete.js` z `data-confirm-bound` markerem | Stare widoki (email-mailboxes, automation, email-templates) maja inline scripts robiace to samo. Marker zapobiega podwojnemu bindowi gdy modul globalny widzi juz-bound buttony | Mozna stopniowo migrowac stare widoki usuwajac ich inline scripts bez ryzyka regresji | | `OrderProAlerts.confirm({title, message, onConfirm})` API nie pozycyjne | API biblioteki jq-alerts wymaga options-object. Pozycyjne wywolanie `(title, message, callback)` cicho fail'uje (callback ginie, options to string) | Pattern dla wszystkich przyszlych confirm dialogow + udokumentowany w SUMMARY/architecture | | Legacy aliasy starych endpointow `/settings/accounting/save\|toggle\|delete` | Brak inwentaryzacji zewnetrznych klientow/bookmark. Duplicate route registration to zero-koszt | Zero ryzyka 404 dla starych referencji; mozna usunac w przyszlym major release | | Walidacja delegacji w Repo (nie tylko JS) | JS toggle to UX; ktos moze obejsc przez POST bez JS lub bezposrednio przez API | Bezpieczna delegacja — nie da sie zapisac `is_delegated=1` bez waznego `integration_id` typu 'fakturownia' | ## Deviations from Plan ### Summary | Type | Count | Impact | |------|-------|--------| | Auto-fixed | 1 | Drobne (bug w API call) - naprawione w czasie APPLY po user feedback | | Scope additions | 1 | Globalny `confirm-delete.js` (plan zakladal tylko `invoice-config-form.js`) - przedluzona wartosc dla calej aplikacji | | Deferred | 0 | - | **Total impact:** Plan w pelnym zakresie + 1 wartosciowa dodatkowa rzecz (globalny confirm handler). Bez scope creep. ### Auto-fixed Issues **1. [JS] `OrderProAlerts.confirm` pozycyjne wywolanie cicho fail'uje** - **Found during:** User smoke test (feedback "Usuwanie konfiguracji faktur nie dziala" → potem "Teraz pojawia sie alert z potwierdzeniem, ale potwierdzenie nic nie powoduje") - **Issue:** `confirm-delete.js` wywolywal `window.OrderProAlerts.confirm(title, message, callback)` jako pozycyjne argumenty. Biblioteka `jquery-alerts.js` przyjmuje `confirm(options)` gdzie `options.onConfirm` to callback. Pierwsza wersja: modal nie pokazywal sie. Druga wersja (po fix #1): modal pokazywal sie, ale `confirmButton.click()` resolve'owal Promise bez wywolania callback przekazanego pozycyjnie. - **Fix #1:** Wprowadzono `class="js-confirm-delete"` + `class="js-delete-btn"` + global module rejestracja w layout (zamiast inline scripts per view). - **Fix #2:** Zmieniono wywolanie na `OrderProAlerts.confirm({title, message, danger:true, confirmLabel:'Usun', onConfirm: doSubmit})` + Promise fallback z guard `submitted` przeciw podwojnemu submit. - **Files:** `public/assets/js/modules/confirm-delete.js` - **Verification:** User potwierdzil "Teraz jest ok". ### Scope Addition **1. [Reusable] `confirm-delete.js` jako globalny modul** - **Context:** Plan zakladal tylko `invoice-config-form.js`. Po feedbacku usera o niedzialajacym delete oraz odkryciu ze KAZDY istniejacy widok ma swoj wlasny inline `