Improve rounding taxes when the tax_rounding field is set to 'document'

Rational

We detect too many decimals of difference when calculating ‘Tax Lines’ on invoices, with the tax_rounding field set to ‘document’, if you take the tax base and try to apply the tax rate directly. In some countries that different are not allowed. They need to be exactly and now we have found some invoices with 4 decimals of differences.

For example, if the currency is euro (2 decimals) and you have an invoice with 50 lines and all of them with the same tax and the unit price of each line has 3 or more decimals, the calculating of tax base and amount are not coherent, because on the one hand the base is rounded for each line to be consistent when creating the move lines and on the other the tax is rounded at the end. And this produces that if you take the final base and apply the rate, the result is too much different from the calculated.

Proposal

Calculate the tax amount of ‘Tax Lines’ using it base.

Implementation

A first approach could be something like that:

--- a/tax.py    Sat Jan 26 01:12:50 2019 +0100
+++ b/tax.py    Thu Feb 21 15:06:49 2019 +0100
@@ -1181,6 +1181,10 @@
                 if tax_rounding == 'line':
                     self._round_taxes(taxes)
         if tax_rounding == 'document':
+            for taxline in taxes.itervalues():
+                tax_compute = Tax.compute(Tax.browse([taxline['tax']]),
+                    taxline['base'], 1)
+                taxline['amount'] = tax_compute[0]['amount']
             self._round_taxes(taxes)
         return taxes

I know it’s not the best way, but with this you could understand the problem better, I think.

I would say to not use document rounding if you do not want any rounding difference.

Your proposal will just move the rounding issue on the accounting as your base amount for the tax will not be the sum of the product lines. This should also not be accepted by authorities if they do not accept the other rounding difference. But it is bigger issue because you can no more proof with your accounting, your tax report.
Indeed what you want is that the base was not rounded on each line: modules/account: 9a9d55047b05 tax.py but only in _round_taxes.

Maybe what you would like is to group lines from an invoice that have the same accounting configuration (account, taxes etc.) and create a single line for it. That would be a valid option but I doubt it is doable without increasing a lot the complexity of account_invoice module.

1 Like

I remember having this kind of request and implementing it with a customization module. With the current design it was possible without touching the account_invoice code.

In this case it could be a complementary standard module if the code is clean and maintainable.

Cédric, grouping lines could a good solution.

Sergi if its possible, could you share the module? I will try it. And if all works well and Cédric agree with the code, we could add as a complementary standard modules as he said.

I do not think it is doable to group lines in standard because now we have the invoice line stored as origin.
Also in such implementation, the untaxed amount of the invoice will not be same as the sum of the revenue/expense move lines.

Now we could maybe use the base rounding per document if the invoice adds extra lines on revenue/expense for the rounding difference of the base. The difficulty will be to choose the account to use: one of the line with the tax, one from the configuration… But I’m not sure such behavior is allowed.

I found this explanation from Dolibarr wiki (fr) which is very useful to understand that there will be always inconsistency.

IIUC it is the known problem of sum preserving rounding in tables.
The problem on rounding which doesn’t preserves the sum appears when calculating, rounding and printing taxes for each invoice line. If we add-up the line-wise rounded taxes, this sum may differ to the total taxes calculated by the summed up base-amounts of each tax.
To solve this we need an algorithm, which is similar to curve-fitting in science. IIUC, the general idea of this algorithm is, to distribute the summed-up rounding errors back to the lines. That means the lines with the biggest rounding errors get tweaked by a small difference (the minimal currency precision, like 0.01EUR). With this tweaking on the line level, the sums getting correct. S.a. https://groups.google.com/d/msg/tryton/_sFvv3EW8Ak/dDF-UAZVEL8J

No, you can not solve this by distributing the rounding issue because the base amount on the tax line must be equal to the amount booked in the move lines and you can not change the move lines amount because it must be the same as the invoice line.
There is no solution to this problem because indeed there is no problem. It is well known that no matter the way you compute taxes, you will always find some numbers that does not fit exactly. That’s why we have option to round tax on line or on document. The first one is the most common practice and the easiest to explain but some rare countries require the second one.

FYI, this is what I use in the point of sale to ensure tax included price stay the same. But it does not apply to invoice with price tax excluded.

1 Like

And unfortunately, suppliers don’t always use the same method either.

Therefore it appears that there should also be configuration on a party basis where the default is the company default.

Also, can we presume that the tax amount (not the base amount) can be forced in the tax line box without breaking cash basis when the Tryton calculation is different than the supplier’s?