fatalEN 16931EN 16931 business ruleCIIUBLBG-20BG-21BG-23BG-25BT-102BT-118BT-151BT-95
An Invoice that contains an Invoice line (BG-25), a Document level allowance (BG-20) or a Document level charge (BG-21) where the VAT category code (BT-151, BT-95 or BT-102) is "Not subject to VAT" shall contain exactly one VAT breakdown group (BG-23) with the VAT category code (BT-118) equal to "Not subject to VAT".
The invoice has at least one line, allowance or charge with VAT category Not subject to VAT (O), but the VAT breakdown (BG-23) has no group for that category.
Add a VAT breakdown group (BG-23) with VAT category code O and its taxable amount (BT-116) — the sum of the net amounts in that category. Set the VAT category tax amount (BT-117) to 0 (BR-O-09) and add the exemption reason text (BT-120) "Not subject to VAT" (BR-O-10). O is the odd one out on rates: BR-O-05/06/07 say the line, allowance and charge VAT rate must be absent entirely, not zero — do not write a 0 where the standard wants nothing. A category code used anywhere on the invoice needs exactly one matching VAT breakdown group (BG-23) — the breakdown is a summary per category, not per line.
CII — context /rsm:CrossIndustryInvoice
not(//ram:ApplicableHeaderTradeSettlement/ram:ApplicableTradeTax[ram:CategoryCode='O']) or ( count(//ram:ApplicableHeaderTradeSettlement/ram:ApplicableTradeTax[ram:CategoryCode='O'])=1 and (exists(//ram:SpecifiedLineTradeSettlement/ram:ApplicableTradeTax[ram:CategoryCode='O']) or exists(//ram:CategoryTradeTax[ram:CategoryCode='O'])))
UBL — context /ubl:Invoice | /cn:CreditNote
((exists(//cac:TaxCategory[cac:TaxScheme/normalize-space(upper-case(cbc:ID))='VAT']/cbc:ID[normalize-space(.) = 'O']) or exists(//cac:ClassifiedTaxCategory[cac:TaxScheme/normalize-space(upper-case(cbc:ID))='VAT']/cbc:ID[normalize-space(.) = 'O'])) and (count(cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory[cac:TaxScheme/normalize-space(upper-case(cbc:ID))='VAT']/cbc:ID[normalize-space(.) = 'O']) = 1)) or (not(//cac:TaxCategory[cac:TaxScheme/normalize-space(upper-case(cbc:ID))='VAT']/cbc:ID[normalize-space(.) = 'O']) and not(//cac:ClassifiedTaxCategory[cac:TaxScheme/normalize-space(upper-case(cbc:ID))='VAT']/cbc:ID[normalize-space(.) = 'O']))
Nothing is stored, and the whole invoice is checked, not just this rule. A PDF only works if it is Factur-X / ZUGFeRD — a PDF with the invoice XML inside it.