Reconcile the zero-rated taxable amount

Error BR-FXEXT-Z-08b Factur-X

[BR-FXEXT-Z-08b] - In a VAT breakdown (BG-23) where VAT category code (BT-118) is equal to “Z” ("Zero Rated"), Absolute Value of (VAT category taxable amount (BT-116) - ∑ Invoice line net amounts (BT-131) + Σ Document level allowance amounts (BT-92) - Σ Document level charge amounts (BT-99) - Σ Logistics Service fee amounts (BT-X-272)) <= 0,01 * ((Number of line net amounts (BT-131) + Number of Document level allowance amounts (BT-92) + Number of Document level charge 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 "Zero Rated" (Z), but only for lines where the "Subtype of invoice item" (BT-X-8) has the value "DETAIL" or is not specified.

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

The amount in ram:BasisAmount differs by more than the allowed rounding tolerance from the corresponding net amounts: invoice line amounts plus allowances, minus charges and logistics service fees. Zero-rated amounts with the same tax rate are considered. The test permits either a reconciliation that matches exemption reasons or one that does not apply that restriction; only invoice lines with DETAIL or no status reason are included.

What the rule means

The taxable amount in a VAT breakdown must represent the related net values for zero-rated supplies. Category code Z denotes zero-rated supplies; a different taxable amount makes the VAT breakdown inconsistent.

Please reconcile the taxable amount for `Z`

The taxable amount for zero-rated VAT does not sufficiently match the related invoice components. You can reconcile it against the relevant invoice lines and allowances or charges.

What to do
  1. Compare ram:BasisAmount with the net amounts of the related invoice lines and the allowances, charges, and logistics service fees.
  2. Check that you calculate TradeLineItem.LineTotalAmount and AbstractTradeAllowanceCharge.ActualAmount for category Z and the applicable tax rate.
  3. For invoice lines, include those with status DETAIL or no status reason; the reconciliation may match exemption reasons or omit that matching condition.
  4. Regenerate the invoice 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)
Technical details

The test groups by ram:RateApplicablePercent and compares ram:BasisAmount with sums rounded to two decimal places. The permitted difference is 0.01 multiplied by the number of included lines and allowances or charges. The condition passes if either calculation variant is satisfied.

Where the rule applies

The rule applies to each document-level VAT breakdown in ram:ApplicableTradeTax with category code Z and tax type VAT. It compares the taxable amount with the related invoice lines, allowances, charges, and logistics service fees.

Context (rule/@context)
//ram:ApplicableHeaderTradeSettlement/ram:ApplicableTradeTax[ram:CategoryCode='Z'][upper-case(ram:TypeCode) = 'VAT']
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), $calculatedAmountBT131 in xs:decimal(round(sum(/rsm:CrossIndustryInvoice/ rsm:SupplyChainTradeTransaction/ram:IncludedSupplyChainTradeLineItem[ not(ram:AssociatedDocumentLineDocument/ram:LineStatusReasonCode) or ram:AssociatedDocumentLineDocument/ram:LineStatusReasonCode = 'DETAIL' ]/ram:SpecifiedLineTradeSettlement[ ram:ApplicableTradeTax/ram:CategoryCode = 'Z' and ram:ApplicableTradeTax/xs:decimal(ram:RateApplicablePercent) =$rate and normalize-space(ram:ApplicableTradeTax/ram:ExemptionReasonCode) = $exempReasonCode and normalize-space(ram:ApplicableTradeTax/ram:ExemptionReason) = $exempReasonText ]/ram:SpecifiedTradeSettlementLineMonetarySummation/xs:decimal(ram:LineTotalAmount)) * 100) div 100), $calculatedAmountBT131ini in xs:decimal(round(sum(/rsm:CrossIndustryInvoice/ rsm:SupplyChainTradeTransaction/ram:IncludedSupplyChainTradeLineItem[ not(ram:AssociatedDocumentLineDocument/ram:LineStatusReasonCode) or ram:AssociatedDocumentLineDocument/ram:LineStatusReasonCode = 'DETAIL' ]/ram:SpecifiedLineTradeSettlement[ ram:ApplicableTradeTax/ram:CategoryCode = 'Z' and ram:ApplicableTradeTax/xs:decimal(ram:RateApplicablePercent) =$rate ]/ram:SpecifiedTradeSettlementLineMonetarySummation/xs:decimal(ram:LineTotalAmount)) * 100) div 100), $allowancesAmountBT92 in xs:decimal(round(sum(/rsm:CrossIndustryInvoice/ rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ ram:SpecifiedTradeAllowanceCharge[ ram:ChargeIndicator/udt:Indicator=false() and ram:CategoryTradeTax/ram:CategoryCode='Z' and ram:CategoryTradeTax/xs:decimal(ram:RateApplicablePercent)=$rate and normalize-space(ram:CategoryTradeTax/ram:ExemptionReasonCode) = $exempReasonCode and normalize-space(ram:CategoryTradeTax/ram:ExemptionReason) = $exempReasonText ]/xs:decimal(ram:ActualAmount)) * 100) div 100), $allowancesAmountBT92ini in xs:decimal(round(sum(/rsm:CrossIndustryInvoice/ rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ ram:SpecifiedTradeAllowanceCharge[ ram:ChargeIndicator/udt:Indicator=false() and ram:CategoryTradeTax/ram:CategoryCode='Z' and ram:CategoryTradeTax/xs:decimal(ram:RateApplicablePercent)=$rate ]/xs:decimal(ram:ActualAmount)) * 100) div 100), $chargesAmountBT99 in xs:decimal(round(sum(/rsm:CrossIndustryInvoice/ rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ ram:SpecifiedTradeAllowanceCharge[ ram:ChargeIndicator/udt:Indicator=true() and ram:CategoryTradeTax/ram:CategoryCode='Z' and ram:CategoryTradeTax/xs:decimal(ram:RateApplicablePercent)=$rate and normalize-space(ram:CategoryTradeTax/ram:ExemptionReasonCode) = $exempReasonCode and normalize-space(ram:CategoryTradeTax/ram:ExemptionReason) = $exempReasonText ]/xs:decimal(ram:ActualAmount)) * 100) div 100), $chargesAmountBT99ini in xs:decimal(round(sum(/rsm:CrossIndustryInvoice/ rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ ram:SpecifiedTradeAllowanceCharge[ ram:ChargeIndicator/udt:Indicator=true() and ram:CategoryTradeTax/ram:CategoryCode='Z' and ram:CategoryTradeTax/xs:decimal(ram:RateApplicablePercent)=$rate ]/xs:decimal(ram:ActualAmount)) * 100) div 100), $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 = 'Z' 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 = 'Z' 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='Z' 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='Z' and ram:CategoryTradeTax/xs:decimal(ram:RateApplicablePercent)=$rate ])), $logisticChargeAmount in xs:decimal(round(sum(/rsm:CrossIndustryInvoice/ rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ ram:SpecifiedLogisticsServiceCharge[ ram:AppliedTradeTax/ram:CategoryCode='Z' and ram:AppliedTradeTax/xs:decimal(ram:RateApplicablePercent)=$rate and normalize-space(ram:AppliedTradeTax/ram:ExemptionReasonCode) = $exempReasonCode and normalize-space(ram:AppliedTradeTax/ram:ExemptionReason) = $exempReasonText ]/xs:decimal(ram:AppliedAmount)) * 100) div 100), $logisticChargeAmountini in xs:decimal(round(sum(/rsm:CrossIndustryInvoice/ rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ ram:SpecifiedLogisticsServiceCharge[ ram:AppliedTradeTax/ram:CategoryCode='Z' and ram:AppliedTradeTax/xs:decimal(ram:RateApplicablePercent)=$rate ]/xs:decimal(ram:AppliedAmount)) * 100) div 100), $nblogisticCharge in xs:decimal(count(/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ ram:ApplicableHeaderTradeSettlement/ram:SpecifiedLogisticsServiceCharge[ ram:AppliedTradeTax/ram:CategoryCode='Z' 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='Z' and ram:AppliedTradeTax/xs:decimal(ram:RateApplicablePercent)=$rate ])) return (abs($basisAmount - $calculatedAmountBT131 + $allowancesAmountBT92 - $chargesAmountBT99 - $logisticChargeAmount) le 0.01 * ($nbLineItems + $nbAllowancesOrCharges + $nblogisticCharge)) or (abs($basisAmount - $calculatedAmountBT131ini + $allowancesAmountBT92ini - $chargesAmountBT99ini - $logisticChargeAmountini) le 0.01 * ($nbLineItemsini + $nbAllowancesOrChargesini + $nblogisticChargeini)) )