Magento tax rounding issue
Asked Answered
M

2

8

I got strange rounding issue for VAT in Magento. My product set up is * product price incl 20% VAT is 183.59

I added 30 items into basket and it would cost 30 * 183.59 = 5507.70. I can see this value in basket/checkout so that's fine. If I have just 1 item in basket it's ok.

Also the final VAT would be 5507.70 * 20 / 120 = 917.95, but I'm getting 918.00

Do you have any idea how to fix this or where would I take a look? Thanks in advance.

Mirabel answered 23/11, 2012 at 12:52 Comment(0)
M
11

In the end I found the solution. I changed System > VAT > Tax Calculation Method Based On from Unit price to Row Total and it works, more details here

The issue which I found is in core/store model. I had to rewrite roundPrice method and change rounding precision there.

public function roundPrice($price)
{
   return round($price, 4);
}
Mirabel answered 23/11, 2012 at 13:40 Comment(5)
The rewrite is definitely NOT an appropriate solution! Good for you it worked, but it leads to issues with PayPal payment (valid orders return marked "suspected fraud"). Be careful when you use this rewrite!Ory
Yes, I agree. Changed rounding fixed our issue in one place but broke it in another place. I think it's not basically possible to have a solution which works perfectly in all scenarios.Mirabel
I finally managed to get around some issues with te official knowledge base entry: magentocommerce.com/knowledge-base/entry/…Ory
Precision of 4 "fixes" subtotals in the shopping cart, but messes up net/tax calculation (net + tax = expected total + 0.01) under certain circumstances. This also leads to paypal errors, because the API complains about wrong values: 'ITEMAMT' + 'TAXAMT' != 'AMT'.Bossuet
This issue has been fixed now, with 1.13.1 Magento EE magentocommerce.com/knowledge-base/entry/…Cristiecristin
P
6

Info

Round price in Magento based on previous rounding operation delta.

app/code/core/Mage/Tax/Model/Sales/Total/Quote/Tax.php:1392 app/code/core/Mage/Tax/Model/Sales/Total/Quote/Subtotal.php:719

protected function _deltaRound($price, $rate, $direction, $type = 'regular')
{
    if ($price) {
        $rate = (string)$rate;
        $type = $type . $direction;
        // initialize the delta to a small number to avoid non-deterministic behavior with rounding of 0.5
        $delta = isset($this->_roundingDeltas[$type][$rate]) ? $this->_roundingDeltas[$type][$rate] : 0.000001;
        $price += $delta;
        $this->_roundingDeltas[$type][$rate] = $price - $this->_calculator->round($price);
        $price = $this->_calculator->round($price);
    }
    return $price;
}

Sometimes this can cause an error due to the high delta calculation error ($this->_calculator->round($price)). For example, for this reason, some prices can vary in the range of ±1 cent.

Solution

To avoid this, you need to improve the accuracy of the delta calculation.

Change

$this->_roundingDeltas[$type][$rate] = $price - $this->_calculator->round($price);

to

$this->_roundingDeltas[$type][$rate] = $price - round($price, 4);

Changes need to be made in both files:

app/code/core/Mage/Tax/Model/Sales/Total/Quote/Tax.php:1392 app/code/core/Mage/Tax/Model/Sales/Total/Quote/Subtotal.php:719

Don't modify or hack core files! Do a rewrite!

The solution was tested on different versions of Magento 1.9.x, but maybe this will work in earlier versions.

P.S.

Change roundPrice function, as shown below, can solve the rounding error problem, but it can cause others (for example, some platforms require rounding up to 2 decimal places).

app/code/core/Mage/Core/Model/Store.php:995

public function roundPrice($price)
{
    return round($price, 4);
}
Pitterpatter answered 30/1, 2018 at 14:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.