Reconcile the VAT amount for category S

Error BR-FXEXT-S-09b Factur-X

[BR-FXEXT-S-09b] - For each different value of VAT rate (BT-119) where the VAT category code (BT-118) is equal to “S” ("Standard rated"), Absolute Value of (VAT  category  tax  amount  (BT-117) - VAT category taxable amount (BT-116) multiplied by the VAT category rate (BT-119)/100) <= 0,01 * ((Number of line net amounts (BT-131) + Number of Document level allowance amounts (BT-92) + Number of Document level allowance amounts (BT-99) + Number of Logistics Service fee amounts (BT-X-272)), where the VAT category code (BT-151, BT-95, BT-102, BT-X-273) is " Standard rated " (S), and the VAT rate (BT-152, BT-96, BT-103, BT-X-274) equals the VAT category rate (BT-119), and only for lines where the "Subtype of invoice line item" (EXT-FR-FE-163 / BT-X-8) has the value "DETAIL" or is not specified or the same rule but also taking into account the exemption reasons in Text (BT-120) and Code (BT-121) in BG-23 and the exemption reasons on each line (BT-X-96 / BT-X-97), on Document level Allowances (BT-173 / BT-174) and on Document Level Charges (BT-175 / BT-176) and on Service logistic charges (BT-X-591 / BT-X-592). One of the two rules must be followed, bearing in mind that ultimately only the second one will have to be followed.

Mandatory rule: As long as it is violated, the invoice is invalid and will be rejected by validators.
What is wrong

The VAT amount in ram:CalculatedAmount differs too much from the result of ram:BasisAmount multiplied by ram:RateApplicablePercent and rounded to two decimal places. The test allows a tolerance of 0.01 per included invoice line, allowance, charge, or logistics service; it permits counting with or without matching exemption details.

What the rule means

For category S, VAT is calculated from the taxable amount and its applicable rate. The stated VAT amount must match that result within the permitted rounding tolerance.

Please reconcile the VAT amount for category `S`

The VAT amount for category S does not sufficiently match the calculation based on the taxable amount and rate. Also check which related amounts are included in the tolerance calculation.

What to do
  1. Calculate the expected VAT amount from ram:BasisAmount and ram:RateApplicablePercent, then compare it with ram:CalculatedAmount.
  2. Check TaxCategoryCodes, TradeLineItem.LineTotalAmount, and AbstractTradeAllowanceCharge.ActualAmount for the amounts included in the tolerance calculation.
  3. Check that AssociatedDocument.LineStatusReasonCode or LineStatusReasonCodes is DETAIL or absent, and that the category, rate, and, where applicable, exemption details match.
  4. Generate the invoice again and validate it again.
Check in FactoorSharp
  • TaxCategoryCodes (BT-151; BT-95; BT-102; BT-118)
  • AbstractTradeAllowanceCharge.ActualAmount (Document level allowance: BT-92; Document level charge: BT-99)
  • AssociatedDocument.LineStatusReasonCode (BT-X-8)
  • LineStatusReasonCodes (BT-X-8)
  • TradeLineItem.LineTotalAmount (BT-131)
Good to know

For the rounding tolerance, amounts can be counted with matching exemption details or all amounts in the same category and at the same rate can be counted.

Technical details

Compares ram:CalculatedAmount with ram:BasisAmount multiplied by ram:RateApplicablePercent and rounded to two decimal places. The tolerance is 0.01 multiplied by the number of relevant entries; the test provides two counting methods, with and without filtering by exemption details.

Where the rule applies

The rule applies to category S ram:ApplicableTradeTax in ram:ApplicableHeaderTradeSettlement and checks the VAT amount calculated from the taxable amount and rate.

Context (rule/@context)
//ram:ApplicableHeaderTradeSettlement/ram:ApplicableTradeTax[ram:CategoryCode='S']
Test expression (assert/@test)
( for $rate in xs:decimal(ram:RateApplicablePercent), $exempReasonText in normalize-space(ram:ExemptionReason), $exempReasonCode in normalize-space(ram:ExemptionReasonCode), $basisAmount in xs:decimal(ram:BasisAmount), $nbLineItems in xs:decimal(count(/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ ram:IncludedSupplyChainTradeLineItem[ ( not(ram:AssociatedDocumentLineDocument/ram:LineStatusReasonCode) or ram:AssociatedDocumentLineDocument/ram:LineStatusReasonCode = 'DETAIL' ) and ram:SpecifiedLineTradeSettlement/ram:ApplicableTradeTax/ram:CategoryCode = 'S' and ram:SpecifiedLineTradeSettlement/ram:ApplicableTradeTax/xs:decimal(ram:RateApplicablePercent) =$rate and normalize-space(ram:SpecifiedLineTradeSettlement/ram:ApplicableTradeTax/ ram:ExemptionReasonCode) = $exempReasonCode and normalize-space(ram:SpecifiedLineTradeSettlement/ram:ApplicableTradeTax/ ram:ExemptionReason) = $exempReasonText ])), $nbLineItemsini in xs:decimal(count(/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ ram:IncludedSupplyChainTradeLineItem[ ( not(ram:AssociatedDocumentLineDocument/ram:LineStatusReasonCode) or ram:AssociatedDocumentLineDocument/ram:LineStatusReasonCode = 'DETAIL' ) and ram:SpecifiedLineTradeSettlement/ram:ApplicableTradeTax/ram:CategoryCode = 'S' and ram:SpecifiedLineTradeSettlement/ram:ApplicableTradeTax/xs:decimal(ram:RateApplicablePercent) =$rate ])), $nbAllowancesOrCharges in xs:decimal(count(/rsm:CrossIndustryInvoice/ rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ ram:SpecifiedTradeAllowanceCharge[ ram:CategoryTradeTax/ram:CategoryCode='S' and ram:CategoryTradeTax/xs:decimal(ram:RateApplicablePercent)=$rate and normalize-space(ram:CategoryTradeTax/ram:ExemptionReasonCode) = $exempReasonCode and normalize-space(ram:CategoryTradeTax/ram:ExemptionReason) = $exempReasonText ])), $nbAllowancesOrChargesini in xs:decimal(count(/rsm:CrossIndustryInvoice/ rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ ram:SpecifiedTradeAllowanceCharge[ ram:CategoryTradeTax/ram:CategoryCode='S' and ram:CategoryTradeTax/xs:decimal(ram:RateApplicablePercent)=$rate ])), $nblogisticCharge in xs:decimal(count(/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ ram:ApplicableHeaderTradeSettlement/ram:SpecifiedLogisticsServiceCharge[ ram:AppliedTradeTax/ram:CategoryCode='S' and ram:AppliedTradeTax/xs:decimal(ram:RateApplicablePercent)=$rate and normalize-space(ram:AppliedTradeTax/ram:ExemptionReasonCode) = $exempReasonCode and normalize-space(ram:AppliedTradeTax/ram:ExemptionReason) = $exempReasonText ])), $nblogisticChargeini in xs:decimal(count(/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ ram:ApplicableHeaderTradeSettlement/ram:SpecifiedLogisticsServiceCharge[ ram:AppliedTradeTax/ram:CategoryCode='S' and ram:AppliedTradeTax/xs:decimal(ram:RateApplicablePercent)=$rate ])), $vATAmountBT117 in xs:decimal(ram:CalculatedAmount), $calculatedBT117 in xs:decimal(round($basisAmount * $rate div 100 * 100) div 100) return (abs($vATAmountBT117 - $calculatedBT117) le 0.01 * ($nbLineItems + $nbAllowancesOrCharges + $nblogisticCharge)) or (abs($vATAmountBT117 - $calculatedBT117) le 0.01 * ($nbLineItemsini + $nbAllowancesOrChargesini + $nblogisticChargeini)) )