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

BR-CO-13

The middle link of the totals chain: BR-CO-13 requires the invoice total without VAT (BT-109) to equal the sum of line net amounts minus document level allowances plus document level charges. When a lower link is broken, this rule usually fails right along with it.

What BR-CO-13 checks

BR-CO-13 defines the invoice's net total: Invoice total amount without VAT (BT-109) = Σ Invoice line net amount (BT-131) minus Sum of allowances on document level (BT-107) plus Sum of charges on document level (BT-108). It is the point where the three lower bookkeeping rules meet: the lines, the discounts, and the surcharges must combine, to the cent, into the declared net total. In UBL, BT-109 is the cbc:TaxExclusiveAmount of the legal monetary total.

Layer and formats

An en16931 core layer rule for every syntax and profile. Because the equation reuses the line amounts, an error low in the chain propagates: a wrong line amount typically fails BR-CO-10, BR-CO-13, BR-CO-15 and BR-CO-16 in one report. Fix bottom-up: lines first, then allowances and charges, then the derived totals.

Why it fails in practice

  • Double-counted discounts. A rebate is baked into the line prices and declared again as a document level allowance, so BT-109 subtracts it twice relative to the lines.
  • Charges missing from the total. Shipping or handling is added as a BG-21 charge group, but the pre-existing totals block never adds BT-108.
  • Rounding at the wrong step. The net total is computed from unrounded intermediate values while the declared BT-131, BT-107 and BT-108 are already rounded; on the wrong invoice the results differ by a cent.

How to fix it

Compute BT-109 from the declared components, not from source data: sum the emitted line amounts, subtract the emitted allowance sum, add the emitted charge sum.

<cac:LegalMonetaryTotal>
  <cbc:LineExtensionAmount currencyID="EUR">1000.00</cbc:LineExtensionAmount>
  <cbc:AllowanceTotalAmount currencyID="EUR">50.00</cbc:AllowanceTotalAmount>
  <cbc:ChargeTotalAmount currencyID="EUR">20.00</cbc:ChargeTotalAmount>
  <cbc:TaxExclusiveAmount currencyID="EUR">970.00</cbc:TaxExclusiveAmount>
  ...
</cac:LegalMonetaryTotal>

In an InvoiceXML create request the field is totals.taxBasisTotalAmount, and the reliable fix is to omit invoice.totals entirely: the API derives the whole block from lines, allowances and charges server-side.

The raw rejection vs the InvoiceXML finding

The Schematron report hands you the equation and nothing else:

<svrl:failed-assert id="BR-CO-13" flag="fatal"
    location="/*:Invoice[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:Invoice-2'][1]">
  <svrl:text>[BR-CO-13]-Invoice total amount without VAT (BT-109) =
    Σ Invoice line net amount (BT-131) - Sum of allowances on document
    level (BT-107) + Sum of charges on document level (BT-108).</svrl:text>
</svrl:failed-assert>

The InvoiceXML finding for the same failure:

{
  "rule": "BR-CO-13",
  "layer": "en16931",
  "line": null,
  "message": "The total amount without VAT must equal the sum of line net amounts minus document level allowances plus document level charges. Check totals.",
  "btCodes": ["BT-109", "BT-131", "BT-107", "BT-108"],
  "fields": ["totals.taxBasisTotalAmount", "totals.sumOfAllowances", "totals.sumOfCharges"],
  "raw": "[BR-CO-13] EN16931: Invoice total amount without VAT (BT-109) = Σ Invoice line net amount (BT-131) - Sum of allowances on document level (BT-107) + Sum of charges on document level (BT-108)."
}

The message is display-ready and fields lists the request paths involved in the equation, so your UI can highlight all of them. Localization stays a lookup by the stable rule key.

Check or generate documents with correct totals

Validate incoming files in the UBL validator or the XRechnung validator. If your own pipeline trips the chain, that first failing report is usually the argument for moving generation to the API too: POST /v1/create/ubl and POST /v1/create/facturx compute the chain server-side from your line items. The arithmetic is walked through in EN 16931 explained.

  • BR-CO-10, the line sum (BT-106)
  • BR-CO-11, the allowance sum (BT-107)
  • BR-CO-13, the total without VAT (BT-109), this page
  • 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 exactly is the BR-CO-13 equation?

BT-109 = Σ BT-131 (line net amounts) - BT-107 (sum of allowances) + BT-108 (sum of charges). Absent optional totals count as zero. Note that the equation uses the line amounts directly, so a wrong BT-106 fails BR-CO-10 while BT-109 can still be arithmetically right, and vice versa.

BR-CO-10 passes but BR-CO-13 fails. How?

The declared line sum matches the lines, but BT-109 does not reflect the allowances or charges: typically a discount was subtracted from the line amounts and again via BT-107 (double counting), or a charge exists but BT-108 was never added into the total.

Does VAT play any role here?

No. Everything in the BR-CO-13 equation is net. VAT enters one link later: BR-CO-15 adds the VAT total (BT-110) onto BT-109 to reach the total with VAT (BT-112).

Can documents created via the API fail this rule?

Not in practice. Leave invoice.totals out of a /v1/create/* request and BT-109 is computed server-side from lines, allowances and charges, then the whole document is validated before delivery. The rule bites on documents arriving from other systems.