Automation MCP Server Features Blog Pricing Contact
Validation rule EN 16931 core

BR-CO-11

Document level discounts have their own bookkeeping: BR-CO-11 requires the declared sum of allowances (BT-107) to equal the actual sum of every document level allowance amount (BT-92). It fires the moment a discount is added or edited without refreshing the totals block.

What BR-CO-11 checks

BR-CO-11 is the allowance-side bookkeeping rule: Sum of allowances on document level (BT-107) = Σ Document level allowance amount (BT-92). Every document level allowance is a BG-20 group with its own amount; the totals block declares their sum, and the validator recomputes it. In UBL, BT-107 is the cbc:AllowanceTotalAmount in the legal monetary total, and each BT-92 is the cbc:Amount of an cac:AllowanceCharge with ChargeIndicator false.

Layer and formats

An en16931 core layer rule, applying to every syntax and profile. It is the second link of the totals chain: BR-CO-10 anchors the line sum, BR-CO-11 and its charge twin BR-CO-12 anchor the document level adjustments, and BR-CO-13 combines all three into the total without VAT.

Why it fails in practice

  • A discount added after totals were computed. The order pipeline appends a rebate group to the XML, but the monetary total block was rendered earlier and never updated.
  • Sign confusion. Allowances are positive amounts subtracted downstream; emitting them negative (or mixing a charge into the allowance sum via a wrong ChargeIndicator) breaks the equation.
  • Hardcoded template totals. BT-107 carries a leftover value from the template or a previous document while the allowance list changed.

How to fix it

Recompute BT-107 as the sum of the BT-92 amounts you actually emit, with allowances kept strictly positive:

<cac:LegalMonetaryTotal>
  ...
  <cbc:AllowanceTotalAmount currencyID="EUR">50.00</cbc:AllowanceTotalAmount>
</cac:LegalMonetaryTotal>

In an InvoiceXML create request the allowances live in the invoice.allowances array and the sum is totals.sumOfAllowances. The robust fix is omission: leave invoice.totals out and the API computes BT-107 from the allowance entries server-side.

The raw rejection vs the InvoiceXML finding

The Schematron report states the equation:

<svrl:failed-assert id="BR-CO-11" flag="fatal"
    location="/*:Invoice[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:Invoice-2'][1]">
  <svrl:text>[BR-CO-11]-Sum of allowances on document level (BT-107) =
    Σ Document level allowance amount (BT-92).</svrl:text>
</svrl:failed-assert>

The InvoiceXML finding for the same failure:

{
  "rule": "BR-CO-11",
  "layer": "en16931",
  "line": null,
  "message": "The sum of allowances on document level must equal the sum of all document level allowance amounts. Check the allowance totals.",
  "btCodes": ["BT-107", "BT-92"],
  "fields": ["totals.sumOfAllowances"],
  "raw": "[BR-CO-11] EN16931: Sum of allowances on document level (BT-107) = Σ Document level allowance amount (BT-92)."
}

A readable message plus the dotted path of the request field to fix, no rule-code parsing on your side. Clients that want their own wording localize by the stable rule key and keep the mapping.

Check or generate documents with correct totals

Validate a file in the UBL validator or the XRechnung validator. Generating via POST /v1/create/ubl or POST /v1/create/facturx computes the whole chain server-side from lines and allowances, so it cannot drift. Background on the arithmetic: EN 16931 explained.

  • BR-CO-10, the line sum (BT-106)
  • BR-CO-11, the allowance sum (BT-107), this page, with BR-CO-12 as its charge twin
  • BR-CO-13, the total without VAT (BT-109)
  • BR-CO-14, the VAT total against the breakdown (BT-110)
  • BR-CO-15, the total with VAT (BT-112), and BR-CO-16, the amount due (BT-115)

Frequently asked questions

What counts as a document level allowance?

A discount that applies to the whole invoice rather than one line: an early-payment rebate, a campaign discount, a contractual reduction. Each is a BG-20 group with its amount in BT-92. Line-level allowances (BG-27) are a different mechanism and are already inside the line net amounts.

I have no allowances at all. Can BR-CO-11 still fire?

Only if BT-107 is present with a non-zero value while no allowance groups exist, which usually means a stale or hardcoded totals block. Either add the matching allowance groups or drop BT-107 entirely; an absent optional total is treated as zero.

Is there a matching rule for charges?

Yes, BR-CO-12: the sum of charges on document level (BT-108) must equal the sum of the document level charge amounts (BT-99). The two rules are symmetric, and both feed BR-CO-13, where allowances are subtracted and charges added to reach the total without VAT.

Can documents created via the API fail this rule?

Not in practice. Omit invoice.totals in a /v1/create/* request and BT-107 is computed server-side from the allowances you supply, along with the rest of the totals chain, and the document is validated before delivery. The rule bites on documents arriving from other systems.