Files
orderPRO/.paul/phases/114-accounting-configs-refactor/114-01-SUMMARY.md
Jacek Pyziak 6129042ff6 feat(114): accounting configs refactor + invoice configs CRUD
Phase 114 complete (v3.7 Invoices):
- /settings/accounting jako hub-rozdroze (Paragony / Faktury)
- /settings/accounting/receipts + /invoices osobne podstrony list i edycji
- InvoiceConfigRepository + Controller (CRUD z walidacja delegacji)
- Seed Domyslny VAT (NOT EXISTS idempotent)
- invoice-config-form.js (toggle is_delegated -> integration_id)
- confirm-delete.js (globalny modul OrderProAlerts.confirm)
- Legacy aliasy starych endpointow /settings/accounting/save|toggle|delete

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

202 lines
14 KiB
Markdown

---
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 `<script>` z handlerem `js-delete-btn`, zdecydowano stworzyc globalny modul.
- **Decision:** Modul + rejestracja w `layouts/app.php` zamiast dodawania inline script tylko do 4 nowych widokow.
- **Korzysc:** Wszystkie przyszle widoki z `js-delete-btn` dzialaja od razu. Stare widoki (email-mailboxes, automation, email-templates) nie zmieniaja zachowania dzieki `data-confirm-bound` guard.
### Deferred Items
Brak. Plan wykonany w pelnym zakresie.
## Issues Encountered
| Issue | Resolution |
|-------|------------|
| MySQL/XAMPP offline przy `php bin/migrate.php` | Migracja czeka na uruchomienie XAMPP po stronie usera. Smoke testy UI wykonane manualnie. |
| Brak handlera JS dla `.js-delete-btn` w nowych widokach | Stworzony globalny modul `confirm-delete.js` (scope addition) |
| API `OrderProAlerts.confirm` pomylone z pozycyjnym signature | Po inspekcji `jquery-alerts.js:109` poprawiono na options-object z `onConfirm` callback |
## Next Phase Readiness
**Ready:**
- `InvoiceConfigRepository::findById/listAll` gotowe do uzycia przez `InvoiceService` (Phase 115 wystawianie faktur).
- Conditional select integracji Fakturowni pre-walidowany w UI - operator wie ktore konfiguracje sa delegowane.
- Wzorzec hub→lista→edycja gotowy do reuse w Phase 116 (lista wystawionych faktur w sekcji Ksiegowosc).
- Globalny `confirm-delete.js` zniweluje duplikacje inline scripts w kolejnych widokach.
**Concerns:**
- Stare widoki (`email-mailboxes`, `email-templates`, `automation`) maja inline scripts duplikujace logike `confirm-delete.js`. Idempotentny `data-confirm-bound` zapobiega koliziom, ale to dlug techniczny - kandydat do osobnego sprzata-tasku (~30min).
- `invoice_configs.name` nie jest UNIQUE - seed idempotentnosc oparta na NOT EXISTS po name. Jesli operator zmieni nazwe `Domyslny VAT` -> kolejna migracja zrobi duplikat. Akceptowalne: nie planuje sie kolejnych seed'ow.
**Blockers:**
- Brak.
---
*Phase: 114-accounting-configs-refactor, Plan: 01*
*Completed: 2026-05-10*