BR-DEC-15A VAT amount in the accounting currency is written with more than two decimal places

Mutabiq checks Saudi ZATCA Phase 2 e-invoice XML before you submit it: pre-validation against published ZATCA requirements, not an approval by the authority. This page explains one rule, BR-DEC-15.

Validate 5 invoices free

Five checks a month on the Free plan. The file is checked in memory and is never stored.

The message ZATCA prints

[BR-DEC-15]-The allowed maximum number of decimals for the Invoice total VAT amount in accounting currency (BT-111) is 2.

What Mutabiq reports

One entry for each way this rule can be reported.

Reported as
What kind of value was found — empty, not_15_digits and the like — never the value itself.

A VAT amount in the accounting currency is written with more than two decimal places

Reported asmore_than_two_decimalsmore than two decimal places

What is wrong

A cbc:TaxAmount whose parent is a cac:TaxTotal block, and whose currencyID attribute matches the tax currency code the document declares in cbc:TaxCurrencyCode, carries more than two characters after its first full stop, and ZATCA flags it under EN 16931 rule BR-DEC-15 as a warning, which does not by itself reject the document. The element the message names is BT-111, the invoice total VAT amount restated in the currency the seller keeps books in. Two things follow that are worth knowing before you go looking. First, if the document declares no tax currency at all, this rule's pattern matches nothing and it cannot fire, so seeing it means a tax currency is declared somewhere in the file. Second, on a Saudi invoice the tax currency is usually the same code as the document currency, in which case a single element satisfies both this pattern and BR-DEC-13's and the two rules are raised together over one figure - two findings, one defect. And as with BR-DEC-13, the pattern is not anchored to the top of the document: a cac:TaxTotal inside a cac:InvoiceLine is matched too, so a line VAT amount with three decimals is reported here even though the message names an invoice total. The rule counts the characters after the first full stop in the element's text rather than judging the value, so a third digit fails even when it is a nought, and a value written with no full stop at all passes however large it is. An absent or empty element passes as well.

What to check in your ERP

Start by establishing which of the two figures you are looking at, because the fix differs. If the tax currency and the document currency are the same code, this is the defect BR-DEC-13 describes and the fix is the one given there: round each line's VAT once and sum the rounded values. If the two currencies genuinely differ, the accounting-currency amount is a converted figure and the conversion is what produces the long fraction, since a rate carrying four or six decimals applied to a two-decimal amount almost never lands on two. Round after converting, and convert the total rather than converting a figure that was already rounded elsewhere, so that what you print is what your ledger holds. Check as well that the currencyID attribute on each amount is the one you intend: an amount tagged with the tax currency by a template that hard-codes it is a common way for an ordinary figure to end up under this rule.

The clause that runs

Quoted from the validation-rule stylesheet ZATCA publishes, at the file and line named below. The executed guard is what the check runs; the reported test is what it prints when it fails, and the two are not always the same.

Executed guard

not((string-length(substring-after(.,'.'))<=2))

Reported test

(string-length(substring-after(.,'.'))<=2)
Evaluated against
ubl:Invoice/cac:TaxTotal/cbc:TaxAmount[@currencyID = //cbc:TaxCurrencyCode]
Source
vendor/zatca/schematron/CEN-EN16931-UBL.xsl:1780

As shipped in ZATCA SDK 3.4.8: the copy quoted here is, byte for byte, the file that release ships. The date in the file name is the name ZATCA gives the file; the rules in it are those of SDK 3.4.8.

A worked example

A synthetic document from the measured test corpus that trips this rule, shown where it differs from one that passed. Mutabiq's report names the class of the value, never the value itself.

Where it differs from a document that passed

  • This example
  • A document that passed
<cbc:InvoiceTypeCode name="0100000">388</cbc:InvoiceTypeCode><cbc:DocumentCurrencyCode>SAR</cbc:DocumentCurrencyCode>This example: <cbc:TaxCurrencyCode>USD</cbc:TaxCurrencyCode>A document that passed: <cbc:TaxCurrencyCode>SAR</cbc:TaxCurrencyCode><cac:AdditionalDocumentReference>  <cbc:ID>ICV</cbc:ID>⋯</cac:TaxTotal><cac:TaxTotal>This example:   <cbc:TaxAmount currencyID="USD">15.000</cbc:TaxAmount>A document that passed:   <cbc:TaxAmount currencyID="SAR">15.00</cbc:TaxAmount></cac:TaxTotal><cac:LegalMonetaryTotal>
Document
bad-101-total-vat-accounting-currency-decimals.xml
Mutabiq's verdict
Not passed
Reported as
more_than_two_decimalsmore than two decimal places

Download this example (.xml)Check it in Mutabiq

This page's example, checked by the same rules your own upload goes through. No upload and no sign-in.

Rules evaluated against the same part of the document. One wrong value often reports several of them at once.

Check an invoice

Check your own invoice

© 2026 Hayatiq AI Solutions F.Z.E. All rights reserved.