0

Faktury korygujące w KSeF - kilka pułapek z integracji

VATreturns_PL3 godz. temu0 wyświetleń

Dzielę się doświadczeniami z implementacji faktur korygujących w KSeF, bo widzę że temat często powraca.

**Podstawy:**

Faktura korygująca to osobny dokument w KSeF z `KodSysteomwy` = `FK`. W XML trzeba wypełnić sekcję `FakturaKorygujaca` z referencją do oryginalnej faktury przez `P_13_6_3` (numer KSeF oryginału).

**Co mnie zaskoczyło:**

1. **Walidacja referencji** - KSeF sprawdza czy faktura oryginalna rzeczywiście istnieje. Jeśli próbujesz skorygować nieistniejący dokument, dostaaniesz błąd na etapie wysyłania.

2. **Pola obowiązkowe** - w korekcie musisz podać wszystkie pozycje, nie tylko te zmieniane. Różnica jest w `P_12_*` gdzie wpisujesz wartości po korekcie.

3. **Problem z datami** - `P_1` (data wystawienia korekty) nie może być wcześniejsza niż data oryginału. Wydaje się oczywiste, ale w praktyce zdarza się gdy klient chce "cofnąć" datę.

**Przykład struktury XML:**

```xml

<FakturaKorygujaca>

<P_13_6_1>2</P_13_6_1> <!-- przyzyna korekty -->

<P_13_6_2>Korekta ilości</P_13_6_2>

<P_13_6_3>1234567890123456789012345678-20240101-1A2B3C4D5E</P_13_6_3>

<!-- reszta danych -->

</FakturaKorygujaca>

```

**Tip praktyczny:**

W TypeScript robię sobie helper do budowania referencji KSeF - łatwiej się nie pomylić w tym długim numerze.

Czy ktoś miał problemy z korektami obcych faktur (wystawionych przed wejściem do KSeF)? U mnie demo środowisko czasem dziwnie się zachowuje przy takich przypadkach.

5 odpowiedzi

0
JakubPiotrowski2 godz. temu
Dzięki za zebranie tego w jednym miejcsu! Akurat wczoraj męczyłem się z podobnym problemem. Co do obcych faktur - u mnie w deom też były dziwne zachowania. Konkretnie gdy próbowałem skorygować fakturę wystawioną "na papierze" przed migracją do KSeF, system rzucał błędem że nie może znaleźć oryginału (co logiczne), ale komunikat błędu był bardzo niejasny. Rozwiązanie które znalazłem: w `P_13_6_3` zamiast numeru KSeF podajesz numer faktury oryginalnej w formacie jaki był na papierowej fakturze. Ale to tylko w przypadku gdy oryginał nie był w KSeF. ```python # Mój helper do sprawdzania czy faktura była w KSeF def is_ksef_invoice(invoice_number): return len(invoice_number) > 30 and '-' in invoice_number ``` Jeszcze jedno - zauważyłeś może problem z korektami VAT marży? W `P_13_7` trzeba bardzo uważać na procedury szczególne, bo walidator czasem nie łapie błędów które potem MF odrzuca na produkcji. Poza tym świetne zestawienie, bookmarkuje sobie 👍
0
KonradWitkowski1 godz. temu
@JakubPiotrowski - dokładnie, komunikaty błędów dla obcych faktur są beznadziejne. Twoje rozwiązanie z podmianą na oryginalny numer faktury też stosuję, ale mam z tym jeden problem - czasem klienci mają dziwne numeracje (np. z ukośnikaami czy spacjami) i trzeba to sanityzować. ```typescript function sanitizeLegacyInvoiceNumber(number: string): string { return number.replace(/[\/\s]/g, '_').subtsring(0, 50); } ``` Co do VAT marży - tak, to istny horror. Szczególnie jak klient ma faktury ze starym kodem GTU/procedury i trzeba to mapować na nowe. W `P_13_7` najczęściej zapominam o `PMarza_1` gdy jest marża turystyczna. Demo tego nie wyłapuje ale produkcja od razu odrzuca. **Pytanie do wszystkich**: ktoś ma sprawdzone rozwiązanie na korekty ilościowe vs kwotowe? Bo w praktyce klient często nie wie co chce skorygować i system musi sam to wydedukować z różnic. Robię to przez porównanie `P_12_2` (ilość) i `P_12_3` (wartość netto), ale nie jestem pewien czy to zawsze zadziała. Jeszcze jedna rzecz - zauważyłem że korekty z ujemną wartością netto czasem dziwnie się walidują. Czy u kogoś podobnie?
0
eInvoice_dev1 godz. temu
@KonradWitkowski - twój helper do sanityzacji numerów to dobry pomysł, ale uwaga na jedną rzecz którą odkryliśmy przy większych wdrożeniach. Niektórzy klienci mają w starych numeracjach znaki specjalne które są legalne w polskim systemie ale KSeF ich nie akceptuje. My rozszerzyliśmy sanityzację o dodatkowe edge case'y: ```typescript function sanitizeInvoiceNumber(number: string): string { return number .replace(/[\/\s\(\)]/g, '_') .replace(/[ąćęłńóśźż]/gi, (match) => { const map = {'ą':'a', 'ć':'c', 'ę':'e', 'ł':'l', 'ń':'n', 'ó':'o', 'ś':'s', 'ź':'', 'ż':'z'}; return map[match.toLowerCase()] || match; }) .substring(0, 50); } ``` Co do **korekt ilościowych vs kwotowch** - mamy podobny problem. Rozwiązaliśmy to przez dodanie metadanych do naszego systemu które trackują intent użytkownika. Gdy klient wprowadza korektę, system pyta wprost "co chcesz zmienić - ilość czy cenę?" i na tej podstawie wypełnia odpoiednie pola w XML. Nie jest to eleganckie ale działa lepiej niż próby automatycznego wydedukowania. **Ujemne wartości netto w korektach** - tak, widziałem to samo. Problem pojawia się szczególnie gdy korekta powoduje że całkowita wartość faktury staje się ujemna (np. zwrot większy niż oryginalna wartość). System waliduje to dziwnie i czasem przechodzi w demo ale pada na produkcji. Rozwiązanie które u nas działa: dla takich przypadków dzielimy koretę na dwie - jedna anluuje oryginalną pozycję, druga dodaje nową z prawidłową wartością. Jeszcze jedna obserwacja - zauważyłeś może że korekty faktur z procedurami szczególnymi (GTU, MPP) mają dodatkowe wymagania walidacyjne które nie są jasno opisane w dokumentacji? Szczególnie problemattyczne są korekty faktur z `MPP_1` gdzie trzeba bardzo uważać na mapowanie przyczyn koreky.
0
TeresaBorkowska14 min temu
Super zestawienie! Ja akurat w tym tygodniu walczyłam z korektami u klienta i trafiłaś w sedno z tymi pułapkami. Do tego co napisał @JakubPiotrowski o obcych fakturach - u mnie podobnie, ale odkryłam jeszcze jeden case. Gdy klient ma faktury wystawione w starym systemie z numeracją typu "FV/2023/001", to w `P_13_6_3` czasem trzeba też uważać na długość. System akceptuje max 50 znaków, a niektórzy mają bardzo rozbudowane schematy numeracji. **Co do korekt ilościowych vs kwotowych** - @KonradWitkowski, my rozwiązaliśmy to przez dodanie w interfejsie użytkownika prostego wyboru "co korygujesz?". Nie jest to może najelegntsze, ale klienic wolą jasno powiedzieć niż potem się dziwić że system źle zinterpretował ich intent. ```typescript // Mój helper do sprawdzania typu korekty function detectCorrectionType(original: InvoiceItem, corrected: InvoiceItem) { if (original.quantity !== corrected.quantity) return 'quantity'; if (original.unitPrice !== corrected.unitPrice) return 'price'; return 'other'; // np. stawka VAT } ``` **Jedna rzecz która mine ostatnio zaskoczyła** - korekty faktur z GTU_13 (paliwa) mają dodatkowe wymagania walidacyjne które nie są jasno opisane w dokumentacji. System wymaga podania dodatkowych danych w sekcji `P_13_10` nawet gdy oryginalna faktura ich nie miał. Czy ktoś się z tym spotkał? Co do ujemnych wartości - tk, widziałam podobne dziwne zachownia. Szczególnie gdy korekta powoduje że wartość VAT staje się ujemna. Demo przepuszcza, produkcja czasem odrzuca z niejasnym komunikatem.
0
Świetne podsumowanie! Ja akurat niedawno kończyłam implementację korekt w systemie Comarch ERP i moęg potwierdzić większość problemów które opisaliście. Co do **korekt obcych faktur** - @JakubPiotrowski, twoje rozwiązanie z podmianą na oryginalny numer to standard, ale uwaga na jdeną rzecz. W SAP-ie mieliśmy przypadek gdzie klient miał faktury z numeracją zawierającą polskie znaki (np. "FV/Kraków/2023/001") i KSeF to odrzucał mimo że w `P_13_6_3` powinno przejść. Musieliśmy doać transliterację przed wysłaniem. **Problem z ujemnymi wartościami** który wspomina @eInvoice_dev to rzeczywiście częsty case. W moim doświadczeniu najlepiej sprawdza się podejście które stosujesz - dzielenie na dwie korekty. Ale jest jeszcze jedna pułapka: gdy korekta dotyczy faktury z procedurą MPP (szczególnie MPP_2), to system bardzo restrykcyjnie waliduje czy suma wszystkich korekt nie przekracza pewnych limitów. Dokumentacja tego nie opisuje jasno, ale w praktyce trzeba uważać. Co do **GTU1_3 i paliw** - @TeresaBorkowska, tak, spotkałam się z tym. Problem w tym że sekcja `P_13_10` ma inne wymagania w korektach niż w oryginalnych fakturach. Szczególnie pole `P_13_10_1` (kod CN) czasem musi być wypełnione naet gdy w oryginale go nie było. To chyba bug w walidatorze, ale trzeba z tym żyć. **Praktyczny tip**: w integracji z Comarch robię sobie cache referencji KSeF żeby nie odpytywać systemu za każdym razem czy oryginalna faktura istnieje. To znacznie przyspiesza proces gdy klient masowo koryguje faktury. Jedna rzecz której jeszcze nie widziałam w dyskusji - ktoś miał problemy z korektami faktur wystawionych przez podmioty trzecie? Typ `P_13_6_4` czasem dziwnie się waliduje gdy próbujesz skorygować fakturę otrzymaną od dostawcy.

Twoja odpowiedź

Zaloguj się, aby odpowiedzieć w tej dyskusji.