Rechenregeln und Querbezüge — wenn die Summen nicht zusammenpassen
BR-CO prüft nicht einzelne Felder, sondern deren Verhältnis zueinander: dass die Summen aufgehen, dass sich zwei Angaben nicht widersprechen, dass ein Wert zu den Werten passt, aus denen er entsteht.
23 Regeln · 19 erklärt · Regelwerk v2026-08-31
Rundung ist die häufigste Ursache
Die Summenregeln — BR-CO-10 bis BR-CO-17 — scheitern selten daran, dass jemand falsch gerechnet hat. Sie scheitern daran, wann gerundet wurde. Wer Positionsbeträge intern mit vier Nachkommastellen führt, sie erst beim Schreiben des XML auf zwei rundet und die Summe aus den ungerundeten Werten bildet, bekommt eine Rechnung, deren Positionen sich nicht zur eigenen Summe addieren.
Die Norm verlangt es andersherum: erst runden, dann summieren. Das ist eine Zeile im Mapping und der Unterschied zwischen einer angenommenen und einer abgelehnten Rechnung.
Wie genau gerechnet werden muss, ist innerhalb der Familie nicht gleich. BR-CO-10, BR-CO-13, BR-CO-14, BR-CO-15 und BR-CO-16 vergleichen auf den Cent — ein Cent Abweichung meldet die Regel. BR-CO-17 vergleicht mit „größer als minus eins“ und „kleiner als plus eins“ und lässt damit eine ganze Währungseinheit Spielraum. Am 17. September 2026 am laufenden Prüfer nachgestellt: ein Cent zu viel im Steuerbetrag einer Kategorie meldet nur BR-CO-14, ein voller Euro meldet BR-CO-14, BR-CO-17 und BR-S-09. Welche Regeln zusammen auftreten, sagt Ihnen also, wie weit Sie danebenliegen.
Sich ausschließende Angaben
Die zweite Hälfte der Familie prüft Paare, von denen genau eines gesetzt sein darf: der Steuerzeitpunkt als Datum (BT-7) oder als Code (BT-8), niemals beides. Systeme, die beide Felder „sicherheitshalber“ füllen, verstoßen genau deshalb dagegen.
Hier hilft kein Nachrechnen, sondern eine Entscheidung im Mapping: welches der beiden Felder ist die Quelle, und das andere bleibt leer.
Vier Regeln der Familie verlangen etwas, das nichts durchsetzt. BR-CO-05 bis BR-CO-08 fordern, dass ein Ab- oder Zuschlagsgrund im Klartext und sein Code dasselbe meinen — und ob ein Code und ein Satz dasselbe bedeuten, kann Schematron nicht entscheiden. Der kompilierte Test lautet in beiden Syntaxen true(). Die Anforderung steht in der Norm, gemeldet wird sie nie: ein falsch gesetzter Code kommt am Prüfer vorbei und fällt erst dem Menschen auf, der die Rechnung liest.
Alle Rechen- und Querbezugsregeln
Mit dem offiziellen Regeltext. Regeln mit ausgeschriebener Erklärung tragen Ursache und Behebung direkt darunter.
BR-CO-03
Value added tax point date (BT-7) and Value added tax point date code (BT-8) are mutually exclusive.
- Was die Regel verlangt
- Die Rechnung darf den Steuerstichtag entweder als Datum (BT-7) oder als Code (BT-8) angeben — niemals beides. Beide Felder beantworten dieselbe Frage: wann die Umsatzsteuer entsteht.
- Warum sie ausgelöst wird
- Mappings setzen BT-7 aus dem Leistungsdatum und füllen BT-8 zusätzlich mit einem Standardwert, weil beide Felder im Zielschema vorhanden sind und keines von beiden als „entweder/oder“ gekennzeichnet ist.
- Wie Sie es beheben
- Entscheiden Sie sich für eines. Liegt ein konkretes Datum vor, senden Sie BT-7 (cbc:TaxPointDate in UBL, ram:TaxPointDate in CII) und lassen BT-8 weg; andernfalls nur den Code in BT-8 (cac:InvoicePeriod/cbc:DescriptionCode in UBL, ram:DueDateTypeCode in CII).
- Was der Validator prüft
UBL(exists(cbc:TaxPointDate) and not(cac:InvoicePeriod/cbc:DescriptionCode)) or (not(cbc:TaxPointDate) and exists(cac:InvoicePeriod/cbc:DescriptionCode)) or (not(cbc:TaxPointDate) and not(cac:InvoicePeriod/cbc:DescriptionCode))CII((//ram:TaxPointDate) and not(//ram:DueDateTypeCode)) or (not (//ram:TaxPointDate) and (//ram:DueDateTypeCode)) or (not (//ram:TaxPointDate) and not (//ram:DueDateTypeCode))
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cbc:TaxPointDate>2026-08-26</cbc:TaxPointDate> <cac:InvoicePeriod> <cbc:DescriptionCode>3</cbc:DescriptionCode> </cac:InvoicePeriod>Korrigiert <cbc:TaxPointDate>2026-08-26</cbc:TaxPointDate>BR-CO-04
Each Invoice line (BG-25) shall be categorized with an Invoiced item VAT category code (BT-151).
- Was die Regel verlangt
- Jede Rechnungsposition (BG-25) muss einen Umsatzsteuer-Kategoriecode (BT-151) tragen — S für den Regelsatz, E für steuerfrei, Z für den Nullsatz, AE für Reverse Charge und so weiter.
- Warum sie ausgelöst wird
- Der Code steht im Kopf der Rechnung, weil dort ohnehin die Steuerübersicht gebildet wird, und wird auf Positionsebene vergessen — besonders bei Rechnungen mit nur einem Steuersatz, wo er redundant wirkt.
- Wie Sie es beheben
- Setzen Sie BT-151 auf jeder Position: cac:InvoiceLine/cac:Item/cac:ClassifiedTaxCategory/cbc:ID in UBL, ram:ApplicableTradeTax/ram:CategoryCode auf Positionsebene in CII. Auch bei einheitlichem Steuersatz muss jede Position ihn nennen.
- Was der Validator prüft
UBL(cac:Item/cac:ClassifiedTaxCategory[cac:TaxScheme/(normalize-space(upper-case(cbc:ID))='VAT')]/cbc:ID)CII(ram:SpecifiedLineTradeSettlement/ram:ApplicableTradeTax[upper-case(ram:TypeCode) = 'VAT']/ram:CategoryCode)
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:LineExtensionAmount currencyID="EUR">1000.00</cbc:LineExtensionAmount> <cac:Item> <cbc:Name>Beratungsleistung</cbc:Name> </cac:Item> </cac:InvoiceLine>Korrigiert <cac:InvoiceLine> <cbc:ID>1</cbc:ID> <cbc:LineExtensionAmount currencyID="EUR">1000.00</cbc:LineExtensionAmount> <cac:Item> <cbc:Name>Beratungsleistung</cbc:Name> <cac:ClassifiedTaxCategory> <cbc:ID>S</cbc:ID> <cbc:Percent>19</cbc:Percent> <cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme> </cac:ClassifiedTaxCategory> </cac:Item> </cac:InvoiceLine>BR-CO-05
Document level allowance reason code (BT-98) and Document level allowance reason (BT-97) shall indicate the same type of allowance.greift nie
BR-CO-06
Document level charge reason code (BT-105) and Document level charge reason (BT-104) shall indicate the same type of charge.greift nie
BR-CO-07
Invoice line allowance reason code (BT-140) and Invoice line allowance reason (BT-139) shall indicate the same type of allowance reason.greift nie
BR-CO-08
Invoice line charge reason code (BT-145) and Invoice line charge reason (BT-144) shall indicate the same type of charge reason.greift nie
BR-CO-09
The Seller VAT identifier (BT-31), the Seller tax representative VAT identifier (BT-63) and the Buyer VAT identifier (BT-48) shall have a prefix in accordance with ISO code ISO 3166-1 alpha-2 by which the country of issue may be identified. Nevertheless, Greece may use the prefix ‘EL’.
UBL 252 · CII 252 zulässige Werte · nur in UBL: SS · nur in CII: AN
- Was die Regel verlangt
- Die Umsatzsteuer-Identifikationsnummern von Verkäufer (BT-31), Steuervertreter (BT-63) und Käufer (BT-48) müssen mit dem Länderkürzel nach ISO 3166-1 alpha-2 beginnen. Griechenland darf abweichend „EL“ verwenden.
- Warum sie ausgelöst wird
- Im Debitoren- und Kreditorenstamm steht die Nummer oft ohne Präfix, weil das Land in einem eigenen Feld gepflegt wird. Beim Mapping wird dann der reine Zahlenteil übernommen — „811234567“ statt „DE811234567“.
- Wie Sie es beheben
- Stellen Sie das Länderkürzel voran und entfernen Sie Leerzeichen: cac:PartyTaxScheme/cbc:CompanyID mit cac:TaxScheme/cbc:ID = VAT in UBL, ram:SpecifiedTaxRegistration/ram:ID mit schemeID="VA" in CII.
- Was der Validator prüft
UBL( contains( ' 1A AD AE AF AG AI AL AM AO AQ AR AS AT AU AW AX AZ BA BB BD BE BF BG BH BI BJ BL BM BN BO BQ BR BS BT BV BW BY BZ CA CC CD CF CG CH CI CK CL CM CN CO CR CU CV CW CX CY CZ DE DJ DK DM DO DZ EC EE EG EH EL ER ES ET FI FJ FK FM FO FR GA GB GD GE GF GG GH GI GL GM GN GP GQ GR GS GT GU GW GY HK HM HN HR HT HU ID IE IL IM IN IO IQ IR IS IT JE JM JO JP KE KG KH KI KM KN KP KR KW KY KZ LA LB LC LI LK LR LS LT LU LV LY MA MC MD ME MF MG MH MK ML MM MN MO MP MQ MR MS MT MU MV MW MX MY MZ NA NC NE NF NG NI NL NO NP NR NU NZ OM PA PE PF PG PH PK PL PM PN PR PS PT PW PY QA RE RO RS RU RW SA SB SC SD SE SG SH SI SJ SK SL SM SN SO SR SS ST SV SX SY SZ TC TD TF TG TH TJ TK TL TM TN TO TR TT TV TW TZ UA UG UM US UY UZ VA VC VE VG VI VN VU WF WS XI YE YT ZA ZM ZW ',substring(cbc:CompanyID,1,2) ) )CIIcontains(' 1A AD AE AF AG AI AL AM AN AO AQ AR AS AT AU AW AX AZ BA BB BD BE BF BG BH BI BL BJ BM BN BO BQ BR BS BT BV BW BY BZ CA CC CD CF CG CH CI CK CL CM CN CO CR CU CV CW CX CY CZ DE DJ DK DM DO DZ EC EE EG EH EL ER ES ET FI FJ FK FM FO FR GA GB GD GE GF GG GH GI GL GM GN GP GQ GR GS GT GU GW GY HK HM HN HR HT HU ID IE IL IM IN IO IQ IR IS IT JE JM JO JP KE KG KH KI KM KN KP KR KW KY KZ LA LB LC LI LK LR LS LT LU LV LY MA MC MD ME MF MG MH MK ML MM MN MO MP MQ MR MS MT MU MV MW MX MY MZ NA NC NE NF NG NI NL NO NP NR NU NZ OM PA PE PF PG PH PK PL PM PN PR PS PT PW PY QA RE RO RS RU RW SA SB SC SD SE SG SH SI SJ SK SL SM SN SO SR ST SV SX SY SZ TC TD TF TG TH TJ TK TL TM TN TO TR TT TV TW TZ UA UG UM US UY UZ VA VC VE VG VI VN VU WF WS XI YE YT ZA ZM ZW ', concat(' ', substring(.,1,2), ' '))
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:PartyTaxScheme> <cbc:CompanyID>811234567</cbc:CompanyID> <cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme> </cac:PartyTaxScheme>Korrigiert <cac:PartyTaxScheme> <cbc:CompanyID>DE811234567</cbc:CompanyID> <cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme> </cac:PartyTaxScheme>BR-CO-10
Sum of Invoice line net amount (BT-106) = Σ Invoice line net amount (BT-131).
- Was die Regel verlangt
- Die Summe der Positionsnettobeträge (BT-106) muss exakt der Summe aller einzelnen Positionsbeträge (BT-131) entsprechen.
- Warum sie ausgelöst wird
- Tritt auf, wenn Positionsbeträge einzeln gerundet und anschließend addiert werden, während die Gesamtsumme aus ungerundeten Werten berechnet wird. Beide Wege ergeben unterschiedliche Ergebnisse.
- Wie Sie es beheben
- Runden Sie jeden Positionsbetrag auf zwei Nachkommastellen und bilden Sie die Summe aus genau diesen gerundeten Werten — nicht aus den Rohwerten.
- Was der Validator prüft
UBL(xs:decimal(cbc:LineExtensionAmount) = xs:decimal(round(sum(//(cac:InvoiceLine|cac:CreditNoteLine)/xs:decimal(cbc:LineExtensionAmount)) * 10 * 10) div 100))CIIxs:decimal(ram:LineTotalAmount) = round(xs:decimal(sum(../../ram:IncludedSupplyChainTradeLineItem/ram:SpecifiedLineTradeSettlement/ram:SpecifiedTradeSettlementLineMonetarySummation/ram:LineTotalAmount)) * xs:decimal(100)) div xs:decimal(100)
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:LegalMonetaryTotal> <cbc:LineExtensionAmount currencyID="EUR">1000.00</cbc:LineExtensionAmount> </cac:LegalMonetaryTotal> <cac:InvoiceLine> <cbc:ID>1</cbc:ID> <cbc:LineExtensionAmount currencyID="EUR">333.34</cbc:LineExtensionAmount> </cac:InvoiceLine> <cac:InvoiceLine> <cbc:ID>2</cbc:ID> <cbc:LineExtensionAmount currencyID="EUR">666.67</cbc:LineExtensionAmount> </cac:InvoiceLine>Korrigiert <cac:LegalMonetaryTotal> <cbc:LineExtensionAmount currencyID="EUR">1000.01</cbc:LineExtensionAmount> </cac:LegalMonetaryTotal> <cac:InvoiceLine> <cbc:ID>1</cbc:ID> <cbc:LineExtensionAmount currencyID="EUR">333.34</cbc:LineExtensionAmount> </cac:InvoiceLine> <cac:InvoiceLine> <cbc:ID>2</cbc:ID> <cbc:LineExtensionAmount currencyID="EUR">666.67</cbc:LineExtensionAmount> </cac:InvoiceLine>BR-CO-11
Sum of allowances on document level (BT-107) = Σ Document level allowance amount (BT-92).
- Was die Regel verlangt
- Die Summe der Abschläge auf Dokumentebene (BT-107) muss exakt der Summe der einzelnen Abschlagsbeträge (BT-92) entsprechen.
- Warum sie ausgelöst wird
- Der Summenwert wird aus dem eigenen Rechnungsobjekt übernommen, die Einzelabschläge aber gefiltert geschrieben — etwa weil ein Abschlag mit Betrag 0 übersprungen oder ein Rabatt zusätzlich in die Position gerechnet wurde.
- Wie Sie es beheben
- Bilden Sie BT-107 aus genau den Abschlägen, die auch im Dokument stehen: cbc:AllowanceTotalAmount in cac:LegalMonetaryTotal als Summe aller cac:AllowanceCharge mit cbc:ChargeIndicator false (UBL), ram:AllowanceTotalAmount in CII.
- Was der Validator prüft
UBLxs:decimal(cbc:AllowanceTotalAmount) = (round(sum(../cac:AllowanceCharge[cbc:ChargeIndicator=false()]/xs:decimal(cbc:Amount)) * 10 * 10) div 100) or (not(cbc:AllowanceTotalAmount) and not(../cac:AllowanceCharge[cbc:ChargeIndicator=false()]))CII(not(/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeAllowanceCharge[ram:ChargeIndicator/udt:Indicator=false()])and not (ram:AllowanceTotalAmount)) or ram:AllowanceTotalAmount = (round(sum(/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeAllowanceCharge[ram:ChargeIndicator/udt:Indicator=false()]/ram:ActualAmount[1])* 10 * 10 ) div 100)
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">30.00</cbc:Amount> </cac:AllowanceCharge> <cac:AllowanceCharge> <cbc:ChargeIndicator>false</cbc:ChargeIndicator> <cbc:Amount currencyID="EUR">30.00</cbc:Amount> </cac:AllowanceCharge> <cac:LegalMonetaryTotal> <cbc:AllowanceTotalAmount currencyID="EUR">50.00</cbc:AllowanceTotalAmount> </cac:LegalMonetaryTotal>Korrigiert <cac:AllowanceCharge> <cbc:ChargeIndicator>false</cbc:ChargeIndicator> <cbc:Amount currencyID="EUR">30.00</cbc:Amount> </cac:AllowanceCharge> <cac:AllowanceCharge> <cbc:ChargeIndicator>false</cbc:ChargeIndicator> <cbc:Amount currencyID="EUR">30.00</cbc:Amount> </cac:AllowanceCharge> <cac:LegalMonetaryTotal> <cbc:AllowanceTotalAmount currencyID="EUR">60.00</cbc:AllowanceTotalAmount> </cac:LegalMonetaryTotal>BR-CO-12
Summe der Zuschläge (BT-108) stimmt nicht
Sum of charges on document level (BT-108) = Σ Document level charge amount (BT-99).
- Was die Regel verlangt
- Die Summe der Zuschläge auf Dokumentebene (BT-108) muss exakt der Summe der einzelnen Zuschlagsbeträge (BT-99) entsprechen — das Gegenstück zu BR-CO-11.
- Warum sie ausgelöst wird
- Wie bei BR-CO-11, nur auf der Zuschlagsseite: BT-108 stammt aus dem eigenen Rechnungsobjekt, die einzelnen Zuschläge werden gefiltert geschrieben. Ein häufiger Sonderfall ist ein Zuschlag, der versehentlich mit cbc:ChargeIndicator false im Dokument steht — er zählt dann als Abschlag und fällt aus der Summe, die ihn noch enthält.
- Wie Sie es beheben
- Summieren Sie BT-108 aus allen cac:AllowanceCharge mit cbc:ChargeIndicator true und schreiben Sie das Ergebnis nach cbc:ChargeTotalAmount (UBL) beziehungsweise ram:ChargeTotalAmount (CII). Ein Zuschlag gehört entweder in die Position oder auf Dokumentebene, nie in beide.
- Was der Validator prüft
UBLxs:decimal(cbc:ChargeTotalAmount) = (round(sum(../cac:AllowanceCharge[cbc:ChargeIndicator=true()]/xs:decimal(cbc:Amount)) * 10 * 10) div 100) or (not(cbc:ChargeTotalAmount) and not(../cac:AllowanceCharge[cbc:ChargeIndicator=true()]))CII(not(/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeAllowanceCharge[ram:ChargeIndicator/udt:Indicator=true()])and not (ram:ChargeTotalAmount)) or ram:ChargeTotalAmount = (round(sum(/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeAllowanceCharge[ram:ChargeIndicator/udt:Indicator=true()]/ram:ActualAmount[1])* 10 * 10 ) div 100)
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:AllowanceCharge> <cbc:ChargeIndicator>true</cbc:ChargeIndicator> <cbc:Amount currencyID="EUR">20.00</cbc:Amount> </cac:AllowanceCharge> <cac:LegalMonetaryTotal> <cbc:ChargeTotalAmount currencyID="EUR">35.00</cbc:ChargeTotalAmount> </cac:LegalMonetaryTotal>Korrigiert <cac:AllowanceCharge> <cbc:ChargeIndicator>true</cbc:ChargeIndicator> <cbc:Amount currencyID="EUR">20.00</cbc:Amount> </cac:AllowanceCharge> <cac:LegalMonetaryTotal> <cbc:ChargeTotalAmount currencyID="EUR">20.00</cbc:ChargeTotalAmount> </cac:LegalMonetaryTotal>BR-CO-13
Invoice total amount without VAT (BT-109) = Σ Invoice line net amount (BT-131) - Sum of allowances on document level (BT-107) + Sum of charges on document level (BT-108).
- Was die Regel verlangt
- Der Gesamtbetrag ohne Umsatzsteuer (BT-109) muss der Summe aller Positionsnettobeträge (BT-131) abzüglich der Abschläge (BT-107) zuzüglich der Zuschläge (BT-108) auf Dokumentenebene entsprechen.
- Warum sie ausgelöst wird
- Meist werden Abschläge oder Zuschläge auf Dokumentenebene zwar ausgewiesen, aber beim Berechnen von BT-109 vergessen — oder sie stecken bereits in den Positionspreisen und werden dann doppelt abgezogen.
- Wie Sie es beheben
- Berechnen Sie BT-109 strikt nach der Formel Σ BT-131 − BT-107 + BT-108 aus genau den Werten, die im Dokument stehen. Ein Rabatt gehört entweder in die Position oder auf Dokumentenebene — nie in beide.
- Was der Validator prüft
UBL((cbc:ChargeTotalAmount) and (cbc:AllowanceTotalAmount) and (xs:decimal(cbc:TaxExclusiveAmount) = round((xs:decimal(cbc:LineExtensionAmount) + xs:decimal(cbc:ChargeTotalAmount) - xs:decimal(cbc:AllowanceTotalAmount)) * 10 * 10) div 100 )) or (not(cbc:ChargeTotalAmount) and (cbc:AllowanceTotalAmount) and (xs:decimal(cbc:TaxExclusiveAmount) = round((xs:decimal(cbc:LineExtensionAmount) - xs:decimal(cbc:AllowanceTotalAmount)) * 10 * 10 ) div 100)) or ((cbc:ChargeTotalAmount) and not(cbc:AllowanceTotalAmount) and (xs:decimal(cbc:TaxExclusiveAmount) = round((xs:decimal(cbc:LineExtensionAmount) + xs:decimal(cbc:ChargeTotalAmount)) * 10 * 10 ) div 100)) or (not(cbc:ChargeTotalAmount) and not(cbc:AllowanceTotalAmount) and (xs:decimal(cbc:TaxExclusiveAmount) = xs:decimal(cbc:LineExtensionAmount)))CII(xs:decimal(ram:TaxBasisTotalAmount[1]) = round((xs:decimal(ram:LineTotalAmount[1]) - xs:decimal(ram:AllowanceTotalAmount[1]) + xs:decimal(ram:ChargeTotalAmount[1])) * 10 * 10) div 100) or ((xs:decimal(ram:TaxBasisTotalAmount[1]) = round((xs:decimal(ram:LineTotalAmount[1]) - xs:decimal(ram:AllowanceTotalAmount[1])) * 10 * 10) div 100) and not(ram:ChargeTotalAmount)) or ((xs:decimal(ram:TaxBasisTotalAmount[1]) = round((xs:decimal(ram:LineTotalAmount[1]) + xs:decimal(ram:ChargeTotalAmount[1])) * 10 * 10) div 100) and not(ram:AllowanceTotalAmount)) or ((xs:decimal(ram:TaxBasisTotalAmount[1]) = round((xs:decimal(ram:LineTotalAmount[1])) * 10 * 10) div 100) and not(ram:ChargeTotalAmount) and not(ram:AllowanceTotalAmount))
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:LegalMonetaryTotal> <cbc:LineExtensionAmount currencyID="EUR">1000.00</cbc:LineExtensionAmount> <cbc:TaxExclusiveAmount currencyID="EUR">1000.00</cbc:TaxExclusiveAmount> <cbc:AllowanceTotalAmount currencyID="EUR">50.00</cbc:AllowanceTotalAmount> <cbc:ChargeTotalAmount currencyID="EUR">20.00</cbc:ChargeTotalAmount> </cac:LegalMonetaryTotal>Korrigiert <cac:LegalMonetaryTotal> <cbc:LineExtensionAmount currencyID="EUR">1000.00</cbc:LineExtensionAmount> <cbc:TaxExclusiveAmount currencyID="EUR">970.00</cbc:TaxExclusiveAmount> <cbc:AllowanceTotalAmount currencyID="EUR">50.00</cbc:AllowanceTotalAmount> <cbc:ChargeTotalAmount currencyID="EUR">20.00</cbc:ChargeTotalAmount> </cac:LegalMonetaryTotal>BR-CO-14
Invoice total VAT amount (BT-110) = Σ VAT category tax amount (BT-117).
- Was die Regel verlangt
- Der Gesamtsteuerbetrag der Rechnung (BT-110) muss der Summe der Steuerbeträge aller Steuerkategorien (BT-117) entsprechen.
- Warum sie ausgelöst wird
- Klassisch, wenn BT-110 aus den einzeln gerundeten Positionssteuern berechnet wird, die Kategoriebeträge aber aus den Bemessungsgrundlagen — beide Wege weichen um Rundungsdifferenzen voneinander ab.
- Wie Sie es beheben
- Berechnen Sie zuerst je Kategorie BT-117 aus der Bemessungsgrundlage und bilden Sie BT-110 als exakte Summe genau dieser Kategoriebeträge — nicht als eigene, unabhängige Rechnung.
- Was der Validator prüft
UBL(xs:decimal(child::cbc:TaxAmount)= round((sum(cac:TaxSubtotal/xs:decimal(cbc:TaxAmount)) * 10 * 10)) div 100) or not(cac:TaxSubtotal)CII. = (round(sum(/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:ApplicableTradeTax/ram:CalculatedAmount)*10*10)div 100)
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: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>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>BR-CO-15
Invoice total amount with VAT (BT-112) = Invoice total amount without VAT (BT-109) + Invoice total VAT amount (BT-110).
- Was die Regel verlangt
- Der Gesamtbetrag mit Umsatzsteuer (BT-112) muss exakt der Summe aus Gesamtbetrag ohne Umsatzsteuer (BT-109) und Gesamtsteuerbetrag (BT-110) entsprechen.
- Warum sie ausgelöst wird
- Häufig wird BT-112 aus dem internen System übernommen, während BT-109 und BT-110 neu berechnet werden — schon ein Cent Rundungsdifferenz zwischen beiden Welten löst den Fehler aus.
- Wie Sie es beheben
- Leiten Sie BT-112 immer als BT-109 + BT-110 aus den beiden Dokumentwerten ab, statt einen unabhängig berechneten Bruttobetrag einzutragen. Dezimalarithmetik verwenden, nie float.
- Was der Validator prüft
UBLevery $Currency in cbc:DocumentCurrencyCode satisfies (count(cac:TaxTotal/xs:decimal(cbc:TaxAmount[@currencyID=$Currency])) eq 1) and (cac:LegalMonetaryTotal/xs:decimal(cbc:TaxInclusiveAmount) = round( (cac:LegalMonetaryTotal/xs:decimal(cbc:TaxExclusiveAmount) + cac:TaxTotal/xs:decimal(cbc:TaxAmount[@currencyID=$Currency])) * 10 * 10) div 100)CIIevery $Currency in /rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:InvoiceCurrencyCode satisfies ( ( count(/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeSettlementHeaderMonetarySummation/ram:TaxTotalAmount[@currencyID = $Currency]) = 1 and xs:decimal((/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeSettlementHeaderMonetarySummation/ram:GrandTotalAmount)[1]) = round( ( xs:decimal((/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeSettlementHeaderMonetarySummation/ram:TaxBasisTotalAmount)[1]) + xs:decimal((/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeSettlementHeaderMonetarySummation/ram:TaxTotalAmount[@currencyID = $Currency])[1]) ) * 100 ) div 100 ) or ( xs:decimal((/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeSettlementHeaderMonetarySummation/ram:GrandTotalAmount)[1]) = xs:decimal((/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeSettlementHeaderMonetarySummation/ram:TaxBasisTotalAmount)[1]) ) )
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:LegalMonetaryTotal> <cbc:TaxExclusiveAmount currencyID="EUR">1000.00</cbc:TaxExclusiveAmount> <cbc:TaxInclusiveAmount currencyID="EUR">1189.99</cbc:TaxInclusiveAmount> </cac:LegalMonetaryTotal>Korrigiert <cac:LegalMonetaryTotal> <cbc:TaxExclusiveAmount currencyID="EUR">1000.00</cbc:TaxExclusiveAmount> <cbc:TaxInclusiveAmount currencyID="EUR">1190.00</cbc:TaxInclusiveAmount> </cac:LegalMonetaryTotal>BR-CO-16
Zahlbetrag (BT-115) geht nicht auf
Amount due for payment (BT-115) = Invoice total amount with VAT (BT-112) -Paid amount (BT-113) +Rounding amount (BT-114).
- Was die Regel verlangt
- Der Zahlbetrag (BT-115) muss rechnerisch aufgehen: Bruttobetrag (BT-112) minus bereits gezahlter Betrag (BT-113) plus Rundungsbetrag (BT-114).
- Warum sie ausgelöst wird
- Der Ausdruck prüft vier Fälle, je nachdem ob ein Anzahlungsbetrag (BT-113) und ein Rundungsbetrag (BT-114) im Dokument stehen. Ohne beide bleibt schlicht BT-115 = BT-112 übrig — wer dort danebenliegt, hat den Zahlbetrag unabhängig berechnet statt ihn abzuleiten. Erst mit Anzahlung wird gerundet, und dort ist der klassische Gleitkommafehler die häufigste Ursache: ein Cent Abweichung, sichtbar erst in der Prüfung.
- Wie Sie es beheben
- Rechnen Sie Beträge durchgängig mit Dezimalarithmetik, nicht mit float oder double, und runden Sie erst bei der Ausgabe auf zwei Nachkommastellen. Prüfen Sie außerdem, ob ein Anzahlungsbetrag (BT-113) gesetzt ist, den Ihre Berechnung nicht berücksichtigt.
- Was der Validator prüft
UBL(exists(cbc:PrepaidAmount) and not(exists(cbc:PayableRoundingAmount)) and (xs:decimal(cbc:PayableAmount) = (round((xs:decimal(cbc:TaxInclusiveAmount) - xs:decimal(cbc:PrepaidAmount)) * 10 * 10) div 100))) or (not(exists(cbc:PrepaidAmount)) and not(exists(cbc:PayableRoundingAmount)) and xs:decimal(cbc:PayableAmount) = xs:decimal(cbc:TaxInclusiveAmount)) or (exists(cbc:PrepaidAmount) and exists(cbc:PayableRoundingAmount) and ((round((xs:decimal(cbc:PayableAmount) - xs:decimal(cbc:PayableRoundingAmount)) * 10 * 10) div 100) = (round((xs:decimal(cbc:TaxInclusiveAmount) - xs:decimal(cbc:PrepaidAmount)) * 10 * 10) div 100))) or (not(exists(cbc:PrepaidAmount)) and exists(cbc:PayableRoundingAmount) and ((round((xs:decimal(cbc:PayableAmount) - xs:decimal(cbc:PayableRoundingAmount)) * 10 * 10) div 100) = xs:decimal(cbc:TaxInclusiveAmount)))CII(xs:decimal(ram:DuePayableAmount[1]) = xs:decimal(ram:GrandTotalAmount[1]) - xs:decimal(ram:TotalPrepaidAmount[1]) + xs:decimal(ram:RoundingAmount[1])) or ((xs:decimal(ram:DuePayableAmount[1]) = xs:decimal(ram:GrandTotalAmount[1]) + xs:decimal(ram:RoundingAmount[1])) and not(ram:TotalPrepaidAmount)) or ((xs:decimal(ram:DuePayableAmount[1]) = xs:decimal(ram:GrandTotalAmount[1]) - xs:decimal(ram:TotalPrepaidAmount[1])) and not(ram:RoundingAmount)) or ((xs:decimal(ram:DuePayableAmount[1]) = xs:decimal(ram:GrandTotalAmount[1])) and not(ram:TotalPrepaidAmount) and not(ram:RoundingAmount))
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:LegalMonetaryTotal> <cbc:TaxInclusiveAmount currencyID="EUR">1190.00</cbc:TaxInclusiveAmount> <cbc:PrepaidAmount currencyID="EUR">200.00</cbc:PrepaidAmount> <cbc:PayableAmount currencyID="EUR">1190.00</cbc:PayableAmount> </cac:LegalMonetaryTotal>Korrigiert <cac:LegalMonetaryTotal> <cbc:TaxInclusiveAmount currencyID="EUR">1190.00</cbc:TaxInclusiveAmount> <cbc:PrepaidAmount currencyID="EUR">200.00</cbc:PrepaidAmount> <cbc:PayableAmount currencyID="EUR">990.00</cbc:PayableAmount> </cac:LegalMonetaryTotal>BR-CO-17
Steuerbetrag (BT-117) passt nicht zum Satz
VAT category tax amount (BT-117) = VAT category taxable amount (BT-116) x (VAT category rate (BT-119) / 100), rounded to two decimals.±1 Toleranz
- Was die Regel verlangt
- Je Steuerkategorie muss der Steuerbetrag (BT-117) der Bemessungsgrundlage (BT-116) multipliziert mit dem Steuersatz (BT-119) entsprechen — mit einer Toleranz von einer ganzen Einheit der Währung nach oben und unten. Das steht so nicht im Regeltext, aber im Ausdruck, den der Prüfer auswertet: er vergleicht mit „− 1 <“ und „+ 1 >“, nicht auf den Cent.
- Warum sie ausgelöst wird
- Weil die Toleranz einen Euro beträgt, ist ein Rundungsfehler von ein paar Cent gerade nicht die Ursache — der meldet BR-CO-14 und BR-CO-15, die exakt prüfen. BR-CO-17 schlägt an, wenn etwas Größeres schiefgegangen ist: der falsche Steuersatz auf die Bemessungsgrundlage angewendet, eine Kategorie mit dem Satz einer anderen gerechnet, oder eine Position, die in der Aufschlüsselung in der falschen Kategorie gelandet ist. Bei einem Steuersatz von 0 greift ein anderer Zweig des Ausdrucks: dort verlangt er nur, dass der Steuerbetrag gerundet 0 ergibt. Für steuerfreie, innergemeinschaftliche und Reverse-Charge-Kategorien ist BR-CO-17 also eine Nullprüfung, keine Multiplikation.
- Wie Sie es beheben
- Gruppieren Sie die Positionen nach Steuerkategorie, summieren Sie die Nettobeträge zur Bemessungsgrundlage BT-116 und berechnen Sie die Steuer einmal daraus: BT-116 × BT-119 / 100. Prüfen Sie dabei zuerst, ob der Satz zur Kategorie passt — bei einer Abweichung in dieser Größenordnung stimmt fast immer der Satz nicht, nicht die Rundung. Bei den Kategorien mit Regelsatz meldet sich BR-S-09 gemeinsam mit dieser Regel.
- Was der Validator prüft
UBL(round(cac:TaxCategory[cac:TaxScheme/normalize-space(upper-case(cbc:ID))='VAT']/xs:decimal(cbc:Percent)) = 0 and (round(xs:decimal(cbc:TaxAmount)) = 0)) or (round(cac:TaxCategory[cac:TaxScheme/normalize-space(upper-case(cbc:ID))='VAT']/xs:decimal(cbc:Percent)) != 0 and ((abs(xs:decimal(cbc:TaxAmount)) - 1 < round(abs(xs:decimal(cbc:TaxableAmount)) * (cac:TaxCategory[cac:TaxScheme/normalize-space(upper-case(cbc:ID))='VAT']/xs:decimal(cbc:Percent) div 100) * 10 * 10) div 100 ) and (abs(xs:decimal(cbc:TaxAmount)) + 1 > round(abs(xs:decimal(cbc:TaxableAmount)) * (cac:TaxCategory[cac:TaxScheme/normalize-space(upper-case(cbc:ID))='VAT']/xs:decimal(cbc:Percent) div 100) * 10 * 10) div 100 ))) or (not(exists(cac:TaxCategory[cac:TaxScheme/normalize-space(upper-case(cbc:ID))='VAT']/xs:decimal(cbc:Percent))) and (round(xs:decimal(cbc:TaxAmount)) = 0))CII(round(.[normalize-space(upper-case(ram:TypeCode)) = 'VAT']/xs:decimal(ram:RateApplicablePercent)) = 0 and (round(xs:decimal(ram:CalculatedAmount)) = 0)) or (round(.[normalize-space(upper-case(ram:TypeCode)) = 'VAT']/xs:decimal(ram:RateApplicablePercent)) != 0 and ((abs(xs:decimal(ram:CalculatedAmount)) - 1 <= round(abs(xs:decimal(ram:BasisAmount)) * (.[normalize-space(upper-case(ram:TypeCode)) = 'VAT']/xs:decimal(ram:RateApplicablePercent) div 100) * 10 * 10) div 100 ) and (abs(xs:decimal(ram:CalculatedAmount)) + 1 >= round(abs(xs:decimal(ram:BasisAmount)) * (.[normalize-space(upper-case(ram:TypeCode)) = 'VAT']/xs:decimal(ram:RateApplicablePercent) div 100) * 10 * 10) div 100 ))) or (not(exists(.[normalize-space(upper-case(ram:TypeCode))='VAT']/xs:decimal(ram:RateApplicablePercent))) and (round(xs:decimal(ram:CalculatedAmount)) = 0))
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:TaxSubtotal> <cbc:TaxableAmount currencyID="EUR">1000.00</cbc:TaxableAmount> <cbc:TaxAmount currencyID="EUR">70.00</cbc:TaxAmount> <cac:TaxCategory> <cbc:ID>S</cbc:ID> <cbc:Percent>19</cbc:Percent> <cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme> </cac:TaxCategory> </cac:TaxSubtotal>Korrigiert <cac:TaxSubtotal> <cbc:TaxableAmount currencyID="EUR">1000.00</cbc:TaxableAmount> <cbc:TaxAmount currencyID="EUR">190.00</cbc:TaxAmount> <cac:TaxCategory> <cbc:ID>S</cbc:ID> <cbc:Percent>19</cbc:Percent> <cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme> </cac:TaxCategory> </cac:TaxSubtotal>BR-CO-18
An Invoice shall at least have one VAT breakdown group (BG-23).
- Was die Regel verlangt
- Die Rechnung muss mindestens eine Umsatzsteuer-Aufschlüsselung (BG-23) enthalten — je Steuerkategorie einen Block mit Nettobetrag, Steuerbetrag, Kategorie und Satz.
- Warum sie ausgelöst wird
- Bei steuerfreien Rechnungen wirkt der Block überflüssig und wird weggelassen. Die Regel verlangt ihn trotzdem: „keine Steuer“ ist selbst eine Aussage, und sie gehört aufgeschlüsselt.
- Wie Sie es beheben
- Schreiben Sie je Steuerkategorie ein cac:TaxTotal/cac:TaxSubtotal (UBL) beziehungsweise ein ram:ApplicableTradeTax (CII) — auch für E oder Z, dort mit Steuerbetrag 0 und dem Befreiungsgrund.
- Was der Validator prüft
UBLexists(cac:TaxTotal/cac:TaxSubtotal)CII//rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:ApplicableTradeTax
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:LegalMonetaryTotal> <cbc:TaxExclusiveAmount currencyID="EUR">1000.00</cbc:TaxExclusiveAmount> <cbc:TaxInclusiveAmount currencyID="EUR">1000.00</cbc:TaxInclusiveAmount> </cac:LegalMonetaryTotal>Korrigiert <cac:TaxTotal> <cbc:TaxAmount currencyID="EUR">0.00</cbc:TaxAmount> <cac:TaxSubtotal> <cbc:TaxableAmount currencyID="EUR">1000.00</cbc:TaxableAmount> <cbc:TaxAmount currencyID="EUR">0.00</cbc:TaxAmount> <cac:TaxCategory> <cbc:ID>E</cbc:ID> <cbc:Percent>0</cbc:Percent> <cbc:TaxExemptionReason>Kleinunternehmer nach § 19 UStG</cbc:TaxExemptionReason> <cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme> </cac:TaxCategory> </cac:TaxSubtotal> </cac:TaxTotal> <cac:LegalMonetaryTotal> <cbc:TaxExclusiveAmount currencyID="EUR">1000.00</cbc:TaxExclusiveAmount> <cbc:TaxInclusiveAmount currencyID="EUR">1000.00</cbc:TaxInclusiveAmount> </cac:LegalMonetaryTotal>BR-CO-19
If Invoicing period (BG-14) is used, the Invoicing period start date (BT-73) or the Invoicing period end date (BT-74) shall be filled, or both.
- Was die Regel verlangt
- Wird ein Abrechnungszeitraum (BG-14) übermittelt, muss mindestens ein Datum darin stehen: Beginn (BT-73), Ende (BT-74) oder beides. Ein leerer Zeitraum ist keine Angabe.
- Warum sie ausgelöst wird
- Die Gruppe wird im Mapping bedingungslos angelegt und erst danach befüllt. Fehlen beide Daten im Quellsystem — etwa bei einer einmaligen Leistung —, bleibt eine leere Hülle im Dokument stehen.
- Wie Sie es beheben
- Legen Sie die Gruppe nur an, wenn wenigstens ein Datum vorliegt: cac:InvoicePeriod mit cbc:StartDate und/oder cbc:EndDate in UBL, ram:BillingSpecifiedPeriod mit ram:StartDateTime und/oder ram:EndDateTime in CII.
- Was der Validator prüft
UBLexists(cbc:StartDate) or exists(cbc:EndDate) or (exists(cbc:DescriptionCode) and not(exists(cbc:StartDate)) and not(exists(cbc:EndDate)))CII(ram:StartDateTime) or (ram:EndDateTime)
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cbc:BuyerReference>04011000-12345-03</cbc:BuyerReference> <cac:InvoicePeriod/>Korrigiert <cbc:BuyerReference>04011000-12345-03</cbc:BuyerReference> <cac:InvoicePeriod> <cbc:StartDate>2026-08-01</cbc:StartDate> <cbc:EndDate>2026-08-31</cbc:EndDate> </cac:InvoicePeriod>BR-CO-20
If Invoice line period (BG-26) is used, the Invoice line period start date (BT-134) or the Invoice line period end date (BT-135) shall be filled, or both.
- Was die Regel verlangt
- Wird auf einer Position ein Leistungszeitraum (BG-26) übermittelt, muss mindestens ein Datum darin stehen: Beginn (BT-134), Ende (BT-135) oder beides. Das Gegenstück zu BR-CO-19 auf Positionsebene.
- Warum sie ausgelöst wird
- Derselbe Fehler wie im Kopf, nur häufiger: Positionen werden in einer Schleife erzeugt, und die Zeitraum-Gruppe wird für jede Position angelegt, obwohl nur manche davon einen Zeitraum haben.
- Wie Sie es beheben
- Erzeugen Sie cac:InvoicePeriod innerhalb der cac:InvoiceLine nur dann, wenn ein Datum vorliegt — in CII entsprechend ram:BillingSpecifiedPeriod innerhalb der Position.
- Was der Validator prüft
UBLexists(cbc:StartDate) or exists(cbc:EndDate)CII(ram:StartDateTime) or (ram:EndDateTime)
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:LineExtensionAmount currencyID="EUR">1000.00</cbc:LineExtensionAmount> <cac:InvoicePeriod/> </cac:InvoiceLine>Korrigiert <cac:InvoiceLine> <cbc:ID>1</cbc:ID> <cbc:LineExtensionAmount currencyID="EUR">1000.00</cbc:LineExtensionAmount> <cac:InvoicePeriod> <cbc:StartDate>2026-08-01</cbc:StartDate> <cbc:EndDate>2026-08-31</cbc:EndDate> </cac:InvoicePeriod> </cac:InvoiceLine>BR-CO-21
Each Document level allowance (BG-20) shall contain a Document level allowance reason (BT-97) or a Document level allowance reason code (BT-98), or both.
- Was die Regel verlangt
- Jeder Abschlag auf Dokumentebene (BG-20) muss begründet sein — im Klartext (BT-97), als Code (BT-98) oder beides. Ein Betrag ohne Grund ist für den Empfänger nicht prüfbar.
- Warum sie ausgelöst wird
- Der Betrag steht im Rechnungsobjekt, der Grund nur in der PDF-Darstellung. Im strukturierten Datensatz bleibt dann eine Zeile über 50,00 € Abzug ohne jede Erklärung übrig.
- Wie Sie es beheben
- Geben Sie mindestens eines der beiden an: cbc:AllowanceChargeReason oder cbc:AllowanceChargeReasonCode im cac:AllowanceCharge (UBL), ram:Reason oder ram:ReasonCode im ram:SpecifiedTradeAllowanceCharge (CII).
- Was der Validator prüft
UBLexists(cbc:AllowanceChargeReason) or exists(cbc:AllowanceChargeReasonCode)CII(../ram:Reason) or (../ram:ReasonCode)
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">50.00</cbc:Amount> </cac:AllowanceCharge>Korrigiert <cac:AllowanceCharge> <cbc:ChargeIndicator>false</cbc:ChargeIndicator> <cbc:AllowanceChargeReason>Mengenrabatt</cbc:AllowanceChargeReason> <cbc:Amount currencyID="EUR">50.00</cbc:Amount> </cac:AllowanceCharge>BR-CO-22
Each Document level charge (BG-21) shall contain a Document level charge reason (BT-104) or a Document level charge reason code (BT-105), or both.
- Was die Regel verlangt
- Jeder Zuschlag auf Dokumentebene (BG-21) muss einen Grund tragen — im Klartext (BT-104), als Code (BT-105) oder beides.
- Warum sie ausgelöst wird
- Zuschläge entstehen oft erst spät im Prozess, etwa aus dem Versanddienstleister, und werden als reiner Betrag durchgereicht. Beim Empfänger landet ein Aufschlag, den niemand zuordnen kann, und Rechnungen mit unerklärten Aufschlägen bleiben liegen.
- Wie Sie es beheben
- Ergänzen Sie cbc:AllowanceChargeReason oder cbc:AllowanceChargeReasonCode im cac:AllowanceCharge mit cbc:ChargeIndicator true (UBL) beziehungsweise ram:Reason oder ram:ReasonCode im ram:SpecifiedTradeAllowanceCharge (CII).
- Was der Validator prüft
UBLexists(cbc:AllowanceChargeReason) or exists(cbc:AllowanceChargeReasonCode)CII(../ram:Reason) or (../ram:ReasonCode)
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:AllowanceCharge> <cbc:ChargeIndicator>true</cbc:ChargeIndicator> <cbc:Amount currencyID="EUR">20.00</cbc:Amount> </cac:AllowanceCharge>Korrigiert <cac:AllowanceCharge> <cbc:ChargeIndicator>true</cbc:ChargeIndicator> <cbc:AllowanceChargeReason>Frachtkosten</cbc:AllowanceChargeReason> <cbc:Amount currencyID="EUR">20.00</cbc:Amount> </cac:AllowanceCharge>BR-CO-23
Each Invoice line allowance (BG-27) shall contain an Invoice line allowance reason (BT-139) or an Invoice line allowance reason code (BT-140), or both.
- Was die Regel verlangt
- Jeder Abschlag auf einer Rechnungsposition (BG-27) muss begründet sein — im Klartext (BT-139), als Code (BT-140) oder beides.
- Warum sie ausgelöst wird
- Positionsrabatte kommen aus der Preisfindung und tragen dort selten mehr als einen Prozentsatz. Der Grund existiert im Quellsystem oft gar nicht und kann deshalb auch nicht gemappt werden.
- Wie Sie es beheben
- Übernehmen Sie die Rabattart aus der Preisfindung, oder setzen Sie einen zutreffenden Standardgrund. Geschrieben wird cbc:AllowanceChargeReason beziehungsweise cbc:AllowanceChargeReasonCode im cac:AllowanceCharge der Position (UBL), ram:Reason oder ram:ReasonCode in CII.
- Was der Validator prüft
UBLexists(cbc:AllowanceChargeReason) or exists(cbc:AllowanceChargeReasonCode)CII(../ram:Reason) or (../ram:ReasonCode)
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:AllowanceCharge> <cbc:ChargeIndicator>false</cbc:ChargeIndicator> <cbc:Amount currencyID="EUR">10.00</cbc:Amount> </cac:AllowanceCharge> </cac:InvoiceLine>Korrigiert <cac:InvoiceLine> <cbc:ID>1</cbc:ID> <cac:AllowanceCharge> <cbc:ChargeIndicator>false</cbc:ChargeIndicator> <cbc:AllowanceChargeReason>Rabatt</cbc:AllowanceChargeReason> <cbc:Amount currencyID="EUR">10.00</cbc:Amount> </cac:AllowanceCharge> </cac:InvoiceLine>BR-CO-24
Each Invoice line charge (BG-28) shall contain an Invoice line charge reason (BT-144) or an Invoice line charge reason code (BT-145), or both.
- Was die Regel verlangt
- Jeder Zuschlag auf einer Rechnungsposition (BG-28) muss einen Grund tragen — im Klartext (BT-144), als Code (BT-145) oder beides.
- Warum sie ausgelöst wird
- Der seltenste der vier Fälle, und deshalb der, für den im Mapping am ehesten gar kein Feld vorgesehen wurde: der Betrag wird durchgereicht, weil er in der Summe gebraucht wird, der Grund fällt weg.
- Wie Sie es beheben
- Schreiben Sie cbc:AllowanceChargeReason oder cbc:AllowanceChargeReasonCode in das cac:AllowanceCharge der Position mit cbc:ChargeIndicator true (UBL) beziehungsweise ram:Reason oder ram:ReasonCode in das ram:SpecifiedTradeAllowanceCharge der Position (CII).
- Was der Validator prüft
UBLexists(cbc:AllowanceChargeReason) or exists(cbc:AllowanceChargeReasonCode)CII(../ram:Reason) or (../ram:ReasonCode)
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:AllowanceCharge> <cbc:ChargeIndicator>true</cbc:ChargeIndicator> <cbc:Amount currencyID="EUR">25.00</cbc:Amount> </cac:AllowanceCharge> </cac:InvoiceLine>Korrigiert <cac:InvoiceLine> <cbc:ID>1</cbc:ID> <cac:AllowanceCharge> <cbc:ChargeIndicator>true</cbc:ChargeIndicator> <cbc:AllowanceChargeReason>Montage</cbc:AllowanceChargeReason> <cbc:Amount currencyID="EUR">25.00</cbc:Amount> </cac:AllowanceCharge> </cac:InvoiceLine>BR-CO-26
In order for the buyer to automatically identify a supplier, the Seller identifier (BT-29), the Seller legal registration identifier (BT-30) and/or the Seller VAT identifier (BT-31) shall be present.
- Was die Regel verlangt
- Damit der Käufer den Lieferanten automatisch zuordnen kann, muss mindestens eine Kennung des Verkäufers vorhanden sein: eine Verkäuferkennung (BT-29), die Registernummer (BT-30) oder die Umsatzsteuer-Identifikationsnummer (BT-31).
- Warum sie ausgelöst wird
- Der Verkäufer wird mit Name und Anschrift übermittelt, weil das für den Menschen genügt. Für den automatischen Abgleich im Kreditorenstamm des Empfängers reicht ein Name nicht — Schreibweisen ändern sich, Kennungen nicht.
- Wie Sie es beheben
- Senden Sie mindestens eine davon: cac:PartyIdentification/cbc:ID (BT-29), cac:PartyLegalEntity/cbc:CompanyID (BT-30) oder cac:PartyTaxScheme/cbc:CompanyID (BT-31) in UBL; in CII ram:SellerTradeParty/ram:ID, ram:SpecifiedLegalOrganization/ram:ID beziehungsweise ram:SpecifiedTaxRegistration/ram:ID.
- Was der Validator prüft
UBLexists(cac:Party/cac:PartyTaxScheme[cac:TaxScheme/normalize-space(upper-case(cbc:ID))='VAT']/cbc:CompanyID) or exists(cac:Party/cac:PartyIdentification/cbc:ID[not(@schemeID = 'SEPA')]) or exists(cac:Party/cac:PartyLegalEntity/cbc:CompanyID)CII(ram:ID) or (ram:GlobalID) or (ram:SpecifiedLegalOrganization/ram:ID) or (ram:SpecifiedTaxRegistration/ram:ID[@schemeID='VA'])
Im XML
Ausschnitt in UBL. Der CII-Pfad steht oben im Text — dieselbe Änderung, andere Elementnamen.
Fehlerhaft <cac:Party> <cac:PartyName> <cbc:Name>Muster GmbH</cbc:Name> </cac:PartyName> <cac:PostalAddress> <cbc:CityName>Berlin</cbc:CityName> </cac:PostalAddress> </cac:Party>Korrigiert <cac:Party> <cac:PartyName> <cbc:Name>Muster GmbH</cbc:Name> </cac:PartyName> <cac:PostalAddress> <cbc:CityName>Berlin</cbc:CityName> </cac:PostalAddress> <cac:PartyTaxScheme> <cbc:CompanyID>DE811234567</cbc:CompanyID> <cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme> </cac:PartyTaxScheme> </cac:Party>
NormAPI liefert technische Validierung, keine Steuer- oder Rechtsberatung.