Here is a possible fix if like me you sell products that have different tax rates:
Product A 10% tax
Product B 0% tax.
buy Product A and get B at discount. Or buy B and get A at discount.
Will give you the right result depending on your tax setting in admin.
i.e for items that have 0% TAX for discount you must set "Include Tax"=false and "Re-calculate Tax"=none
i.e for items that have X% TAX for discount you must set "Include Tax"=true and "Re-calculate Tax"=Standard
Possible Fix (test it first)
open includes/modules/order_total/ot_better_together.php
and add the following function:
Code:
function get_indvidual_tax(){
require_once(DIR_WS_CLASSES . 'order.php');
$orderz = new order;
$getid = array();
$globTAX = array();
for ($i=0, $m=sizeof($orderz->products); $i<$m; $i++) {
//gather up all the different types of tax rates used in our cart
$getTAX_group = array();
foreach ($orderz->products[$i]['tax_groups'] as $j => $value) {
$getTAX_group[$j] = $value;
if (isset($globTAX[$j]) == false){
$globTAX[$j] = 0;
}
}
unset($value);
//collect tax rates for each items in our cart
$getid[(int)$orderz->products[$i]['id']] = $getTAX_group;
}
$combinLocalGlob = array();
array_push($combinLocalGlob,$getid);
array_push($combinLocalGlob,$globTAX);
return $combinLocalGlob;
}
This function captures the tax rates for each individual products in our basket.
Now go to the calculate_deductions() function and assign these tax rates to our products.
replace in the calculate_deductions() function with:
Code:
function calculate_deductions() {
global $db, $order, $currencies;
$od_amount = array();
$od_amount['tax'] = 0;
$products = $_SESSION['cart']->get_products();
reset($products);
$rc = usort($products, "bt_cmp");
$discountable_products = array();
// Build discount list
$getindTAX = $this->get_indvidual_tax(); //collects tax rates from function
$getindTAXglobal = $getindTAX[1];// collects all the tax rates used in our cart (will be used to calculate final tax amount)
$getindTAXlocal = $getindTAX[0];// collects tax rates for eaxh individual products in cart
for ($i=0, $n=sizeof($products); $i<$n; $i++) {
$discountable_products[$i] = $products[$i];
$discountable_products[$i]['tax_value'] = $getindTAXlocal[(int)$discountable_products[$i]['id']]; // assign the tax rate for each individual item in cart
}
// Now compute discounts
$discount = 0;
for ($i=0, $n=sizeof($discountable_products); $i<$n; $i++) {
// Is it a twofer?
if ($this->is_twofer($discountable_products[$i])) {
$npairs = (int)($discountable_products[$i]['quantity']/2);
$discountable_products[$i]['quantity'] -= ($npairs * 2);
$item_discountable = $npairs * $discountable_products[$i]['final_price'];
$discount += $item_discountable;
if ($this->include_tax == 'true') {
$item_being_discounted = $discountable_products[$i];
foreach ($item_being_discounted['tax_value'] as $taxrate => $taxvalue) {
//calculate tax amount for discounted item
$item_tax_at = ($item_being_discounted['final_price']*$taxvalue)/100;
$remove_discount_from_tax = $item_tax_at*($item_discountable/$item_being_discounted['final_price']);
//add this amount to the global tax variable (ready to be used to calc tax)
$getindTAXglobal[$taxrate] += $remove_discount_from_tax;
}
unset($taxvalue);
}
}
// Otherwise, do regular bt processing
while ($discountable_products[$i]['quantity'] > 0) {
$discountable_products[$i]['quantity'] -= 1;
$item_discountable = $this->get_discount(
$discountable_products[$i], $discountable_products);
$discount_amount = $item_discountable[0];
if (isset($item_discountable[0]) == false){
$discount_amount = 0;
}
if ($discount_amount == 0) {
$discountable_products[$i]['quantity'] += 1;
break;
} else {
$discount += $discount_amount;
if ($this->include_tax == 'true') {
$item_being_discounted = $item_discountable[1];
foreach ($item_being_discounted['tax_value'] as $taxrate => $taxvalue) {
//calculate tax amount for discounted item
$item_tax_at = ($item_being_discounted['final_price']*$taxvalue)/100;
$remove_discount_from_tax = $item_tax_at*($discount_amount/$item_being_discounted['final_price']);
//add this amount to the global tax variable (ready to be used to calc tax)
$getindTAXglobal[$taxrate] += $remove_discount_from_tax;
}
unset($taxvalue);
}
}
}
}
$od_amount['total'] = round($discount, 2);
switch ($this->calculate_tax) {
case 'Standard':
reset($order->info['tax_groups']);
while (list($key, $value) = each($order->info['tax_groups']))
{
$tax_rate = zen_get_tax_rate_from_desc($key);
if ($tax_rate > 0) {
// this will deduct the correct tax amount for each individual items
$od_amount[$key] = $tod_amount = round($getindTAXglobal[$key], 2) ;
$od_amount['tax'] += $tod_amount;
}
}
break;
case 'VAT':
reset($order->info['tax_groups']);
while (list($key, $value) = each($order->info['tax_groups']))
{
$tax_rate = zen_get_tax_rate_from_desc($key);
if ($tax_rate > 0) {
$od_amount[$key] = $tod_amount = $this->gross_down($od_amount['total']);
$od_amount['tax'] += $tod_amount;
}
}
break;
}
return $od_amount;
}
you will also need to replace the get_discount function with:
Code:
function get_discount($discount_item, &$all_items) {
$discount = 0;
for ($dis=0, $n=count($this->discountlist); $dis<$n; $dis++) {
$li = $this->discountlist[$dis];
// Based on type, check ident1
if ( ($li->flavor == PROD_TO_PROD) ||
($li->flavor == PROD_TO_CAT) ) {
if ($li->ident1 != $discount_item['id']) {
continue;
}
} else { // CAT_TO_CAT, CAT_TO_PROD
if ($li->ident1 != $discount_item['category']) {
continue;
}
}
for ($i=sizeof($all_items) - 1; $i>= 0; $i--) {
if ($all_items[$i]['quantity'] == 0)
continue;
$match = 0;
if ( ($li->flavor == PROD_TO_PROD) ||
($li->flavor == CAT_TO_PROD) ) {
if ($all_items[$i]['id'] == $li->ident2) {
$match = 1;
}
} else { // CAT_TO_CAT, PROD_TO_CAT
if ($all_items[$i]['category'] == $li->ident2) {
$match = 1;
}
}
if ($match == 1) {
$all_items[$i]['quantity'] -= 1;
if ($li->type == "$") {
$discount = $li->amt;
} else { // %
$discount = $all_items[$i]['final_price'] *
$li->amt / 100;
}
$discount_and_product = array();
array_push($discount_and_product,$discount);//discount amount
array_push($discount_and_product,$all_items[$i]);//item being discounted need to be used to calculate tax
return $discount_and_product;
}
}
}
return 0;
}
now you will have to set "Include Tax"=true and "Re-calculate Tax"=Standard
and it should work with different tax rated items!
Bookmarks