---
phase: 05-finances-fakturownia-import
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
  - cron.php
  - autoload/class.Cron.php
  - autoload/Controllers/FinancesController.php
  - autoload/Domain/Finances/FinanceRepository.php
  - autoload/Domain/Finances/FakturowniaApiClient.php
  - autoload/Domain/Finances/FakturowniaImportRepository.php
  - autoload/Domain/Finances/FakturowniaInvoiceImporter.php
  - templates/finances/main-view.php
  - templates/finances/fakturownia-import-panel.php
  - .env.example
autonomous: true
---

<objective>
## Goal
Dodac automatyczny import faktur przychodowych i kosztowych z Fakturowni do finansow crmPRO, z mechanizmem uczenia mapowan klientow i produktow/uslug.

## Purpose
Zminimalizowac reczna prace w finansach: pierwsze faktury wymagaja mapowania, ale kolejne dokumenty z tymi samymi klientami i pozycjami maja importowac sie juz calkowicie automatycznie.

## Output
- Warstwa integracji API Fakturowni z konfiguracja przez `.env`
- Trwale mapowania klientow i produktow/uslug do struktur finansowych crmPRO
- Automatyczny import przez cron z idempotencja i data startu
- Panel w finansach do obslugi brakujacych mapowan
</objective>

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

## Source Files
@cron.php
@autoload/class.Cron.php
@autoload/Controllers/FinancesController.php
@autoload/Domain/Finances/FinanceRepository.php
@templates/finances/main-view.php
@config.php
</context>

<acceptance_criteria>

## AC-1: Konfiguracja API i data startu importu
```gherkin
Given w pliku .env ustawiono dane dostepowe Fakturowni oraz date startu importu
When cron uruchamia proces importu
Then importer laczy sie z API Fakturowni i pobiera tylko dokumenty od skonfigurowanej daty
  And brakujaca konfiguracja zwraca czytelny blad bez przerwania calego crona
```

## AC-2: Import przychodow i kosztow z idempotencja
```gherkin
Given faktura przychodowa lub kosztowa istnieje w Fakturowni
When dokument ma komplet mapowan klienta i pozycji
Then powstaje operacja finansowa w crmPRO z poprawnym znakiem kwoty (przychod > 0, koszt < 0)
  And ponowne uruchomienie importu nie tworzy duplikatu tej samej faktury
```

## AC-3: Mechanizm uczenia mapowan
```gherkin
Given dokument zawiera klienta lub pozycje bez mapowania
When importer przetwarza dokument
Then dokument nie jest importowany do finansow, a brakujace mapowania trafiaja na liste do recznego przypisania
  And po zapisaniu mapowania kolejne faktury z tym klientem/pozycja importuja sie automatycznie
```

## AC-4: Obsluga mapowan w zakladce finansow
```gherkin
Given uzytkownik jest na /finances/main_view/
When otwiera panel importu Fakturownia
Then widzi brakujace mapowania klientow i produktow/uslug
  And moze przypisac klienta CRM i kategorie finansowa
  And zapis mapowania jest chroniony tokenem CSRF
```

</acceptance_criteria>

<tasks>

<task type="auto">
  <name>Task 1: Zbudowac warstwe integracji Fakturownia + trwawe mapowania</name>
  <files>
    autoload/Domain/Finances/FakturowniaApiClient.php,
    autoload/Domain/Finances/FakturowniaImportRepository.php,
    autoload/Domain/Finances/FinanceRepository.php,
    .env.example
  </files>
  <action>
    1. Dodac loader `.env` (bez nowych bibliotek) i zdefiniowac klucze:
       - `FAKTUROWNIA_API_DOMAIN`
       - `FAKTUROWNIA_API_TOKEN`
       - `FAKTUROWNIA_START_DATE`
       - `FAKTUROWNIA_PAGE_LIMIT` (opcjonalnie)
    2. Dodac klienta API Fakturowni z obsluga paginacji i timeoutow:
       - pobieranie faktur przychodowych (np. endpoint invoices)
       - pobieranie faktur kosztowych (np. endpoint costs/expenses)
    3. Dodac repozytorium importu z tabelami tworzonymi przez `CREATE TABLE IF NOT EXISTS`:
       - tabela mapowania klientow Fakturownia -> crm_client.id
       - tabela mapowania pozycji (nazwa produktu/uslugi) -> finance_categories.id
       - tabela stanu importu i idempotencji (external_id + typ dokumentu)
       - tabela kolejki brakujacych mapowan do panelu finansow
    4. Wszystkie zapytania SQL wykonywac przez medoo/query z parametrami bindowanymi (bez sklejania SQL z danymi wejsciowymi).
    5. W `FinanceRepository` dodac metody pomocnicze do pobierania kategorii i klientow dla panelu mapowan.

    Unikac: trzymania tokenu API w `config.php`, mapowan w sesji i importu bez kontroli duplikatow.
  </action>
  <verify>
    - Odczyt `.env.example` potwierdza nowe klucze integracji.
    - Odczyt nowych klas potwierdza osobne odpowiedzialnosci (API, repo mapowan, state importu).
    - Test manualny: dwukrotne wywolanie zapisu importu dla tego samego external_id nie tworzy duplikatu.
  </verify>
  <done>AC-1 i AC-2 i AC-3 satisfied: konfiguracja, idempotencja i struktury mapowan gotowe</done>
</task>

<task type="auto">
  <name>Task 2: Dodac importer dokumentow i podpiac go pod cron</name>
  <files>
    autoload/Domain/Finances/FakturowniaInvoiceImporter.php,
    autoload/class.Cron.php,
    cron.php
  </files>
  <action>
    1. Dodac serwis importera, ktory:
       - pobiera dokumenty od `FAKTUROWNIA_START_DATE`,
       - scala dane klienta i pozycji,
       - sprawdza mapowania klienta i pozycji,
       - przy komplecie mapowan zapisuje operacje finansowe,
       - przy brakach wpisuje rekordy do kolejki brakow mapowan i pomija import dokumentu.
    2. Dodac polityke znaku kwoty:
       - przychodowe -> dodatnie `amount`
       - kosztowe -> ujemne `amount`
    3. Wprowadzic idempotencje na poziomie zrodlowego `external_id` + typ dokumentu.
    4. Rozszerzyc `Cron` i `cron.php` o krok `import_finances_from_fakturownia()`:
       - uruchamiany przy kazdym cyklu crona,
       - zwraca statusy `ok|empty|error` analogicznie do obecnych zadan,
       - loguje krotki komunikat o liczbie zaimportowanych i pominietych dokumentow.

    Unikac: przerywania calego crona przy pojedynczym bledzie faktury.
  </action>
  <verify>
    - Suchy przebieg importera zwraca licznik imported/skipped/unmapped.
    - Uruchomienie `php cron.php` wykonuje nowy krok i nie psuje istniejacych zadan cron.
    - Powtorne uruchomienie dla tych samych danych nie dubluje wpisow w `finance_operations`.
  </verify>
  <done>AC-1 i AC-2 i AC-3 satisfied: cron importuje faktury cyklicznie i bez duplikatow</done>
</task>

<task type="auto">
  <name>Task 3: Dodac panel mapowan Fakturowni w finansach i zapis mapowan</name>
  <files>
    autoload/Controllers/FinancesController.php,
    templates/finances/main-view.php,
    templates/finances/fakturownia-import-panel.php
  </files>
  <action>
    1. Rozszerzyc `FinancesController` o akcje:
       - pobranie brakujacych mapowan do widoku finansow,
       - zapis mapowania klienta,
       - zapis mapowania produktu/uslugi do kategorii,
       - wszystkie zapisy z walidacja i `S::csrf_verify()`.
    2. W `templates/finances/main-view.php` dolaczyc panel importu (partial) pokazujacy:
       - liste nieprzypisanych klientow z Fakturowni + select klienta CRM,
       - liste nieprzypisanych pozycji + select kategorii finansowej,
       - status ostatniego importu (czas, liczba imported/skipped/unmapped).
    3. W panelu uzyc escapingu danych wyjsciowych (np. `htmlspecialchars`) i komunikatow zgodnych z UI crmPRO.

    Unikac: logiki biznesowej bezposrednio w widoku.
  </action>
  <verify>
    - Wejscie na `/finances/main_view/` pokazuje panel mapowan bez regresji istniejacych statystyk.
    - Zapis mapowania bez tokenu CSRF jest odrzucany.
    - Po zapisaniu mapowania i ponownym imporcie dokument znika z listy brakow i tworzy operacje automatycznie.
  </verify>
  <done>AC-3 i AC-4 satisfied: mapowania sa obslugiwane z UI i kolejne faktury wpadaja automatycznie</done>
</task>

</tasks>

<boundaries>

## DO NOT CHANGE
- modules niezwiązane z finansami (tasks, projects, wiki)
- mechanizm logowania i sesji poza niezbednym CSRF check
- istniejace endpointy email importera zadan

## SCOPE LIMITS
- Ten plan obejmuje tylko import i mapowania Fakturownia -> Finanse
- Bez refaktoryzacji calego modulu finansow
- Bez zmian w zewnetrznym harmonogramie systemowym (zakladamy, ze cron systemowy juz wywoluje `cron.php`)
- Bez automatycznego tworzenia nowych klientow CRM (tylko mapowanie do istniejacych)

</boundaries>

<verification>
Before declaring plan complete:
- [ ] `.env.example` zawiera komplet nowych zmiennych Fakturowni
- [ ] Importer obsluguje dokumenty przychodowe i kosztowe
- [ ] Idempotencja blokuje duplikaty importu
- [ ] Brakujace mapowania sa kolejkowane i widoczne w finansach
- [ ] Zapis mapowan wymaga poprawnego tokenu CSRF
- [ ] `php cron.php` wykonuje import bez zatrzymywania pozostalych krokow
- [ ] All acceptance criteria met
</verification>

<success_criteria>
- Faktury przychodowe i kosztowe importuja sie automatycznie po uzupelnieniu mapowan
- Pierwszy import nie robi blednych przypisan: nieznane rekordy trafiaja do kolejki mapowania
- Kolejne dokumenty z tym samym klientem i pozycja sa przypisywane bez interwencji recznej
- Import uruchamia sie cyklicznie przez cron i jest bezpieczny na ponowne wykonanie
</success_criteria>

<output>
After completion, create `.paul/phases/05-finances-fakturownia-import/05-01-SUMMARY.md`
</output>
