Repository navigation
Conversation
A line's VAT may differ from net x rate by one cent when net and VAT are derived from a fixed gross price. The item-based tax check now compares numbers and fails on a mismatch instead of only noting it.
3 of 4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When the gross price of a line is fixed and net and VAT are derived from it (common for hotel and event invoices in Germany), the VAT can be one cent off net × rate. Example: 8 nights at 52.00 gross → net 388.79, VAT 27.21, while 388.79 × 7 % rounds to 27.22.
LineItem#valid?requires exact equality, so such an invoice is refused, and the only way through is to let the gem recalculate the VAT (:VERTICAL) — which makes the XML say 27.22 / 416.01 while the human-readable invoice says 27.21 / 416.00. EN 16931 itself tolerates this rounding (BR-CO-17).Second, the VAT base (BT-116) is summed from
net_amount × billed_quantityrather than from the line totals. With unit prices stored to four decimals the two drift apart: two lines of 120 × 41.6667 (5,000.00 each) give a base of 10000.008, written as 10000.01 next to line totals of 5000.00 + 5000.00 — the XML then violates BR-CO-10 and BR-S-08. Once the line totals are rounded to cents, the invoice is refused instead ("Base amount and summed tax base amount deviate").Third, the
:ITEM_BASEDcheck inInvoice#valid?comparestax_amountwith the summed line tax without converting either side, so a total passed as a string never matches. It records an error message but does not returnfalse, so the invoice is still reported as valid — with a misleading entry inerrors.Change
LineItem#valid?: a line's VAT may differ from net × rate by at most one cent (LINE_TAX_ROUNDING_TOLERANCE). Larger differences are still refused. The invoice-level checks stay exact.Invoice#taxes: the VAT base is the sum of the line totals (LineItem#signed_charge_amount— negative for a negative quantity, the same rule#valid?already uses when it checks that the lines add up to the basis).Invoice#valid?(:ITEM_BASED): compares the values asBigDecimal, returnsfalseon a mismatch, and prints the amounts in plain notation.Tests
Five new tests in
test/invoice_test.rb: the gross-leading invoice is accepted and its XML carries 27.21 / 416.00; a line two cents off is still refused; item-based totals passed as strings leave no error; an item-based total that differs from its lines is refused; two lines of 120 × 41.6667 give a VAT base of 10000.00. The full suite passes.Related
The VAT-base change is the same idea as #45 (tax base from
charge_amount), keeping the sign for negative quantities; #45's contact fields andto_xmlchanges are not included. It also covers what #51 addresses: summing the line totals means each line is already rounded before the sum.