|
This is a rounding error:
The error happens just when the program runs into line 501 (in class Mage_Tax_Helper_Data and method getPrice()), which means
$includingTax = null (I’m not sure what this parameter means) and $priceIncludesTax = true (which means the price in your store includes the tax)
case Mage_Tax_Model_Config::DISPLAY_TYPE_INCLUDING_TAX: $price = $this->_calculatePrice($price, $includingPercent, false); $price = $this->_calculatePrice($price, $percent, true); break;
Here the price is calculated twice, i don’t know why (I don’t think it is necessary. If the price in my store already includes the tax and i want to show the price with tax, why it needs to be calculated it?). However it would be fine if there is no round().
Unfortunately there HAS “round()” when the price is calculated
in the class Mage_Tax_Model_Calculation
public function calcTaxAmount($price, $taxRate, $priceIncludeTax=false, $round=true) { $taxRate = $taxRate/100;
if ($priceIncludeTax) { $amount = $price*(1-1/(1+$taxRate)); } else { $amount = $price*$taxRate; }
if ($round) { return $this->round($amount); }
return $amount; }
The default value of $round is true. so the tax is no more precise. It is ok for just showing the tax. But using this rounded tax to calculate the price causes round error
A simple code to reproduce the error like:
<?php
function calcTaxAmount($price, $taxRate, $priceIncludeTax=false, $round=true) { $taxRate = $taxRate/100;
if ($priceIncludeTax) { $amount = $price*(1-1/(1+$taxRate)); } else { $amount = $price*$taxRate; }
if ($round) { return round($amount, 2); }
return $amount; } function calcPrice($price, $percent, $type) { if ($type) { $taxAmount = calcTaxAmount($price, $percent, false); return $price + $taxAmount; } else { $taxAmount = calcTaxAmount($price, $percent, true); return $price - $taxAmount; } } $price = calcPrice(15.50, 19, false); $finalPrice = calcPrice($price, 19, true); var_dump($finalPrice);
Which will output float(15.51)
The solution may be return the price directly without calculating or set $round as false.
|