Peppol-BIS-Regeln — was zusätzlich gilt, wenn über Peppol zugestellt wird
Peppol ist ein Zustellnetz, keine zweite Norm. Diese Regeln prüfen genau das, was ein Netz braucht und eine Datei allein nicht: wohin sie geht, in welchem Prozess sie steht, und dass sie unterwegs nicht auseinanderfällt.
23 Regeln · 23 erklärt · Regelwerk v2026-08-31
Adressierung ist der Unterschied
Die Regeln, an denen es am häufigsten scheitert, verlangen eine elektronische Adresse für Käufer und Verkäufer (BT-49 und BT-34) samt Schema-Kennung. Eine Rechnung, die per E-Mail oder über ein Portal einwandfrei ankommt, hat diese Felder oft gar nicht — sie brauchte sie nie.
In Deutschland ist die Leitweg-ID der verwandte Fall auf der Verwaltungsseite: dieselbe Idee, eine Adressierung im Dokument, aber ein anderes Feld und ein anderes Schema. Wer beides verwechselt, füllt das falsche.
Strenger als die Norm, mit Absicht
Mehrere Peppol-Regeln verbieten, was EN 16931 zulässt — leere Elemente etwa. Der Grund ist betrieblich: ein Netz mit hunderten Zugangspunkten kann sich Uneindeutigkeit nicht leisten, weil jeder Empfänger sie anders auflöst.
Praktisch heißt das: eine Datei kann gegen EN 16931 sauber sein und über Peppol trotzdem abgewiesen werden. Prüfen Sie gegen das Profil, über das Sie tatsächlich zustellen, nicht gegen das allgemeinste.
Bei PEPPOL-EN16931-R008 lohnt der Blick ins kompilierte Regelwerk. Geprüft wird jedes Element ohne Inhalt, und genau eines darf leer bleiben — in UBL cbc:ID unter cac:OrderReference, in CII ram:ApplicableHeaderTradeDelivery, das vom Test ausgenommen ist. Jedes andere leere Tag wird gemeldet, auch eines, das die Norm selbst durchgehen ließe.
Zwei Regeln rechnen umgekehrt mit Spielraum. PEPPOL-EN16931-R040 und PEPPOL-EN16931-R120 vergleichen über die Funktion u:slack, und das ausgelieferte Stylesheet setzt sie auf 0,02 — zwei Cent nach oben wie nach unten, bei Rechnungen in ungarischen Forint 0,5. Die Summenregeln der Norm rechnen dagegen auf den Cent genau. An dieser Stelle ist Peppol also nicht strenger, sondern nachsichtiger.
Alle Peppol-Regeln
Mit dem offiziellen Regeltext. Regeln mit ausgeschriebener Erklärung tragen Ursache und Behebung direkt darunter.
PEPPOL-EN16931-R001
Business process MUST be provided.
- Was die Regel verlangt
- Die Rechnung muss den Geschäftsprozess (BT-23) nennen — die Kennung des Prozesses, in dem sie verschickt wird. Sie sagt dem Empfänger, nach welchem Regelwerk er die Rechnung erwartet.
- Warum sie ausgelöst wird
- Der Wert ist eine Konstante und wird deshalb gern als selbstverständlich behandelt: die Spezifikations-Kennung (BT-24) wird gesetzt, die Prozess-Kennung daneben vergessen, weil beide gleich aussehen und keine aus den Rechnungsdaten stammt.
- Wie Sie es beheben
- Setzen Sie BT-23 fest auf urn:fdc:peppol.eu:2017:poacc:billing:01:1.0 — cbc:ProfileID in UBL, ram:BusinessProcessSpecifiedDocumentContextParameter/ram:ID in CII. Der Wert hängt nicht von der Rechnung ab.
- Was der Validator prüft
UBLcbc:ProfileIDCIIram:BusinessProcessSpecifiedDocumentContextParameter/ram:ID
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0</cbc:CustomizationID> <cbc:ID>RE-2026-0042</cbc:ID>Korrigiert <cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0</cbc:CustomizationID> <cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID> <cbc:ID>RE-2026-0042</cbc:ID>PEPPOL-EN16931-R005
VAT accounting currency code MUST be different from invoice currency code when provided.
- Was die Regel verlangt
- Wird eine abweichende Währung für die Umsatzsteuer (BT-6) angegeben, muss sie sich von der Rechnungswährung (BT-5) unterscheiden. Das Feld existiert nur für den Fall, dass die Steuer in einer anderen Währung zu melden ist.
- Warum sie ausgelöst wird
- Das Mapping füllt BT-6 vorsorglich mit derselben Währung wie BT-5, weil ein leeres Feld nach einer Lücke aussieht. Damit behauptet die Rechnung eine Währungsumrechnung, die es nicht gibt.
- Wie Sie es beheben
- Lassen Sie BT-6 weg, wenn Steuer und Rechnung dieselbe Währung verwenden: cbc:TaxCurrencyCode in UBL, ram:TaxCurrencyCode in CII. Nur bei tatsächlich abweichender Meldewährung wird es gesetzt.
- Was der Validator prüft
UBLnot(normalize-space(text()) = normalize-space(../cbc:DocumentCurrencyCode/text()))CIInot(ram:TaxCurrencyCode) or normalize-space(ram:TaxCurrencyCode/text()) != normalize-space(ram:InvoiceCurrencyCode/text())
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode> <cbc:TaxCurrencyCode>EUR</cbc:TaxCurrencyCode>Korrigiert <cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>PEPPOL-EN16931-R008
Document MUST not contain empty elements.
- Was die Regel verlangt
- Das Dokument darf keine leeren Elemente enthalten. Ein Tag ohne Inhalt ist keine Angabe, sondern eine Behauptung, dass etwas übermittelt wurde.
- Warum sie ausgelöst wird
- Mappings schreiben Felder unbedingt und setzen den Wert danach. Ist die Quelle null, bleibt ein leeres Tag stehen — besonders häufig bei Notizfeldern, Referenzen und optionalen Kennungen, die nur manchmal belegt sind.
- Wie Sie es beheben
- Schreiben Sie ein Element erst, wenn ein Wert vorliegt. In den meisten Serialisierern ist das eine Bedingung um den Schreibaufruf herum, keine nachgelagerte Bereinigung — leere Tags nachträglich zu entfernen erwischt selten alle.
- Was der Validator prüft
UBLself::cbc:ID[parent::cac:OrderReference]
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cbc:ID>RE-2026-0042</cbc:ID> <cbc:IssueDate>2026-08-26</cbc:IssueDate> <cbc:Note/>Korrigiert <cbc:ID>RE-2026-0042</cbc:ID> <cbc:IssueDate>2026-08-26</cbc:IssueDate>PEPPOL-EN16931-R010
Käuferadresse (BT-49) fehlt
Buyer electronic address MUST be provided
- Was die Regel verlangt
- Die elektronische Adresse des Käufers (BT-49) muss übermittelt werden — die Kennung, an die die Rechnung zugestellt wird. Das zugehörige Schema verlangt nicht diese Regel, sondern BR-63.
- Warum sie ausgelöst wird
- Die Adresse gehört zum Übertragungsweg und nicht zur Rechnung, also steht sie im Versandsystem und nicht im Rechnungsdatensatz. Beim Erzeugen des Dokuments fehlt sie dann, obwohl der Versand sie kennt. Geprüft wird allein, dass das Element da ist: ein leeres cbc:EndpointID erfüllt diese Regel und fällt stattdessen PEPPOL-EN16931-R008 auf, die leere Elemente im ganzen Dokument verbietet.
- Wie Sie es beheben
- Setzen Sie BT-49 mit passendem Schema-Attribut: cbc:EndpointID mit schemeID unter cac:AccountingCustomerParty/cac:Party in UBL, ram:BuyerTradeParty/ram:URIUniversalCommunication/ram:URIID in CII. EM steht für eine E-Mail-Adresse, 0204 für die Leitweg-ID — der früher übliche Code 9958 steht nicht mehr in der Liste, die BR-CL-25 prüft.
- Was der Validator prüft
UBLcbc:EndpointIDCIIram:URIUniversalCommunication/ram:URIID
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:AccountingCustomerParty> <cac:Party> <cac:PartyName> <cbc:Name>Behörde Bonn</cbc:Name> </cac:PartyName> </cac:Party> </cac:AccountingCustomerParty>Korrigiert <cac:AccountingCustomerParty> <cac:Party> <cbc:EndpointID schemeID="EM">rechnung@behoerde-bonn.de</cbc:EndpointID> <cac:PartyName> <cbc:Name>Behörde Bonn</cbc:Name> </cac:PartyName> </cac:Party> </cac:AccountingCustomerParty>PEPPOL-EN16931-R020
Seller electronic address MUST be provided
- Was die Regel verlangt
- Die elektronische Adresse des Verkäufers (BT-34) muss übermittelt werden — das Gegenstück zu BT-49, an das der Empfänger antworten oder eine Rückmeldung schicken kann.
- Warum sie ausgelöst wird
- Dieselbe Ursache wie beim Käufer, nur wird sie hier zusätzlich für verzichtbar gehalten: „der Empfänger weiß doch, von wem die Rechnung kommt“. Für die automatische Verarbeitung ist der Absender aber genauso eine Kennung wie der Empfänger.
- Wie Sie es beheben
- Setzen Sie BT-34 mit Schema-Attribut unter cac:AccountingSupplierParty/cac:Party: cbc:EndpointID mit schemeID in UBL, ram:SellerTradeParty/ram:URIUniversalCommunication/ram:URIID in CII. Der Wert ist für Ihr Unternehmen konstant.
- Was der Validator prüft
UBLcbc:EndpointIDCIIram:URIUniversalCommunication/ram:URIID
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:AccountingSupplierParty> <cac:Party> <cac:PartyName> <cbc:Name>Muster GmbH</cbc:Name> </cac:PartyName> </cac:Party> </cac:AccountingSupplierParty>Korrigiert <cac:AccountingSupplierParty> <cac:Party> <cbc:EndpointID schemeID="EM">rechnung@muster.de</cbc:EndpointID> <cac:PartyName> <cbc:Name>Muster GmbH</cbc:Name> </cac:PartyName> </cac:Party> </cac:AccountingSupplierParty>PEPPOL-EN16931-R040
Allowance/charge amount must equal base amount * percentage/100 if base amount and percentage exists
- Was die Regel verlangt
- Sind sowohl der Grundbetrag als auch der Prozentsatz eines Ab- oder Zuschlags angegeben, muss der Betrag genau daraus folgen: Grundbetrag × Prozentsatz ÷ 100.
- Warum sie ausgelöst wird
- Der Betrag stammt aus der Preisfindung, Grundbetrag und Prozentsatz werden zur Erläuterung nachträglich ergänzt. Rundet die Preisfindung anders — oder wurde der Rabatt auf einen anderen Grundbetrag gerechnet —, passen die drei Zahlen nicht zusammen.
- Wie Sie es beheben
- Rechnen Sie den Betrag aus genau den beiden Werten, die im Dokument stehen: cbc:Amount aus cbc:BaseAmount und cbc:MultiplierFactorNumeric im selben cac:AllowanceCharge (UBL), ram:ActualAmount aus ram:BasisAmount und ram:CalculationPercent (CII). Wer den Prozentsatz nicht belegen kann, lässt beide erläuternden Felder weg.
- Was der Validator prüft
UBLnot(cbc:MultiplierFactorNumeric and cbc:BaseAmount) or u:slack(if (cbc:Amount) then cbc:Amount else 0, (xs:decimal(cbc:BaseAmount) * xs:decimal(cbc:MultiplierFactorNumeric)) div 100, $slackValue)Variablen darin
- $slackValue
- if($documentCurrencyCode = 'HUF') then 0.5 else 0.02
- $documentCurrencyCode
- /*/cbc:DocumentCurrencyCode
CIInot(ram:CalculationPercent and ram:BasisAmount) or u:slack(if (ram:ActualAmount) then ram:ActualAmount else 0, (xs:decimal(ram:BasisAmount) * xs:decimal(ram:CalculationPercent)) div 100, $slackValue)Variablen darin
- $slackValue
- if($documentCurrencyCode = 'HUF') then 0.5 else 0.02
- $documentCurrencyCode
- /rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:InvoiceCurrencyCode
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:AllowanceCharge> <cbc:ChargeIndicator>false</cbc:ChargeIndicator> <cbc:MultiplierFactorNumeric>10</cbc:MultiplierFactorNumeric> <cbc:Amount currencyID="EUR">50.00</cbc:Amount> <cbc:BaseAmount currencyID="EUR">1000.00</cbc:BaseAmount> </cac:AllowanceCharge>Korrigiert <cac:AllowanceCharge> <cbc:ChargeIndicator>false</cbc:ChargeIndicator> <cbc:MultiplierFactorNumeric>10</cbc:MultiplierFactorNumeric> <cbc:Amount currencyID="EUR">100.00</cbc:Amount> <cbc:BaseAmount currencyID="EUR">1000.00</cbc:BaseAmount> </cac:AllowanceCharge>PEPPOL-EN16931-R041
Allowance/charge base amount MUST be provided when allowance/charge percentage is provided.
- Was die Regel verlangt
- Wird der Prozentsatz eines Ab- oder Zuschlags angegeben, muss auch der Grundbetrag dabeistehen. Ein Prozentsatz ohne Bezugsgröße lässt sich nicht nachrechnen.
- Warum sie ausgelöst wird
- Der Prozentsatz ist das, was im Vertrag steht, und wird deshalb übernommen. Der Grundbetrag ist ein Zwischenergebnis der Preisfindung und existiert im Rechnungsobjekt oft gar nicht als eigenes Feld.
- Wie Sie es beheben
- Übermitteln Sie beide oder keines: cbc:MultiplierFactorNumeric zusammen mit cbc:BaseAmount im selben cac:AllowanceCharge (UBL), ram:CalculationPercent zusammen mit ram:BasisAmount (CII). Der reine Betrag allein ist immer zulässig.
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:AllowanceCharge> <cbc:ChargeIndicator>false</cbc:ChargeIndicator> <cbc:MultiplierFactorNumeric>10</cbc:MultiplierFactorNumeric> <cbc:Amount currencyID="EUR">100.00</cbc:Amount> </cac:AllowanceCharge>Korrigiert <cac:AllowanceCharge> <cbc:ChargeIndicator>false</cbc:ChargeIndicator> <cbc:MultiplierFactorNumeric>10</cbc:MultiplierFactorNumeric> <cbc:Amount currencyID="EUR">100.00</cbc:Amount> <cbc:BaseAmount currencyID="EUR">1000.00</cbc:BaseAmount> </cac:AllowanceCharge>PEPPOL-EN16931-R042
Allowance/charge percentage MUST be provided when allowance/charge base amount is provided.
- Was die Regel verlangt
- Wird der Grundbetrag eines Ab- oder Zuschlags angegeben, muss auch der Prozentsatz dabeistehen — das Gegenstück zu R041.
- Warum sie ausgelöst wird
- Der Grundbetrag wird gesetzt, weil er in den Daten vorhanden ist, der Prozentsatz nicht, weil der Rabatt in Wahrheit ein fester Betrag war. Dann steht eine Bezugsgröße im Dokument, aus der nichts folgt.
- Wie Sie es beheben
- Ergänzen Sie cbc:MultiplierFactorNumeric (UBL) beziehungsweise ram:CalculationPercent (CII) — oder lassen Sie den Grundbetrag weg, wenn es sich um einen Festbetrag handelt. Ein Festbetrag braucht nur cbc:Amount.
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:AllowanceCharge> <cbc:ChargeIndicator>false</cbc:ChargeIndicator> <cbc:Amount currencyID="EUR">100.00</cbc:Amount> <cbc:BaseAmount currencyID="EUR">1000.00</cbc:BaseAmount> </cac:AllowanceCharge>Korrigiert <cac:AllowanceCharge> <cbc:ChargeIndicator>false</cbc:ChargeIndicator> <cbc:Amount currencyID="EUR">100.00</cbc:Amount> </cac:AllowanceCharge>PEPPOL-EN16931-R043
Allowance/charge ChargeIndicator value MUST equal 'true' or 'false'
- Was die Regel verlangt
- Das Kennzeichen, ob es sich um einen Zuschlag oder einen Abschlag handelt, muss genau true oder false lauten — kleingeschrieben, ohne Alternativen.
- Warum sie ausgelöst wird
- Boolesche Werte werden von Serialisierern unterschiedlich geschrieben: 1 und 0 aus vielen Datenbanken, True aus Python, TRUE aus manchen Templates. Jede dieser Schreibweisen ist für einen Menschen eindeutig und für das Schema falsch.
- Wie Sie es beheben
- Schreiben Sie den Wert als Zeichenkette true oder false in cbc:ChargeIndicator (UBL). Verlassen Sie sich nicht auf die Standard-Serialisierung Ihres booleschen Typs, sondern setzen Sie die beiden Literale ausdrücklich.
- Was der Validator prüft
UBLnormalize-space(cbc:ChargeIndicator/text()) = 'true' or normalize-space(cbc:ChargeIndicator/text()) = 'false'
Im XML
Ausschnitt in UBL — die Regel gilt nur für diese Syntax.
Fehlerhaft <cac:AllowanceCharge> <cbc:ChargeIndicator>0</cbc:ChargeIndicator> <cbc:Amount currencyID="EUR">50.00</cbc:Amount> </cac:AllowanceCharge>Korrigiert <cac:AllowanceCharge> <cbc:ChargeIndicator>false</cbc:ChargeIndicator> <cbc:Amount currencyID="EUR">50.00</cbc:Amount> </cac:AllowanceCharge>PEPPOL-EN16931-R043-1
Allowance/charge ChargeIndicator value MUST equal 'true' or 'false'
- Was die Regel verlangt
- In CII muss das Zuschlags-Kennzeichen eines Ab- oder Zuschlags auf Dokument- oder Positionsebene genau true oder false lauten. Diese Regel prüft die Gruppe ram:SpecifiedTradeAllowanceCharge.
- Warum sie ausgelöst wird
- In CII steckt der Wert eine Ebene tiefer als in UBL, in ram:ChargeIndicator/udt:Indicator. Mappings, die von UBL portiert wurden, schreiben den Wert versehentlich direkt in ram:ChargeIndicator oder übernehmen die Schreibweise 1 und 0 aus der Datenbank.
- Wie Sie es beheben
- Schreiben Sie true oder false kleingeschrieben in ram:ChargeIndicator/udt:Indicator innerhalb von ram:SpecifiedTradeAllowanceCharge. Für Ab- und Zuschläge im Preis gilt dieselbe Anforderung an anderer Stelle — siehe R043-2.
- Was der Validator prüft
CIInormalize-space(ram:ChargeIndicator/udt:Indicator/text()) = 'true' or normalize-space(ram:ChargeIndicator/udt:Indicator/text()) = 'false'
Im XML
Ausschnitt in CII — die Regel gilt nur für diese Syntax.
Fehlerhaft <ram:SpecifiedTradeAllowanceCharge> <ram:ChargeIndicator> <udt:Indicator>0</udt:Indicator> </ram:ChargeIndicator> <ram:ActualAmount>50.00</ram:ActualAmount> </ram:SpecifiedTradeAllowanceCharge>Korrigiert <ram:SpecifiedTradeAllowanceCharge> <ram:ChargeIndicator> <udt:Indicator>false</udt:Indicator> </ram:ChargeIndicator> <ram:ActualAmount>50.00</ram:ActualAmount> </ram:SpecifiedTradeAllowanceCharge>PEPPOL-EN16931-R043-2
Allowance/charge ChargeIndicator value MUST equal 'true' or 'false'
- Was die Regel verlangt
- Dieselbe Anforderung wie R043-1, aber für den Ab- oder Zuschlag im Preis: ram:AppliedTradeAllowanceCharge innerhalb des Bruttopreises muss ein Kennzeichen von genau true oder false tragen.
- Warum sie ausgelöst wird
- Der Preisrabatt wird oft von einer anderen Stelle im Mapping geschrieben als die Rabatte auf Dokumentebene — häufig direkt aus der Artikel-Preisfindung. Eine dort abweichende Schreibweise fällt erst hier auf, obwohl R043-1 längst sauber ist.
- Wie Sie es beheben
- Schreiben Sie true oder false kleingeschrieben in ram:ChargeIndicator/udt:Indicator innerhalb von ram:AppliedTradeAllowanceCharge unter ram:GrossPriceProductTradePrice. Im Preis ist ohnehin nur false zulässig — siehe R044.
- Was der Validator prüft
CIInormalize-space(ram:ChargeIndicator/udt:Indicator/text()) = 'true' or normalize-space(ram:ChargeIndicator/udt:Indicator/text()) = 'false'
Im XML
Ausschnitt in CII — die Regel gilt nur für diese Syntax.
Fehlerhaft <ram:GrossPriceProductTradePrice> <ram:ChargeAmount>110.00</ram:ChargeAmount> <ram:AppliedTradeAllowanceCharge> <ram:ChargeIndicator> <udt:Indicator>FALSE</udt:Indicator> </ram:ChargeIndicator> <ram:ActualAmount>10.00</ram:ActualAmount> </ram:AppliedTradeAllowanceCharge> </ram:GrossPriceProductTradePrice>Korrigiert <ram:GrossPriceProductTradePrice> <ram:ChargeAmount>110.00</ram:ChargeAmount> <ram:AppliedTradeAllowanceCharge> <ram:ChargeIndicator> <udt:Indicator>false</udt:Indicator> </ram:ChargeIndicator> <ram:ActualAmount>10.00</ram:ActualAmount> </ram:AppliedTradeAllowanceCharge> </ram:GrossPriceProductTradePrice>PEPPOL-EN16931-R044
Charge on price level is NOT allowed. Only value 'false' allowed.
- Was die Regel verlangt
- Im Preis einer Position ist kein Zuschlag erlaubt. Das Kennzeichen dort darf nur false lauten: der Preis kennt ausschließlich den Abschlag vom Bruttopreis auf den Nettopreis.
- Warum sie ausgelöst wird
- Wer einen Aufschlag auf einen Artikel abbilden will — Mindermenge, Eilzuschlag, Verpackung —, sucht ihn intuitiv im Preis, weil er dort im eigenen System gepflegt wird. Die Norm sieht Zuschläge aber nur auf Positions- oder Dokumentebene vor.
- Wie Sie es beheben
- Verschieben Sie den Zuschlag in das cac:AllowanceCharge der Position oder des Dokuments mit cbc:ChargeIndicator true. Innerhalb von cac:Price bleibt nur der Abschlag mit false — in CII entsprechend ram:AppliedTradeAllowanceCharge.
- Was der Validator prüft
UBLnormalize-space(cbc:ChargeIndicator) = 'false'CIInot(ram:AppliedTradeAllowanceCharge/ram:ActualAmount) or ram:AppliedTradeAllowanceCharge/ram:ChargeIndicator/udt:Indicator = 'false'
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:Price> <cbc:PriceAmount currencyID="EUR">100.00</cbc:PriceAmount> <cac:AllowanceCharge> <cbc:ChargeIndicator>true</cbc:ChargeIndicator> <cbc:Amount currencyID="EUR">10.00</cbc:Amount> </cac:AllowanceCharge> </cac:Price>Korrigiert <cac:Price> <cbc:PriceAmount currencyID="EUR">100.00</cbc:PriceAmount> <cac:AllowanceCharge> <cbc:ChargeIndicator>false</cbc:ChargeIndicator> <cbc:Amount currencyID="EUR">10.00</cbc:Amount> <cbc:BaseAmount currencyID="EUR">110.00</cbc:BaseAmount> </cac:AllowanceCharge> </cac:Price>PEPPOL-EN16931-R046
Preisberechnung stimmt nicht
Item net price MUST equal (Gross price - Allowance amount) when gross price is provided.
- Was die Regel verlangt
- Wird ein Bruttopreis angegeben, muss der Nettopreis genau daraus folgen: Bruttopreis minus Preisnachlass, ohne Toleranz. Die drei Zahlen beschreiben eine einzige Rechnung und müssen aufgehen.
- Warum sie ausgelöst wird
- Der Nettopreis kommt aus der Preisfindung und ist bereits gerundet; Bruttopreis und Nachlass werden zur Nachvollziehbarkeit ergänzt und stammen aus der Konditionspflege. Zwischen beiden liegt oft ein Cent — und der reicht: verglichen wird mit einem schlichten Gleichheitszeichen auf Dezimalzahlen, ohne jede Toleranz. Die Rechenregeln der Norm sind da großzügiger, BR-CO-17 etwa lässt eine ganze Währungseinheit zu. In CII kommen zwei Eigenheiten dazu: ein fehlender Nachlass wird über u:decimalOrZero als 0 gerechnet, und von mehreren angewandten Nachlässen zählt nur der erste.
- Wie Sie es beheben
- Leiten Sie cbc:PriceAmount aus cbc:BaseAmount minus cbc:Amount des Preis-Abschlags ab (UBL) beziehungsweise ram:ChargeAmount minus ram:ActualAmount in CII. Wenn Sie den Bruttopreis nicht belegen können, lassen Sie ihn und den Nachlass weg — der Nettopreis allein genügt.
- Was der Validator prüft
UBLnot(cbc:BaseAmount) or xs:decimal(../cbc:PriceAmount) = xs:decimal(cbc:BaseAmount) - xs:decimal(cbc:Amount)CIInot(ram:ChargeAmount) or xs:decimal(../ram:NetPriceProductTradePrice/ram:ChargeAmount) = xs:decimal(ram:ChargeAmount) - u:decimalOrZero(ram:AppliedTradeAllowanceCharge/ram:ActualAmount[1])
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:Price> <cbc:PriceAmount currencyID="EUR">105.00</cbc:PriceAmount> <cac:AllowanceCharge> <cbc:ChargeIndicator>false</cbc:ChargeIndicator> <cbc:Amount currencyID="EUR">10.00</cbc:Amount> <cbc:BaseAmount currencyID="EUR">110.00</cbc:BaseAmount> </cac:AllowanceCharge> </cac:Price>Korrigiert <cac:Price> <cbc:PriceAmount currencyID="EUR">100.00</cbc:PriceAmount> <cac:AllowanceCharge> <cbc:ChargeIndicator>false</cbc:ChargeIndicator> <cbc:Amount currencyID="EUR">10.00</cbc:Amount> <cbc:BaseAmount currencyID="EUR">110.00</cbc:BaseAmount> </cac:AllowanceCharge> </cac:Price>PEPPOL-EN16931-R053
Only one tax total with tax subtotals MUST be provided.
Wortlaut in CII
No more than one tax total amount must be provided where currency id equals document currency code.
- Was die Regel verlangt
- Die Rechnung darf genau eine Steuersumme in Rechnungswährung enthalten — also genau einen Block mit Aufschlüsselung. Mehrere Steuerkategorien gehören als mehrere Unterblöcke in diesen einen Block.
- Warum sie ausgelöst wird
- Wer je Steuersatz einen eigenen Steuerblock erzeugt, bildet die Struktur des eigenen Systems ab statt die der Norm. Die Rechnung sieht dann korrekt aus und hat trotzdem zwei Gesamtsummen.
- Wie Sie es beheben
- Erzeugen Sie ein einziges cac:TaxTotal mit cbc:TaxAmount und darin je Steuerkategorie ein cac:TaxSubtotal (UBL). In CII gibt es diese Verschachtelung nicht: dort steht je Kategorie ein ram:ApplicableTradeTax.
- Was der Validator prüft
UBLcount(cac:TaxTotal[cac:TaxSubtotal]) = 1CIIcount(ram:SpecifiedTradeSettlementHeaderMonetarySummation/ram:TaxTotalAmount[@currencyID = $documentCurrencyCode]) <=1Variablen darin
- $documentCurrencyCode
- /rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:InvoiceCurrencyCode
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:TaxTotal> <cbc:TaxAmount currencyID="EUR">152.00</cbc:TaxAmount> <cac:TaxSubtotal> <cbc:TaxableAmount currencyID="EUR">800.00</cbc:TaxableAmount> <cbc:TaxAmount currencyID="EUR">152.00</cbc:TaxAmount> </cac:TaxSubtotal> </cac:TaxTotal> <cac:TaxTotal> <cbc:TaxAmount currencyID="EUR">14.00</cbc:TaxAmount> <cac:TaxSubtotal> <cbc:TaxableAmount currencyID="EUR">200.00</cbc:TaxableAmount> <cbc:TaxAmount currencyID="EUR">14.00</cbc:TaxAmount> </cac:TaxSubtotal> </cac:TaxTotal>Korrigiert <cac:TaxTotal> <cbc:TaxAmount currencyID="EUR">166.00</cbc:TaxAmount> <cac:TaxSubtotal> <cbc:TaxableAmount currencyID="EUR">800.00</cbc:TaxableAmount> <cbc:TaxAmount currencyID="EUR">152.00</cbc:TaxAmount> </cac:TaxSubtotal> <cac:TaxSubtotal> <cbc:TaxableAmount currencyID="EUR">200.00</cbc:TaxableAmount> <cbc:TaxAmount currencyID="EUR">14.00</cbc:TaxAmount> </cac:TaxSubtotal> </cac:TaxTotal>PEPPOL-EN16931-R054
Only one tax total without tax subtotals MUST be provided when tax currency code is provided.
Wortlaut in CII
Only one tax total amount must be provided where currency id equals tax currency code, if tax currency code (BT-6) is provided.
- Was die Regel verlangt
- Ein zweiter Steuerblock ohne Aufschlüsselung ist nur erlaubt, wenn eine abweichende Steuerwährung (BT-6) angegeben ist — und dann genau einer. Er nennt die Steuersumme in der Meldewährung.
- Warum sie ausgelöst wird
- Der Block entsteht aus einer Vorlage für Auslandsrechnungen und bleibt stehen, wenn BT-6 im konkreten Fall nicht gesetzt wird. Dann steht eine Steuersumme in einer Währung im Dokument, die die Rechnung gar nicht kennt.
- Wie Sie es beheben
- Erzeugen Sie das zusätzliche cac:TaxTotal ohne cac:TaxSubtotal nur zusammen mit cbc:TaxCurrencyCode — beide oder keines. Die eigentliche Aufschlüsselung bleibt im Block der Rechnungswährung, siehe R053.
- Was der Validator prüft
UBLcount(cac:TaxTotal[not(cac:TaxSubtotal)]) = (if (cbc:TaxCurrencyCode) then 1 else 0)CIIcount(ram:SpecifiedTradeSettlementHeaderMonetarySummation/ram:TaxTotalAmount[@currencyID != $documentCurrencyCode]) = (if (ram:TaxCurrencyCode) then 1 else 0)Variablen darin
- $documentCurrencyCode
- /rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:InvoiceCurrencyCode
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode> <cac:TaxTotal> <cbc:TaxAmount currencyID="EUR">190.00</cbc:TaxAmount> <cac:TaxSubtotal> <cbc:TaxableAmount currencyID="EUR">1000.00</cbc:TaxableAmount> <cbc:TaxAmount currencyID="EUR">190.00</cbc:TaxAmount> </cac:TaxSubtotal> </cac:TaxTotal> <cac:TaxTotal> <cbc:TaxAmount currencyID="SEK">2090.00</cbc:TaxAmount> </cac:TaxTotal>Korrigiert <cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode> <cbc:TaxCurrencyCode>SEK</cbc:TaxCurrencyCode> <cac:TaxTotal> <cbc:TaxAmount currencyID="EUR">190.00</cbc:TaxAmount> <cac:TaxSubtotal> <cbc:TaxableAmount currencyID="EUR">1000.00</cbc:TaxableAmount> <cbc:TaxAmount currencyID="EUR">190.00</cbc:TaxAmount> </cac:TaxSubtotal> </cac:TaxTotal> <cac:TaxTotal> <cbc:TaxAmount currencyID="SEK">2090.00</cbc:TaxAmount> </cac:TaxTotal>PEPPOL-EN16931-R055
Invoice total VAT amount and Invoice total VAT amount in accounting currency MUST have the same operational sign
- Was die Regel verlangt
- Die Steuersumme in Rechnungswährung und die Steuersumme in der Meldewährung müssen dasselbe Vorzeichen tragen. Beide beschreiben denselben Betrag, nur in zwei Währungen.
- Warum sie ausgelöst wird
- Bei Gutschriften mit negativen Beträgen wird das Vorzeichen an einer Stelle gedreht und an der anderen nicht — typischerweise, weil die Umrechnung in die Meldewährung über einen Betragsdienst läuft, der den Absolutwert liefert.
- Wie Sie es beheben
- Rechnen Sie die Meldewährung aus dem vorzeichenbehafteten Betrag um, statt Vorzeichen und Betrag getrennt zu behandeln. Geprüft werden die beiden cbc:TaxAmount in den cac:TaxTotal-Blöcken (UBL) beziehungsweise die entsprechenden Beträge in CII.
- Was der Validator prüft
UBLnot(cbc:TaxCurrencyCode) or (cac:TaxTotal/cbc:TaxAmount[@currencyID=normalize-space(../../cbc:TaxCurrencyCode)] <= 0 and cac:TaxTotal/cbc:TaxAmount[@currencyID=normalize-space(../../cbc:DocumentCurrencyCode)] <= 0) or (cac:TaxTotal/cbc:TaxAmount[@currencyID=normalize-space(../../cbc:TaxCurrencyCode)] >= 0 and cac:TaxTotal/cbc:TaxAmount[@currencyID=normalize-space(../../cbc:DocumentCurrencyCode)] >= 0)CIInot(/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:TaxCurrencyCode and ram:SpecifiedTradeSettlementHeaderMonetarySummation/ram:TaxTotalAmount[@currencyID = $documentCurrencyCode]) or (ram:SpecifiedTradeSettlementHeaderMonetarySummation/ram:TaxTotalAmount[@currencyID = $taxCurrencyCode] < 0 and ram:SpecifiedTradeSettlementHeaderMonetarySummation/ram:TaxTotalAmount[@currencyID = $documentCurrencyCode] < 0) or (ram:SpecifiedTradeSettlementHeaderMonetarySummation/ram:TaxTotalAmount[@currencyID = $taxCurrencyCode] >= 0 and ram:SpecifiedTradeSettlementHeaderMonetarySummation/ram:TaxTotalAmount[@currencyID = $documentCurrencyCode] >= 0)Variablen darin
- $documentCurrencyCode
- /rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:InvoiceCurrencyCode
- $taxCurrencyCode
- /rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:TaxCurrencyCode
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:TaxTotal> <cbc:TaxAmount currencyID="EUR">-190.00</cbc:TaxAmount> </cac:TaxTotal> <cac:TaxTotal> <cbc:TaxAmount currencyID="SEK">2090.00</cbc:TaxAmount> </cac:TaxTotal>Korrigiert <cac:TaxTotal> <cbc:TaxAmount currencyID="EUR">-190.00</cbc:TaxAmount> </cac:TaxTotal> <cac:TaxTotal> <cbc:TaxAmount currencyID="SEK">-2090.00</cbc:TaxAmount> </cac:TaxTotal>PEPPOL-EN16931-R061
Mandatsreferenz fehlt
Mandate reference MUST be provided for direct debit.
- Was die Regel verlangt
- Bei Lastschrift muss die Mandatsreferenz übermittelt werden — die Kennung des Mandats, mit dem der Zahler dem Einzug zugestimmt hat.
- Warum sie ausgelöst wird
- Das Mandat liegt beim Zahlungsdienstleister, und die Rechnung wird als reine Zahlungsaufforderung gebaut. Die Referenz existiert also, steht aber in einem anderen System als dem, das die Rechnung erzeugt. Die Peppol-Regel greift dabei bei zwei Zahlungsmittelcodes, 49 und 59, während die deutschen Lastschriftregeln nur auf 59 hören: eine Rechnung mit Code 49 löst hier aus und bei BR-DE-25-a nicht. Und sie verlangt die Referenz selbst, nicht bloß die Gruppe — ein leeres cac:PaymentMandate erfüllt BR-DE-25-a und scheitert an dieser Regel.
- Wie Sie es beheben
- Übernehmen Sie die Mandatsreferenz nach BT-89: cac:PaymentMeans/cac:PaymentMandate/cbc:ID in UBL, ram:SpecifiedTradePaymentTerms/ram:DirectDebitMandateID in CII. Für den deutschen Prüfweg gilt zusätzlich BR-DE-25-a.
- Was der Validator prüft
UBLcac:PaymentMandate/cbc:IDCII../ram:SpecifiedTradePaymentTerms/ram:DirectDebitMandateID
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:PaymentMeans> <cbc:PaymentMeansCode>59</cbc:PaymentMeansCode> <cac:PaymentMandate> <cac:PayerFinancialAccount> <cbc:ID>DE02120300000000202051</cbc:ID> </cac:PayerFinancialAccount> </cac:PaymentMandate> </cac:PaymentMeans>Korrigiert <cac:PaymentMeans> <cbc:PaymentMeansCode>59</cbc:PaymentMeansCode> <cac:PaymentMandate> <cbc:ID>MANDAT-2026-0007</cbc:ID> <cac:PayerFinancialAccount> <cbc:ID>DE02120300000000202051</cbc:ID> </cac:PayerFinancialAccount> </cac:PaymentMandate> </cac:PaymentMeans>PEPPOL-EN16931-R101
Element Document reference can only be used for Invoice line object
Wortlaut in CII
Element Additional referenced document can only be used for Invoice line object.
- Was die Regel verlangt
- Auf einer Rechnungsposition ist als zusätzliche Dokumentenreferenz nur der Objektbezeichner zulässig — der Typcode 130. Andere Belegverweise gehören auf Dokumentebene.
- Warum sie ausgelöst wird
- Lieferschein- oder Auftragsnummern werden je Position gepflegt und deshalb auch je Position ausgegeben. Auf Positionsebene sieht die Norm dafür aber nur den Objektbezeichner vor.
- Wie Sie es beheben
- Setzen Sie auf der Position cbc:DocumentTypeCode auf 130 (UBL: cac:InvoiceLine/cac:DocumentReference; CII: ram:AdditionalReferencedDocument der Position). Lieferschein und Auftrag gehören in cac:DespatchDocumentReference beziehungsweise cac:OrderReference auf Dokumentebene.
- Was der Validator prüft
UBL(not(cac:DocumentReference) or (cac:DocumentReference/cbc:DocumentTypeCode='130'))CII(not(ram:SpecifiedLineTradeSettlement/ram:AdditionalReferencedDocument) or (ram:SpecifiedLineTradeSettlement/ram:AdditionalReferencedDocument/ram:TypeCode='130'))
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:InvoiceLine> <cbc:ID>1</cbc:ID> <cac:DocumentReference> <cbc:ID>LS-2026-0007</cbc:ID> <cbc:DocumentTypeCode>50</cbc:DocumentTypeCode> </cac:DocumentReference> </cac:InvoiceLine>Korrigiert <cac:InvoiceLine> <cbc:ID>1</cbc:ID> <cac:DocumentReference> <cbc:ID>LS-2026-0007</cbc:ID> <cbc:DocumentTypeCode>130</cbc:DocumentTypeCode> </cac:DocumentReference> </cac:InvoiceLine>PEPPOL-EN16931-R110
Start date of line period MUST be within invoice period.
- Was die Regel verlangt
- Beginnt eine Position einen eigenen Leistungszeitraum, muss dieser innerhalb des Abrechnungszeitraums der Rechnung liegen: das Startdatum der Position darf nicht vor dem Start der Rechnung liegen.
- Warum sie ausgelöst wird
- Nachberechnungen sind der klassische Fall: eine Leistung aus dem Vormonat wird in die laufende Rechnung aufgenommen und behält ihren echten Zeitraum, während der Rechnungszeitraum nur den aktuellen Monat abdeckt.
- Wie Sie es beheben
- Weiten Sie den Rechnungszeitraum (cac:InvoicePeriod im Kopf) so, dass er alle Positionen umfasst, oder stellen Sie die Nachberechnung in eine eigene Rechnung. Geprüft wird cbc:StartDate der Position gegen cbc:StartDate im Kopf.
- Was der Validator prüft
UBLxs:date(text()) >= xs:date(../../../cac:InvoicePeriod/cbc:StartDate)CIIudt:DateTimeString >= ../../../../ram:ApplicableHeaderTradeSettlement/ram:BillingSpecifiedPeriod/ram:StartDateTime/udt:DateTimeString
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:InvoicePeriod> <cbc:StartDate>2026-08-01</cbc:StartDate> <cbc:EndDate>2026-08-31</cbc:EndDate> </cac:InvoicePeriod> <cac:InvoiceLine> <cbc:ID>1</cbc:ID> <cac:InvoicePeriod> <cbc:StartDate>2026-07-15</cbc:StartDate> </cac:InvoicePeriod> </cac:InvoiceLine>Korrigiert <cac:InvoicePeriod> <cbc:StartDate>2026-07-01</cbc:StartDate> <cbc:EndDate>2026-08-31</cbc:EndDate> </cac:InvoicePeriod> <cac:InvoiceLine> <cbc:ID>1</cbc:ID> <cac:InvoicePeriod> <cbc:StartDate>2026-07-15</cbc:StartDate> </cac:InvoicePeriod> </cac:InvoiceLine>PEPPOL-EN16931-R111
End date of line period MUST be within invoice period.
- Was die Regel verlangt
- Das Enddatum eines Positionszeitraums darf nicht nach dem Ende des Abrechnungszeitraums liegen — das Gegenstück zu R110 am anderen Ende.
- Warum sie ausgelöst wird
- Vorausberechnete Leistungen laufen über das Rechnungsende hinaus: eine Jahreslizenz wird im August in Rechnung gestellt und endet im nächsten Juli, während der Rechnungszeitraum den August abdeckt.
- Wie Sie es beheben
- Setzen Sie den Rechnungszeitraum so, dass er die längste Position einschließt, oder verzichten Sie auf den Kopf-Zeitraum, wenn die Positionen ohnehin eigene tragen. Geprüft wird cbc:EndDate der Position gegen cbc:EndDate im Kopf.
- Was der Validator prüft
UBLxs:date(text()) <= xs:date(../../../cac:InvoicePeriod/cbc:EndDate)CIIudt:DateTimeString <= ../../../../ram:ApplicableHeaderTradeSettlement/ram:BillingSpecifiedPeriod/ram:EndDateTime/udt:DateTimeString
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:InvoicePeriod> <cbc:StartDate>2026-08-01</cbc:StartDate> <cbc:EndDate>2026-08-31</cbc:EndDate> </cac:InvoicePeriod> <cac:InvoiceLine> <cbc:ID>1</cbc:ID> <cac:InvoicePeriod> <cbc:EndDate>2027-07-31</cbc:EndDate> </cac:InvoicePeriod> </cac:InvoiceLine>Korrigiert <cac:InvoicePeriod> <cbc:StartDate>2026-08-01</cbc:StartDate> <cbc:EndDate>2027-07-31</cbc:EndDate> </cac:InvoicePeriod> <cac:InvoiceLine> <cbc:ID>1</cbc:ID> <cac:InvoicePeriod> <cbc:EndDate>2027-07-31</cbc:EndDate> </cac:InvoicePeriod> </cac:InvoiceLine>PEPPOL-EN16931-R120
Invoice line net amount MUST equal (Invoiced quantity * (Item net price/item price base quantity) + Sum of invoice line charge amount - sum of invoice line allowance amountWarnung
- Was die Regel verlangt
- Der Nettobetrag einer Position muss aus ihren eigenen Angaben folgen: Menge × (Nettopreis ÷ Preiseinheit), zuzüglich der Zuschläge und abzüglich der Abschläge auf der Position.
- Warum sie ausgelöst wird
- Der Positionsbetrag stammt aus dem Rechnungsobjekt und ist dort längst berechnet; Menge, Preis und Rabatte werden daneben geschrieben. Sobald die Preiseinheit nicht 1 ist oder ein Positionsrabatt hinzukommt, weichen die beiden Wege voneinander ab.
- Wie Sie es beheben
- Berechnen Sie cbc:LineExtensionAmount aus genau den Werten, die in der Position stehen — cbc:InvoicedQuantity, cac:Price/cbc:PriceAmount, cac:Price/cbc:BaseQuantity und die cac:AllowanceCharge der Position. Diese Regel ist eine Warnung, keine Ablehnung: die Rechnung bleibt gültig, aber die Zahlen widersprechen sich.
- Was der Validator prüft
UBLu:slack($lineExtensionAmount, ($quantity * ($priceAmount div $baseQuantity)) + $chargesTotal - $allowancesTotal, $slackValue)Variablen darin
- $lineExtensionAmount
- if (cbc:LineExtensionAmount) then xs:decimal(cbc:LineExtensionAmount) else 0
- $quantity
- if (/ubl-invoice:Invoice) then (if (cbc:InvoicedQuantity) then xs:decimal(cbc:InvoicedQuantity) else 1) else (if (cbc:CreditedQuantity) then xs:decimal(cbc:CreditedQuantity) else 1)
- $priceAmount
- if (cac:Price/cbc:PriceAmount) then xs:decimal(cac:Price/cbc:PriceAmount) else 0
- $baseQuantity
- if (cac:Price/cbc:BaseQuantity and xs:decimal(cac:Price/cbc:BaseQuantity) != 0) then xs:decimal(cac:Price/cbc:BaseQuantity) else 1
- $chargesTotal
- if (cac:AllowanceCharge[normalize-space(cbc:ChargeIndicator) = 'true']) then round(sum(cac:AllowanceCharge[normalize-space(cbc:ChargeIndicator) = 'true']/cbc:Amount/xs:decimal(.)) * 10 * 10) div 100 else 0
- $allowancesTotal
- if (cac:AllowanceCharge[normalize-space(cbc:ChargeIndicator) = 'false']) then round(sum(cac:AllowanceCharge[normalize-space(cbc:ChargeIndicator) = 'false']/cbc:Amount/xs:decimal(.)) * 10 * 10) div 100 else 0
- $slackValue
- if($documentCurrencyCode = 'HUF') then 0.5 else 0.02
- $documentCurrencyCode
- /*/cbc:DocumentCurrencyCode
CIIu:slack($lineExtensionAmount, ($quantity * ($priceAmount div $baseQuantity)) + $chargesTotal - $allowancesTotal, $slackValue)Variablen darin
- $lineExtensionAmount
- if (ram:SpecifiedLineTradeSettlement/ram:SpecifiedTradeSettlementLineMonetarySummation/ram:LineTotalAmount) then xs:decimal(ram:SpecifiedLineTradeSettlement/ram:SpecifiedTradeSettlementLineMonetarySummation/ram:LineTotalAmount) else 0
- $quantity
- if (ram:SpecifiedLineTradeDelivery/ram:BilledQuantity) then xs:decimal(ram:SpecifiedLineTradeDelivery/ram:BilledQuantity) else 1
- $priceAmount
- if (ram:SpecifiedLineTradeAgreement/ram:NetPriceProductTradePrice/ram:ChargeAmount) then xs:decimal(ram:SpecifiedLineTradeAgreement/ram:NetPriceProductTradePrice/ram:ChargeAmount) else 0
- $baseQuantity
- if (ram:SpecifiedLineTradeAgreement/ram:NetPriceProductTradePrice/ram:BasisQuantity and xs:decimal(ram:SpecifiedLineTradeAgreement/ram:NetPriceProductTradePrice/ram:BasisQuantity) != 0) then xs:decimal(ram:SpecifiedLineTradeAgreement/ram:NetPriceProductTradePrice/ram:BasisQuantity) else if (ram:SpecifiedLineTradeAgreement/ram:GrossPriceProductTradePrice/ram:BasisQuantity and xs:decimal(ram:SpecifiedLineTradeAgreement/ram:GrossPriceProductTradePrice/ram:BasisQuantity) != 0) then xs:decimal(ram:SpecifiedLineTradeAgreement/ram:GrossPriceProductTradePrice/ram:BasisQuantity) else 1
- $chargesTotal
- if (ram:SpecifiedLineTradeSettlement/ram:SpecifiedTradeAllowanceCharge[normalize-space(ram:ChargeIndicator/udt:Indicator) = 'true']) then round(sum(ram:SpecifiedLineTradeSettlement/ram:SpecifiedTradeAllowanceCharge[normalize-space(ram:ChargeIndicator/udt:Indicator) = 'true']/ram:ActualAmount/xs:decimal(.)) * 10 * 10) div 100 else 0
- $allowancesTotal
- if (ram:SpecifiedLineTradeSettlement/ram:SpecifiedTradeAllowanceCharge[normalize-space(ram:ChargeIndicator/udt:Indicator) = 'false']) then round(sum(ram:SpecifiedLineTradeSettlement/ram:SpecifiedTradeAllowanceCharge[normalize-space(ram:ChargeIndicator/udt:Indicator) = 'false']/ram:ActualAmount/xs:decimal(.)) * 10 * 10) div 100 else 0
- $slackValue
- if($documentCurrencyCode = 'HUF') then 0.5 else 0.02
- $documentCurrencyCode
- /rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:InvoiceCurrencyCode
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:InvoiceLine> <cbc:ID>1</cbc:ID> <cbc:InvoicedQuantity unitCode="C62">10</cbc:InvoicedQuantity> <cbc:LineExtensionAmount currencyID="EUR">1000.00</cbc:LineExtensionAmount> <cac:AllowanceCharge> <cbc:ChargeIndicator>false</cbc:ChargeIndicator> <cbc:Amount currencyID="EUR">50.00</cbc:Amount> </cac:AllowanceCharge> <cac:Price> <cbc:PriceAmount currencyID="EUR">100.00</cbc:PriceAmount> </cac:Price> </cac:InvoiceLine>Korrigiert <cac:InvoiceLine> <cbc:ID>1</cbc:ID> <cbc:InvoicedQuantity unitCode="C62">10</cbc:InvoicedQuantity> <cbc:LineExtensionAmount currencyID="EUR">950.00</cbc:LineExtensionAmount> <cac:AllowanceCharge> <cbc:ChargeIndicator>false</cbc:ChargeIndicator> <cbc:Amount currencyID="EUR">50.00</cbc:Amount> </cac:AllowanceCharge> <cac:Price> <cbc:PriceAmount currencyID="EUR">100.00</cbc:PriceAmount> </cac:Price> </cac:InvoiceLine>PEPPOL-EN16931-R121
Preiseinheit ist null
Base quantity MUST be a positive number above zero.
- Was die Regel verlangt
- Die Preiseinheit (BT-149) muss größer als null sein — sie sagt, auf wie viele Einheiten sich der Preis bezieht, etwa 100 je 100 Stück. Null scheitert daran ebenso wie ein negativer Wert; ganz weglassen ist dagegen erlaubt und bedeutet: Preis je Einheit.
- Warum sie ausgelöst wird
- Das Feld wird mit dem Standardwert des eigenen Datentyps belegt, und der ist bei einer nicht gepflegten Zahl oft 0. Ein Preis je null Einheiten ist eine Division durch null und macht jede Nachrechnung unmöglich.
- Wie Sie es beheben
- Lassen Sie cac:Price/cbc:BaseQuantity weg, wenn sich der Preis auf eine Einheit bezieht — das ist der Standardfall und braucht keine Angabe. Andernfalls setzen Sie die tatsächliche Bezugsmenge, in CII ram:BasisQuantity.
- Was der Validator prüft
UBLnot(cac:Price/cbc:BaseQuantity) or xs:decimal(cac:Price/cbc:BaseQuantity) > 0CIInot(ram:BasisQuantity) or xs:decimal(ram:BasisQuantity) > 0
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:Price> <cbc:PriceAmount currencyID="EUR">100.00</cbc:PriceAmount> <cbc:BaseQuantity unitCode="C62">0</cbc:BaseQuantity> </cac:Price>Korrigiert <cac:Price> <cbc:PriceAmount currencyID="EUR">100.00</cbc:PriceAmount> <cbc:BaseQuantity unitCode="C62">1</cbc:BaseQuantity> </cac:Price>PEPPOL-EN16931-R130
Unit code of price base quantity MUST be same as invoiced quantity.
- Was die Regel verlangt
- Die Maßeinheit der Preiseinheit muss dieselbe sein wie die der berechneten Menge. Preis und Menge müssen sich auf dasselbe messen, sonst ist der Positionsbetrag nicht nachrechenbar.
- Warum sie ausgelöst wird
- Menge und Preis kommen aus verschiedenen Quellen: die Menge aus dem Auftrag, die Preiseinheit aus dem Artikelstamm. Wird dort in Kilogramm gepflegt und im Auftrag in Stück bestellt, treffen zwei verschiedene Einheiten aufeinander.
- Wie Sie es beheben
- Setzen Sie das unitCode-Attribut von cac:Price/cbc:BaseQuantity gleich dem von cbc:InvoicedQuantity, oder rechnen Sie den Preis vorher auf die berechnete Einheit um. In CII gilt dasselbe für ram:BasisQuantity und ram:BilledQuantity.
- Was der Validator prüft
UBLnot($hasQuantity) or @unitCode = $quantity/@unitCodeVariablen darin
- $hasQuantity
- ../../cbc:InvoicedQuantity or ../../cbc:CreditedQuantity
- $quantity
- if (/ubl-invoice:Invoice) then ../../cbc:InvoicedQuantity else ../../cbc:CreditedQuantity
CII@unitCode = ../../../ram:SpecifiedLineTradeDelivery/ram:BilledQuantity/@unitCode
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:InvoiceLine> <cbc:ID>1</cbc:ID> <cbc:InvoicedQuantity unitCode="C62">10</cbc:InvoicedQuantity> <cac:Price> <cbc:PriceAmount currencyID="EUR">100.00</cbc:PriceAmount> <cbc:BaseQuantity unitCode="KGM">1</cbc:BaseQuantity> </cac:Price> </cac:InvoiceLine>Korrigiert <cac:InvoiceLine> <cbc:ID>1</cbc:ID> <cbc:InvoicedQuantity unitCode="C62">10</cbc:InvoicedQuantity> <cac:Price> <cbc:PriceAmount currencyID="EUR">100.00</cbc:PriceAmount> <cbc:BaseQuantity unitCode="C62">1</cbc:BaseQuantity> </cac:Price> </cac:InvoiceLine>
NormAPI liefert technische Validierung, keine Steuer- oder Rechtsberatung.