Forums / Bug Reports / [Done 1.3.6] 1.3.5 coupon tax calculation and fix

[Done 1.3.6] 1.3.5 coupon tax calculation and fix

Locked

Started by swguy on 4 Sep 2006, 1:59 PM · Views: 12,404

Results 21 to 33 of 33
This thread is locked. New replies are disabled.
28 Sep 2006, 3:05 PM
#21
ttalk avatar

ttalk

New Zenner

Join Date:
Sep 2006
Posts:
27
Plugin Contributions:
0

[Done 1.3.6] 1.3.5 coupon tax calculation and fix

Just wondering why it hasn't been posted to the "Confirmed bugs and workarounds in v1.3.5" thread. Seems like this is an important fix.

28 Sep 2006, 8:18 PM
#22
wilt avatar

wilt

Oji-san

Join Date:
Jun 2003
Location:
Newcastle UK
Posts:
1,940
Plugin Contributions:
3

Re: [Done 1.3.6] 1.3.5 coupon tax calculation and fix

Hi,

Scott on another thread alerted us to a prob with tax calculation(although that was group disccount) which is why I have not come back and confirmed, unitl I was sure the discount coupons did not suffer from the same bug.

Fortunately they did not, so the fix posted earlier still stands

28 Sep 2006, 8:30 PM
#23
swguy avatar

swguy

Administrator

Join Date:
Feb 2006
Location:
Tampa Bay, Florida
Posts:
10,747
Plugin Contributions:
56

Re: [Done 1.3.6] 1.3.5 coupon tax calculation and fix

Thanks, Wilt! This is great. There have been a lot of fixes to order total modules since 1.3.0; you've done a great job improving this part of the code.

Scott

That Software Guy. My Store: Zen Cart Support
Available for hire - See my ad in Services
Plugin Moderator, Documentation Curator, Chief Cook and Bottle-Washer.
Do you benefit from Zen Cart? Then please support the project.

6 Oct 2006, 4:03 PM
#24
jeffd avatar

jeffd

Totally Zenned

Join Date:
Sep 2004
Posts:
605
Plugin Contributions:
1

Re: [Done 1.3.6] 1.3.5 coupon tax calculation and fix

Wilt,

I have one more small addition to your code to support folks who charge tax on shipping as the current version still produces the wrong tax amount for free shipping coupons:

  function calculate_deductions($order_total) {
    global $db, $order, $messageStack;
    $tax_address = zen_get_tax_locations();
    $od_amount = array();
    if ($_SESSION['cc_id']) {
      $coupon = $db->Execute("select * from " . TABLE_COUPONS . " where coupon_id = '" . (int)$_SESSION['cc_id'] . "'");
      if (($coupon->RecordCount() > 0 && $order_total !=0) || ($coupon->RecordCount() > 0 && $coupon->fields['coupon_type']=='S') ) {
        if ($coupon->fields['coupon_minimum_order'] <= $order_total) {
          if ($coupon->fields['coupon_type']=='S') {
            $od_amount['total'] = $order->info['shipping_cost'];
            $od_amount['type'] = 'S';
            // JTD:04/20/06 - added support to subtract coupon tax from tax total when shipping includes tax
             if ($this->include_tax == 'true') {
                $tax_rate = zen_get_tax_rate($this->tax_class, $tax_address['country_id'], $tax_address['zone_id']);
                $tax_desc = zen_get_tax_description($this->tax_class, $tax_address['country_id'], $tax_address['zone_id']);
                if ($tax_rate > 0) {
                    $od_amount['tax'] -= ($order->info['shipping_cost'] * $tax_rate)/100;
                    $od_amount[$tax_desc]  += ($order->info['shipping_cost'] * $tax_rate)/100;
                  }
                }
            // JTD:04/20/06 - end of addition for support to subtract coupon tax from tax total when shipping includes tax
          } else {
            if ($coupon->fields['coupon_type'] == 'P') {
              $od_amount['total'] = zen_round($order_total*($coupon->fields['coupon_amount']/100), 2);
            } else {
              $od_amount['total'] = $coupon->fields['coupon_amount'] * ($order_total>0);
            }
            if ($od_amount['total']>$order_total) $od_amount['total'] = $order_total;
            $products = $_SESSION['cart']->get_products();
            for ($i=0; $i<sizeof($products); $i++) {
              // speed up process and store value
              $is_valid_results = is_product_valid($products[$i]['id'], $_SESSION['cc_id']);
              if ($is_valid_results) {
                if ($coupon->fields['coupon_type'] == 'P') {
                  switch ($this->calculate_tax) {
                    case 'Credit Note':
                      $tax_rate = zen_get_tax_rate($this->tax_class, $tax_address['country_id'], $tax_address['zone_id']);
                      $tax_desc = zen_get_tax_description($this->tax_class, $tax_address['country_id'], $tax_address['zone_id']);
                      $od_amount[$tax_desc] = $od_amount['total'] / 100 * $tax_rate;
                      $od_amount['tax'] += $od_amount[$tax_desc];
                    break;
                    case 'Standard':
                      $ratio = $od_amount['total']/$this->get_order_total();
                        $t_prid = zen_get_prid($products[$i]['id']);
                        $cc_result = $db->Execute("select products_tax_class_id
                                                   from " . TABLE_PRODUCTS . " where products_id = '" . $t_prid . "'");

                        if ($is_valid_results) {
                          $tax_rate = zen_get_tax_rate($cc_result->fields['products_tax_class_id'], $tax_address['country_id'], $tax_address['zone_id']);
                          $tax_desc = zen_get_tax_description($cc_result->fields['products_tax_class_id'], $tax_address['country_id'], $tax_address['zone_id']);
                          if ($tax_rate > 0) {
                            $od_amount[$tax_desc] += round(((($products[$j]['final_price'] * $products[$j]['quantity']) * $tax_rate) + .5)/100 * $ratio, 2); // JTD:08/30/05 - Tax Calc bug fix
                            $od_amount['tax'] += $od_amount[$tax_desc];
                          }
                        }
                    break;
                    default:
                  }
                }
                if ($coupon->fields['coupon_type'] == 'F') {
                  switch ($this->calculate_tax) {
                    case 'Credit Note':
                      $tax_rate = zen_get_tax_rate($this->tax_class, $tax_address['country_id'], $tax_address['zone_id']);
                      $tax_desc = zen_get_tax_description($this->tax_class, $tax_address['country_id'], $tax_address['zone_id']);
                      $od_amount[$tax_desc] = $od_amount['total'] / 100 * $tax_rate;
                      $od_amount['tax'] += $od_amount[$tax_desc];
                    break;
                    case 'Standard':
                      $ratio = $od_amount['total']/$this->get_order_total();
                      $products = $_SESSION['cart']->get_products();
                        $t_prid = zen_get_prid($products[$i]['id']);
                        $cc_result = $db->Execute("select products_tax_class_id
                                                   from " . TABLE_PRODUCTS . " where products_id = '" . $t_prid . "'");

                        if ($is_valid_results) {
                          $tax_rate = zen_get_tax_rate($cc_result->fields['products_tax_class_id'], $tax_address['country_id'], $tax_address['zone_id']);
                          $tax_desc = zen_get_tax_description($cc_result->fields['products_tax_class_id'], $tax_address['country_id'], $tax_address['zone_id']);
                          if ($tax_rate > 0) {
                            $od_amount[$tax_desc] += round(((($products[$j]['final_price'] * $products[$j]['quantity']) * $tax_rate) + .5)/100 * $ratio, 2); // JTD:08/30/05 - Tax Calc bug fix
                            $od_amount['tax'] += $od_amount[$tax_desc];
                          }
                        }
                    break;
                    default:
                  }
                }
              }
            }
          }
        }
      }
    }
    return $od_amount;
  }

I also have some other changes and additions to ot_coupon.php to properly support those who use the "Display Prices with Tax" feature as the current code fails to produce the correct values when this configuration is enabled. If you are interested I would be glad post them as well?

Jeff

10 Nov 2006, 5:34 PM
#25
bikemike avatar

bikemike

New Zenner

Join Date:
Oct 2006
Location:
Christchurch, New Zealand
Posts:
44
Plugin Contributions:
0

Re: [Done 1.3.6] 1.3.5 coupon tax calculation and fix

Hi there. Do the fixes for multi line orders calculating discount correctly, and the fix to handle discounts display with tax included work together?

In my log I noted that the fix for multiple lines with discounts worked ok. http://www.zen-cart.com/forum/showpost.php?p=257158&postcount=9

I then re-tackled the problem of the discount showing ex-gst, whereas all my prices are shown with gst added.

After testing all the combinations of the ot_coupon settings I also found the fix for that on the forum at :[
http://www.zen-cart.com/forum/showpost.php?p=148590&postcount=22](http://www.zen-cart.com/forum/showpost.php?p=148590&postcount=22)

That worked too :smile:

Only later when looking to test gift vouchers did I spot that my multi line problem was back...with or without GV.

I don't know if I've broken my ot_coupon.php, or have the wrong settings somewhere but I can't figure it out. I did get into the ot_coupon code in detail, and made a fresh copy from 1.3.5, adding in the changes necessary.
It still works for one item, showing the amount correctly, with tax. With two items, the discount is out by the tax on the second item... I even tried the slightly modified fixes as used in the 1.3.6 version - though the multi line order fix was not in there yet:no:

I have the ot_coupon set for FALSE, FALSE, Standard, None.
I am running 1.3.5 and all other values in the checkout are fine.

I am stuck at this point with only this, and gift voucher account balances to sort out. I'd really appreciate some input.

bikemike
'If language is not used correctly, what is said is not what is meant. If what is said is not what is meant, what ought to be done remains undone' Kǒng fū zǐ

10 Nov 2006, 5:45 PM
#26
jeffd avatar

jeffd

Totally Zenned

Join Date:
Sep 2004
Posts:
605
Plugin Contributions:
1

Re: [Done 1.3.6] 1.3.5 coupon tax calculation and fix

Here is the version of ot_coupon.php that we are using with 1.3.6 and has all of the fixes applied that I am aware of, including one that is not in 1.3.6. I would be interested in feedback if you wish to test it to see if it produces the correct totals?

ot_coupon.zip

Jeff

11 Nov 2006, 8:57 AM
#27
bikemike avatar

bikemike

New Zenner

Join Date:
Oct 2006
Location:
Christchurch, New Zealand
Posts:
44
Plugin Contributions:
0

Re: [Done 1.3.6] 1.3.5 coupon tax calculation and fix

Thanks for quick reply, unfortunately I went off to bed, it was after 6am and I was feeling like ...

No, the file you send does not do the trick. (I used the file as is except for reinstating the 1.3.5 collect_posts function as it has code for coupon zones only supported in 1.3.6, and I am still on 1.3.5)
In fact, with the new files, for multi-line orders, now the gst and the totals are wrong too.

Starting with a single line order, monitoring the Process function;

For example with a 10% discount (11 is nov)
bikemike : $od_amount['total'] before zen_calculate_tax is : 44.75
bikemike : $tax is : 5.59
bikemike : $od_amount['total'] after zen_calculate_tax is : 47.25
Sub-Total: $503.40

Courier (Best Way): $13.93
Discount Coupon: ORGDIR11 : -$47.25

GST Component: $51.89
Total: $466.99

GST is 12.5% so 44.75 is correct, and 5.59 is correct (503.4 / 1.125 = 447.4666, 10% discount value is therefore 44.75. Tax on that is 44.75 * .125 = 5.59. Add those up 44.75 + 5.59 = 50.34 i.e. 10% of 503.40 - correct. But the figure it's coming up with is -$47.24, not -$50.34, So zen_calculate_tax is doing something odd.....

That function expects the tax_rate, not the tax (amount) :shocking:
\includes\functions\general.php

 // Calculates Tax rounding the result
  function zen_calculate_tax($price, $tax) {
    global $currencies;

    return zen_round($price * $tax / 100, $currencies->currencies[DEFAULT_CURRENCY]['decimal_places']);
  }
```If you ran tests with 100 dollar items at 10% discount you'd never spot this :wink2:OK, so changed the call in function Process to pass the tax_rate, and that's all tickety boo.

bikemike : od_amount['total'] before zen_calculate_tax is : 44.75
bikemike : $tax_rate is : 12.5
bikemike : od_amount['total'] after zen_calculate_tax is : 50.34
      Sub-Total:                             $503.40
Courier (Best Way):                    $13.93
            Discount Coupon: ORGDIR11 :  -$50.34
GST Component:                            $51.89
      Total:                                         $466.99

  So replace line 51 in the file you sent me
```php
// bikemike 11/11/06 (1.3.5) - this function expects tax_rate
//$od_amount['total'] += zen_calculate_tax($od_amount['total'], $tax);
  $od_amount['total'] += zen_calculate_tax($od_amount['total'], $tax_rate);
```Now, back to multi line orders.
_________SHOULD BE___ex gst_________gst__________zc        ___diff
__sub    ___$566.85___503.8666____$62.9800___$566.8500    
_ship    ____$22.87____20.3288_____$2.5400____$22.8700    
_disc    ___-$56.69___-50.3911____-$6.3000___-$56.6900    
__gst    ____$59.23___________________________$46.6500___-$12.5800
total    ___$533.03__$473.8044____$59.2300___$520.4600___-$12.5700 i.e. the gst is the error.

The discount is ok though!
Here are the order values:

__________________Headline price_____________________Discount values_________________Discounted prices
____________________Inc_________Exc_______gst_________Inc________ex______gst___________Inc__________ex_______gst
________Line 1__$503.4000___$447.4667__$55.9333____$50.3400__$44.7467__$5.5933_____$453.0600___$402.7200__$50.3400
________Line 2___$39.9500____$35.5111___$4.4389_____$3.9950___$3.5511__$0.4439______$35.9550____$31.9600___$3.9950
________Line 3___$23.5000____$20.8889___$2.6111_____$2.3500___$2.0889__$0.2611______$21.1500____$18.8000___$2.3500
Product_________$566.8500___$503.8667__$62.9833____$56.6850__$50.3867__$6.2983_____$510.1650___$453.4800__$56.6850
Shipping_________$22.8713____$20.3300___$2.5413_____$0.0000___$0.0000__$0.0000______$22.8713____$20.3300___$2.5413
Order___________$589.7213___$524.1967__$65.5246____$56.6850__$50.3867__$6.2983_____$533.0363___$473.8100__$59.2263
Not sure why this is yet....

How come the inner loops for the product list inside the coupon type / recalc type blocks are reinstated in the version you are using? I thought these were removed to fix the problem with multi lines... (I think there is a problem with i's and j's in the Fixed / Standard block in some versions floating around)
I was using Wilt's fix : <http://www.zen-cart.com/forum/showpost.php?p=257158&postcount=9>

Just going to go play with that, and do some more debugging

bikemike
'If language is not used correctly, what is said is not what is meant. If what is said is not what is meant, what ought to be done remains undone' Kǒng fū zǐ

11 Nov 2006, 10:40 AM
#28
bikemike avatar

bikemike

New Zenner

Join Date:
Oct 2006
Location:
Christchurch, New Zealand
Posts:
44
Plugin Contributions:
0

Re: [Done 1.3.6] 1.3.5 coupon tax calculation and fix

OK, so I reinstated the fixed calculate_deductions from wilt's post, http://www.zen-cart.com/forum/showpost.php?p=257158&postcount=9, and low and behold it all seems to work.

In the example I was using above, I now get :
Sub-Total:$566.85
Courier (Best Way): $22.87
Discount Coupon: ORGDIR11 : -$56.69

GST Component: $59.23

Total:$533.04

Moreover, seeing the 533.04, rather than the 533.03 which I had expected, showed there was an error in my utterly invaluable Excel Order Simulator. (I was adding up my rounded values :blush:)

The number of times I got screwed in knots trying to work out what I *should *be seeing, and especially working the tax out in the wrong direction and getting a couple of dollars here or there. I'd recommend creating such a tool to anyone who is struggling with proving their numbers in Zen Cart. It is far easier to use Excel functions to code the various cases, plug in the numbers and see what the answers are. Sure, there could be bugs in Excel too, but I haven't found any that affect me on this yet.
It works for single line orders, mutli line order, whether discounted or not.

A question in passing, the file you sent has line 45 commented out. It is included in the default for 1.3.5 and 1.3.6. Is there a reason you have this commented?

//     if ($od_amount['type'] == 'S') $order->info['shipping_cost'] = 0; // JTD:09/28/06 - allow shipping_cost amount to be written to orders_total as negative coupon amount will justify
```And finally, for anyone using the previous copies of the ot_coupon, or specifically the calculate_deductions function, which have been fixed to get discounts calculating correctly for multi-line orders-as per wilt's post-and who are using Fixed discounts with calculate tax = standard, unless I hit any more problems, or someone can tell me otherwise, I still reckon the statement near the end is wrong:  I think with the removal of the old loop using 'j'as the loop variable means that this line should be using 'i' for the loop index, not 'j'.

```php
if ($coupon->fields['coupon_type'] == 'F') {
  switch ($this->calculate_tax) {
    case 'Credit Note':
      $tax_rate = zen_get_tax_rate($this->tax_class, $tax_address['country_id'], $tax_address['zone_id']);
      $tax_desc = zen_get_tax_description($this->tax_class, $tax_address['country_id'], $tax_address['zone_id']);
      $od_amount[$tax_desc] = $od_amount['total'] / 100 * $tax_rate;
      $od_amount['tax'] += $od_amount[$tax_desc];
    break;
    case 'Standard':
      $ratio = $od_amount['total']/$this->get_order_total();
      $products = $_SESSION['cart']->get_products();
    $t_prid = zen_get_prid($products[$i]['id']);
    $cc_result = $db->Execute("select products_tax_class_id
                   from " . TABLE_PRODUCTS . " where products_id = '" . $t_prid . "'");

    if ($is_valid_results) {
      $tax_rate = zen_get_tax_rate($cc_result->fields['products_tax_class_id'], $tax_address['country_id'], $tax_address['zone_id']);
      $tax_desc = zen_get_tax_description($cc_result->fields['products_tax_class_id'], $tax_address['country_id'], $tax_address['zone_id']);
      if ($tax_rate > 0) {
        //$od_amount[$tax_desc] += round(((($products[$j]['final_price'] * $products[$j]['quantity']) * $tax_rate) + .5)/100 * $ratio, 2);
        $od_amount[$tax_desc] += round(((($products[$i]['final_price'] * $products[$i]['quantity']) * $tax_rate) + .5)/100 * $ratio, 2);
        $od_amount['tax'] += $od_amount[$tax_desc];
      }
    }
    break;
    default:
  }
}
```I don't pretend to know all the implications of my changes, but it is working for me.  Now I need to go and test Gift Vouchers again.  Thanks to everyone for contributions on this thread, I'd be even more lost without it.  

Cheers.

bikemike
'If language is not used correctly, what is said is not what is meant. If what is said is not what is meant, what ought to be done remains undone' Kǒng fū zǐ

13 Nov 2006, 3:45 PM
#29
jeffd avatar

jeffd

Totally Zenned

Join Date:
Sep 2004
Posts:
605
Plugin Contributions:
1

Re: [Done 1.3.6] 1.3.5 coupon tax calculation and fix

bikemike,

Good catch on the $tax to $tax_rate variable fix! You should also make this fix to the ot_group_pricing.php module as well since it has the same problem.

I have read your posts and examined wilts fixes and have applied them to our file set and tested them and as you suggest, the changes do seem to work properly, at least for us with the limited coupons I tested against. I have subsequently added the two changed files to the below archive if anyone wants the complete changed file set to test against.

order_total.zip

As to why I am commenting out the line that says:

//     if ($od_amount['type'] == 'S') $order->info['shipping_cost'] = 0; // JTD:09/28/06 - allow shipping_cost amount to be written to orders_total as negative coupon amount will justify 

Here is a thread that explains the issue:

http://www.zen-cart.com/forum/showthread.php?t=47523

As the thread explains it is more likely an issue that folks who query the orders_totals table to generate reports will have. I have found no situation where commenting this line out affects the order total in any way, it only affects what is written out to the order_totals table.

Jeff

11 Dec 2006, 1:11 PM
#30
bikemike avatar

bikemike

New Zenner

Join Date:
Oct 2006
Location:
Christchurch, New Zealand
Posts:
44
Plugin Contributions:
0

Re: [Done 1.3.6] 1.3.5 coupon tax calculation and fix

Jeff,
I have run my store steady for a couple of weeks now, and just wanted to offer an exclusive free shipping discount coupon. I found I could not get all of order totals Discount, Tax and Total to come out correctly. Mostly the difference was the tax on shipping. Was like trying to push two radio buttons...

I specifically found that adjusting the tax for shipping discounts in the calculate_deductions function was causing side effects, with the Total going out by the tax on shipping.

Having moved it instead to the process function, and cut out all my debug dross, I tried to move it back to the calculate_deductions function as my changes seemed minor in the end. Alas, it still does not work there, but does work in the process function. So I thought I'd share this with you, and all, for comment.

To make this change, I switched off the test for 'include_tax'

if ($this->include_tax == 'true') {  
```brought in the line 

$tax_address = zen_get_tax_locations();

$order->info['tax_groups'][$tax_desc] += $od_amount['tax'];

if ($od_amount['type'] == 'S') $order->info['shipping_cost'] = 0;


Here's the whole fn as I have it:

```php
function process() {
    global $order, $currencies, $db;
    $od_amount = $this->calculate_deductions($this->get_order_total());
    $this->deduction = $od_amount['total'];
    if ($od_amount['total'] > 0) {
      reset($order->info['tax_groups']);
      $tax = 0;
      while (list($key, $value) = each($order->info['tax_groups'])) {
        $tax_rate = zen_get_tax_rate_from_desc($key);
        if ($od_amount[$key]) {
          $order->info['tax_groups'][$key] -= $od_amount[$key];
          $order->info['total'] -=  $od_amount[$key];
          $tax += $od_amount[$key];
        }
      }
      //if ($od_amount['type'] == 'S') $order->info['shipping_cost'] = 0;    // bikemike : moved to later, needed below!
      $sql = "select coupon_code from " . TABLE_COUPONS . " where coupon_id = '" . (int)$_SESSION['cc_id'] . "'";
      $zq_coupon_code = $db->Execute($sql);
      $this->coupon_code = $zq_coupon_code->fields['coupon_code'];
      $order->info['total'] = $order->info['total'] - $od_amount['total'];
      if (DISPLAY_PRICE_WITH_TAX == 'true') {
        $tax_address = zen_get_tax_locations();  // added by bikemike to get JTDs code to run in this context
        if ($od_amount['type'] == 'S') {
            //  bikemike MOVED this JTD code from calculate_deductions
            // JTD:04/20/06 - added support to subtract coupon tax from tax total when shipping includes tax
            //if ($this->include_tax == 'true') {
                $tax_rate = zen_get_tax_rate($this->tax_class, $tax_address['country_id'], $tax_address['zone_id']);
                $tax_desc = zen_get_tax_description($this->tax_class, $tax_address['country_id'], $tax_address['zone_id']);
                if ($tax_rate > 0) {
                    //bikemike 11 Dec 2006: $od_amount['tax'] -= ($order->info['shipping_cost'] * $tax_rate)/100;
                    //bikemike 11 Dec 2006: $od_amount[$tax_desc]  += ($order->info['shipping_cost'] * $tax_rate)/100;
                    $od_amount['tax'] -= ($order->info['shipping_cost']/(1+$tax_rate/100)) * $tax_rate/100;
                    $od_amount[$tax_desc] += ($order->info['shipping_cost']/(1+$tax_rate/100)) * $tax_rate/100;
                    $order->info['tax_groups'][$tax_desc] += $od_amount['tax'];
                  }
            //}
            // JTD:04/20/06 - end of addition for support to subtract coupon tax from tax total when shipping includes tax
        } else {
           // bikemike 11/11/06 (1.3.5) - this function expects tax_rate
           //$od_amount['total'] += zen_calculate_tax($od_amount['total'], $tax);
           $od_amount['total'] += zen_calculate_tax($od_amount['total'], $tax_rate);
        }
      }
      if ($od_amount['type'] == 'S') $order->info['shipping_cost'] = 0;  // MOVED here by bikemike  12 Dec 2006

      $this->output[] = array('title' => $this->title . ': ' . '<a href="javascript:couponpopupWindow(\'' . zen_href_link(FILENAME_POPUP_COUPON_HELP, 'cID=' . $_SESSION['cc_id']) . '\')">' . $this->coupon_code . '</a> :',
                              'text' => '-' . $currencies->format($od_amount['total']),
                              'value' => $od_amount['total']);
    }
  }
```I commented out the equivalent code in calculate_deductions
```php
...
          if ($coupon->fields['coupon_type']=='S') {
            $od_amount['total'] = $order->info['shipping_cost'];
            $od_amount['type'] = 'S';
            // JTD:04/20/06 - added support to subtract coupon tax from tax total when shipping includes tax
            // bikemike: moved this to fn.process 12 Dec 2006 - with modifications
            //if ($this->include_tax == 'true') {
            //    $tax_rate = zen_get_tax_rate($this->tax_class, $tax_address['country_id'], $tax_address['zone_id']);
            //    $tax_desc = zen_get_tax_description($this->tax_class, $tax_address['country_id'], $tax_address['zone_id']);
            //    if ($tax_rate > 0) {
            //        //bikemike: $od_amount['tax'] -= ($order->info['shipping_cost'] * $tax_rate)/100;
            //        //bikemike: $od_amount[$tax_desc]  += ($order->info['shipping_cost'] * $tax_rate)/100;
            //        $od_amount['tax'] -= ($order->info['shipping_cost']/(1+$tax_rate/100)) * $tax_rate/100;
            //        $od_amount[$tax_desc] += ($order->info['shipping_cost']/(1+$tax_rate/100)) * $tax_rate/100;
            //      }
            //}
            // JTD:04/20/06 - end of addition for support to subtract coupon tax from tax total when shipping includes tax
          } else {
...
```Keen to hear any comments, I'll try and use it for real tomorrow.  It's working this way for %age discounts coupons, and shipping discount coupons.

I have Display Prices with Tax TRUE, and the discount ot is set to Include Shipping=FALSE, Include Tax=FALSE, Re-Calculate Tax=STANDARD, Tax Class=taxable goods...

bikemike
'If language is not used correctly, what is said is not what is meant. If what is said is not what is meant, what ought to be done remains undone' Kǒng fū zǐ

12 Dec 2006, 1:28 AM
#31
jackal avatar

jackal

New Zenner

Join Date:
Oct 2006
Posts:
7
Plugin Contributions:
0

Re: [Done 1.3.6] 1.3.5 coupon tax calculation and fix

I have a tax calculation problem when group discounts are enabled. Could this be related ?

Here is a copy paste of the explanation of the bug, with numbers as examples

Tax bug

$9.99 (taxable goods)
Sub-Total:

$7.37
Canada Post (Shipping to CA (1 x 1.00lb(s))): (taxable freight)

-$5.00
Group Discount (50% of the 9.99 regular price):

$0.69
6% GST #856134168RT0001 + 7.5% TVQ # 1030064140TQ0001: on taxable goods

$0.51
6% GST on shipping + 7.5% TVQ on shipping:

$13.56
Total:

Tax on shipping is the bug because it was charged on 50% of the 7.37 freight charge.

It looks like it applies the 50% group discount to the freight as well before calculating the tax but it leaves the original freight amount correct.

The tax on shipping should be (7.37*1.06)*1.075 = 1.03

The way is does it (7.37 less50%*1.06)*1.075 = .51 but fortunately it leaves the freight cost at 7.37

12 Dec 2006, 5:36 AM
#32
bikemike avatar

bikemike

New Zenner

Join Date:
Oct 2006
Location:
Christchurch, New Zealand
Posts:
44
Plugin Contributions:
0

Re: [Done 1.3.6] 1.3.5 coupon tax calculation and fix

Jackal, as with the sub total showing the full pre-discount value, $9.99, so the freight shows in full, $7.37. The adjustments are taken care of in the tax, discount and total lines. So don't assume the discount applies or not on that basis...> but it leaves the original freight amount correct

I'm curious about the 69cents, check that this is as you expect -- The sum of the TVQ on the discounted goods and shipping comes to 0.690855. The sum of GST AND TVQ on the discounted goods ALONE is 0.6975 (or .70 with 2dp rounding along the way) I think that would show as 0.70 cents instead? What is the actual text on the tax line of the order? Maybe do some different numbers to confirm it's working as you expect.

As for the application of discount to the shipping, what's the setting you have in the modules | order totals | Group Discount for Include Shipping?

Are you using 1.3.6, and or Jeff's addition to handle shipping tax?

JTD:04/20/06 - added support to subtract coupon tax from tax total when shipping includes tax    

bikemike
'If language is not used correctly, what is said is not what is meant. If what is said is not what is meant, what ought to be done remains undone' Kǒng fū zǐ

1 Feb 2010, 5:59 AM
#33
willem avatar

willem

New Zenner

Join Date:
May 2007
Posts:
24
Plugin Contributions:
0

Re: [Done 1.3.6] 1.3.5 coupon tax calculation and fix

wilt:

Actually once I had your figures and I tested against a couple of different selections of cart contents I found the bug fairly quickly.

I am a bit shamefaced that this made its way thru testing, as I was sure that I had tested this fairly comprehensivly

As mentioned the bug only shows if there is more than 1 item in the cart, the bug however has nothing to do with the restriction code.

heres my updated function. Note I would like to test this a bit more before saying that this fix is authorative, especially as I have not tested this with restrictions in place.

function calculate_deductions($order_total) {
global $db, $order, $messageStack;
$tax_address = zen_get_tax_locations();
$od_amount = array();
if ($_SESSION['cc_id']) {
$coupon = $db->Execute("select * from " . TABLE_COUPONS . " where coupon_id = '" . (int)$_SESSION['cc_id'] . "'");
if (($coupon->RecordCount() > 0 && $order_total !=0) || ($coupon->RecordCount() > 0 && $coupon->fields['coupon_type']=='S') ) {
if ($coupon->fields['coupon_minimum_order'] <= $order_total) {
if ($coupon->fields['coupon_type']=='S') {
$od_amount['total'] = $order->info['shipping_cost'];
$od_amount['type'] = 'S';
} else {
if ($coupon->fields['coupon_type'] == 'P') {
$od_amount['total'] = zen_round($order_total*($coupon->fields['coupon_amount']/100), 2);
} else {
$od_amount['total'] = $coupon->fields['coupon_amount'] * ($order_total>0);
}
if ($od_amount['total']>$order_total) $od_amount['total'] = $order_total;
$products = $_SESSION['cart']->get_products();
for ($i=0; $i<sizeof($products); $i++) {
// speed up process and store value
$is_valid_results = is_product_valid($products[$i]['id'], $_SESSION['cc_id']);
if ($is_valid_results) {
if ($coupon->fields['coupon_type'] == 'P') {
switch ($this->calculate_tax) {
case 'Credit Note':
$tax_rate = zen_get_tax_rate($this->tax_class, $tax_address['country_id'], $tax_address['zone_id']);
$tax_desc = zen_get_tax_description($this->tax_class, $tax_address['country_id'], $tax_address['zone_id']);
$od_amount[$tax_desc] = $od_amount['total'] / 100 * $tax_rate;
$od_amount['tax'] += $od_amount[$tax_desc];
break;
case 'Standard':
$ratio = $od_amount['total']/$this->get_order_total();
$t_prid = zen_get_prid($products[$i]['id']);
$cc_result = $db->Execute("select products_tax_class_id
from " . TABLE_PRODUCTS . " where products_id = '" . $t_prid . "'");

                    if ($is_valid_results) {
                      $tax_rate = zen_get_tax_rate($cc_result->fields['products_tax_class_id'], $tax_address['country_id'], $tax_address['zone_id']);
                      $tax_desc = zen_get_tax_description($cc_result->fields['products_tax_class_id'], $tax_address['country_id'], $tax_address['zone_id']);
                      if ($tax_rate > 0) {
                        $od_amount[$tax_desc] += round(((($products[$i]['final_price'] * $products[$i]['quantity']) * $tax_rate) + .5)/100 * $ratio, 2);
                        $od_amount['tax'] += $od_amount[$tax_desc];
                      }
                    }
                break;
                default:
              }
            }
            if ($coupon->fields['coupon_type'] == 'F') {
              switch ($this->calculate_tax) {
                case 'Credit Note':
                  $tax_rate = zen_get_tax_rate($this->tax_class, $tax_address['country_id'], $tax_address['zone_id']);
                  $tax_desc = zen_get_tax_description($this->tax_class, $tax_address['country_id'], $tax_address['zone_id']);
                  $od_amount[$tax_desc] = $od_amount['total'] / 100 * $tax_rate;
                  $od_amount['tax'] += $od_amount[$tax_desc];
                break;
                case 'Standard':
                  $ratio = $od_amount['total']/$this->get_order_total();
                  $products = $_SESSION['cart']->get_products();
                    $t_prid = zen_get_prid($products[$i]['id']);
                    $cc_result = $db->Execute("select products_tax_class_id
                                               from " . TABLE_PRODUCTS . " where products_id = '" . $t_prid . "'");

                    if ($is_valid_results) {
                      $tax_rate = zen_get_tax_rate($cc_result->fields['products_tax_class_id'], $tax_address['country_id'], $tax_address['zone_id']);
                      $tax_desc = zen_get_tax_description($cc_result->fields['products_tax_class_id'], $tax_address['country_id'], $tax_address['zone_id']);
                      if ($tax_rate > 0) {
                        $od_amount[$tax_desc] += round(((($products[$j]['final_price'] * $products[$j]['quantity']) * $tax_rate) + .5)/100 * $ratio, 2);
                        $od_amount['tax'] += $od_amount[$tax_desc];
                      }
                    }
                break;
                default:
              }
            }
          }
        }
      }
    }
  }
}
return $od_amount;

}


This worked for me. Thanks!!

Willem