Files
orderPRO/.paul/phases/09-receipt-config/09-01-PLAN.md
Jacek Pyziak ed057fc304 feat(08-10-receipt-module): phases 08-10 complete — receipt issuing from orders
Phase 08 — DB Foundation:
- 3 new tables: receipt_configs, receipts, receipt_number_counters
- company_settings extended with BDO, REGON, KRS, logo fields

Phase 09 — Receipt Config:
- CRUD for receipt configurations (Settings > Accounting)
- ReceiptConfigController + ReceiptConfigRepository

Phase 10 — Receipt Issuing:
- ReceiptRepository with atomic numbering (INSERT ON DUPLICATE KEY UPDATE)
- ReceiptController with snapshot pattern (seller/buyer/items as JSON)
- "Wystaw paragon" button in order view
- Documents tab showing both receipts and marketplace documents
- Activity log entry on receipt creation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 19:49:06 +01:00

13 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous
phase plan type wave depends_on files_modified autonomous
09-receipt-config 01 execute 1
08-01
src/Modules/Settings/ReceiptConfigController.php
src/Modules/Settings/ReceiptConfigRepository.php
resources/views/settings/accounting.php
resources/views/layouts/app.php
resources/lang/pl.php
routes/web.php
DOCS/ARCHITECTURE.md
false
## Goal Wdrozyc CRUD konfiguracji paragonow w sekcji Ustawienia > Ksiegowosc: lista konfiguracji, tworzenie, edycja, aktywacja/dezaktywacja, usuwanie. Dodac sublinek "Ksiegowosc" do nawigacji ustawien.

Purpose

Umozliwienie zarzadzania szablonami paragonow (numeracja, imiennosc, zrodlo daty sprzedazy) — fundament pod wystawianie paragonow w fazie 10.

Output

  • ReceiptConfigController (index, save, toggleStatus, delete)
  • ReceiptConfigRepository (CRUD na receipt_configs)
  • Widok settings/accounting.php z lista i formularzem
  • Sublinek w sidebarze Ustawienia
  • Tlumaczenia PL
## Project Context @.paul/PROJECT.md @.paul/ROADMAP.md @.paul/STATE.md

Prior Work

@.paul/phases/08-db-foundation/08-01-SUMMARY.md

Source Files (wzorce)

@src/Modules/Settings/CompanySettingsController.php @src/Modules/Settings/CompanySettingsRepository.php @resources/views/settings/company.php @resources/views/layouts/app.php @routes/web.php @resources/lang/pl.php

## Required Skills (from SPECIAL-FLOWS.md)
Skill Priority When to Invoke Loaded?
sonar-scanner required Po APPLY, przed UNIFY

<acceptance_criteria>

AC-1: Lista konfiguracji paragonow

Given uzytkownik jest zalogowany
When wchodzi na /settings/accounting
Then widzi liste wszystkich konfiguracji paragonow (nazwa, status, format numeracji, typ)
And widzi przycisk "Dodaj konfiguracje"

AC-2: Tworzenie nowej konfiguracji

Given uzytkownik jest na /settings/accounting
When wypelnia formularz (nazwa, format numeracji, typ numeracji, imiennosc, zrodlo daty, referencja zamowienia) i klika Zapisz
Then konfiguracja jest zapisana w receipt_configs
And pojawia sie na liscie z flash message sukcesu

AC-3: Edycja istniejącej konfiguracji

Given istnieje konfiguracja paragonow
When uzytkownik klika "Edytuj" przy konfiguracji
Then formularz jest wypelniony danymi konfiguracji
When zmienia dane i klika Zapisz
Then zmiany sa zapisane i widoczne na liscie

AC-4: Aktywacja/dezaktywacja konfiguracji

Given istnieje konfiguracja paragonow
When uzytkownik klika przycisk aktywuj/dezaktywuj
Then status konfiguracji zmienia sie (is_active toggle)
And lista odswiezja sie z nowym statusem

AC-5: Usuwanie konfiguracji

Given istnieje konfiguracja paragonow bez wystawionych paragonow
When uzytkownik klika "Usun" i potwierdza w OrderProAlerts.confirm()
Then konfiguracja jest usunieta z bazy
And znika z listy

AC-6: Nawigacja — sublinek Ksiegowosc

Given uzytkownik jest zalogowany
When patrzy na sidebar w sekcji Ustawienia
Then widzi sublinek "Ksiegowosc" prowadzacy do /settings/accounting
And sublinek jest podswietlony gdy jest na stronie konfiguracji

</acceptance_criteria>

Task 1: ReceiptConfigRepository — CRUD na receipt_configs src/Modules/Settings/ReceiptConfigRepository.php Utworzyc klase `App\Modules\Settings\ReceiptConfigRepository` wzorowana na CompanySettingsRepository: - Konstruktor: `private readonly PDO $pdo` - `listAll(): array` — SELECT * FROM receipt_configs ORDER BY created_at DESC - `findById(int $id): ?array` — SELECT * WHERE id = :id - `save(array $data): void` — INSERT lub UPDATE (jesli data['id'] istnieje): - pola: name, is_active, number_format, numbering_type, is_named, sale_date_source, order_reference - INSERT: prepared statement z VALUES - UPDATE: prepared statement z WHERE id = :id - `toggleStatus(int $id): void` — UPDATE receipt_configs SET is_active = NOT is_active WHERE id = :id - `delete(int $id): bool` — DELETE FROM receipt_configs WHERE id = :id (zwraca false jesli FK RESTRICT zablokuje) - Wszystko przez prepared statements (wzorzec z CompanySettingsRepository) - Klasa final Sprawdzic syntax PHP: php -l src/Modules/Settings/ReceiptConfigRepository.php AC-2, AC-3, AC-4, AC-5 (backend) spelnione Task 2: ReceiptConfigController — kontroler CRUD src/Modules/Settings/ReceiptConfigController.php Utworzyc klase `App\Modules\Settings\ReceiptConfigController` wzorowana na CompanySettingsController: - Konstruktor: Template, Translator, AuthService, ReceiptConfigRepository (readonly) - `index(Request $request): Response`: - Pobiera liste konfiguracji z repository->listAll() - Jesli query param `edit` — laduje konfiguracje do edycji (findById) - Renderuje 'settings/accounting' z layout 'layouts/app' - Przekazuje: activeMenu='settings', activeSettings='accounting', csrfToken, configs, editConfig, flash messages - `save(Request $request): Response`: - Waliduje CSRF (Csrf::validate) - Waliduje: name wymagane, number_format wymagane i zawiera %N - Wywoluje repository->save([...]) z danymi z $request->input(...) - Flash::set('settings.accounting.flash.saved/save_failed') - Redirect do /settings/accounting - `toggleStatus(Request $request): Response`: - Waliduje CSRF i id - Wywoluje repository->toggleStatus((int) $request->input('id')) - Redirect do /settings/accounting - `delete(Request $request): Response`: - Waliduje CSRF i id - try: repository->delete((int) $request->input('id')) - catch (Throwable): flash error (konfiguracja ma powiazane paragony) - Redirect do /settings/accounting - Klasa final - Uzyc Flash::set/get wzorca, walidacja CSRF przez Csrf::validate($request->input('_token')) Sprawdzic syntax PHP: php -l src/Modules/Settings/ReceiptConfigController.php AC-1, AC-2, AC-3, AC-4, AC-5 (kontroler) spelnione Task 3: Widok settings/accounting.php, routing, nawigacja, tlumaczenia resources/views/settings/accounting.php, resources/views/layouts/app.php, routes/web.php, resources/lang/pl.php 1. Utworzyc `resources/views/settings/accounting.php`: - Sekcja .card z tytulem "Ksiegowosc — Konfiguracje paragonow" - Flash messages (error/success) - Tabela lista konfiguracji: - Kolumny: Nazwa, Format numeracji, Typ, Imienny, Data sprzedazy, Ref. zamowienia, Status, Akcje - Status: badge aktywny/nieaktywny - Akcje: Edytuj (link z ?edit=ID), Aktywuj/Dezaktywuj (form POST), Usun (form POST z OrderProAlerts.confirm) - Formularz dodawania/edycji (pod tabelą lub w osobnej sekcji): - hidden: _token, id (jesli edycja) - Nazwa (text, required) - Format numeracji (text, required, placeholder: PAR/%N/%M/%Y) - Typ numeracji (select: miesięczny/roczny) - Imienny (checkbox) - Domyslna data sprzedazy (select: wg daty zamowienia/oplacenia/wystawienia) - Informacja o zamowieniu (select: brak/numer orderPRO/numer integracji) - Przycisk Zapisz - Styl: uzyc istniejacych klas .card, .form-control, .form-field, .btn, .form-grid-2, table.data-table - Usun potwierdzenie: window.OrderProAlerts.confirm() (NIE natywny confirm())
2. W `resources/views/layouts/app.php`:
   - Dodac sublinek "Ksiegowosc" po "Dane firmy" w sekcji settings:
     ```php
     <a class="sidebar__sublink<?= $currentMenu === 'settings' && $currentSettings === 'accounting' ? ' is-active' : '' ?>" href="/settings/accounting">
       <?= $e($t('navigation.accounting')) ?>
     </a>
     ```

3. W `routes/web.php`:
   - Instantiacja: new ReceiptConfigRepository($app->db()), new ReceiptConfigController($template, $translator, $auth, $receiptConfigRepository)
   - Trasy:
     - GET /settings/accounting -> [$receiptConfigController, 'index'], [$authMiddleware]
     - POST /settings/accounting/save -> [$receiptConfigController, 'save'], [$authMiddleware]
     - POST /settings/accounting/toggle -> [$receiptConfigController, 'toggleStatus'], [$authMiddleware]
     - POST /settings/accounting/delete -> [$receiptConfigController, 'delete'], [$authMiddleware]
   - Dodac use statement dla nowych klas

4. W `resources/lang/pl.php`:
   - navigation.accounting => 'Ksiegowosc'
   - settings.accounting.title => 'Konfiguracje paragonow'
   - settings.accounting.description => 'Zarzadzaj szablonami numeracji i ustawieniami paragonow'
   - settings.accounting.fields.* => tlumaczenia pol formularza
   - settings.accounting.flash.saved => 'Konfiguracja zapisana'
   - settings.accounting.flash.save_failed => 'Blad zapisu konfiguracji'
   - settings.accounting.flash.deleted => 'Konfiguracja usunieta'
   - settings.accounting.flash.delete_failed => 'Nie mozna usunac — konfiguracja ma powiazane paragony'
   - settings.accounting.flash.toggled => 'Status zmieniony'
   - settings.accounting.actions.* => etykiety przyciskow
   - settings.accounting.table.* => naglowki kolumn tabeli
   - settings.accounting.options.* => opcje selectow (miesięczny/roczny, daty, referencje)
Sprawdzic syntax: php -l resources/views/settings/accounting.php Sprawdzic syntax routes: php -l routes/web.php AC-1, AC-6 spelnione CRUD konfiguracji paragonow w Ustawienia > Ksiegowosc 1. Wejdz na strone — w sidebarze Ustawienia powinien byc sublinek "Ksiegowosc" 2. Kliknij — powinna wyswietlic sie strona /settings/accounting z pusta lista i formularzem 3. Dodaj nowa konfiguracje: nazwa "Paragony standardowe", format "PAR/%N/%M/%Y", typ miesięczny 4. Sprawdz czy pojawila sie na liscie 5. Kliknij Edytuj — formularz powinien sie wypelnic danymi 6. Zmien nazwe i zapisz — sprawdz aktualizacje 7. Kliknij Dezaktywuj — status powinien sie zmienic 8. Kliknij Usun — powinien pojawic sie modal potwierdzenia (OrderProAlerts) 9. Potwierdz — konfiguracja powinna zniknac z listy Type "approved" to continue, or describe issues to fix Task 4: Aktualizacja ARCHITECTURE.md DOCS/ARCHITECTURE.md Dodac w ARCHITECTURE.md: 1. W sekcji "Kluczowe klasy": - App\Modules\Settings\ReceiptConfigController - App\Modules\Settings\ReceiptConfigRepository 2. W sekcji "Routing" nowe trasy: - GET /settings/accounting - POST /settings/accounting/save - POST /settings/accounting/toggle - POST /settings/accounting/delete 3. Nowa sekcja "Przeplyw Ustawienia > Ksiegowosc" opisujaca CRUD konfiguracji 4. W sekcji "Nawigacja ustawien" dodac sublinek Ksiegowosc Przejrzec ARCHITECTURE.md pod katem kompletnosci AC-1 do AC-6 udokumentowane

DO NOT CHANGE

  • database/migrations/* — schemat zablokowany (migracje z fazy 08)
  • Istniejace kontrolery i widoki niezwiazane z accounting
  • src/Modules/Settings/CompanySettingsController.php
  • src/Modules/Settings/CompanySettingsRepository.php

SCOPE LIMITS

  • Nie tworzymy sekcji glownej Ksiegowosc w sidebarze (to faza 12)
  • Nie tworzymy logiki wystawiania paragonow (faza 10)
  • Nie dodajemy walidacji unikalnosci nazwy konfiguracji (nice-to-have)
  • Nie dodajemy sortowania/filtrowania listy konfiguracji (prostota)
Before declaring plan complete: - [ ] ReceiptConfigRepository — CRUD dziala (list, find, save, toggle, delete) - [ ] ReceiptConfigController — 4 endpointy dzialaja - [ ] Widok accounting.php renderuje liste i formularz - [ ] Sublinek "Ksiegowosc" widoczny w sidebarze ustawien - [ ] Tlumaczenia PL kompletne - [ ] Routing zarejestrowany i dziala - [ ] OrderProAlerts.confirm() dla usuwania - [ ] ARCHITECTURE.md zaktualizowany

<success_criteria>

  • Uzytkownik moze tworzyc, edytowac, aktywowac/dezaktywowac i usuwac konfiguracje paragonow
  • Nawigacja w sidebarze dziala poprawnie
  • Brak regresji w istniejacych ustawieniach </success_criteria>
After completion, create `.paul/phases/09-receipt-config/09-01-SUMMARY.md`