---
phase: 12-accounting-list
plan: 01
type: execute
wave: 1
depends_on: ["11-01"]
files_modified:
  - src/Modules/Accounting/AccountingController.php
  - src/Modules/Accounting/ReceiptRepository.php
  - resources/views/accounting/index.php
  - resources/views/layouts/app.php
  - routes/web.php
  - resources/lang/pl.php
  - resources/scss/app.scss
  - public/assets/css/app.css
  - composer.json
  - DOCS/ARCHITECTURE.md
autonomous: false
---

<objective>
## Goal
Sekcja Ksiegowosc w nawigacji glownej z lista wszystkich paragonow, filtrami, paginacja i eksportem do XLSX.

## Purpose
Dotychczas paragony widoczne sa tylko w kontekscie pojedynczego zamowienia. Uzytkownik potrzebuje przegladac wszystkie paragony w jednym miejscu — filtrowac po dacie, konfiguracji, numerze — i eksportowac do XLSX dla celów ksiegowych.

## Output
- Nowy AccountingController z metoda index() i export()
- Widok listy paragonow z filtrami (reuse komponentu table-list)
- Eksport XLSX przez PhpSpreadsheet
- Nowy link "Ksiegowosc" w nawigacji glownej (sidebar)
</objective>

<context>
## Project Context
@.paul/PROJECT.md
@.paul/ROADMAP.md
@.paul/STATE.md

## Prior Work
@.paul/phases/11-receipt-print/11-01-SUMMARY.md — podglad, druk, PDF paragonu
@.paul/phases/10-receipt-issue/10-01-SUMMARY.md — wystawianie paragonow, ReceiptRepository

## Source Files
@src/Modules/Accounting/ReceiptRepository.php
@src/Modules/Accounting/ReceiptController.php
@resources/views/components/table-list.php
@resources/views/orders/list.php — wzorzec listy z filtrami
@src/Modules/Orders/OrdersController.php — wzorzec metody index() z tableList
@resources/views/layouts/app.php — sidebar navigation
</context>

<skills>
## Required Skills (from SPECIAL-FLOWS.md)

| Skill | Priority | When to Invoke | Loaded? |
|-------|----------|----------------|---------|
| sonar-scanner | required | Po APPLY, przed UNIFY | ○ |

## Skill Invocation Checklist
- [ ] sonar-scanner uruchomiony po APPLY
</skills>

<acceptance_criteria>

## AC-1: Link Ksiegowosc w nawigacji glownej
```gherkin
Given uzytkownik jest zalogowany
When widzi sidebar nawigacji
Then widoczny jest nowy link "Ksiegowosc" prowadzacy do /accounting
And link jest aktywny gdy uzytkownik jest na stronie /accounting
```

## AC-2: Lista paragonow z paginacja
```gherkin
Given istnieja paragony w bazie danych
When uzytkownik otwiera /accounting
Then wyswietlana jest tabela paragonow z kolumnami:
  - Numer paragonu, Data wystawienia, Data sprzedazy, Kwota brutto, Konfiguracja, Zamowienie
And tabela jest paginowana (domyslnie 20 na strone)
And mozna sortowac po: numer, data wystawienia, kwota brutto
```

## AC-3: Filtry listy
```gherkin
Given uzytkownik jest na stronie /accounting
When uzywa filtrow
Then moze filtrowac po:
  - Szukaj (numer paragonu, numer zamowienia)
  - Konfiguracja (select z aktywnych konfiguracji)
  - Data wystawienia od / do
And filtry sa zachowane w URL (query string)
```

## AC-4: Eksport XLSX
```gherkin
Given uzytkownik jest na stronie /accounting z zastosowanymi filtrami
When klika przycisk "Eksportuj XLSX"
Then przeglądarka pobiera plik .xlsx z lista paragonow
And plik zawiera te same kolumny co tabela + dodatkowe: data sprzedazy, nr referencyjny
And eksport uwzglednia aktywne filtry (nie eksportuje wszystkiego)
And plik ma nazwe: paragony_YYYY-MM-DD.xlsx
```

## AC-5: Pusta lista
```gherkin
Given brak paragonow spelniajacych kryteria (pusta baza lub filtr bez wynikow)
When uzytkownik otwiera /accounting
Then wyswietlany jest komunikat "Brak paragonow"
```

</acceptance_criteria>

<tasks>

<task type="auto">
  <name>Task 1: ReceiptRepository — metoda paginate() i exportData()</name>
  <files>
    src/Modules/Accounting/ReceiptRepository.php
  </files>
  <action>
    1. **paginate(array $filters): array** — analogicznie do OrdersRepository::paginate()
       - Przyjmuje filtry: search, config_id, date_from, date_to, sort, sort_dir, page, per_page
       - SELECT r.*, rc.name AS config_name, o.internal_order_number, o.external_order_id
         FROM receipts r
         LEFT JOIN receipt_configs rc ON rc.id = r.config_id
         LEFT JOIN orders o ON o.id = r.order_id
       - WHERE dynamiczne na podstawie filtrow:
         - search: LIKE na receipt_number i o.internal_order_number i o.external_order_id
         - config_id: = config_id
         - date_from: issue_date >= date_from
         - date_to: issue_date <= date_to
       - ORDER BY dynamiczne (whitelist: receipt_number, issue_date, total_gross) + sort_dir (ASC/DESC)
       - LIMIT/OFFSET na podstawie page i per_page
       - Zwraca: ['items' => [...], 'total' => int, 'page' => int, 'per_page' => int]
       - Uzyj COUNT(*) osobnym zapytaniem dla total

    2. **exportData(array $filters): array** — ta sama logika WHERE co paginate, ale BEZ LIMIT/OFFSET
       - Zwraca flat array wierszy z tymi samymi kolumnami
       - Uzywany przez export XLSX

    Wzorzec: prepared statements, whitelist dla sort, max per_page = 100.
  </action>
  <verify>
    - `php -l src/Modules/Accounting/ReceiptRepository.php`
  </verify>
  <done>AC-2 backend, AC-3 backend, AC-4 backend</done>
</task>

<task type="auto">
  <name>Task 2: AccountingController + trasy + nawigacja + widok</name>
  <files>
    src/Modules/Accounting/AccountingController.php,
    routes/web.php,
    resources/views/accounting/index.php,
    resources/views/layouts/app.php,
    resources/lang/pl.php,
    composer.json
  </files>
  <action>
    1. **Instalacja PhpSpreadsheet:**
       - `php composer.phar require phpoffice/phpspreadsheet --ignore-platform-reqs`

    2. **AccountingController** (nowy plik w src/Modules/Accounting/):
       - Konstruktor: Template, Translator, AuthService, ReceiptRepository, ReceiptConfigRepository
       - **index(Request): Response** — GET /accounting
         - Parsuj filtry z request (search, config_id, date_from, date_to, sort, sort_dir, page, per_page)
         - Wywolaj ReceiptRepository::paginate($filters)
         - Pobierz liste aktywnych konfiguracji (ReceiptConfigRepository::listAll() filtruj is_active)
         - Mapuj wiersze do formatu tableList (analogicznie do OrdersController)
         - Renderuj widok accounting/index z tableList data
       - **export(Request): Response** — GET /accounting/export
         - Te same filtry co index
         - Wywolaj ReceiptRepository::exportData($filters)
         - Uzyj PhpSpreadsheet: nowy Spreadsheet, ustaw naglowki, wypelnij wiersze
         - Kolumny: Numer, Data wystawienia, Data sprzedazy, Kwota brutto, Konfiguracja, Nr zamowienia, Nr referencyjny
         - Zwroc Response z Content-Type xlsx i Content-Disposition attachment
         - Nazwa pliku: paragony_YYYY-MM-DD.xlsx
         - UWAGA: PhpSpreadsheet zapisuje do php://output — uzyj ob_start/ob_get_clean

    3. **routes/web.php:**
       - Dodaj instancje AccountingController (reuse receiptRepository, receiptConfigRepository)
       - `GET /accounting` → [$accountingController, 'index'], [$authMiddleware]
       - `GET /accounting/export` → [$accountingController, 'export'], [$authMiddleware]
       - Dodaj PRZED trasami receipt (logicznie: sekcja accounting)

    4. **resources/views/accounting/index.php:**
       - Uzyj komponentu table-list (include components/table-list.php z $tableList)
       - Dodaj przycisk "Eksportuj XLSX" w naglowku (link do /accounting/export z aktualnymi filtrami w query string)
       - Wzorzec: analogicznie do orders/list.php

    5. **resources/views/layouts/app.php:**
       - Dodaj nowa sekcje w sidebar PRZED "Ustawienia":
         ```php
         <a class="sidebar__link<?= $currentMenu === 'accounting' ? ' is-active' : '' ?>" href="/accounting">
           <svg>...</svg> <?= $e($t('navigation.accounting_section')) ?>
         </a>
         ```
       - Uzyj ikony dokumentu/receipt (inline SVG)

    6. **resources/lang/pl.php:**
       - Dodaj klucze: `navigation.accounting_section` => 'Ksiegowosc'
       - `accounting.title`, `accounting.export`, `accounting.empty`
       - `accounting.filters.*`: search, config, date_from, date_to, any
       - `accounting.columns.*`: number, issue_date, sale_date, total_gross, config, order

    Wzorzec: Reuse komponentu table-list.php, analogia do OrdersController::index().
  </action>
  <verify>
    - `php -l src/Modules/Accounting/AccountingController.php`
    - `php -l routes/web.php`
    - `php -l resources/views/accounting/index.php`
    - `php -l resources/views/layouts/app.php`
    - `composer show phpoffice/phpspreadsheet` — zainstalowany
  </verify>
  <done>AC-1, AC-2, AC-3, AC-4, AC-5 spelnione</done>
</task>

<task type="auto">
  <name>Task 3: SCSS build + aktualizacja dokumentacji</name>
  <files>
    resources/scss/app.scss,
    public/assets/css/app.css,
    DOCS/ARCHITECTURE.md
  </files>
  <action>
    1. Build SCSS do CSS (jesli nowe klasy dodane)
    2. Zaktualizuj DOCS/ARCHITECTURE.md:
       - Dodaj AccountingController (index, export) do sekcji Modules/Accounting
       - Dodaj ReceiptRepository::paginate(), exportData()
       - Dodaj trasy /accounting i /accounting/export
  </action>
  <verify>
    - `npx sass --style=compressed --no-source-map resources/scss/app.scss public/assets/css/app.css`
    - Brak bledow
  </verify>
  <done>Dokumentacja zaktualizowana, CSS zbudowany</done>
</task>

<task type="checkpoint:human-verify" gate="blocking">
  <what-built>Sekcja Ksiegowosc: lista paragonow z filtrami, paginacja, eksport XLSX, link w nawigacji</what-built>
  <how-to-verify>
    1. Otworz aplikacje → sidebar → kliknij "Ksiegowosc"
    2. Sprawdz: tabela paragonow wyswietla sie z kolumnami
    3. Uzyj filtrow: szukaj po numerze, wybierz konfiguracje, ustaw daty
    4. Sprawdz paginacje: zmien strone, zmien ilosc na strone
    5. Kliknij "Eksportuj XLSX" — plik pobiera sie
    6. Otworz XLSX — dane poprawne, filtry uwzglednione
    7. Sprawdz czy link do zamowienia w tabeli dziala
    8. Sprawdz pusta liste (filtr bez wynikow) — komunikat "Brak paragonow"
  </how-to-verify>
  <resume-signal>Type "approved" to continue, or describe issues to fix</resume-signal>
</task>

</tasks>

<boundaries>

## DO NOT CHANGE
- database/migrations/* (schemat zablokowany)
- src/Modules/Settings/ReceiptConfigRepository.php (gotowe z fazy 09)
- src/Modules/Accounting/ReceiptController.php (gotowe z fazy 11 — tylko odczyt)
- resources/views/receipts/* (gotowe z fazy 11)

## SCOPE LIMITS
- Brak edycji/anulowania paragonu — poza zakresem v0.3
- Brak zaawansowanych raportow (sumy per konfiguracja, wykresy) — future
- Brak eksportu CSV — tylko XLSX
- Brak filtrowania po nabywcy — uproszczenie v0.3

</boundaries>

<verification>
Before declaring plan complete:
- [ ] `composer show phpoffice/phpspreadsheet` — zainstalowany
- [ ] `php -l src/Modules/Accounting/AccountingController.php`
- [ ] `php -l src/Modules/Accounting/ReceiptRepository.php`
- [ ] `php -l resources/views/accounting/index.php`
- [ ] `php -l routes/web.php`
- [ ] Link "Ksiegowosc" widoczny w sidebar nawigacji
- [ ] Lista paragonow wyswietla sie z paginacja
- [ ] Filtry dzialaja (search, config, date_from, date_to)
- [ ] Sortowanie dziala (numer, data, kwota)
- [ ] Eksport XLSX pobiera sie i zawiera poprawne dane
- [ ] Pusta lista wyswietla komunikat
- [ ] All acceptance criteria met
</verification>

<success_criteria>
- Wszystkie 3 taski auto + 1 checkpoint ukonczone
- Wszystkie AC-1 do AC-5 spelnione
- PhpSpreadsheet zainstalowany i dzialajacy
- Brak bledow PHP
- Weryfikacja manualna przez uzytkownika (checkpoint)
</success_criteria>

<output>
After completion, create `.paul/phases/12-accounting-list/12-01-SUMMARY.md`
</output>
