[Fixed v1.5.1] compounding or multiple tax problem
hi,
i can't get compounding or multiple taxes to work properly in zen cart 1.5. But it work perfectly in 1.39h.
So i created 2 fresh installations of both zen cart 1.39 and 1.5
For both shops:
The shops location is Alabama.
The customers are from California.
I have made 2 zone definitions (world and California).
For Tax Classes i have only "Taxable Goods".
I have made 2 tax rates (world 20% and California 15%).
when I tested it on 1.39 it works perfectly:
Sub-Total: $32.00
Free Shipping Options (Free Shipping): $0.00
tax 20: $6.40
CA tax15: $4.80
Total: $43.20
But on 1.5 i get:
Sub-Total: $32.00
Free Shipping Discount Options (Free Shipping): $0.00
CA tax15: $0.00
tax 20: $0.00
Total: $32.00
After spending hours with different settings and searching on the forums, i couldn't find anything for this on it.
But i managed to get a work around. If you open includes/classes/order.php and uncomment the if statement on line 523:
//if ($taxDescription == $products_tax_description)...
and replace:
Code:
$taxAdd = zen_calculate_tax($this->products[$index]['final_price'], $this->products[$index]['tax']) * $this->products[$index]['qty']
+ zen_round(zen_calculate_tax($this->products[$index]['onetime_charges'], $this->products[$index]['tax']), $decimals);
with this taken from v1.39:
Code:
$taxAdd = zen_calculate_tax($this->products[$index]['final_price']*$this->products[$index]['qty'], $taxRate)
+ zen_calculate_tax($this->products[$index]['onetime_charges'], $taxRate);
then everything seems to work well.
The reason i uncommented the IF statement ($taxDescription == $products_tax_description) was that the loop would fail every time when:
"CA tax15" == "CA tax15 + tax 20"
and
"tax 20" == "CA tax15 + tax 20"
But i'm not sure this is the right way to go about doing this! Is this a bug or am i doing something wrong???
thanks in advance.
Re: compounding or multiple tax problem
Anyone??
I'm sure i'm doing something wrong! or has compounding tax been removed from v1.5?
Re: compounding or multiple tax problem
Ok.
I assume this is a bug in v1.5 off zen cart. Anyways i have created a fix for it with explanation in the code, if anyone can verify this then that would be great, if not then no problem:
replace the code in includes/classes/order.php
between the lines 508-546:
Code:
/*********************************************
* Calculate taxes for this product
*********************************************/
$shown_price = zen_round(zen_add_tax($this->products[$index]['final_price'], $this->products[$index]['tax']) ,$decimals) * $this->products[$index]['qty'];
$shown_price += zen_round(zen_add_tax($this->products[$index]['onetime_charges'], $this->products[$index]['tax']), $decimals);
$this->notify('NOTIFIY_ORDER_CART_SUBTOTAL_CALCULATE', array('shown_price'=>$shown_price));
// find product's tax rate and description
$products_tax = $this->products[$index]['tax'];
$products_tax_description = $this->products[$index]['tax_description'];
$this->info['subtotal'] += $shown_price;
$totalTaxAdd = 0;
foreach ($taxRates as $taxDescription=>$taxRate)
{
$taxAdd = 0;
if ($taxDescription == $products_tax_description)
{
if (DISPLAY_PRICE_WITH_TAX == 'true')
{
$taxAdd = zen_round($shown_price / (100 + $this->products[$index]['tax']) * $this->products[$index]['tax'], $decimals);
} else
{
$taxAdd = zen_calculate_tax($this->products[$index]['final_price'], $this->products[$index]['tax']) * $this->products[$index]['qty'];
+ zen_round(zen_calculate_tax($this->products[$index]['onetime_charges'], $this->products[$index]['tax']), $decimals);
}
if (isset($this->info['tax_groups'][$taxDescription]))
{
$this->info['tax_groups'][$taxDescription] += $taxAdd;
} else
{
$this->info['tax_groups'][$taxDescription] = $taxAdd;
}
}
$totalTaxAdd += $taxAdd;
}
$this->info['tax'] += $totalTaxAdd;
/*********************************************
* END: Calculate taxes for this product
*********************************************/
with this code:
Code:
/*********************************************
* Calculate taxes for this product
*********************************************/
$shown_price = zen_round(zen_add_tax($this->products[$index]['final_price'], $this->products[$index]['tax']) ,$decimals) * $this->products[$index]['qty'];
$shown_price += zen_round(zen_add_tax($this->products[$index]['onetime_charges'], $this->products[$index]['tax']), $decimals);
$this->notify('NOTIFIY_ORDER_CART_SUBTOTAL_CALCULATE', array('shown_price'=>$shown_price));
// find product's tax rate and description
$products_tax = $this->products[$index]['tax'];
//not required
$products_tax_description = $this->products[$index]['tax_description'];
$this->info['subtotal'] += $shown_price;
$totalTaxAdd = 0;
foreach ($taxRates as $taxDescription=>$taxRate)
{
$taxAdd = 0;
if ($taxDescription <> '0') //since $taxRates = zen_get_multiple_tax_rates(..), and the zen_get_multiple_tax_rates function sets
//rate to 0 and description to unknown for no tax.
//therefore we can ignore when $taxRate = 0.
{
if (DISPLAY_PRICE_WITH_TAX == 'true')
{
//Get the original price without the tax then clculate tax rate
$preTax_Price = $shown_price / (($this->products[$index]['tax']/100) + 1);
$taxAdd = zen_calculate_tax($preTax_Price, $taxRate);
} else
{
// replace $this->products[$index]['tax'] with $taxRate since $this->products[$index]['tax'] is the combined tax rate for multi tax (either summed or compounded)
// and $taxRate is the tax rate for each individual tax.
$taxAdd = zen_calculate_tax($this->products[$index]['final_price']+$this->products[$index]['onetime_charges'], $taxRate) * $this->products[$index]['qty'];
}
if (isset($this->info['tax_groups'][$taxDescription]))
{
$this->info['tax_groups'][$taxDescription] += $taxAdd;
} else
{
$this->info['tax_groups'][$taxDescription] = $taxAdd;
}
}
$totalTaxAdd += $taxAdd;
}
//unset($taxRate) so it can not be used in the next round
unset($taxRate);
$this->info['tax'] += $totalTaxAdd;
/*********************************************
* END: Calculate taxes for this product
*********************************************/
Re: compounding or multiple tax problem
Hi,
Thanks for the report, and the fix.
While we can confirm that there is a problem with compound taxes, we are still looking at the best way to fix this, given the initial changes (which you've removed) were meant to fix some rounding problems that we don't want to re-introduce as well.
Re: compounding or multiple tax problem
Hi wilt,
thanks for reply.
Just an update on the fix i gave, i tested code with data from excel spreed sheets, and both gave similar result, there was only a difference in values after the 3rd decimal place. however i ran into problems when i added a "one time charge" to a product, thats because i included the onetimecharge with the product price, when they should of been separate, anyways here's a temporary fix for the temporary fix:
Code:
/*********************************************
* Calculate taxes for this product
*********************************************/
$shown_price = zen_round(zen_add_tax($this->products[$index]['final_price'], $this->products[$index]['tax']) ,$decimals) * $this->products[$index]['qty'];
$shown_price += zen_round(zen_add_tax($this->products[$index]['onetime_charges'], $this->products[$index]['tax']), $decimals);
$this->notify('NOTIFIY_ORDER_CART_SUBTOTAL_CALCULATE', array('shown_price'=>$shown_price));
// find product's tax rate and description
$products_tax = $this->products[$index]['tax'];
//not required
$products_tax_description = $this->products[$index]['tax_description'];
$this->info['subtotal'] += $shown_price;
$totalTaxAdd = 0;
foreach ($taxRates as $taxDescription=>$taxRate)
{
$taxAdd = 0;
if ($taxDescription <> '0') //since $taxRates = zen_get_multiple_tax_rates(..), and the zen_get_multiple_tax_rates function sets
//rate to 0 and description to unknown for no tax.
//therefore we can ignore when $taxRate = 0.
{
if (DISPLAY_PRICE_WITH_TAX == 'true')
{
//Get the original price without the tax then clculate tax rate
$preTax_Price = $shown_price / (($this->products[$index]['tax']/100) + 1);
$taxAdd = zen_calculate_tax($preTax_Price, $taxRate);
} else
{
// replace $this->products[$index]['tax'] with $taxRate since $this->products[$index]['tax'] is the combined tax rate for multi tax (either summed or compounded)
// and $taxRate is the tax rate for each individual tax.
$taxAdd = zen_calculate_tax($this->products[$index]['final_price'], $taxRate) * $this->products[$index]['qty']
+ zen_calculate_tax($this->products[$index]['onetime_charges'], $taxRate);
}
if (isset($this->info['tax_groups'][$taxDescription]))
{
$this->info['tax_groups'][$taxDescription] += $taxAdd;
} else
{
$this->info['tax_groups'][$taxDescription] = $taxAdd;
}
}
$totalTaxAdd += $taxAdd;
}
//unset($taxRate) so it can not be used in the next round
unset($taxRate);
$this->info['tax'] += $totalTaxAdd;
/*********************************************
* END: Calculate taxes for this product
*********************************************/
Re: compounding or multiple tax problem
Are you using the tax system to collect some other fee?
I ask because the US doesn't collect taxes for more than one state like you are doing.
Re: compounding or multiple tax problem
Hi, did some work for a client from Canada, Prince Edward Island and he upgraded to v1.5, he wanted the feature.
Re: compounding or multiple tax problem
Hi, Just wanted to update this to confirm the bug.
The original fix was meant to address some rounding issues, and line item issues related to paypal. However looks like I was a little agressive in the fix.
I haven't tested your fix per se, but the fix I applied was to revert code in the includes/classes/order.php file between the
PHP Code:
/*********************************************
* Calculate taxes for this product
*********************************************/
PHP Code:
/*********************************************
* END: Calculate taxes for this product
*********************************************/
Markers, to the original 139h code.
I've created some new tests for this(ie for a compound tax system, using both split tax and non split tax displays), and reverting the code now passes these as well as the original tests that checked tax calculations and rounding errors.
will address this in a future bugfix version.
Re: compounding or multiple tax problem
Re: compounding or multiple tax problem
Well, this is interesting.
1.3.9:
Code:
$taxAdd = zen_calculate_tax($this->products[$index]['final_price']*$this->products[$index]['qty'], $taxRate)
+ zen_calculate_tax($this->products[$index]['onetime_charges'], $this->products[$index]['tax']);
1.5
Code:
$taxAdd = zen_calculate_tax($this->products[$index]['final_price'], $this->products[$index]['tax']) * $this->products[$index]['qty'];
+ zen_round(zen_calculate_tax($this->products[$index]['onetime_charges'], $this->products[$index]['tax']), $decimals);
Not quite sure why, but the two tax variables are different, and in 1.5 it appears that it is incorrect:
$this->products[$index]['tax'] <> $taxRate
Changing this alone does allow the tax to be calcuated correctly
New, working 1.5 code:
1.5
Code:
$taxAdd = zen_calculate_tax($this->products[$index]['final_price'], $taxRate) * $this->products[$index]['qty'];
+ zen_round(zen_calculate_tax($this->products[$index]['onetime_charges'], $taxRate), $decimals);
The order of the quantity and price including tax is of no consequence.
This means, you can continue to use the new zen_round function without too drastically changing the code.
As for the description, well, that's another story. I just thought I should add this bit about the tax rates to enable a different perspective on the possible fix.
Ray