Walidacja JPK_KR_PD
Błąd sum kontrolnych Ctrl C_1–C_5 w JPK_KR_PD
Objaw / komunikat błędu
Bramka albo lokalny walidator: niezgodność sekcji <Ctrl> (C_1, C_2, C_3, C_4, C_5) z liczbą węzłów albo sumą kwot.
Sekcja Ctrl w JPK_KR_PD jest kontraktem między nagłówkiem a treścią. C_1 i C_3 liczą węzły, C_2, C_4 i C_5 sumują kwoty. ERP, który dodaje złotówki na float, potrafi oddać sumę różniącą się o grosz od tego, co jest w węzłach.
Przyczyna techniczna
- C_1 to liczba węzłów Dziennik, C_2 suma kwot D_11, C_3 liczba KontoZapis, C_4 suma Z_4 (Wn), C_5 suma Z_7 (Ma). Walidator MF porównuje te liczby z faktyczną treścią, a nie z opisem w dokumentacji wdrożenia.
- Kwoty w JPK są dziesiętne, ale wewnętrznie muszą schodzić do groszy. Liczenie na number/float (IEEE-754) gubi końcówki przy długich sumach: 0,1 + 0,2 nie jest 0,3. Po zaokrągleniu „na końcu” C_4 różni się od sumy Z_4 o 0,01.
- KontoZapis nie jest rodzeństwem Dziennika na tym samym poziomie. Leży wewnątrz Dziennik. Parser, który liczy wszystkie elementy o nazwie lokalnej bez zejścia w głąb, albo zlicza sam kontener, psuje C_1 albo C_3.
- Prefiks przestrzeni nazw (np. tns:Dziennik) nie zmienia semantyki, ale psuje selektor, który szuka dosłownego tagu Dziennik. Stąd raport „brak węzłów” przy pliku, który w edytorze wygląda kompletnie.
Jak naprawić błąd krok po kroku
- 1
Policz węzły, nie linie pliku
C_1 to liczba elementów Dziennik, C_3 to liczba KontoZapis wewnątrz nich. Puste linie, komentarze i węzeł Ctrl nie wchodzą do licznika.
- 2
Sumuj w groszach, nie na float
Zamień każdą kwotę na liczbę całkowitą groszy (BigInt) zanim dodasz. C_2 jest sumą D_11, C_4 sumą Z_4, C_5 sumą Z_7. Na końcu wypisz kwotę z dwoma miejscami.
- 3
Zejdź do KontoZapis wewnątrz Dziennik
Nie szukaj KontoZapis jako bezpośredniego dziecka JPK. Każdy dekret jest zagnieżdżony. Brak zejścia zaniża C_3, C_4 i C_5 przy poprawnym C_1.
- 4
Wpisz nowe Ctrl i dopiero podpisz InitUpload
Poprawka sum po złożeniu podpisu XAdES unieważnia podpis. Najpierw lokalny raport, potem ewentualna korekta pliku, na końcu szyfrowanie i podpis InitUpload.
Jak rozwiązuje to architektura SecureJPK
Walidator JPK_KR_PD w workerze czyta plik strumieniem TextDecoderStream i zlicza Dziennik oraz zagnieżdżone KontoZapis bez DOMParsera. Kwoty idą na BigInt w groszach, więc C_2, C_4 i C_5 nie dziedziczą błędu float. Raport pokazuje C_1–C_5 z pliku obok wartości policzonych. Ostrzeżenia logiczne nie zmieniają samego Ctrl i nie blokują wysyłki, ale twarde rozjazdy sum widać zanim plik pójdzie na bramkę. Jawny XML zostaje w OPFS na urządzeniu.
Najczęstsze pytania (FAQ)
- Które pole Ctrl odpowiada sumie Wn?
- C_4 jest sumą Z_4, czyli strony Wn w KontoZapis. C_5 jest sumą Z_7 (Ma). C_2 jest sumą kwot operacji D_11 w Dziennik, a nie sumą obu stron naraz.
- Czy różnica 0,01 zł może przejść na bramce?
- Nie należy na to liczyć. Kontrola zgodności Ctrl z treścią jest arytmetyczna. Grosz różnicy między C_4 a sumą Z_4 jest błędem pliku, nie zaokrągleniem „do zwyczaju księgowego”.
- Czy prefiks tns: psuje licznik?
- Sam prefiks jest legalny. Psuje go narzędzie, które porównuje pełną nazwę kwalifikowaną zamiast nazwy lokalnej. Walidator strumieniowy powinien zdejmować prefiks przed rozpoznaniem Dziennik i KontoZapis.