Drupal + Ubercart tax calculations go wrong..
Posted by Kim | Posted in Content Management Systems, Drupal | Posted on 22-07-2011
0
Hi guys,
We’ve encountered some strange behaviour while implementing Ubercart on a client’s website. it seems that when you’re having multiple tax-rates, they all get added, and there is no real way to “filter” out the last correct one.
Also there seems to be a buggy code issue, where a line item is not added when your tax-rate is set to “0%”.
The following code proves this:
<?php
function uc_taxes_apply_tax($order, $tax) {
$amount = 0;
$taxable_amount = 0;
if (is_array($order->products)) {
foreach ($order->products as $item) {
$taxable_amount += uc_taxes_apply_item_tax($item, $tax);
}
}
$taxed_line_items = $tax->taxed_line_items;
if (is_array($order->line_items) && is_array($taxed_line_items)) {
foreach ($order->line_items as $key => $line_item) {
if ($line_item['type'] == ‘tax’) {
// Don’t tax old taxes.
continue;
}
if (in_array($line_item['type'], $taxed_line_items)) {
$taxable_amount += $line_item['amount'];
}
}
}
if (isset($taxed_line_items['tax'])) {
// Tax taxes that were just calculated.
foreach ($order->taxes as $other_tax) {
$taxable_amount += $other_tax->amount;
}
}
$amount = $taxable_amount * $tax->rate;
if ( $amount ) {
$line_item = (object)array(
‘id’ => $tax->id,
‘name’ => $tax->name,
‘amount’ => $amount,
‘weight’ => $tax->weight,
‘summed’ => 1,
);
$line_item->data = array(
‘tax_id’ => $tax->id,
‘tax_rate’ => $tax->rate,
‘taxable_amount’ => $taxable_amount,
‘tax_jurisdiction’ => $tax->name,
);
return $line_item;
}
}
?>
In the above function, the line item is only added when the $amount variable equals something “true”. This does *not* include the *valid* value of “0″ €, in the case you have set a tax rate of 0 (because 3 € * 0 % = 0).
The following behaviour can be fixed by just commenting the if ( $amount ) as follows:
<?php
//if ( $amount ) {
$line_item = (object)array(
‘id’ => $tax->id,
‘name’ => $tax->name,
‘amount’ => $amount,
‘weight’ => $tax->weight,
‘summed’ => 1,
);
$line_item->data = array(
‘tax_id’ => $tax->id,
‘tax_rate’ => $tax->rate,
‘taxable_amount’ => $taxable_amount,
‘tax_jurisdiction’ => $tax->name,
);
return $line_item;
//}
?>
Say you have 2 tax rates:
A. 21% for everyone
B. 0% for specific case with conditions.
Then, both tax rates should be applied, but only *one* should remain and be added to the order?
For example:
Subtotal = 5 €
Taxrate A = 5 € * 21% == 1.05 €
Taxrate B = 5 € * 0% == 0.00 €
Total = 5€ + 1.05 € + 0.00 €…
I hope this can help some other people when looking into Tax rates.


