Counterfoil rule note

BR-O-12

Quoted from a public specification. This page is not a validator, and it is not tax, legal, or accounting advice.

Country
EU
Syntax
UBL
Severity
fatal
Last verified
2026-10-18

Official statement

An Invoice that contains a VAT breakdown group (BG-23) with a VAT category code (BT-118) "Not subject to VAT" shall not contain an Invoice line (BG-25) where the Invoiced item VAT category code (BT-151) is not "Not subject to VAT".

Source: https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-tc434/BR-O-12/

Peppol BIS Billing 3.0, May 2026 release, EN 16931 model bound to UBL

Severity note: fatal, from the Flag column of the Peppol BIS Billing 3.0 UBL rules index retrieved 2026-10-18.

Plain-language reading

If a VAT breakdown uses the category "Not subject to VAT", the invoice must not contain an invoice line (BG-25) whose VAT category code (BT-151) is not "Not subject to VAT". The official message includes "the" before "Invoiced item VAT category code" and says "an Invoice line" in the singular. It says "shall not contain" that line, not a VAT identifier and not a VAT rate. The quoted category name has no space after the opening quote. The published test passes when no O VAT breakdown exists. The negative branch is not(...) and does not call exists. When an O breakdown exists, the count of classified tax categories whose code is not O must be 0. That count uses //cac:ClassifiedTaxCategory. The positive branch calls exists. The tax-scheme comparison is cbc:ID)='VAT' with no space before =. The line-category comparison is normalize-space(cbc:ID) != 'O' with spaces around !=.

What to change

When a VAT breakdown is category O, set every invoice line VAT category to O, or remove the line that uses another category.

Illustration

Illustration of the condition in the official statement. Not an example published by the source.

Fails the stated condition. An O VAT breakdown is present and an invoice line uses a classified tax category that is not O.

Passes the stated condition. An O breakdown is present and every classified tax category is O, or the invoice has no O breakdown.

Published context and test

Copied from the source. Not reimplemented on this page.

/ubl:Invoice | /cn:CreditNote
(exists(cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory[cac:TaxScheme/normalize-space(upper-case(cbc:ID))='VAT']/cbc:ID[normalize-space(.) = 'O']) and count(//cac:ClassifiedTaxCategory[normalize-space(cbc:ID) != 'O'][cac:TaxScheme/normalize-space(upper-case(cbc:ID))='VAT']) = 0) or not(cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory[cac:TaxScheme/normalize-space(upper-case(cbc:ID))='VAT']/cbc:ID[normalize-space(.) = 'O'])

All rule notes · JSON · Markdown · llms.txt · Invoice page · Privacy