Skill: alexwoo-awso/ksef-accountant-pl (version 2.2.6)

--- name: ksef-accountant-pl description: "Asystent ksiegowy Krajowego Systemu e-Faktur (KSeF) w jezyku polskim. Uzyj przy pracy z KSeF 2.0 API, fakturami FA(3), zgodnoscia z polskim VAT, przetwarzaniem e-faktur, dopasowywaniem platnosci, rejestrami VAT (JPK_V7), fakturami korygujacymi, mechanizmem podzielonej platnosci (MPP) lub polskimi przeplywami ksiegowymi. Dostarcza wiedze domenowa do wystawiania faktur, przetwarzania zakupow, klasyfikacji kosztow, wykrywania fraudu i prognozowania cash flow w ekosystemie KSeF." license: MIT homepage: https://github.com/alexwoo-awso/skills source: https://github.com/alexwoo-awso/skills/tree/main/ksef-accountant-pl disableModelInvocation: true disable-model-invocation: true allowModelInvocation: false instruction_only: true has_executable_code: false credential_scope: "optional-user-provided" env: KSEF_TOKEN: description: "Token API KSeF do uwierzytelniania sesji. Dostarczany przez uzytkownika — skill nie generuje, nie przechowuje ani nie przesyla tokenow. Konfiguruj TYLKO po zweryfikowaniu, ze platforma wymusza flage disableModelInvocation (patrz sekcja Model bezpieczenstwa i skill.json)." required: false secret: true KSEF_ENCRYPTION_KEY: description: "Klucz szyfrowania Fernet do bezpiecznego przechowywania tokenow. Uzycie opcjonalne — przyklad wzorca bezpieczenstwa opisanego w dokumentacji referencyjnej. Konfiguruj TYLKO po zweryfikowaniu, ze platforma wymusza flage disableModelInvocation." required: false secret: true KSEF_BASE_URL: description: "Bazowy URL API KSeF. Domyslnie https://ksef-demo.mf.gov.pl (DEMO). Produkcja: https://ksef.mf.gov.pl — wymaga jawnej zgody uzytkownika. Uzywaj produkcji TYLKO po pelnej weryfikacji bezpieczenstwa platformy." required: false default: "https://ksef-demo.mf.gov.pl" --- # Agent Ksiegowy KSeF Specjalistyczna wiedza do obslugi Krajowego Systemu e-Faktur (KSeF) w srodowisku KSeF 2.0 ze struktura FA(3). Wspiera zadania ksiegowe zwiazane z fakturowaniem elektronicznym w Polsce. ## Model bezpieczenstwa Ten skill jest **wylacznie instrukcyjny** — sklada sie z plikow Markdown zawierajacych wiedze domenowa, wzorce architektoniczne i przyklady kodu. Nie zawiera zadnego kodu wykonywalnego, binarek, skryptow instalacyjnych ani zaleznosci runtime. **Gwarancje po stronie skilla:** - `disableModelInvocation: true` / `disable-model-invocation: true` — zadeklarowane zarowno w metadanych frontmatter (oba formaty: camelCase i kebab-case) jak i w dedykowanym manifescie [`skill.json`](skill.json). Skill nie powinien byc wywolywany autonomicznie przez model. - `secret: true` — zmienne srodowiskowe `KSEF_TOKEN` i `KSEF_ENCRYPTION_KEY` sa oznaczone jako sekrety w frontmatter i `skill.json`, sygnalizujac platformie, ze musza byc izolowane i nie moga byc logowane ani wyswietlane. - Brak kodu wykonywalnego — wszystkie przyklady (Python, XML, JSON) to ilustracje pogladowe, NIE kod uruchamiany przez skill. - Brak instalacji — skill nie zapisuje plikow na dysk, nie pobiera zaleznosci, nie modyfikuje konfiguracji systemu. - Dedykowany manifest [`skill.json`](skill.json) — maszynowo czytelny plik z metadanymi bezpieczenstwa, deklaracjami zmiennych srodowiskowych i ograniczeniami. Jesli platforma nie parsuje frontmatter SKILL.md poprawnie, powinna odczytac metadane z `skill.json`. **UWAGA — weryfikacja metadanych rejestru przed instalacja:** Flagi bezpieczenstwa sa zadeklarowane w dwoch zrodlach: frontmatter SKILL.md i [`skill.json`](skill.json). Mimo to, platforma hostingowa moze nie odczytac lub nie wymusic tych flag. **Przed instalacja MUSISZ wykonac ponizsze kroki:** 1. **Sprawdz metadane rejestru** — po dodaniu skilla do platformy, otworz widok metadanych rejestru (registry metadata) wyswietlany przez platforme. Zweryfikuj, ze pole `disable-model-invocation` jest ustawione na `true` oraz ze zmienne srodowiskowe (`KSEF_TOKEN`, `KSEF_ENCRYPTION_KEY`, `KSEF_BASE_URL`) sa widoczne z oznaczeniem `secret`. Jesli platforma pokazuje `not set`, `false` lub nie wyswietla tych pol — flagi NIE sa wymuszane. 2. **Jesli metadane rejestru nie pasuja do frontmatter/skill.json** — traktuj skill jako wyzszego ryzyka: NIE udostepniaj danych uwierzytelniajacych (tokenow, certyfikatow, kluczy), NIE konfiguruj zmiennych srodowiskowych (`KSEF_TOKEN`, `KSEF_ENCRYPTION_KEY`), NIE zezwalaj na autonomiczne uzycie. 3. **Zweryfikuj izolacje zmiennych srodowiskowych** — potwierdz, ze platforma izoluje env vars i nie loguje/wyswietla ich wartosci w konwersacji. 4. **Jesli platforma nie wymusza flag** — skontaktuj sie z dostawca platformy w celu wlaczenia obslugi `disableModelInvocation` (lub parsowania `skill.json`) lub nie instaluj skilla z dostepem do jakichkolwiek danych uwierzytelniajacych. **Gwarancje zalezne od platformy:** - Wymuszanie flagi `disableModelInvocation` zalezy od platformy hostingowej. Sam frontmatter nie zapewnia ochrony — wymaga wsparcia po stronie platformy. - Izolacja zmiennych srodowiskowych (env vars) zalezy od platformy. Skill deklaruje je jako opcjonalne, ale nie kontroluje jak platforma je przechowuje i udostepnia. - Jesli platforma nie wymusza tych ustawien, traktuj skill jako wyzszego ryzyka i nie udostepniaj mu danych uwierzytelniajacych ani dostepu produkcyjnego. ## Ograniczenia - **Tylko wiedza — brak wykonywania kodu** - Dostarcza wiedze domenowa, wzorce architektoniczne i wskazowki. Wszystkie przyklady kodu (w tym ML/AI) sa edukacyjne i pogladowe. Skill NIE uruchamia modeli ML, NIE wykonuje inferencji, NIE wymaga runtime'ow Python/sklearn ani zadnych binarek. Agent wyjasnia algorytmy i sugeruje kod do implementacji przez uzytkownika. - **Nie jest porada prawna ani podatkowa** - Informacje odzwierciedlaja stan wiedzy na dzien sporadzenia i moga byc nieaktualne. Zawsze zalecaj konsultacje z doradca podatkowym przed wdrozeniem. - **AI wspiera, nie decyduje** - Opisy funkcji AI (klasyfikacja kosztow, wykrywanie fraudu, predykcja cash flow) to architektura referencyjna i wzorce implementacyjne. Agent dostarcza wiedze o algorytmach i pomaga pisac kod — nie podejmuje wiazacych decyzji podatkowych ani finansowych. - **Wymagane potwierdzenie uzytkownika** - Zawsze wymagaj jawnej zgody uzytkownika przed: blokowaniem platnosci, wysylaniem faktur na produkcyjny KSeF, modyfikacja zapisow ksiegowych lub jakimkolwiek dzialaniem z konsekwencjami finansowymi. - **Dane uwierzytelniajace zarzadzane przez uzytkownika** - Tokeny KSeF API, certyfikaty i klucze szyfrowania musza byc dostarczone przez uzytkownika przez zmienne srodowiskowe (zadeklarowane w metadanych: `KSEF_TOKEN`, `KSEF_ENCRYPTION_KEY`, `KSEF_BASE_URL`) lub menedzer sekretow. Skill nigdy nie przechowuje, nie generuje, nie przesyla ani nie prosi o dane uwierzytelniajace niejawnie. **NIGDY nie wklejaj danych uwierzytelniajacych (tokenow, kluczy, certyfikatow) bezposrednio w rozmowie z agentem** — uzyj zmiennych srodowiskowych lub menedzera sekretow platformy. Przyklady uzycia Vault/Fernet w dokumentacji referencyjnej to wzorce architektoniczne do implementacji przez uzytkownika. - **Uzyj DEMO do testow** - Produkcja (`https://ksef.mf.gov.pl`) wystawia prawnie wiazace faktury. Uzyj DEMO (`https://ksef-demo.mf.gov.pl`) do developmentu i testow. - **Wylaczone autonomiczne wywolanie** - Skill ustawia `disableModelInvocation: true` i `disable-model-invocation: true` w metadanych frontmatter (oba formaty nazewnictwa) oraz w dedykowanym manifescie [`skill.json`](skill.json). Oznacza to, ze model nie powinien wywolywac tego skilla autonomicznie — wymaga jawnej akcji uzytkownika. **UWAGA:** Frontmatter i `skill.json` to deklaracje — nie gwarancje. Wymuszanie zalezy od platformy. Przed uzyciem zweryfikuj, ze metadane rejestru (registry metadata) wyswietlane przez platforme rowniez pokazuja `disable-model-invocation: true`. Jesli platforma pokazuje `not set` lub `false`, flaga nie jest wymuszana i skill moze byc wywolywany autonomicznie (patrz sekcja "Model bezpieczenstwa" powyzej). ## Checklist przed instalacja Przed instalacja skilla i konfiguracja zmiennych srodowiskowych wykonaj ponizsze kroki: - [ ] Zweryfikuj metadane rejestru platformy — pole `disable-model-invocation` musi pokazywac `true` - [ ] Zweryfikuj, ze platforma odczytala deklaracje env vars z frontmatter lub [`skill.json`](skill.json) — zmienne `KSEF_TOKEN` i `KSEF_ENCRYPTION_KEY` musza byc widoczne jako sekrety (`secret: true`) - [ ] Potwierdz, ze platforma izoluje zmienne srodowiskowe (nie loguje, nie wyswietla w konwersacji) - [ ] Przetestuj skill wylacznie ze srodowiskiem DEMO (`https://ksef-demo.mf.gov.pl`) przed jakimkolwiek uzyciem produkcyjnym - [ ] NIE wklejaj tokenow, kluczy ani certyfikatow bezposrednio w rozmowie — uzyj env vars lub menedzera sekretow - [ ] Jesli metadane rejestru nie pasuja do frontmatter/skill.json — NIE konfiguruj danych uwierzytelniajacych i zglos problem dostawcy platformy ## Glowne kompetencje ### 1. Obsluga KSeF 2.0 API Wystawianie faktur FA(3), pobieranie faktur zakupowych, zarzadzanie sesjami/tokenami, obsluga trybu Offline24 (awaryjny), pobieranie UPO (Urzedowe Poswiadczenie Odbioru). Kluczowe endpointy: ```http POST /api/online/Session/InitToken # Inicjalizacja sesji POST /api/online/Invoice/Send # Wyslanie faktury GET /api/online/Invoice/Status/{ref} # Sprawdzenie statusu POST /api/online/Query/Invoice/Sync # Zapytanie o faktury zakupowe ``` Zobacz [references/ksef-api-reference.md](references/ksef-api-reference.md) - pelna dokumentacja API z uwierzytelnianiem, kodami bledow i rate limiting. ### 2. Struktura FA(3) Roznice FA(3) vs FA(2): zalaczniki do faktur, typ kontrahenta PRACOWNIK, rozszerzone formaty konta bankowego, limit 50 000 pozycji w korekcie, identyfikatory JST i grup VAT. Zobacz [references/ksef-fa3-examples.md](references/ksef-fa3-examples.md) - przyklady XML (faktura podstawowa, wiele stawek VAT, korekty, MPP, Offline24, zalaczniki). ### 3. Przeplywy ksiegowe **Sprzedaz:** Dane -> Generuj FA(3) -> Wyslij KSeF -> Pobierz nr KSeF -> Ksieguj `Wn 300 (Rozrachunki) | Ma 700 (Sprzedaz) + Ma 220 (VAT nalezny)` **Zakupy:** Odpytuj KSeF -> Pobierz XML -> Klasyfikuj AI -> Ksieguj `Wn 400-500 (Koszty) + Wn 221 (VAT) | Ma 201 (Rozrachunki)` Zobacz [references/ksef-accounting-workflows.md](references/ksef-accounting-workflows.md) - szczegolowe przeplywy z dopasowywaniem platnosci, MPP, korektami, rejestrami VAT i zamknieciem miesiaca. ### 4. Funkcje wspomagane AI (architektura referencyjna) Ponizsze opisy to wzorce implementacyjne i architektura referencyjna. Skill NIE uruchamia modeli ML — dostarcza wiedze o algorytmach, pomaga projektowac pipeline'y i pisac kod do implementacji w systemie uzytkownika. Przyklady kodu w plikach referencyjnych (Python, sklearn, pandas) to pseudokod pogladowy — skill nie zawiera wytrenowanych modeli, artefaktow ML ani plikow wykonywalnych. - **Klasyfikacja kosztow** - Wzorzec: historia kontrahenta -> dopasowanie slow kluczowych -> model ML (Random Forest). Flaguj do przegladu jesli confidence < 0.8. - **Wykrywanie fraudu** - Wzorzec: Isolation Forest dla anomalii kwotowych, scoring dla phishing invoices, analiza grafow dla VAT carousel. - **Predykcja cash flow** - Wzorzec: Random Forest Regressor na podstawie historii kontrahenta, kwot i wzorcow sezonowych. Zobacz [references/ksef-ai-features.md](references/ksef-ai-features.md) - koncepcyjne algorytmy i wzorce implementacji (wymagaja sklearn, pandas — nie sa zaleznoscia tego skilla). ### 5. Compliance i bezpieczenstwo (wzorce implementacyjne) Ponizsze to rekomendowane wzorce bezpieczenstwa do implementacji w systemie uzytkownika. Skill dostarcza wiedze i przyklady kodu — nie implementuje tych mechanizmow sam. - Weryfikacja Bialej Listy VAT przed platnosciami - Szyfrowane przechowywanie tokenow (wzorce Fernet/Vault — do implementacji przez uzytkownika) - Audit trail wszystkich operacji - Strategia backup 3-2-1 - Zgodnosc z RODO (anonimizacja po okresie retencji) - RBAC (kontrola dostepu oparta na rolach) Zobacz [references/ksef-security-compliance.md](references/ksef-security-compliance.md) - wzorce implementacji i checklista bezpieczenstwa. ### 6. Faktury korygujace Pobierz oryginal z KSeF -> Utworz korekte FA(3) -> Powiaz z nr KSeF oryginalu -> Wyslij do KSeF -> Ksieguj storno lub roznicowo. ### 7. Rejestry VAT i JPK_V7 Generowanie rejestrow sprzedazy/zakupow (Excel/PDF), JPK_V7M (miesieczny), JPK_V7K (kwartalny). ## Troubleshooting - szybka pomoc | Problem | Przyczyna | Rozwiazanie | |---------|-----------|-------------| | Faktura odrzucona (400/422) | Nieprawidlowy XML, NIP, data, brak pol | Sprawdz UTF-8, waliduj schemat FA(3), weryfikuj NIP | | Timeout API | Awaria KSeF, siec, godziny szczytu | Sprawdz status KSeF, retry z exponential backoff | | Nie mozna dopasowac platnosci | Niezgodna kwota, brak danych, split payment | Rozszerzone wyszukiwanie (+/-2%, +/-14 dni), sprawdz MPP | Zobacz [references/ksef-troubleshooting.md](references/ksef-troubleshooting.md) - pelny przewodnik troubleshooting. ## Pliki referencyjne Laduj w zaleznosci od zadania: | Plik | Kiedy czytac | |------|-------------| | [skill.json](skill.json) | Manifest metadanych — flagi bezpieczenstwa, deklaracje env vars, ograniczenia. Zrodlo prawdy dla rejestrow i skanerow. | | [ksef-api-reference.md](references/ksef-api-reference.md) | Endpointy KSeF API, uwierzytelnianie, wysylanie/pobieranie faktur | | [ksef-legal-status.md](references/ksef-legal-status.md) | Daty wdrozenia KSeF, wymagania prawne, kary | | [ksef-fa3-examples.md](references/ksef-fa3-examples.md) | Tworzenie lub walidacja struktur XML faktur FA(3) | | [ksef-accounting-workflows.md](references/ksef-accounting-workflows.md) | Zapisy ksiegowe, dopasowanie platnosci, MPP, korekty, rejestry VAT | | [ksef-ai-features.md](references/ksef-ai-features.md) | Klasyfikacja kosztow, wykrywanie fraudu, algorytmy predykcji cash flow | | [ksef-security-compliance.md](references/ksef-security-compliance.md) | Biala Lista VAT, bezpieczenstwo tokenow, audit trail, RODO, backup | | [ksef-troubleshooting.md](references/ksef-troubleshooting.md) | Bledy API, problemy walidacji, wydajnosc | ## Zasoby oficjalne - Portal KSeF: https://ksef.podatki.gov.pl - KSeF DEMO: https://ksef-demo.mf.gov.pl - KSeF Produkcja: https://ksef.mf.gov.pl - API Bialej Listy VAT: https://wl-api.mf.gov.pl - KSeF Latarnia (status): https://github.com/CIRFMF/ksef-latarnia

path: references/ksef-accounting-workflows.md
content: # Przepływy Księgowe KSeF

**UWAGA:** Przykłady mają charakter poglądowy i mogą wymagać dostosowania do specyfiki działalności.

---

## Workflow Faktury Sprzedaży

### Proces Kompletny

```mermaid
graph LR
    A[Dane faktury] --> B[Generuj FA3 XML]
    B --> C[Wyślij do KSeF]
    C --> D[Czekaj na status]
    D --> E{Akceptacja?}
    E -->|Tak| F[Pobierz numer KSeF]
    E -->|Nie| G[Analiza błędów]
    F --> H[Zapis księgowy]
    H --> I[Generuj PDF/email]
    G --> J[Popraw XML]
    J --> B
```

### Zapis Księgowy

**Przykład: Faktura sprzedaży usług**
```
FV/2026/02/0008 (KSeF: 1234567890-20260208-ABCDEF1234567890-12)
Data sprzedaży: 08.02.2026
Nabywca: Klient Sp. z o.o. (NIP: 0987654321)

Wn 300 Rozrachunki z odbiorcami     12 300,00 PLN
Ma 700 Sprzedaż usług                10 000,00 PLN
Ma 220 VAT należny                    2 300,00 PLN

Opis: Usługi programistyczne - 100 godz. @ 100 PLN
```

**Przykład: Faktura sprzedaży towarów**
```
FV/2026/02/0009 (KSeF: 1234567890-20260209-BCDEFG2345678901-13)
Data sprzedaży: 09.02.2026

Wn 300 Rozrachunki                   24 600,00 PLN
Ma 701 Sprzedaż towarów              20 000,00 PLN
Ma 220 VAT należny (23%)              4 600,00 PLN

Wn 701 Sprzedaż towarów              15 000,00 PLN
Ma 330 Wartość sprzedanych towarów   15 000,00 PLN
(Rozchód magazynowy)
```

---

## Workflow Faktury Zakupowej

### Proces Kompletny

```mermaid
graph LR
    A[Cron: co 15 min] --> B[Odpytaj KSeF]
    B --> C{Nowe faktury?}
    C -->|Tak| D[Pobierz XML]
    C -->|Nie| A
    D --> E[Parsuj dane]
    E --> F[Klasyfikuj koszt AI]
    F --> G{Confidence > 0.8?}
    G -->|Tak| H[Auto-księguj]
    G -->|Nie| I[Flag do review]
    H --> J[Zapisz do bazy]
    I --> J
```

### Zapis Księgowy

**Przykład: Zakup usług IT**
```
ZAKUP/123/2026 (KSeF: 9876543210-20260205-ZYXWVU9876543210-01)
Data otrzymania: 05.02.2026
Sprzedawca: IT Solutions Sp. z o.o. (NIP: 1122334455)
Kategoria: 402 (Usługi informatyczne) - AI confidence: 0.95

Wn 402 Usługi informatyczne           5 000,00 PLN
Wn 221 VAT naliczony (23%)            1 150,00 PLN
Ma 201 Rozrachunki z dostawcami       6 150,00 PLN

Opis: Hosting i wsparcie techniczne - styczeń 2026
```

**Przykład: Zakup materiałów biurowych**
```
ZAKUP/124/2026 (KSeF: 9876543210-20260206-ZYXWVU9876543211-02)
Kategoria: 502 (Materiały biurowe) - AI confidence: 0.88

Wn 502 Materiały biurowe                 500,00 PLN
Wn 221 VAT naliczony (23%)               115,00 PLN
Ma 201 Rozrachunki z dostawcami          615,00 PLN
```

---

## Dopasowywanie Płatności

### Algorytm Scoring

```python
def match_payment_to_invoice(payment, open_invoices):
    matches = []

    for invoice in open_invoices:
        score = 0

        # 1. Dokładna kwota brutto (+/- 0.01 PLN)
        if abs(payment.amount - invoice.total_gross) < 0.01:
            score += 40

        # 2. NIP w tytule przelewu
        if invoice.seller_nip in payment.title.replace(' ', ''):
            score += 30

        # 3. Numer faktury w tytule
        if invoice.number in payment.title:
            score += 20

        # 4. Data w zakresie (termin płatności +/- 7 dni)
        days_diff = abs((payment.date - invoice.payment_due).days)
        if days_diff <= 7:
            score += 10 - days_diff

        # 5. Numer KSeF w tytule
        if invoice.ksef_number and invoice.ksef_number in payment.title:
            score += 25

        if score >= 70:
            matches.append({
                'invoice': invoice,
                'score': score,
                'confidence': score / 100
            })

    return sorted(matches, key=lambda x: x['score'], reverse=True)
```

### Zapis Księgowy - Płatność

**Przykład: Płatność faktury zakupowej**
```
Płatność: 6 150,00 PLN
Tytuł: "ZAKUP/123/2026 NIP 1122334455"
Data: 15.02.2026
Matched: ZAKUP/123/2026 (score: 90, confidence: 0.90)

Wn 201 Rozrachunki z dostawcami       6 150,00 PLN
Ma 130 Rachunek bieżący               6 150,00 PLN

Opis: Zapłata faktury ZAKUP/123/2026
```

**Przykład: Płatność faktury sprzedażowej**
```
Wpłata: 12 300,00 PLN
Tytuł: "FV/2026/02/0008"
Data: 20.02.2026
Matched: FV/2026/02/0008 (score: 85)

Wn 130 Rachunek bieżący              12 300,00 PLN
Ma 300 Rozrachunki z odbiorcami      12 300,00 PLN

Opis: Wpłata za FV/2026/02/0008
```

---

## Mechanizm Podzielonej Płatności (MPP)

### Warunki (zgodnie z obecnymi przepisami)
- Faktury >15 000 PLN brutto
- Towary/usługi z załącznika 15 do ustawy VAT

### Implementacja

```python
def handle_split_payment(invoice):
    if invoice.total_gross > 15000 and invoice.has_attachment_15_goods:
        net_payment = invoice.total_net
        vat_payment = invoice.total_vat

        # Przelew 1: Część netto
        bank_transfer_1 = {
            'to_account': invoice.seller_account,
            'amount': net_payment,
            'title': f'Faktura {invoice.number} (część netto)'
        }

        # Przelew 2: VAT na specjalne konto VAT
        bank_transfer_2 = {
            'to_account': invoice.seller_vat_account,
            'amount': vat_payment,
            'title': f'Faktura {invoice.number} (VAT - split payment)'
        }

        return [bank_transfer_1, bank_transfer_2]
```

### Zapis Księgowy

**Przykład: MPP - część netto**
```
Wn 201 Rozrachunki z dostawcami      20 000,00 PLN
Ma 130 Rachunek bieżący              20 000,00 PLN

Opis: Zapłata netto - MPP - ZAKUP/200/2026
```

**Przykład: MPP - część VAT**
```
Wn 201 Rozrachunki z dostawcami       4 600,00 PLN
Ma 130 Rachunek bieżący               4 600,00 PLN

Opis: Zapłata VAT na konto VAT - MPP - ZAKUP/200/2026
```

---

## Faktury Korygujące

### Proces Korekty

```mermaid
graph TD
    A[Potrzeba korekty] --> B[Pobierz oryginał z KSeF]
    B --> C[Utwórz FA3 korekty]
    C --> D[Powiąż z nr KSeF oryginału]
    D --> E[Wyślij do KSeF]
    E --> F[Otrzymaj nr KSeF korekty]
    F --> G{Metoda księgowania?}
    G -->|Storno| H[Storno + Nowa]
    G -->|Różnicowa| I[Tylko różnica]
```

### Metoda Storno

**Oryginał:**
```
FV/2026/02/0005 (KSeF: 1234567890-20260205-ORIGINAL123456-12)
Kwota: 12 300,00 PLN (netto: 10 000,00, VAT: 2 300,00)

Wn 300 Rozrachunki    12 300,00
Ma 700 Sprzedaż       10 000,00
Ma 220 VAT należny     2 300,00
```

**Storno oryginału:**
```
FV/2026/02/0005/K01 (Korekta - storno)
Data korekty: 08.02.2026
Przyczyna: Błąd w cenie jednostkowej

Wn 700 Sprzedaż       10 000,00 (czerwone)
Wn 220 VAT należny     2 300,00 (czerwone)
Ma 300 Rozrachunki    12 300,00 (czerwone)
```

**Nowa wartość:**
```
FV/2026/02/0005/K01 (Korekta - nowa wartość)

Wn 300 Rozrachunki     6 150,00
Ma 700 Sprzedaż        5 000,00
Ma 220 VAT należny     1 150,00
```

**Efekt netto:** Zmniejszenie sprzedaży o 5 000 PLN netto, VAT o 1 150 PLN

---

### Metoda Różnicowa

**Korekta (tylko różnica):**
```
FV/2026/02/0005/K01 (KSeF: 1234567890-20260208-CORRECT234567-13)
Różnica: -6 150,00 PLN

Wn 700 Sprzedaż        5 000,00 (czerwone)
Wn 220 VAT należny     1 150,00 (czerwone)
Ma 300 Rozrachunki     6 150,00 (czerwone)
```

---

## Rejestry VAT

### Rejestr Sprzedaży (Generowanie)

```python
def generate_sales_register(period_start, period_end):
    invoices = ksef_client.query_invoices(
        date_from=period_start,
        date_to=period_end,
        subject_type='subject1'  # sprzedawca
    )

    register = []
    for invoice in invoices:
        register.append({
            'lp': invoice.ordinal,
            'data_wystawienia': invoice.issue_date,
            'data_sprzedazy': invoice.sale_date,
            'numer_faktury': invoice.number,
            'numer_ksef': invoice.ksef_number,
            'nabywca_nazwa': invoice.buyer_name,
            'nabywca_nip': invoice.buyer_nip,
            'netto_23': invoice.net_23,
            'vat_23': invoice.vat_23,
            'netto_8': invoice.net_8,
            'vat_8': invoice.vat_8,
            'netto_5': invoice.net_5,
            'vat_5': invoice.vat_5,
            'netto_0': invoice.net_0,
            'netto_zw': invoice.net_exempt,
            'brutto': invoice.total_gross
        })

    export_to_excel(register, f'Rejestr_sprzedazy_{period_start}_{period_end}.xlsx')
    return register
```

### Rejestr Zakupów (Generowanie)

```python
def generate_purchase_register(period_start, period_end):
    invoices = ksef_client.query_invoices(
        date_from=period_start,
        date_to=period_end,
        subject_type='subject2'  # nabywca
    )

    register = []
    for invoice in invoices:
        register.append({
            'lp': invoice.ordinal,
            'data_otrzymania': invoice.acquisition_date,
            'data_wystawienia': invoice.issue_date,
            'numer_faktury': invoice.number,
            'numer_ksef': invoice.ksef_number,
            'sprzedawca_nazwa': invoice.seller_name,
            'sprzedawca_nip': invoice.seller_nip,
            'kategoria': invoice.category,  # AI classification
            'netto': invoice.net_amount,
            'vat': invoice.vat_amount,
            'brutto': invoice.total_gross
        })

    export_to_excel(register, f'Rejestr_zakupow_{period_start}_{period_end}.xlsx')
    return register
```

---

## Zamknięcie Miesiąca

### Checklist

**Przed zamknięciem:**
- [ ] Wszystkie faktury sprzedaży wysłane do KSeF
- [ ] Wszystkie faktury zakupowe pobrane z KSeF
- [ ] Wszystkie płatności dopasowane
- [ ] Korekty zaksięgowane
- [ ] Rejestr sprzedaży wygenerowany
- [ ] Rejestr zakupów wygenerowany
- [ ] Bilans otwarć/zamknięć kont rozrachunkowych
- [ ] JPK_V7M wygenerowany
- [ ] Deklaracja VAT-7 przygotowana

**Zapisy zamykające miesiąc:**
```
# Rozliczenie VAT
Wn 220 VAT należny         28 750,00
Ma 221 VAT naliczony       17 250,00
Ma 225 VAT do zapłaty      11 500,00

# Płatność VAT
Wn 225 VAT do zapłaty      11 500,00
Ma 130 Rachunek bieżący    11 500,00
```

---

**Zobacz również:**
- [Funkcje AI - Klasyfikacja](ksef-ai-features.md#klasyfikacja)
- [Przykłady JPK_V7](ksef-jpk-examples.md)


path: references/ksef-ai-features.md
content: # Funkcje AI dla KSeF

**UWAGA OGÓLNA:** Cały kod w tym dokumencie to **koncepcyjna architektura referencyjna** — wzorce implementacyjne do adaptacji przez użytkownika w jego własnym systemie. Ten skill NIE uruchamia modeli ML, NIE wykonuje inferencji i NIE wymaga runtime'ów Python, sklearn, pandas ani żadnych innych zależności. Agent korzysta z tych wzorców wyłącznie jako bazy wiedzy do wyjaśniania algorytmów, projektowania pipeline'ów i pomocy w pisaniu kodu.

**Zależności wymagane do implementacji (NIE zależności tego skilla):** sklearn, pandas, numpy — do zainstalowania przez użytkownika w jego środowisku.

Wszystkie funkcje AI/ML mają charakter wspierający i wymagają nadzoru personelu księgowego. Wskaźniki wydajności są celami projektowymi i mogą się różnić. Systemy AI nie podejmują wiążących decyzji podatkowych.

---

## Klasyfikacja Kosztów

### Algorytm (wysokopoziomowy)

```python
def classify_expense(invoice_data):
    """
    Klasyfikacja kosztu na podstawie wielu źródeł danych
    """
    features = {
        'seller_name': invoice_data.seller_name,
        'item_names': [item.name for item in invoice_data.items],
        'pkwiu_codes': [item.pkwiu for item in invoice_data.items if item.pkwiu],
        'total_amount': invoice_data.total_gross,
        'seller_nip': invoice_data.seller_nip
    }

    # 1. Historia z kontrahentem (najwyższy priorytet)
    historical = get_historical_category(features['seller_nip'])
    if historical and historical.confidence > 0.9:
        return historical.category, historical.confidence

    # 2. Dopasowanie słów kluczowych
    keyword_match = match_keywords(features['item_names'])
    if keyword_match and keyword_match.confidence > 0.85:
        return keyword_match.category, keyword_match.confidence

    # 3. Model ML (Random Forest / Neural Network)
    ml_prediction = ml_model.predict(features)

    # 4. Flagowanie do review jeśli niska pewność
    if ml_prediction.confidence < 0.8:
        flag_for_manual_review(invoice_data)

    return ml_prediction.category, ml_prediction.confidence
```

### Kategorie Kosztów (Przykładowe)

```python
COST_CATEGORIES = {
    # Usługi obce
    400: "Usługi obce (ogólne)",
    401: "Usługi transportowe",
    402: "Usługi informatyczne (hosting, development, IT support)",
    403: "Usługi prawne i doradcze",
    404: "Usługi najmu i dzierżawy",
    405: "Usługi marketingowe i reklamowe",
    406: "Usługi księgowe",
    407: "Usługi konsultingowe",

    # Materiały i surowce
    500: "Materiały i surowce (ogólne)",
    501: "Energia, woda, paliwo",
    502: "Materiały biurowe",
    503: "Części zamienne",

    # Inne
    600: "Wynagrodzenia i pochodne",
    700: "Amortyzacja",
}
```

### Słowa Kluczowe (Przykłady)

```python
KEYWORDS = {
    402: ["hosting", "server", "cloud", "AWS", "Azure", "development",
          "programowanie", "IT support", "software", "licencja"],
    405: ["reklama", "marketing", "Google Ads", "Facebook Ads",
          "social media", "SEO", "content"],
    501: ["energia", "prąd", "gaz", "woda", "paliwo", "benzyna"],
    502: ["papier", "długopis", "toner", "biuro", "artykuły"],
}
```

### Trenowanie Modelu ML

```python
from sklearn.ensemble import RandomForestClassifier
from sklearn.feature_extraction.text import TfidfVectorizer

class ExpenseClassifier:
    def __init__(self):
        self.model = RandomForestClassifier(n_estimators=200, random_state=42)
        self.vectorizer = TfidfVectorizer(max_features=500)

    def train(self, historical_invoices):
        """
        Trenowanie na danych historycznych
        """
        # Przygotuj dane
        X_text = [
            f"{inv.seller_name} {' '.join(inv.item_names)}"
            for inv in historical_invoices
        ]
        X_vectors = self.vectorizer.fit_transform(X_text)

        y = [inv.category for inv in historical_invoices]

        # Trenuj model
        self.model.fit(X_vectors, y)

    def predict(self, invoice):
        """
        Predykcja kategorii
        """
        X_text = f"{invoice.seller_name} {' '.join(invoice.item_names)}"
        X_vector = self.vectorizer.transform([X_text])

        prediction = self.model.predict(X_vector)[0]
        probabilities = self.model.predict_proba(X_vector)[0]
        confidence = max(probabilities)

        return {
            'category': prediction,
            'confidence': confidence,
            'alternatives': self._get_alternatives(probabilities)
        }
```

---

## Wykrywanie Anomalii i Fraudu

### Detekcja Anomalii (Isolation Forest)

```python
from sklearn.ensemble import IsolationForest
import numpy as np

class FraudDetector:
    def __init__(self):
        self.model = IsolationForest(contamination=0.05, random_state=42)
        self.is_trained = False

    def extract_features(self, invoice):
        """Ekstrakcja cech do analizy"""
        return np.array([
            invoice.total_gross,
            len(invoice.items),
            invoice.items_avg_price,
            invoice.payment_term_days,
            invoice.hour_of_day,  # 0-23
            int(invoice.is_weekend),  # 0 lub 1
            invoice.seller_transaction_count,
            invoice.seller_avg_amount,
            invoice.amount_vs_avg_ratio  # aktualna / średnia
        ])

    def train(self, historical_invoices):
        """Trenowanie na danych historycznych"""
        features = [self.extract_features(inv) for inv in historical_invoices]
        self.model.fit(features)
        self.is_trained = True

    def detect(self, invoice):
        """Wykrycie anomalii"""
        if not self.is_trained:
            return {'anomaly': False, 'reason': 'Model nie wytrenowany'}

        features = self.extract_features(invoice)
        prediction = self.model.predict([features])[0]

        if prediction == -1:  # Anomalia
            return {
                'anomaly': True,
                'risk_level': 'HIGH',
                'reasons': self._analyze_reasons(invoice),
                'action': 'MANUAL_REVIEW_REQUIRED'
            }

        return {'anomaly': False}

    def _analyze_reasons(self, invoice):
        """Analiza przyczyn anomalii"""
        reasons = []

        if invoice.total_gross > invoice.seller_avg_amount * 3:
            reasons.append("Kwota 3x większa niż średnia od tego sprzedawcy")

        if invoice.is_weekend and invoice.hour_of_day < 6:
            reasons.append("Wystawiona w nocy w weekend (nietypowe)")

        if invoice.seller_transaction_count == 1:
            reasons.append("Pierwszy kontakt z tym sprzedawcą")

        if invoice.payment_term_days < 3:
            reasons.append("Bardzo krótki termin płatności (możliwy phishing)")

        return reasons
```

### Detekcja Phishing Invoices

```python
def detect_phishing_invoice(invoice):
    """
    Wykrywa potencjalne faktury phishingowe
    """
    score = 0
    reasons = []

    # 1. Podobna nazwa do znanego kontrahenta
    similar = find_similar_contractor_names(invoice.seller_name)
    for known_contractor in similar:
        if known_contractor.nip != invoice.seller_nip:
            score += 30
            reasons.append(f"Podobna nazwa do {known_contractor.name} ale inny NIP")

        if known_contractor.bank_account != invoice.bank_account:
            score += 40
            reasons.append("Inne konto bankowe niż znany kontrahent")

    # 2. Krótki termin płatności
    if invoice.payment_term_days <= 2:
        score += 20
        reasons.append("Bardzo krótki termin płatności (typowe dla phishingu)")

    # 3. Pierwszy kontakt
    if get_transaction_count(invoice.seller_nip) == 0:
        score += 10
        reasons.append("Pierwszy raz od tego sprzedawcy")

    # 4. Wysoka kwota przy pierwszym kontakcie
    if score > 0 and invoice.total_gross > 10000:
        score += 15
        reasons.append("Wysoka kwota przy pierwszym/podejrzanym kontakcie")

    if score >= 50:
        return {
            'phishing_detected': True,
            'risk': 'CRITICAL',
            'score': score,
            'reasons': reasons,
            'action': 'BLOCK_PAYMENT_AND_VERIFY'
        }

    return {'phishing_detected': False}
```

### Detekcja VAT Carousel

```python
def detect_vat_carousel(invoices, time_window_days=30):
    """
    Wykrywa potencjalne wzorce karuzeli VAT
    """
    # Buduj graf transakcji
    graph = build_transaction_graph(invoices)

    # Szukaj cykli (A → B → C → A)
    cycles = find_cycles(graph)

    suspicious = []
    for cycle in cycles:
        # Sprawdź podejrzane cechy
        if is_suspicious_cycle(cycle):
            suspicious.append({
                'cycle': cycle,
                'risk': 'CRITICAL',
                'participants': [node.nip for node in cycle],
                'total_value': sum(edge.amount for edge in cycle),
                'time_span_days': get_cycle_duration(cycle),
                'action': 'REPORT_TO_TAX_OFFICE'
            })

    return suspicious

def is_suspicious_cycle(cycle):
    """Czy cykl jest podejrzany?"""
    # 1. Cykl zamyka się w <30 dni
    if get_cycle_duration(cycle) > 30:
        return False

    # 2. Kwoty podobne (±10%)
    amounts = [edge.amount for edge in cycle]
    if max(amounts) / min(amounts) > 1.1:
        return False

    # 3. Ten sam towar/usługa
    items = [edge.item_description for edge in cycle]
    if not all_similar(items):
        return False

    return True
```

---

## Predykcja Cash Flow

### Model Predykcyjny

```python
from sklearn.ensemble import RandomForestRegressor
import pandas as pd

class CashFlowPredictor:
    def __init__(self):
        self.model = RandomForestRegressor(n_estimators=100, random_state=42)

    def prepare_training_data(self, historical_data):
        """
        Przygotowanie danych treningowych
        DataFrame z kolumnami:
        - invoice_due_date, invoice_amount, contractor_nip
        - payment_term_days, actual_payment_date, days_late
        """
        X = historical_data[[
            'invoice_amount',
            'payment_term_days',
            'contractor_avg_days_late',
            'contractor_payment_reliability',  # % w terminie
            'month',
            'is_end_of_quarter'
        ]]

        y = historical_data['days_late']

        return X, y

    def train(self, historical_data):
        X, y = self.prepare_training_data(historical_data)
        self.model.fit(X, y)

    def predict_payment_date(self, invoice):
        """Przewiduj rzeczywistą datę płatności"""
        contractor_stats = get_contractor_stats(invoice.buyer_nip)

        features = pd.DataFrame([{
            'invoice_amount': invoice.total_gross,
            'payment_term_days': invoice.payment_term_days,
            'contractor_avg_days_late': contractor_stats['avg_days_late'],
            'contractor_payment_reliability': contractor_stats['reliability'],
            'month': invoice.issue_date.month,
            'is_end_of_quarter': invoice.issue_date.month in [3, 6, 9, 12]
        }])

        predicted_days_late = self.model.predict(features)[0]
        predicted_date = invoice.payment_due_date + timedelta(days=int(predicted_days_late))

        return {
            'predicted_payment_date': predicted_date,
            'expected_days_late': int(predicted_days_late),
            'confidence': self._calculate_confidence(features)
        }

    def predict_monthly_cash_flow(self, year, month):
        """Prognoza miesięczna"""
        # Faktury sprzedaży z terminem w tym miesiącu
        sales_invoices = get_invoices_due_in_month(year, month, type='sales')

        predicted_income = 0
        for invoice in sales_invoices:
            prediction = self.predict_payment_date(invoice)
            # Tylko jeśli przewidywana płatność w tym miesiącu
            if prediction['predicted_payment_date'].month == month:
                predicted_income += invoice.total_gross

        # Faktury zakupowe
        purchase_invoices = get_invoices_due_in_month(year, month, type='purchases')
        predicted_expenses = sum(inv.total_gross for inv in purchase_invoices)

        return {
            'month': f"{year}-{month:02d}",
            'predicted_income': predicted_income,
            'predicted_expenses': predicted_expenses,
            'net_cash_flow': predicted_income - predicted_expenses,
            'note': 'Predykcja ma charakter szacunkowy'
        }
```

### Statystyki Kontrahenta

```python
def get_contractor_stats(nip):
    """
    Oblicz statystyki płatności dla kontrahenta
    """
    invoices = get_all_invoices_for_contractor(nip)

    if not invoices:
        return {
            'avg_days_late': 0,
            'reliability': 1.0,  # Brak historii = optymistyczne założenie
            'total_invoices': 0
        }

    days_late_list = []
    paid_on_time = 0

    for inv in invoices:
        if inv.payment_date:
            days_late = (inv.payment_date - inv.payment_due_date).days
            days_late_list.append(max(0, days_late))  # Tylko dodatnie

            if days_late <= 0:
                paid_on_time += 1

    return {
        'avg_days_late': sum(days_late_list) / len(days_late_list),
        'reliability': paid_on_time / len(invoices),
        'total_invoices': len(invoices),
        'max_days_late': max(days_late_list) if days_late_list else 0
    }
```

---

## Best Practices dla AI

### 1. Ciągłe Uczenie (Continuous Learning)

```python
def retrain_models_monthly():
    """
    Retrenuj modele co miesiąc na świeżych danych
    """
    # Pobierz dane z ostatnich 12 miesięcy
    end_date = datetime.now()
    start_date = end_date - timedelta(days=365)

    historical_data = get_invoices(start_date, end_date)

    # Retrenuj klasyfikator kosztów
    expense_classifier.train(historical_data)

    # Retrenuj detektor anomalii
    fraud_detector.train(historical_data)

    # Retrenuj predyktor cash flow
    cash_flow_predictor.train(historical_data)

    save_models()  # Zapisz do dysku
```

### 2. Human-in-the-Loop

```python
def classify_with_review(invoice):
    """
    Klasyfikacja z flagowaniem do review
    """
    prediction = expense_classifier.predict(invoice)

    if prediction['confidence'] < 0.8:
        # Niska pewność → human review
        task = create_review_task(
            invoice=invoice,
            suggested_category=prediction['category'],
            confidence=prediction['confidence'],
            alternatives=prediction['alternatives']
        )
        return {
            'category': None,  # Czekaj na review
            'status': 'PENDING_REVIEW',
            'task_id': task.id
        }

    # Wysoka pewność → auto-classify
    return {
        'category': prediction['category'],
        'status': 'AUTO_CLASSIFIED',
        'confidence': prediction['confidence']
    }
```

### 3. Audit Trail dla AI

```python
def log_ai_decision(invoice, prediction, action):
    """
    Loguj decyzje AI dla audytu
    """
    ai_audit_log.insert({
        'timestamp': datetime.now(),
        'invoice_id': invoice.id,
        'model_name': 'ExpenseClassifier',
        'model_version': '2.1',
        'prediction': prediction,
        'confidence': prediction['confidence'],
        'action_taken': action,
        'reviewed_by_human': action == 'MANUAL_REVIEW'
    })
```

---

**Ostrzeżenie końcowe:** Wszystkie funkcje AI wymagają regularnego monitorowania, walidacji i nadzoru ze strony wykwalifikowanego personelu. Nie należy polegać wyłącznie na automatycznych decyzjach w sprawach podatkowych i księgowych.

**Przypomnienie:** Powyższe przykłady kodu to architektura referencyjna. Ten skill nie zawiera wytrenowanych modeli, artefaktów ML ani plików wykonywalnych. Implementacja wymaga zainstalowania zależności (sklearn, pandas, numpy) i wytrenowania modeli na danych użytkownika w jego własnym środowisku.


path: references/ksef-api-reference.md
content: # KSeF API 2.0 - Reference

**UWAGA:** Rzeczywiste punkty końcowe i formaty mogą ulec zmianie. Należy zawsze odwoływać się do oficjalnej dokumentacji API KSeF.

---

## Autentykacja

### 1. Inicjalizacja Sesji (Token)

**Endpoint:**
```http
POST /api/online/Session/InitToken
Content-Type: application/json
```

**Request:**
```json
{
  "context": {
    "token": "YOUR_KSEF_TOKEN_HERE"
  }
}
```

**Response (200 OK):**
```json
{
  "referenceNumber": "20260208-SE-1234567890AB-CD",
  "timestamp": "2026-02-08T23:40:00.000Z",
  "sessionToken": {
    "token": "SESSION_TOKEN_VALUE",
    "validity": "2026-02-09T00:10:00.000Z"
  }
}
```

**Ważność tokena:** Typowo 30 minut

---

### 2. Inicjalizacja Sesji (Certyfikat)

**Endpoint:**
```http
POST /api/online/Session/InitSigned
Content-Type: application/octet-stream
```

**Request:** Signed XML Session Request (CAdES)

---

### 3. Status Sesji

**Endpoint:**
```http
GET /api/online/Session/Status/{ReferenceNumber}
[REDACTED_SECRET] {token}
```

**Response (200 OK):**
```json
{
  "referenceNumber": "20260208-SE-1234567890AB-CD",
  "timestamp": "2026-02-08T23:45:00.000Z",
  "processingCode": 200,
  "processingDescription": "Sesja aktywna"
}
```

---

### 4. Zamknięcie Sesji

**Endpoint:**
```http
DELETE /api/online/Session/Terminate
[REDACTED_SECRET] {token}
```

**Response (200 OK):**
```json
{
  "referenceNumber": "20260208-ST-1234567890AB-CD",
  "timestamp": "2026-02-08T23:50:00.000Z",
  "processingCode": 200,
  "processingDescription": "Sesja zakończona"
}
```

---

## Wysyłanie Faktur

### 5. Wysłanie Faktury

**Endpoint:**
```http
POST /api/online/Invoice/Send
[REDACTED_SECRET] {token}
Content-Type: application/octet-stream
```

**Request Body:** FA(3) XML Content (raw bytes)

**Response (200 OK - Przyjęto do przetworzenia):**
```json
{
  "referenceNumber": "20260208-IV-1234567890AB-CD",
  "timestamp": "2026-02-08T23:41:00.000Z",
  "processingCode": 200,
  "processingDescription": "Faktura została przyjęta do przetworzenia"
}
```

---

### 6. Status Faktury

**Endpoint:**
```http
GET /api/online/Invoice/Status/{InvoiceElementReferenceNumber}
[REDACTED_SECRET] {token}
```

**Możliwe statusy:**
- `200` - Przetwarzanie w toku
- `202` - Faktura zaakceptowana
- `400` - Faktura odrzucona (błędy walidacji)

**Response (202 - Zaakceptowana):**
```json
{
  "referenceNumber": "20260208-IV-1234567890AB-CD",
  "timestamp": "2026-02-08T23:41:30.000Z",
  "processingCode": 202,
  "ksefReferenceNumber": "1234567890-20260208-ABCDEF1234567890-12",
  "invoiceNumber": "FV/2026/02/0008",
  "acquisitionTimestamp": "2026-02-08T23:41:25.000Z"
}
```

**Response (400 - Odrzucona):**
```json
{
  "referenceNumber": "20260208-IV-1234567890AB-CD",
  "timestamp": "2026-02-08T23:41:15.000Z",
  "processingCode": 400,
  "exception": {
    "exceptionDetailList": [
      {
        "exceptionCode": "101",
        "exceptionDescription": "Błąd walidacji schematu XSD"
      }
    ]
  }
}
```

---

### 7. Pobieranie UPO

**Endpoint:**
```http
GET /api/online/Invoice/Upo/{KsefReferenceNumber}
[REDACTED_SECRET] {token}
Accept: application/xml
```

**Response (200 OK):** XML z urzędowym poświadczeniem odbioru

---

## Pobieranie Faktur

### 8. Wyszukiwanie Faktur (Synchroniczne)

**Endpoint:**
```http
POST /api/online/Query/Invoice/Sync
[REDACTED_SECRET] {token}
Content-Type: application/json
```

**Request (faktury zakupowe, zakres dat):**
```json
{
  "queryCriteria": {
    "type": "range",
    "invoicingDateFrom": "2026-02-01",
    "invoicingDateTo": "2026-02-08",
    "subjectType": "subject2"
  },
  "pageSize": 100,
  "pageOffset": 0
}
```

**QueryCriteria - typy:**
- `subjectType: "subject1"` - faktury sprzedażowe (jako sprzedawca)
- `subjectType: "subject2"` - faktury zakupowe (jako nabywca)

**Response (200 OK):**
```json
{
  "referenceNumber": "20260208-QS-1234567890AB-CD",
  "timestamp": "2026-02-08T23:42:00.000Z",
  "invoiceHeaderList": [
    {
      "ksefReferenceNumber": "9876543210-20260205-ZYXWVU9876543210-01",
      "invoiceNumber": "ZAKUP/123/2026",
      "acquisitionTimestamp": "2026-02-05T10:30:00.000Z",
      "netAmount": "5000.00",
      "vatAmount": "1150.00",
      "grossAmount": "6150.00",
      "currencyCode": "PLN"
    }
  ],
  "numberOfElements": 1,
  "pageSize": 100,
  "pageOffset": 0,
  "totalPages": 1,
  "totalElements": 1
}
```

---

### 9. Wyszukiwanie Faktur (Asynchroniczne)

**Endpoint:**
```http
POST /api/online/Query/Invoice/Async/Init
[REDACTED_SECRET] {token}
Content-Type: application/json
```

**Użycie:** Dla dużych zbiorów danych (>100 faktur)

**Workflow:**
1. `POST /api/online/Query/Invoice/Async/Init` - inicjalizacja
2. `GET /api/online/Query/Invoice/Async/Status/{QueryElementReferenceNumber}` - sprawdzenie statusu
3. `GET /api/online/Query/Invoice/Async/Fetch/{QueryElementReferenceNumber}` - pobranie wyników

---

### 10. Pobieranie Pełnej Faktury

**Endpoint:**
```http
GET /api/online/Invoice/Get/{KsefReferenceNumber}
[REDACTED_SECRET] {token}
Accept: application/xml
```

**Response (200 OK):** Pełny XML FA(3)

---

## Tryb Offline

### 11. Wysłanie Faktury Offline

**Endpoint:**
```http
POST /api/online/Invoice/Send
[REDACTED_SECRET] {token}
Content-Type: application/octet-stream
```

**FA(3) XML z oznaczeniem Offline24:**
```xml
<Faktura>
  <Naglowek>
    <SystemInfo>Offline24</SystemInfo>
  </Naglowek>
  <!-- ... -->
</Faktura>
```

**Termin wysyłki:** 24h od odzyskania łączności

---

## Kody Błędów

### Najczęstsze

| Kod | Opis | Rozwiązanie |
|-----|------|-------------|
| 100 | Nieprawidłowy format XML | Sprawdź encoding UTF-8 |
| 101 | Błąd walidacji schematu | Upewnij się że używasz FA(3) |
| 102 | Nieprawidłowy NIP | Sprawdź w białej liście VAT |
| 103 | Data w przyszłości | Skoryguj DataWytworzeniaFa |
| 104 | Duplikat numeru faktury | Sprawdź unikalność |
| 401 | Brak autoryzacji | Sesja wygasła, odśwież token |
| 403 | Brak uprawnień | Sprawdź uprawnienia tokena |
| 500 | Błąd serwera | Retry z exponential backoff |
| 503 | Serwis niedostępny | Sprawdź status KSeF (Latarnia) |

---

## Rate Limiting

**UWAGA:** Szczegóły mogą się różnić. Sprawdź aktualną dokumentację.

**Typowe limity (szacunkowe):**
- Sesje: ~100 sesji/godzinę na token
- Faktury: ~1000 faktur/godzinę na sesję
- Queries: ~100 zapytań/godzinę na sesję

**Best practices:**
- Używaj pojedynczej sesji dla wielu faktur
- Implementuj exponential backoff przy 429/503
- Cachuj wyniki queries (nie odpytuj co sekundę)

---

## Środowiska

### DEMO (testowe)
```
Base URL: https://ksef-demo.mf.gov.pl
Przeznaczenie: Testy integracji, development
Dane: Testowe (nie produkcyjne)
```

### PRODUKCJA
```
Base URL: https://ksef.mf.gov.pl
Przeznaczenie: Faktury produkcyjne
Dane: Prawne wiążące
```

**UWAGA:** NIE testuj na produkcji! Zawsze używaj DEMO do developmentu.

---

## Przykładowy Workflow

```python
# 1. Inicjalizacja sesji
session = ksef_client.init_session([REDACTED_SECRET]")

# 2. Wysłanie faktury
invoice_xml = generate_fa3_xml(invoice_data)
ref = ksef_client.send_invoice(session, invoice_xml)

# 3. Sprawdzenie statusu (z retry)
for i in range(10):
    status = ksef_client.get_invoice_status(session, ref)
    if status.code == 202:
        ksef_number = status.ksefReferenceNumber
        break
    elif status.code == 400:
        handle_rejection(status.exception)
        break
    time.sleep(2)  # Czekaj 2s przed następnym sprawdzeniem

# 4. Pobranie UPO
upo_xml = ksef_client.get_upo(session, ksef_number)

# 5. Zamknięcie sesji
ksef_client.terminate_session(session)
```

---

**Oficjalna dokumentacja:** https://ksef.mf.gov.pl/api/docs


path: references/ksef-fa3-examples.md
content: # Przykłady FA(3) XML

**UWAGA:** Wszystkie przykłady mają charakter wyłącznie poglądowy i uproszczony. Nie stanowią gwarancji poprawnej walidacji względem schematu XSD. Przed użyciem w środowisku produkcyjnym należy zweryfikować zgodność z aktualną specyfikacją techniczną FA(3) oraz przeprowadzić testy walidacji.

---

## Podstawowa Faktura VAT

```xml
<?xml version="1.0" encoding="UTF-8"?>
<Faktura xmlns="http://crd.gov.pl/wzor/2023/06/29/12648/"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Naglowek>
        <KodFormularza kodSystemowy="FA(3)" wersjaSchemy="1-0E">FA</KodFormularza>
        <WariantFormularza>3</WariantFormularza>
        <DataWytworzeniaFa>2026-02-08T14:30:00</DataWytworzeniaFa>
        <SystemInfo>Autonomous KSeF Agent v2.1</SystemInfo>
    </Naglowek>

    <!-- Sprzedawca -->
    <Podmiot1>
        <DaneIdentyfikacyjne>
            <NIP>1234567890</NIP>
            <Nazwa>Moja Firma Sp. z o.o.</Nazwa>
        </DaneIdentyfikacyjne>
        <Adres>
            <KodKraju>PL</KodKraju>
            <AdresL1>ul. Przykładowa 1</AdresL1>
            <AdresL2>00-001 Warszawa</AdresL2>
        </Adres>
    </Podmiot1>

    <!-- Nabywca -->
    <Podmiot2>
        <DaneIdentyfikacyjne>
            <NIP>0987654321</NIP>
            <Nazwa>Klient Sp. z o.o.</Nazwa>
        </DaneIdentyfikacyjne>
        <Adres>
            <KodKraju>PL</KodKraju>
            <AdresL1>ul. Testowa 10</AdresL1>
            <AdresL2>02-222 Kraków</AdresL2>
        </Adres>
    </Podmiot2>

    <!-- Dane faktury -->
    <Fa>
        <KodWaluty>PLN</KodWaluty>
        <P_1>2026-02-08</P_1> <!-- Data wystawienia -->
        <P_2>FV/2026/02/0008</P_2> <!-- Numer faktury -->
        <P_6>2026-02-08</P_6> <!-- Data sprzedaży -->

        <!-- Pozycje faktury -->
        <FaWiersz>
            <NrWierszaFa>1</NrWierszaFa>
            <P_7>Usługa programistyczna</P_7>
            <P_8A>godz.</P_8A>
            <P_8B>100</P_8B>
            <P_9A>100.00</P_9A>
            <P_11>10000.00</P_11> <!-- Wartość netto -->
            <P_12>23</P_12> <!-- Stawka VAT -->
        </FaWiersz>

        <!-- Podsumowanie -->
        <P_13_1>10000.00</P_13_1> <!-- Netto 23% -->
        <P_14_1>2300.00</P_14_1> <!-- VAT 23% -->
        <P_15>12300.00</P_15> <!-- Brutto -->

        <RodzajFaktury>VAT</RodzajFaktury>

        <!-- Płatność -->
        <Platnosc>
            <Zaplacono>0</Zaplacono>
            <DataZaplaty>2026-02-22</DataZaplaty>
            <FormaPlatnosci>6</FormaPlatnosci> <!-- Przelew -->
            <RachunekBankowy>12 3456 7890 1234 5678 9012 3456</RachunekBankowy>
        </Platnosc>
    </Fa>
</Faktura>
```

---

## Faktura z Wieloma Pozycjami i Stawkami VAT

```xml
<Fa>
    <KodWaluty>PLN</KodWaluty>
    <P_1>2026-02-09</P_1>
    <P_2>FV/2026/02/0009</P_2>
    <P_6>2026-02-09</P_6>

    <!-- Pozycja 1: VAT 23% -->
    <FaWiersz>
        <NrWierszaFa>1</NrWierszaFa>
        <P_7>Laptop Dell XPS 15</P_7>
        <P_8A>szt.</P_8A>
        <P_8B>2</P_8B>
        <P_9A>5000.00</P_9A>
        <P_11>10000.00</P_11>
        <P_12>23</P_12>
    </FaWiersz>

    <!-- Pozycja 2: VAT 8% -->
    <FaWiersz>
        <NrWierszaFa>2</NrWierszaFa>
        <P_7>Książki techniczne</P_7>
        <P_8A>szt.</P_8A>
        <P_8B>10</P_8B>
        <P_9A>50.00</P_9A>
        <P_11>500.00</P_11>
        <P_12>8</P_12>
    </FaWiersz>

    <!-- Pozycja 3: VAT 0% (eksport) -->
    <FaWiersz>
        <NrWierszaFa>3</NrWierszaFa>
        <P_7>Usługi konsultingowe (eksport)</P_7>
        <P_8A>godz.</P_8A>
        <P_8B>40</P_8B>
        <P_9A>200.00</P_9A>
        <P_11>8000.00</P_11>
        <P_12>0</P_12>
    </FaWiersz>

    <!-- Podsumowanie -->
    <P_13_1>10000.00</P_13_1> <!-- Netto 23% -->
    <P_14_1>2300.00</P_14_1> <!-- VAT 23% -->
    <P_13_2>500.00</P_13_2> <!-- Netto 8% -->
    <P_14_2>40.00</P_14_2> <!-- VAT 8% -->
    <P_13_3>8000.00</P_13_3> <!-- Netto 0% -->
    <P_15>20840.00</P_15> <!-- Brutto -->

    <RodzajFaktury>VAT</RodzajFaktury>
</Fa>
```

---

## Faktura Korygująca

```xml
<Fa>
    <P_2>FV/2026/02/0005/K01</P_2> <!-- Numer korekty -->
    <RodzajFaktury>KOREKTA</RodzajFaktury>
    <PrzyczynaKorekty>Błąd w cenie jednostkowej</PrzyczynaKorekty>

    <!-- Dane faktury korygowanej -->
    <DaneFaKorygowanej>
        <DataWystFaKorygowanej>2026-02-05</DataWystFaKorygowanej>
        <NrFaKorygowanej>FV/2026/02/0005</NrFaKorygowanej>
        <NrKSeFFaKorygowanej>1234567890-20260205-ORIGINAL123456-12</NrKSeFFaKorygowanej>
    </DaneFaKorygowanej>

    <!-- Dane PRZED korektą -->
    <FaWierszCtrl>
        <LiczbaWierszyFa>1</LiczbaWierszyFa>
        <WartoscWierszyFa>12300.00</WartoscWierszyFa>
    </FaWierszCtrl>

    <!-- Dane PO korekcie -->
    <FaWiersz>
        <NrWierszaFa>1</NrWierszaFa>
        <P_7>Usługa programistyczna (cena skorygowana)</P_7>
        <P_8A>godz.</P_8A>
        <P_8B>100</P_8B>
        <P_9A>50.00</P_9A> <!-- Nowa cena: 50 zamiast 100 -->
        <P_11>5000.00</P_11>
        <P_12>23</P_12>
    </FaWiersz>

    <!-- Nowe podsumowanie -->
    <P_13_1>5000.00</P_13_1>
    <P_14_1>1150.00</P_14_1>
    <P_15>6150.00</P_15>
</Fa>
```

---

## Faktura z Kontrahent PRACOWNIK (Delegacja)

**Nowość FA(3):** Nowy typ kontrahenta do rozliczania delegacji

```xml
<Podmiot2>
    <DaneIdentyfikacyjne>
        <TypPodmiotu>PRACOWNIK</TypPodmiotu>
        <PESEL>85010112345</PESEL>
        <ImieNazwisko>Jan Kowalski</ImieNazwisko>
    </DaneIdentyfikacyjne>
    <Adres>
        <KodKraju>PL</KodKraju>
        <AdresL1>ul. Pracownicza 5</AdresL1>
        <AdresL2>03-333 Warszawa</AdresL2>
    </Adres>
</Podmiot2>

<Fa>
    <P_2>DEL/2026/02/001</P_2>
    <FaWiersz>
        <P_7>Rozliczenie delegacji - luty 2026</P_7>
        <P_8A>dni</P_8A>
        <P_8B>5</P_8B>
        <P_9A>150.00</P_9A>
        <P_11>750.00</P_11>
        <P_12>zw</P_12> <!-- VAT zwolniony -->
    </FaWiersz>
    <RodzajFaktury>VAT</RodzajFaktury>
</Fa>
```

---

## Faktura Trybu Offline24

```xml
<Naglowek>
    <KodFormularza kodSystemowy="FA(3)" wersjaSchemy="1-0E">FA</KodFormularza>
    <WariantFormularza>3</WariantFormularza>
    <DataWytworzeniaFa>2026-02-10T08:00:00</DataWytworzeniaFa>
    <SystemInfo>Offline24</SystemInfo> <!-- Oznaczenie offline -->
</Naglowek>
```

**Uwaga:** Wysłać do KSeF w ciągu 24h od odzyskania łączności. Data odbioru = data przypisania numeru KSeF.

---

## Faktura z Załącznikami

**Nowość FA(3):** Możliwość dołączenia załączników

```xml
<Fa>
    <!-- Standardowe dane faktury -->
    <P_2>FV/2026/02/0010</P_2>

    <!-- Załączniki -->
    <Zalaczniki>
        <Zalacznik>
            <NazwaPliku>specyfikacja_techniczna.pdf</NazwaPliku>
            <TypZalacznika>SPECYFIKACJA</TypZalacznika>
            <RozmiarKB>256</RozmiarKB>
            <HashSHA256>a1b2c3d4e5f6...</HashSHA256>
        </Zalacznik>
        <Zalacznik>
            <NazwaPliku>protokol_dostawy.pdf</NazwaPliku>
            <TypZalacznika>PROTOKOL</TypZalacznika>
            <RozmiarKB>128</RozmiarKB>
            <HashSHA256>f6e5d4c3b2a1...</HashSHA256>
        </Zalacznik>
    </Zalaczniki>
</Fa>
```

---

## Faktura z MPP (Mechanizm Podzielonej Płatności)

```xml
<Fa>
    <P_2>FV/2026/02/0011</P_2>

    <FaWiersz>
        <P_7>Stal konstrukcyjna (załącznik 15)</P_7>
        <P_8A>kg</P_8A>
        <P_8B>1000</P_8B>
        <P_9A>20.00</P_9A>
        <P_11>20000.00</P_11>
        <P_12>23</P_12>
        <OznaczenieMPP>1</OznaczenieMPP> <!-- Wymaga MPP -->
    </FaWiersz>

    <P_13_1>20000.00</P_13_1>
    <P_14_1>4600.00</P_14_1>
    <P_15>24600.00</P_15>

    <Platnosc>
        <TypPlatnosci>MPP</TypPlatnosci>
        <RachunekBankowy>12 3456 7890 1234 5678 9012 3456</RachunekBankowy>
        <RachunekBankowyVAT>98 7654 3210 9876 5432 1098 7654</RachunekBankowyVAT>
    </Platnosc>
</Fa>
```

---

## Walidacja przed Wysłaniem

```python
def validate_fa3_before_send(xml_content):
    """
    Podstawowa walidacja przed wysłaniem do KSeF
    """
    checks = []

    # 1. UTF-8 encoding
    try:
        xml_content.encode('utf-8')
        checks.append(('Encoding UTF-8', True))
    except:
        checks.append(('Encoding UTF-8', False))

    # 2. Parsowanie XML
    try:
        root = ET.fromstring(xml_content)
        checks.append(('Poprawny XML', True))
    except:
        checks.append(('Poprawny XML', False))
        return checks

    # 3. Namespace
    if 'http://crd.gov.pl/wzor/2023/06/29/12648/' in xml_content:
        checks.append(('Namespace FA(3)', True))
    else:
        checks.append(('Namespace FA(3)', False))

    # 4. Wersja schematu
    if 'wersjaSchemy="1-0E"' in xml_content:
        checks.append(('Wersja schematu 1-0E', True))
    else:
        checks.append(('Wersja schematu 1-0E', False))

    # 5. Wymagane pola
    required = ['KodFormularza', 'P_1', 'P_2', 'P_15', 'NIP']
    for field in required:
        if f'<{field}' in xml_content or f'<{field}>' in xml_content:
            checks.append((f'Pole {field}', True))
        else:
            checks.append((f'Pole {field}', False))

    return checks
```

---

**Oficjalna dokumentacja FA(3):**
https://ksef.podatki.gov.pl/media/4u1bmhx4/information-sheet-on-the-fa-3-logical-structure.pdf


path: references/ksef-legal-status.md
content: # Stan Prawny KSeF - Szczegóły

**Data aktualizacji:** 8 lutego 2026
**UWAGA:** Informacje mogą ulec zmianie. Należy regularnie weryfikować aktualne przepisy i komunikaty Ministerstwa Finansów.

---

## Harmonogram Wdrożenia (Planowany)

### Faza 1: Duzi Podatnicy (od 1 lutego 2026)
**Kogo dotyczy:** Obrót >200 mln PLN brutto w 2024 roku

**Obowiązki:**
- ✅ Wystawianie faktur przez KSeF
- ✅ Odbieranie faktur przez KSeF

### Faza 2: Pozostali Podatnicy (od 1 kwietnia 2026)
**Kogo dotyczy:** Obrót ≤200 mln PLN

**Obowiązki:**
- ✅ Odbieranie faktur przez KSeF (od 1 lutego 2026)
- ✅ Wystawianie faktur przez KSeF (od 1 kwietnia 2026)
- ⏳ Do 31 marca 2026 mogą wystawiać faktury poza KSeF

### Faza 3: Mikroprzedsiębiorcy (od 1 stycznia 2027)
**Kogo dotyczy:** Miesięczny obrót <10 tys PLN

**Obowiązki:**
- ✅ Odbieranie: od 1 lutego 2026
- ✅ Wystawianie: od 1 stycznia 2027

---

## Okres Przejściowy

**UWAGA:** Szczegóły mogą ulec zmianie. Przedstawione informacje oparte są na aktualnie dostępnych komunikatach.

### Planowany Grace Period
- **Do 31 grudnia 2026** - przewidywany brak kar za błędy
- Dotyczy: błędów w strukturze FA(3), opóźnień wysyłki
- Nie dotyczy: uchylania się od wystawiania faktur

### Tryb Offline24
- **Status:** Planowany jako stały element systemu
- **Przeznaczenie:** Sytuacje awaryjne (brak internetu, awaria KSeF, katastrofy)
- **Termin wysyłki:** 24h od odzyskania łączności
- **Uwaga prawna:** Prawo do odliczenia VAT od daty przypisania numeru KSeF (nie daty wystawienia offline)

### Faktury poza KSeF
- **Do 31 marca 2026:** Dozwolone dla firm ≤200 mln PLN
- **Od 1 kwietnia 2026:** Zakaz (z wyjątkiem przypadków szczególnych)

---

## Zmiany Systemowe

### KSeF 1.0 → KSeF 2.0
- **KSeF 1.0:** Planowane zamknięcie 26 stycznia 2026
- **Przerwa techniczna:** 5 dni (26-31 stycznia 2026)
- **KSeF 2.0:** Planowany start 1 lutego 2026

### FA(2) → FA(3)
- **FA(2):** Planowane zakończenie obsługi 1 lutego 2026
- **FA(3):** Obowiązkowa od 1 lutego 2026
- **Migracja:** Wszyscy podatnicy muszą dostosować systemy

---

## Konsekwencje Prawne (Przyszłe)

**UWAGA:** Poniższe informacje dotyczą planowanego systemu kar po zakończeniu grace period.

### Po 1 stycznia 2027 (Planowane)
- Brak faktury w KSeF → możliwa kara
- Faktura poza KSeF → możliwa kara
- Opóźniona wysyłka → możliwa kara

**Wysokość kar:** Należy konsultować z aktualną ustawą o VAT

---

## Wymagania Techniczne

### Obligatoryjna Struktura
- **FA(3) ver. 1-0E**
- Format: XML zgodny ze schematem
- Encoding: UTF-8
- Walidacja: Automatyczna przy przyjęciu przez KSeF

### Certyfikaty (MCU)
- **MCU:** Moduł Certyfikatów i Uprawnień
- **Status:** Zgodnie z harmonogramem aktywny od 1.11.2025
- **Przeznaczenie:** Alternatywna metoda autoryzacji (oprócz tokenów)

---

## Źródła Informacji

### Oficjalne
- Portal KSeF: https://ksef.podatki.gov.pl
- Ministerstwo Finansów: https://www.gov.pl/web/kas/ksef

### Monitorowanie Zmian
- Komunikaty MF: https://ksef.podatki.gov.pl/web/ksef/aktualnosci
- KSeF Latarnia (status): https://github.com/CIRFMF/ksef-latarnia

---

**Ostatnia aktualizacja:** 8 lutego 2026
**Następna weryfikacja:** Zalecana co 2 tygodnie


path: references/ksef-troubleshooting.md
content: # Troubleshooting KSeF

Przewodnik rozwiązywania najczęstszych problemów z systemem KSeF.

---

## Problemy z Autentykacją

### Błąd 401: Unauthorized

**Objawy:**
```json
{
  "processingCode": 401,
  "processingDescription": "Brak autoryzacji"
}
```

**Przyczyny:**
- Sesja wygasła (token ważny tylko ~30 min)
- Nieprawidłowy token
- Token nie ma wymaganych uprawnień

**Rozwiązanie:**
```python
def handle_401_error():
    # 1. Sprawdź ważność tokena
    if session.is_expired():
        # Odśwież sesję
        session = ksef_client.init_session(token)
        retry_operation()

    # 2. Sprawdź uprawnienia tokena
    # Token musi mieć scope: invoice.read, invoice.write

    # 3. Wygeneruj nowy token w portalu KSeF
```

---

### Błąd 403: Forbidden

**Objawy:**
```json
{
  "processingCode": 403,
  "processingDescription": "Brak uprawnień"
}
```

**Przyczyny:**
- Token nie ma uprawnień do tej operacji
- NIP w tokenie nie zgadza się z NIP w fakturze

**Rozwiązanie:**
1. Sprawdź uprawnienia tokena w portalu KSeF
2. Upewnij się że token jest dla właściwego NIP
3. Sprawdź czy token ma scope dla danej operacji (read/write)

---

## Problemy z Walidacją Faktur

### Błąd 100: Nieprawidłowy format XML

**Objawy:**
```json
{
  "exceptionCode": "100",
  "exceptionDescription": "Nieprawidłowy format XML"
}
```

**Rozwiązanie:**
```python
# 1. Sprawdź encoding
assert xml_content.startswith('<?xml version="1.0" encoding="UTF-8"?>')

# 2. Waliduj XML parser
try:
    ET.fromstring(xml_content)
except ET.ParseError as e:
    print(f"Błąd parsowania: {e}")
    # Sprawdź: unclosed tags, nieprawidłowe znaki

# 3. Usuń BOM (Byte Order Mark)
xml_content = xml_content.lstrip('\ufeff')
```

---

### Błąd 101: Błąd walidacji schematu

**Objawy:**
```json
{
  "exceptionCode": "101",
  "exceptionDescription": "Błąd walidacji schematu XSD"
}
```

**Przyczyny:**
- Używasz FA(2) zamiast FA(3)
- Nieprawidłowa struktura XML
- Brakujące wymagane pola
- Nieprawidłowy namespace

**Rozwiązanie:**
```python
# Checklist FA(3):
checks = {
    'Namespace': 'http://crd.gov.pl/wzor/2023/06/29/12648/',
    'KodFormularza kodSystemowy': 'FA(3)',
    'wersjaSchemy': '1-0E',
    'WariantFormularza': '3'
}

for field, expected in checks.items():
    if expected not in xml_content:
        print(f"BŁĄD: Brak {field} = {expected}")
```

**Częste błędy:**
- `kodSystemowy="FA(2)"` → Zmień na `FA(3)`
- `wersjaSchemy="1-0"` → Zmień na `1-0E`
- Stary namespace z 2021 → Użyj namespace z 2023

---

### Błąd 102: Nieprawidłowy NIP

**Objawy:**
```json
{
  "exceptionCode": "102",
  "exceptionDescription": "Nieprawidłowy NIP"
}
```

**Rozwiązanie:**
```python
def validate_nip(nip):
    # 1. Długość
    if len(nip) != 10:
        return False

    # 2. Cyfry
    if not nip.isdigit():
        return False

    # 3. Suma kontrolna
    weights = [6, 5, 7, 2, 3, 4, 5, 6, 7]
    check_sum = sum(int(nip[i]) * weights[i] for i in range(9))
    check_digit = check_sum % 11

    if check_digit == 10:
        return False

    return check_digit == int(nip[9])

# 4. Sprawdź w białej liście VAT
response = requests.get(f"https://wl-api.mf.gov.pl/api/search/nip/{nip}")
if response.status_code != 200:
    print("NIP nie istnieje w bazie MF")
```

---

### Błąd 103: Data w przyszłości

**Objawy:**
```json
{
  "exceptionCode": "103",
  "exceptionDescription": "Data w przyszłości"
}
```

**Rozwiązanie:**
```python
from datetime import datetime, timedelta

# DataWytworzeniaFa nie może być w przyszłości
now = datetime.now()
data_wytworzenia = now.strftime('%Y-%m-%dT%H:%M:%S')

# BŁĄD: Data jutro
tomorrow = now + timedelta(days=1)
data_wytworzenia = tomorrow.strftime(...)  # ❌

# Uwaga na strefy czasowe
# KSeF używa czasu polskiego (UTC+1/UTC+2)
```

---

### Błąd 104: Duplikat numeru faktury

**Objawy:**
```json
{
  "exceptionCode": "104",
  "exceptionDescription": "Faktura o takim numerze już istnieje"
}
```

**Rozwiązanie:**
```python
def generate_unique_invoice_number():
    # Format: FV/ROK/MIESIĄC/NUMER
    year = datetime.now().year
    month = datetime.now().month

    # Pobierz ostatni numer z bazy
    last_number = db.get_last_invoice_number(year, month)

    next_number = (last_number or 0) + 1

    return f"FV/{year}/{month:02d}/{next_number:04d}"

# Sprawdź czy numer już istnieje w KSeF
existing = ksef_client.check_invoice_number(invoice_number)
if existing:
    print("Numer już użyty - wygeneruj nowy")
```

---

## Problemy z Wydajnością

### Timeout API / Brak Odpowiedzi

**Objawy:**
- Request timeout (>30s)
- 503 Service Unavailable
- Brak odpowiedzi

**Diagnoza:**
```python
def diagnose_timeout():
    # 1. Sprawdź status KSeF
    try:
        response = requests.get('https://ksef.mf.gov.pl/api/health')
        print(f"Status KSeF: {response.status_code}")
    except:
        print("KSeF niedostępny")
        return "KSEF_DOWN"

    # 2. Sprawdź własną sieć
    try:
        requests.get('https://google.com', timeout=5)
    except:
        print("Problem z internetem")
        return "NETWORK_ISSUE"

    # 3. Sprawdź obciążenie (godziny szczytu)
    hour = datetime.now().hour
    if hour in [15, 16, 17]:  # 15:00-18:00
        print("Godziny szczytu - duże obciążenie KSeF")
        return "HIGH_LOAD"

    return "UNKNOWN"
```

**Rozwiązanie:**
```python
import time

def send_with_retry(invoice_xml, max_retries=3):
    for attempt in range(max_retries):
        try:
            response = ksef_client.send_invoice(invoice_xml, timeout=60)
            return response
        except Timeout:
            if attempt < max_retries - 1:
                # Exponential backoff
                wait_time = 2 ** attempt  # 1s, 2s, 4s
                print(f"Timeout - retry {attempt+1}/{max_retries} za {wait_time}s")
                time.sleep(wait_time)
            else:
                raise

# Best practices:
# - Wysyłaj poza godzinami szczytu (21:00-6:00)
# - Użyj queue + background worker
# - Implementuj circuit breaker
```

---

### Rate Limiting (429)

**Objawy:**
```json
{
  "processingCode": 429,
  "processingDescription": "Zbyt wiele żądań"
}
```

**Rozwiązanie:**
```python
import time
from functools import wraps

def rate_limit(max_per_hour=100):
    """Decorator ograniczający liczbę requestów"""
    calls = []

    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            now = time.time()
            # Usuń stare calle (sprzed godziny)
            calls[:] = [c for c in calls if c > now - 3600]

            if len(calls) >= max_per_hour:
                wait_time = 3600 - (now - calls[0])
                print(f"Rate limit - czekaj {wait_time:.0f}s")
                time.sleep(wait_time)

            calls.append(now)
            return func(*args, **kwargs)
        return wrapper
    return decorator

@rate_limit(max_per_hour=100)
def send_invoice(invoice):
    return ksef_client.send_invoice(invoice)
```

---

## Problemy z Płatnościami

### Nie Można Dopasować Płatności

**Przyczyny:**
- Niezgodna kwota (błąd w kwocie przelewu)
- Brak numeru faktury w tytule
- Split payment (MPP) - częściowa płatność
- Płatność zbiorcza (kilka faktur naraz)

**Rozwiązanie:**
```python
def handle_unmatched_payment(payment):
    # 1. Rozszerzone wyszukiwanie (tolerancja ±2%)
    matches = search_invoices_extended(
        amount_min=payment.amount * 0.98,
        amount_max=payment.amount * 1.02,
        date_range_days=14  # ±14 dni zamiast ±7
    )

    if matches:
        return present_to_user_for_confirmation(matches)

    # 2. Sprawdź czy to split payment (część VAT)
    if is_likely_vat_payment(payment):
        net_payment = find_net_payment(payment)
        if net_payment:
            return match_mpp(net_payment, payment)

    # 3. Sprawdź płatność zbiorczą
    invoice_numbers = extract_invoice_numbers_from_title(payment.title)
    if len(invoice_numbers) > 1:
        return split_payment_to_invoices(payment, invoice_numbers)

    # 4. Flaguj do manual review
    flag_for_review(payment)
```

---

## Problemy ze Środowiskiem

### Faktury Testowe na Produkcji

**Problem:** Wysłano faktury testowe na środowisko produkcyjne

**⚠️ UWAGA:** Faktury na produkcji są prawnie wiążące!

**Co zrobić:**
1. NIE usuwaj faktur (niemożliwe w KSeF)
2. Wystaw faktury korygujące do zera
3. Skontaktuj się z kontrahentem
4. Zgłoś do księgowości

**Zapobieganie:**
```python
# Zawsze sprawdzaj środowisko
class KSefClient:
    def __init__(self, environment='demo'):
        if environment == 'production':
            # Wymuś potwierdzenie
            confirm = input("⚠️  PRODUKCJA! Kontynuować? (yes/no): ")
            if confirm != 'yes':
                raise Exception("Anulowano - używaj DEMO do testów")

        self.base_url = {
            'demo': 'https://ksef-demo.mf.gov.pl',
            'production': 'https://ksef.mf.gov.pl'
        }[environment]
```

---

## Monitoring i Alerty

### Konfiguracja Alertów

```python
def setup_monitoring():
    monitors = [
        # 1. Alert przy wysokiej liczbie błędów
        {
            'name': 'High rejection rate',
            'condition': lambda: get_rejection_rate_last_hour() > 0.2,
            'action': send_alert_email
        },

        # 2. Alert przy niedostępności KSeF
        {
            'name': 'KSeF down',
            'condition': lambda: not check_ksef_health(),
            'action': send_sms_alert
        },

        # 3. Alert przy problemach z płatnościami
        {
            'name': 'Too many unmatched payments',
            'condition': lambda: count_unmatched_payments() > 10,
            'action': notify_accountant
        }
    ]

    # Uruchom monitoring co 5 minut
    schedule.every(5).minutes.do(run_monitors, monitors)
```

---

## Pomocne Narzędzia

### KSeF Latarnia (Status Systemu)

```bash
# Sprawdź status KSeF w czasie rzeczywistym
git clone https://github.com/CIRFMF/ksef-latarnia
cd ksef-latarnia
python check_status.py
```

### Walidator XML

```python
from lxml import etree

def validate_fa3_xsd(xml_content):
    """Walidacja względem schematu XSD"""
    xsd_url = "https://ksef.podatki.gov.pl/xsd/FA3_1-0E.xsd"

    # Pobierz schemat
    xsd_doc = etree.parse(xsd_url)
    schema = etree.XMLSchema(xsd_doc)

    # Waliduj XML
    xml_doc = etree.fromstring(xml_content.encode('utf-8'))

    try:
        schema.assertValid(xml_doc)
        return True, "OK"
    except etree.DocumentInvalid as e:
        return False, str(e)
```

---

**Potrzebujesz pomocy?**
- Dokumentacja KSeF: https://ksef.podatki.gov.pl
- Forum: https://github.com/CIRFMF/ksef-discussions
- Helpdesk MF: (sprawdź portal KSeF)


path: skill.json
content: {
  "name": "ksef-accountant-pl",
  "version": "1.0.0",
  "description": "Asystent ksiegowy Krajowego Systemu e-Faktur (KSeF) — wiedza domenowa, wzorce architektoniczne i przyklady kodu. Nie zawiera kodu wykonywalnego.",
  "license": "MIT",
  "homepage": "https://github.com/alexwoo-awso/skills",
  "source": "https://github.com/alexwoo-awso/skills/tree/main/ksef-accountant-pl",
  "type": "instruction-only",
  "has_executable_code": false,
  "has_install_script": false,
  "has_binaries": false,
  "has_runtime_dependencies": false,
  "security": {
    "disable-model-invocation": true,
    "disableModelInvocation": true,
    "allow-model-invocation": false,
    "allowModelInvocation": false,
    "requires-user-action": true,
    "instruction-only": true,
    "credential-handling": "user-managed-only",
    "credential-storage": "none",
    "credential-transmission": "none"
  },
  "env": {
    "KSEF_TOKEN": {
      "description": "Token API KSeF do uwierzytelniania sesji. Dostarczany przez uzytkownika — skill nie generuje, nie przechowuje ani nie przesyla tokenow.",
      "required": false,
      "secret": true,
      "scope": "session-auth"
    },
    "KSEF_ENCRYPTION_KEY": {
      "description": "Klucz szyfrowania Fernet do bezpiecznego przechowywania tokenow. Uzycie opcjonalne — przyklad wzorca bezpieczenstwa.",
      "required": false,
      "secret": true,
      "scope": "encryption"
    },
    "KSEF_BASE_URL": {
      "description": "Bazowy URL API KSeF. Domyslnie https://ksef-demo.mf.gov.pl (DEMO). Produkcja wymaga jawnej zgody uzytkownika.",
      "required": false,
      "secret": false,
      "default": "https://ksef-demo.mf.gov.pl",
      "scope": "api-endpoint"
    }
  },
  "constraints": {
    "no-autonomous-execution": true,
    "requires-explicit-user-consent": true,
    "demo-first": true,
    "production-requires-user-approval": true,
    "never-store-credentials": true,
    "never-transmit-credentials": true,
    "never-generate-credentials": true
  }
}

Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (HIGH)