{
  "id": "BR-CO-17",
  "country": "EU",
  "syntax": "ubl",
  "group": "document",
  "severity": "fatal",
  "severity_note": "fatal, from the Flag column of the Peppol BIS Billing 3.0 UBL rules index retrieved 2026-10-18.",
  "spec": "Peppol BIS Billing 3.0, May 2026 release, EN 16931 model bound to UBL",
  "statement": "VAT category tax amount (BT-117) = VAT category taxable amount (BT-116) x (VAT category rate (BT-119) / 100), rounded to two decimals.",
  "statement_lang": "en",
  "context": "cac:TaxTotal/cac:TaxSubtotal",
  "test": "(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))",
  "meaning": "The VAT category tax amount (BT-117) must equal the VAT category taxable amount (BT-116) multiplied by the VAT category rate (BT-119) divided by 100, rounded to two decimals. The statement uses a lowercase x and ends with a period. The published test allows the tax amount and that rounded product to differ by less than 1 when the rate is not zero. It is not exact equality. When the rounded rate is 0, the rounded tax amount is 0. When the percent is absent, the test calls exists and the rounded tax amount is 0. It is not a percent equal to 0 and not not(cbc:Percent). The tax-scheme comparison is cbc:ID))='VAT' with no space before =. The comparison operators have spaces. A single space sits before the closing parenthesis after two of the div 100 closings.",
  "fix": "Set BT-117 to BT-116 multiplied by BT-119 divided by 100, rounded to two decimals. A rate of zero needs a tax amount of zero.",
  "example_fail": "The taxable amount is 100, the rate is 19, and the tax amount is 20.",
  "example_pass": "Those same taxable amount and rate, and the tax amount is 19.",
  "example_note": "Illustration of the condition in the official statement. Not an example published by the source.",
  "source_url": "https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-tc434/BR-CO-17/",
  "source_retrieved": "2026-10-18",
  "last_verified": "2026-10-18"
}
