Typowe błędy walidacji Peppol BIS 3.0 i jak je naprawić
Błędy walidacji Peppol BIS 3.0 wpadają w przewidywalny zestaw kategorii. Komunikaty o błędach odwołują się do kodów reguł biznesowych (BR-xx) i numerów terminów biznesowych (BT-xx) z normy EN16931, co wymaga lektury specyfikacji do interpretacji. Ten artykuł mapuje najczęstsze błędy na ich przyczyny i podaje konkretne rozwiązania.
Wszystkie przykłady używają składni UBL 2.1. Dla odpowiedników CII zob. UBL vs CII.
BR-01 do BR-06: brakujące obowiązkowe pola nagłówka
Te reguły wymuszają obecność obligatoryjnych pól najwyższego poziomu. Zawodzą, gdy element jest nieobecny lub pusty.
| Reguła | Pole | BT | Rozwiązanie |
|---|---|---|---|
| BR-01 | Identyfikator specyfikacji | BT-24 | Dodaj CustomizationID z dokładnym URI Peppol BIS 3.0 |
| BR-02 | Numer faktury | BT-1 | Dodaj niepusty element ID |
| BR-03 | Data wystawienia faktury | BT-2 | Dodaj IssueDate w formacie YYYY-MM-DD |
| BR-04 | Kod waluty faktury | BT-5 | Dodaj DocumentCurrencyCode z kodem ISO 4217 |
| BR-05 | Nazwa sprzedawcy | BT-27 | Dodaj AccountingSupplierParty/Party/PartyName/Name |
| BR-06 | Nazwa nabywcy | BT-44 | Dodaj AccountingCustomerParty/Party/PartyName/Name |
Specyfika BR-01: najczęstszą przyczyną jest użycie bazowego URI EN16931 zamiast URI Peppol BIS 3.0. Wyglądają podobnie, ale są różne:
Błędnie (baza EN16931):
<cbc:CustomizationID>urn:cen.eu:en16931:2017</cbc:CustomizationID>
Poprawnie (Peppol BIS 3.0):
<cbc:CustomizationID>
urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0::2.1
</cbc:CustomizationID>
Walidator sprawdza dokładny ciąg znaków. Kontekst tego, dlaczego ma to znaczenie, znajdziesz we wprowadzeniu do Peppol BIS 3.0.
BR-CO-10: suma kwot pozycji nie zgadza się z sumą
[BR-CO-10]-Sum of Invoice line net amount (BT-106) =
sum of Invoice line net amount (BT-131).
Ta reguła wymaga, żeby LegalMonetaryTotal/LineExtensionAmount (BT-106) było równe sumie wszystkich wartości InvoiceLine/LineExtensionAmount (BT-131).
Błąd to niemal zawsze błąd zaokrąglania. Jeśli zaokrąglasz każdą kwotę pozycji niezależnie przed zsumowaniem, suma zaokrąglonych wartości może różnić się od zaokrąglonej sumy surowych wartości.
Błędnie (zaokrąglanie na poziomie pozycji, następnie sumowanie):
// Line 1: 3 × 33.333... = 100.00 (rounded)
// Line 2: 3 × 33.333... = 100.00 (rounded)
// Sum of rounded: 200.00
// But raw sum: 3 × 33.333... + 3 × 33.333... = 200.00 exactly in this case
Błąd jest bardziej widoczny przy stawkach jak 7% VAT na różnych ilościach, gdzie zaokrąglanie kumuluje się na wielu pozycjach.
Poprawne podejście: zsumuj surowe, niezaokrąglone wartości dla wszystkich pozycji, a następnie zaokrąglij agregat raz:
var lineNetTotal = invoiceLines.Sum(l => l.Quantity * l.UnitPrice); // raw
var lineNetTotalRounded = Math.Round(lineNetTotal, 2, MidpointRounding.AwayFromZero);
BR-CO-15: błąd arytmetyczny kwoty VAT faktury
[BR-CO-15]-Invoice total VAT amount (BT-110) =
sum of VAT category tax amount (BT-117).
Całkowita kwota VAT w TaxTotal/TaxAmount musi być równa sumie wartości TaxTotal/TaxSubtotal/TaxAmount dla wszystkich kategorii podatkowych.
Dla faktury z jedną stawką wydaje się to trywialne, ale błędy występują gdy:
- Istnieje wiele stawek VAT i zaokrąglanie jest stosowane do każdej kategorii zamiast do agregatu
- Kategoria zerowej stawki lub zwolnienia jest obecna i jej
TaxAmountwynosi0.00zamiast być nieobecna TaxAmountna poziomieTaxTotaljest obliczana niezależnie od kwotTaxSubtotal
Rozwiązanie: najpierw oblicz wszystkie wartości TaxSubtotal/TaxAmount, zsumuj je i użyj tej sumy jako wartości TaxTotal/TaxAmount. Nie obliczaj TaxTotal/TaxAmount osobno.
BR-CO-16: kwota należna do zapłaty
[BR-CO-16]-Amount due for payment (BT-115) =
Invoice total with VAT (BT-112) - Paid amount (BT-113) + Rounding amount (BT-114).
Jeśli BT-113 (kwota zapłacona) i BT-114 (kwota zaokrąglenia) nie są obecne, upraszcza się to do BT-115 = BT-112. Błąd pojawia się, gdy PayableAmount i TaxInclusiveAmount różnią się o więcej niż dopuszczalna tolerancja zaokrąglania.
Częsta przyczyna: obliczanie PayableAmount z zaokrąglonych kwot pozycji i TaxInclusiveAmount z osobnego obliczenia sumy, które daje nieco inny wynik.
Rozwiązanie: oblicz jedną kanoniczną sumę końcową i użyj jej zarówno dla TaxInclusiveAmount, jak i PayableAmount.
BR-S-08 i BR-S-09: spójność stawki i kwoty VAT
[BR-S-08]-For each different value of VAT category rate (BT-119) where the
VAT category code (BT-118) is "S", the VAT category taxable amount (BT-116)
in a VAT breakdown (BG-23) shall equal the sum of Invoice line net amounts
(BT-131) where the VAT category code of the Invoice line (BT-151) is "S"
and the VAT rate for the Invoice line (BT-152) equals the VAT category rate.
Ta reguła grupuje wszystkie pozycje według stawki VAT i weryfikuje, że kwota opodatkowania w każdym TaxSubtotal odpowiada sumie pozycji z tą stawką. Zawodzi gdy:
- Pozycja ma stawkę VAT, dla której nie ma odpowiedniego
TaxSubtotal TaxSubtotalistnieje dla stawki, ale żadna pozycja nie używa tej stawki- Różnice w zaokrąglaniu kumulują się między obliczeniami na poziomie pozycji i poziomu podsumy
Rozwiązanie: buduj elementy TaxSubtotal dynamicznie z pozycji, grupując według (kod kategorii VAT, stawka VAT), zamiast konstruować je niezależnie.
BR-E-01 / BR-AE-01: faktury z odwrotnym obciążeniem i zwolnione z podatku
[BR-E-01]-An Invoice that contains an Invoice line (BG-25), a Document level
allowance (BG-20) or a Document level charge (BG-21) where the VAT category
code (BT-151) is "E" shall contain exactly one VAT breakdown...
Faktury ze zwolnieniem (E), odwrotnym obciążeniem (AE) lub zerową stawką (Z) VAT wymagają specyficznych struktur TaxCategory, różnych od faktur ze standardową (S) stawką.
Typowe błędy:
- Używanie wartości
IDrównejSdla wszystkich pozycji niezależnie od faktycznego traktowania VAT - Pomijanie elementów
TaxExemptionReasonCodelubTaxExemptionReasonwymaganych dla kategorii zwolnionych - Brakujący
AccountingSupplierParty/Party/PartyTaxSchemegdy faktura stosuje odwrotne obciążenie
W przypadku odwrotnego obciążenia (AE) identyfikator VAT schematu podatkowego nabywcy musi być obecny, a identyfikator VAT sprzedawcy musi być również obecny.
Reguły rozszerzeń Peppol dla Niemiec
Niemieckie profile Peppol dodają reguły ponad bazę EN16931. Częste błędy:
BR-DE-TMP-32: data dostawy (BT-72) jest wymagana dla niemieckich faktur B2G. Dodaj Delivery/ActualDeliveryDate w formacie YYYY-MM-DD.
BR-DE-18: musi być obecny identyfikator VAT sprzedawcy (BT-31) lub numer rejestracji podatkowej (BT-32). Brak obu powoduje odrzucenie. Jeśli sprzedawca jest zwolniony z VAT, podaj BT-32 z numerem rejestracji podatkowej.
BR-DE-16: numer referencyjny nabywcy (BT-10, Leitweg-ID) jest obowiązkowy dla niemieckich faktur B2G. Format Leitweg-ID jest walidowany: musi pasować do wzorca \d{2,12}-\d{4,12}-\d{2}.
Efektywne debugowanie
Dane wyjściowe Schematron zawierają lokalizację XPath:
<svrl:failed-assert location="/Invoice[1]/cac:LegalMonetaryTotal[1]">
<svrl:text>[BR-CO-10]-Sum of Invoice line net amounts...</svrl:text>
</svrl:failed-assert>
Użyj lokalizacji XPath, aby przejść bezpośrednio do błędnego elementu. Dla reguł arytmetycznych dodaj dane wyjściowe debugowania rejestrujące surowe wartości przed zaokrąglaniem, żebyś mógł śledzić, gdzie powstaje rozbieżność.
Wstępnie skompilowane pliki XSLT z wydań GitHub Peppol BIS to autorytatywne artefakty walidacyjne. Uruchamiaj je z Saxon HE, jak opisano w artykule generowanie faktur Peppol BIS 3.0 w C#. Ważne jest uruchamianie ich z najnowszym wydaniem: zestawy reguł są aktualizowane przy każdym wydaniu Peppol BIS, a reguła, która przechodzi starszy XSLT, może nie przejść bieżącego.
SealDoc a błędy walidacji
SealDoc uruchamia walidację Schematron EN16931 i Peppol BIS 3.0 dla każdej faktury przed dostarczeniem. Gdy walidacja nie powiedzie się, API zwraca ustrukturyzowaną odpowiedź błędu mapującą każde naruszenie na kod BR, naruszony BT i lokalizację XPath w przesłanym dokumencie.
Dla organizacji debugujących istniejący system generowania faktur publiczny walidator SealDoc akceptuje pliki faktur UBL i CII, uruchamia bieżący XSLT Peppol BIS 3.0 i zwraca pełną listę błędów z opisami w prostym języku. Zestawy reguł są aktualizowane na bieżąco z wydaniami Peppol BIS, więc walidator zawsze odzwierciedla reguły, które zastosuje odbierający Access Point.