einvoice / EN 16931 / XRechnung rule reference
PEPPOL-EN16931-R055
What this rule means and how to fix it
Invoice total VAT amount and Invoice total VAT amount in accounting currency MUST have the same operational sign.
Der Gesamtbetrag der Umsatzsteuer und der Gesamtbetrag der Umsatzsteuer in der Abrechnungswährung MÜSSEN dasselbe Vorzeichen haben.
Deutsche Fassung: Übersetzung der gleichen BT/BG-Semantik (translation — not the official assert).
- Requires
- Invoice total VAT amount and Invoice total VAT amount in accounting currency MUST have the same operational sign
- Business terms
- — (no single business term)
- Syntax
- Binds the UBL-2.1 Invoice / CreditNote syntax and the UN/CEFACT-CII syntax
- Location (UBL-2.1 path)
cac:TaxTotal/cbc:TaxAmount- Fix
- Correct `cac:TaxTotal/cbc:TaxAmount` so that Invoice total VAT amount and Invoice total VAT amount in accounting currency MUST have the same operational sign.
- Fix (Deutsch)
- Korrigieren Sie `cac:TaxTotal/cbc:TaxAmount`, sodass gilt: Der Gesamtbetrag der Umsatzsteuer und der Gesamtbetrag der Umsatzsteuer in der Abrechnungswährung MÜSSEN dasselbe Vorzeichen haben.
- Severity
- fatal
- Provenance source
xrechnung-ubl- Provenance assert
Invoice total VAT amount and Invoice total VAT amount in accounting currency MUST have the same operational sign
The Location above is a UBL-2.1 path, and no UN/CEFACT-CII path for this rule is published here; Fix and Fix (Deutsch), verbatim from remediation_catalog.json and not reworded here; the UN/CEFACT-CII binding of this rule is differentially proven against the official KoSIT XRechnung 2.5.0 (XRechnung 3.0.2) Schematron.
Where to check the fix: paste the corrected invoice into the browser validator at /einvoice/validate/ — it runs this same engine locally in your browser, with no upload, and stops reporting PEPPOL-EN16931-R055 once the edit lands.
Korrektur prüfen: Laden Sie die geänderte Rechnung in den Browser-Validator unter /einvoice/validate/ — er führt dieselbe Engine lokal im Browser aus, ohne Upload, und meldet PEPPOL-EN16931-R055 nicht mehr, sobald die Korrektur greift.
The same invoice, failing and fixed
Read this first. The einvoice validate command does not evaluate the Peppol BIS layer: einvoice.validate never imports einvoice.rules_peppol, so no document makes the CLI print a PEPPOL-EN16931-* id. The pair below was graded by einvoice.rules_peppol directly — the module that transcribes the Peppol asserts and backs this site's conformance matrix. It is a real verdict from real code in this repository, and it is not the verdict the CLI gives you.
The pair was found, not written: the vendored instance corpus/xrechnung-testsuite/src/test/technical-cases/cius/01.01_comprehensive_test_ubl.xml was edited one element at a time with a fixed catalogue of mechanical edits until the Peppol layer's verdict changed. The edit that did it: the text content of DocumentCurrencyCode was deleted, leaving the element present but empty. It is published because that layer reported PEPPOL-EN16931-R055 for the edited document and did not report it for the untouched one.
UBL Invoice — fails
The vendored file around the change, verbatim:
<cbc:DocumentCurrencyCode></cbc:DocumentCurrencyCode>
UBL Invoice — passes
The same lines as 01.01_comprehensive_test_ubl.xml actually ships them — this block is the fix for the block above:
<cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>
What einvoice.rules_peppol reports for the edited invoice
{
"element": "cac:TaxTotal/cbc:TaxAmount",
"message": "Invoice total VAT amount and Invoice total VAT amount in accounting currency MUST have the same operational sign",
"rule": "PEPPOL-EN16931-R055",
"severity": "fatal"
}
Peppol ids that layer reports for 01.01_comprehensive_test_ubl.xml untouched: none. After the edit: PEPPOL-EN16931-R008 PEPPOL-EN16931-R055.
And what einvoice validate --profile xrechnung reports for that same edited document: BR-05 BR-CL-04. No PEPPOL-EN16931-R055 among them, which is the point of the warning above.
Two honest limits. This is an edit that provokes the rule, not the only one, and it is not a claim about how real senders break it. And it is the reverse of the fix a reader needs: the passing block is the vendored file's own content, which is what a conformant invoice looks like here.
Reproduce it yourself: take corpus/xrechnung-testsuite/src/test/technical-cases/cius/01.01_comprehensive_test_ubl.xml from this repository, apply the one edit named above, and run python3 -c "import xml.etree.ElementTree as ET, einvoice.rules_peppol as P; print(P.evaluate_ubl(ET.parse('01.01_comprehensive_test_ubl.xml').getroot()))". To see what the shipped validator says about the same file instead, paste it into the browser validator, which runs the EN 16931 / XRechnung engine locally with no upload.
Everything here is free and open source — pick up whatever helps, at your own pace:
- Licensing — free and open source under Apache-2.0 for everyone, including closed-source embedding: use, modify and ship it inside a commercial product with no fee and no license key.
- German remediation (
--lang de) — the German fix for this rule is in the section above; the CLI surfaces it in place of the English message with--lang de. - Quickstart / free on-ramp — the README, a copy-paste CI-gate recipe, and a 5-minute worked walkthrough.