Afrondingsverschillen in UBL-facturen voorkomen en correct afhandelen: PayableRoundingAmount, BTW-afronding en prijzen inclusief BTW.
Een van de meest frustrerende foutmeldingen bij het versturen van e-facturen is een afrondingsverschil. De BTW-totalen sluiten niet aan op de regelbedragen, of het factuurtotaal wijkt een cent af van de berekende som. Het resultaat: de factuur wordt bij validatie afgekeurd. Dit artikel legt uit waar afrondingsverschillen vandaan komen en hoe je ze voorkomt of oplost.
Afrondingsverschillen ontstaan door de combinatie van drie factoren: vermenigvuldiging, deling en afronding op twee decimalen. Een paar voorbeelden:
Stukprijs met veel decimalen. Een prijs van 3,333... euro per stuk x 3 stuks = 9,999 euro. Afgerond is dat 10,00 euro. Maar als je de stukprijs eerst afrondt naar 3,33 en dan vermenigvuldigt: 3,33 x 3 = 9,99. Een cent verschil.
BTW per regel versus BTW per totaal. Als je de BTW per factuurregel berekent en afrondt, en daarna optelt, kan de som afwijken van de BTW berekend over het totaal. Bij 21% BTW over 33,33 euro is dat 7,00 euro (afgerond). Maar 21% over 3 x 33,33 = 21% over 99,99 = 21,00 euro. Terwijl 3 x 7,00 = 21,00 euro ook. In dit geval klopt het, maar bij andere bedragen niet.
Prijzen inclusief BTW. Sommige sectoren (retail, horeca) werken met prijzen inclusief BTW. Het nettobedrag moet dan worden teruggerekend, wat een extra afrondingsmoment introduceert.
De UBL-standaard kent een speciaal element voor afrondingsverschillen: PayableRoundingAmount in het LegalMonetaryTotal-blok. Dit element vangt kleine afrondingsverschillen op, zodat het PayableAmount een rond bedrag kan zijn:
<cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="EUR">99.99</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="EUR">99.99</cbc:TaxExclusiveAmount>
<cbc:TaxInclusiveAmount currencyID="EUR">120.99</cbc:TaxInclusiveAmount>
<cbc:PayableRoundingAmount currencyID="EUR">0.01</cbc:PayableRoundingAmount>
<cbc:PayableAmount currencyID="EUR">121.00</cbc:PayableAmount>
</cac:LegalMonetaryTotal>
Het verschil van 0,01 euro wordt expliciet benoemd. De validatieregels staan een PayableRoundingAmount toe, mits het verschil klein genoeg is (doorgaans maximaal 1 euro, afhankelijk van het profiel).
De BTW-berekening in een UBL-factuur werkt per BTW-tarief, niet per regel. Alle regelbedragen met hetzelfde BTW-tarief worden opgeteld tot de grondslag (TaxableAmount), en daarover wordt de BTW berekend. Dit voorkomt dat je per regel gaat afronden en vervolgens een cumulatief afrondingsverschil krijgt.
De formule is:
TaxableAmount = som van LineExtensionAmount per BTW-categorie
- AllowanceTotalAmount per BTW-categorie
+ ChargeTotalAmount per BTW-categorie
TaxAmount = TaxableAmount × Percent / 100 (afgerond op 2 decimalen)
Let op: bereken de BTW altijd over de totale grondslag per tarief, niet per regel. Per-regel BTW-berekening is de meest voorkomende oorzaak van afrondingsverschillen.
Bij prijzen inclusief BTW moet het nettobedrag worden teruggerekend. De standaardaanpak is:
bruto / (1 + BTW-percentage/100)LineExtensionAmount is dit nettobedragPayableRoundingAmount<!-- Prijs inclusief BTW: €12,10 per stuk, 3 stuks -->
<cac:InvoiceLine>
<cbc:ID>1</cbc:ID>
<cbc:InvoicedQuantity unitCode="EA">3</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="EUR">30.00</cbc:LineExtensionAmount>
<cac:Price>
<cbc:PriceAmount currencyID="EUR">10.00</cbc:PriceAmount>
</cac:Price>
</cac:InvoiceLine>
In dit voorbeeld is de prijs inclusief BTW 12,10 euro. Het nettobedrag is 10,00 euro per stuk (12,10 / 1,21). Maal 3 = 30,00 euro. BTW: 21% van 30,00 = 6,30 euro. Totaal: 36,30 euro. Dat klopt precies met 3 x 12,10 euro. Maar bij prijzen die niet netjes deelbaar zijn, ontstaat een verschil.
eConnect valideert elke factuur op interne consistentie. Als er een klein afrondingsverschil is dat binnen de tolerantie valt, wordt de factuur geaccepteerd. Bij grotere afwijkingen krijg je een duidelijke foutmelding die aangeeft waar het verschil zit.
De automatische XML-reparatiefunctie van eConnect kan in sommige gevallen een ontbrekend PayableRoundingAmount toevoegen als het verschil kleiner is dan de tolerantiegrens. Maar het is altijd beter om de afronding in je eigen software correct af te handelen.
TaxExclusiveAmount + TaxAmount moet gelijk zijn aan TaxInclusiveAmount. En TaxInclusiveAmount minus PrepaidAmount plus PayableRoundingAmount moet gelijk zijn aan PayableAmount.Bereken de BTW per tarief (niet per regel), werk intern met meer dan twee decimalen en rond pas af bij het vullen van de XML-elementen. Als er ondanks goede afronding een klein verschil overblijft, vang dat dan op met het PayableRoundingAmount-element.
Het is een speciaal UBL-element dat kleine afrondingsverschillen opvangt in de factuurtotalen. Het verschil wordt expliciet benoemd, zodat de factuur toch valideert. De meeste profielen staan een maximum van 1 euro toe.
In sommige gevallen kan de automatische XML-reparatiefunctie een ontbrekend PayableRoundingAmount toevoegen als het verschil binnen de tolerantiegrens valt. Maar het is altijd beter om de afronding in je eigen software correct af te handelen.
Controleer je factuur