I defined a 10% tax rate of VAT type and a product priced at $0.45 excluding VAT. The price displayed, including VAT, was $0.50 which was the price plus the rounded-up tax amount ($0.045 rounded-up to $0.05).
When I added the product to the cart, the unit price and the total shown on the cart matched for quantity of 1. Changing the quantity to other than 1 resulted in mismatch between the unit price and the total. For exampe for quantity of 10, the unit price was $0.50 and the total was $4.95 (should be $5.00).
The problem is the tax was not rounded up/down on calculation. The product price does get rounded-up correctly though (prior to display only?).
The tax is calculated in the following function in commerce_tax.module:
function commerce_tax_rate_calculate($tax_rate, $line_item_wrapper) {
// By default, do not duplicate a tax that's already on the line item.
if (!commerce_price_component_load($line_item_wrapper->commerce_unit_price->value(), $tax_rate['price_component'])) {
return array(
'amount' => $line_item_wrapper->commerce_unit_price->amount->value() * $tax_rate['rate'],
'currency_code' => $line_item_wrapper->commerce_unit_price->currency_code->value(),
'data' => array(
'tax_rate' => $tax_rate,
),
);
}
return FALSE;
}
Rounding up the amount above fixed the mismatch in cart. But I'm not sure, it might introduce problems somewhere else.
| Comment | File | Size | Author |
|---|---|---|---|
| #6 | 1137840-6.tax_rounding.patch | 11.33 KB | rszrama |
| #3 | rounding error in tax.jpg | 51.11 KB | Devline |
| #2 | rounding error in tax fixed.jpg | 70.59 KB | Devline |
| #1 | rounding error in tax.jpg | 70.59 KB | Devline |
Comments
Comment #1
Devline commentedI have exactly the same problem of mismatch in between unit price by quantity, subtotal and tax amount when using a product having a price excluding tax and managing taxes through rules (which adds more flexibility in tax management). But it seems to me that the issue is not related to rounding on tax, but rather on the unit price stored at the product level.
Let say for an example that we have a product with a price including tax of 12$ with a tax of 19.6%, we will store a net price of 10.03$ at the product level, when in fact it should be something equal to 10,0334448 (to keep precision in further calculation).
The only way I see to fix it, is to determine what is the actual price including tax before any calculation. But as in this case we don't know in advance which tax rate is applicable it's impossible to get it before we reach some function that assigns the tax rate to the order line.
As soon as the tax rate is known it is quite easy to get the difference generated by the initial rounding and to apply it both to the the order line amount AND to the subtotal.
At this point, I don't know where is the best place to perform this, so I started some tests adding the following code inside the function commerce_tax_rate_calculate() :
I attached a snapshot of the cart both before and after this fix.
Any help to achieve this in a none-dirty way like it is at this point, would be greatly appreciated.
Comment #2
Devline commentedI finally came up with a solution by implementing hook_commerce_line_item_presave in a custom module. The main idea is to recalculate all prices and tax amounts (unit and total) with all the precision needed before the line item is saved.
In case someone would be interested in some solution to fix this rounding at checkout issue, here is the hook I setted up :
Attached a snapshot of the result
Any suggestion to improve this code is welcomed.
Comment #3
Devline commentedOops ! wrong file attachment...
Comment #4
vasikesubscribe. maybe could be a checkbox for the tax rate definition to be rounded or not.
Comment #5
damien tournoud commentedBumping this to critical. This is a known issue affecting European-style VAT (US sales tax works as intended). We need a rounding option here.
Comment #6
rszrama commentedAttached is a patch that I think addresses this sufficiently. Here's what it does:
I intend to commit this as is; I've tested it, and as I've described it above, it's working. Let me know if you think I did something wrong. : )
Comment #7
rszrama commentedAlrighty, talked this over with Damien, and on his recommendation I did go ahead and change our implementation to support the four rounding methods regardless of your PHP version. It wasn't horribly difficult, and it gave me my first ever excuse to use floor() and ceil() (with a couple of modulus operations thrown in as a bonus). See the commit diff for the final patch. I tested this and it appears to be working for all rounding methods for regular ol' VAT, for VAT inclusive prices, and for VAT inclusive line items whose unit prices are adjusted in the order edit form.
Perhaps I can get some confirmation on this, too. I'm pretty sure this is the expected behavior, but I wanna make sure I'm not crazy, because it could look a little weird in the totals. I have a product that is 60 cents including a 10% VAT. This equates to a base price of 54.54 cents (or 55 cents rounded) and the tax 5.46 cents (or 5 cents rounded). So my 10% VAT rounds out to an actual rate of 8.333% thanks to rounding. I don't see any way around this, but I'm also not sure it's really a problem. Glad I've never had to report VAT. Thoughts?
Commit: http://drupalcode.org/project/commerce.git/commitdiff/df02ca3
Comment #9
candelas commentedhave this been included in drupal commerce? i have this problem and i think that it was closed without it. because that, i reopen it. i have 7.x-1.7
Comment #10
rszrama commentedPlease look at the timestamp and commits. This is over 1.5 years old, and it ended with the patch being committed. You must be experiencing some other issue. My recommendation would be to post a question at http://www.drupalcommerce.org/questions with as much information as you can possibly provide about your setup and your problem.
Comment #11
candelas commented@Devline thanks for your module. I was getting crazy looking all around to find why my vat included was not rounding well. After trying many things, the solution was to not apply any rounding in the VAT, in the tax types configure form and using your module. thanks thanks!!!
I am using commerce 7.x-1.7 without any discounts or any thing that could influence. I reused the sample-french-vat-tax included. I changed it to be the 21% that we have in Spain. I disabled the Calculate taxes: Sales tax also. I put here my trying for debugging purpose.
Correct calculation
product 13,50 € x 4 products = 54,00 €
Subtotal 44,63 €
VAT 21% 9,37 €
Order total 54,00 €
Results using Tax amount rounding mode (without Devline's module):
Do not round at all
product 13,50 € x 4 products = 54,00 €
Subtotal 45,00 €
VAT 21% 9,00 €
Order total 54,00 €
Round the half up
product 13,50 € x 4 products = 54,00 €
Subtotal 44,64 €
VAT 21% 9,36 €
Order total 54,00 €
Round the half down
product 13,50 € x 4 products = 54,00 €
Subtotal 44,64 €
VAT 21% 9,36 €
Order total 54,00 €
Round the half to the nearest even number
product 13,50 € x 4 products = 54,00 €
Subtotal 44,64 €
VAT 21% 9,36 €
Order total 54,00 €
Round the half to the nearest odd number
product 13,50 € x 4 products = 54,00 €
Subtotal 44,64 €
VAT 21% 9,36 €
Order total 54,00 €
@rszrama THANKS FOR YOUR GREAT WORK :)
I reopen, with better documentation, the issue for you to be able to check it. If you need any other information, i will be pleased to provide it.
Edit: I am using PHP Version 5.3.10-1ubuntu3.6 and Apache/2.2.22 (Ubuntu)
Comment #12
rszrama commentedDevline hasn't posted in here for over 2 years. This issue just ain't coming back from the dead. : P
That said, I think you're wrong. VAT is rounded at the unit price level, so you can't have a unit price that gets multiplied by an even number end up an odd number. Your "correct subtotal" of 44,63 € just doesn't make sense to me. It looks to me like the correct calculation is as rounded, which this issue was closed fixed as supporting.
If you think I'm incorrect about VAT calculation, please refer to https://drupal.org/project/commerce_eu_vat for a solution for Spain. : )
Comment #13
candelas commentedThanks :)
I'll try it.
Comment #14
Devline commentedHi rszrama,
I understand why it doesn't make sense for you, but most accounting softwares (at least in France) validate the VAT based on total incl. tax and the tax rate, therefore if you have a total amount of 54 with a tax rate of 21% it will validate only for a net price of 44,63 (54 / 1.21 = 44,628 -> 44,63).
Comment #15
rszrama commentedOk, that sounds like something to take up with dwkitchen in the commerce_eu_vat queue - he's our resident EU tax genius and would know how that works within the system as is. fwiw, I've never heard of a VAT that isn't calculated at the unit price level, but if that is the case then you should still be able to accomplish it - just not by entering prices including VAT.
Comment #16
Devline commentedHi rszrama,
Many thanks for your responsiveness, as usual.... I totally agree with you on using prices not including VAT, and that is how accounting systems are actually doing, but when you enter your net price it let you enter the number of decimal you need to keep precision in tax calculation at the unit price level (generally between 3 To 5 decimals are enough for most business types), therefore the final validation on total, taxes and sub-total will pass.
We also have to keep in mind that when you are exporting sales in an accounting or when the customer records his invoice or when you fill your tax statement, it's at the total level without any knowledge of detail lines, that's why the validation is set on totals. It's acceptable here to display prices on invoices with more than 2 decimals or to have small discrepencies on invoice's detail lines, but never on totals.
I think the long time discussion on EU Tax is all around the number of decimal stored in prices... I can see only two ways to go, either at the price level, either to have some kind of mechanism able to restore at some point a unit price with enough precision.
Sorry to disturb again in this thread... :)
Comment #17
rszrama commentedYeah, in Commerce 2.x we'll actually be separating out the storage / computational precision from the display precision so we can solve these sorts of scenarios for good. dwkitchen is the mastermind behind that plan, so I expect to see him heavily involved in the process.
Comment #18
Devline commentedWonderful Ryan ! this should remove a big pain in the neck for many europeans :)... I saw that dwkitchen has pinpointed the actual issue back in september 2011. So we'll be patient and wait for Commerce 2.x...
Comment #19
Devline commented@candelas I'm glad to see that [#2] was of some help for you in this issue.