Virtuemart discount tax calculation fix

With this post on the virtuemart scene I am hoping a lot of people would be able to benefit. This is a bug in the existing virtuemart (till 1.1.3) system that is seen when discounts are being used and the tax calculation is set to be done after the reduced price.

This issue is not seen when using tax calculation based on vendor address, but only in case of shipping address based tax calculation.

The edit needs to be done only the ps_checkout.php (around line 1469) file as shown below.

		// Shipping address based TAX
		if ( !ps_checkout::tax_based_on_vendor_address () ) {
			$q = "SELECT state, country FROM #__{vm}_user_info ";
			$q .= "WHERE user_info_id='".$ship_to_info_id. "'";
			$db->query($q);
			$db->next_record();
			$state = $db->f("state");
			$country = $db->f("country");
			$q = "SELECT * FROM #__{vm}_tax_rate WHERE tax_country='$country' ";
			if( $state ) {
				$q .= "AND tax_state='$state'";
			}
			$db->query($q);
			if ($db->next_record()) {
				$rate = $order_taxable * floatval( $db->f("tax_rate") );
				if (empty($rate)) {
					$order_tax = 0.0;
				}
				else {
					$order_tax = $rate;
				}
			}
			else {
				$order_tax = 0.0;
			}
			$order_tax_details[$db->f('tax_rate')] = $order_tax;
		}

should be changed to look like

                // Shipping address based TAX
                if ( !ps_checkout::tax_based_on_vendor_address () ) {
                     $q = "SELECT state, country FROM #__{vm}_user_info ";
                     $q .= "WHERE user_info_id='".$ship_to_info_id. "'";
                     $db->query($q);
                    $db->next_record();
                    $state = $db->f("state");
                    $country = $db->f("country");
                    $q = "SELECT * FROM #__{vm}_tax_rate WHERE tax_country='$country' ";
                    if( $state ) {
                        $q .= "AND tax_state='$state'";
                    }
                    $db->query($q);
                    if ($db->next_record()) {
                        $rate = $order_taxable * floatval( $db->f("tax_rate") );
                        if (empty($rate)) {
                            $order_tax = 0.0;
                        } else {
                            $cart = $_SESSION['cart'];
                            if( (!empty( $_SESSION['coupon_discount'] ) || !empty( $d['payment_discount'] ))
                                && PAYMENT_DISCOUNT_BEFORE == '1' ) {

                                require_once(CLASSPATH.'ps_product.php');
                                $ps_product= new ps_product;

                                for($i = 0; $i < $cart["idx"]; $i++) {
                                    $item_weight = ps_shipping_method::get_weight($cart[$i]["product_id"]) * $cart[$i]['quantity'];

                                    if ($item_weight !=0 or TAX_VIRTUAL) {
                                        $price = $ps_product->get_adjusted_attribute_price($cart[$i]["product_id"], $cart[$i]["description"]);
                                        $price['product_price'] = $GLOBALS['CURRENCY']->convert( $price['product_price'], $price['product_currency']);
                                        $tax_rate = $db->f("tax_rate");

                                        $use_coupon_discount= @$_SESSION['coupon_discount'];
                                        if( !empty( $_SESSION['coupon_discount'] )) {
                                            if( $auth["show_price_including_tax"] == 1 ) {
                                                $use_coupon_discount = $_SESSION['coupon_discount'] / ($tax_rate+1);
                                            }
                                        }
                                        $factor = (100 * ($use_coupon_discount + @$d['payment_discount'])) / $this->_subtotal;
                                        $price["product_price"] = $price["product_price"] - ($factor * $price["product_price"] / 100);
                                        @$order_tax_details[$tax_rate] += $price["product_price"] * $tax_rate * $cart[$i]["quantity"];

                                        $order_tax += $price["product_price"] * $tax_rate * $cart[$i]["quantity"];
                                        $total += $price["product_price"] * $cart[$i]["quantity"];
                                    } else {
                                        $order_tax += 0.0;
                                    }
                                }
                            } else {
                                $order_tax = $rate;
                            }
                        }
                    } else {
                        $order_tax = 0.0;
                    }
                    $order_tax_details[$db->f('tax_rate')] = $order_tax;
                }

I think this should pretty much eliminate the issue (unless I have missed something!). Also, if this is the correct fix I hope to have contributed to the future build of virtuemart (which, btw, is the best OSS for ecommerce!)

UPDATE:- After this, in the shopper group defaults, you need to deselect the ‘show price with tax’ variable and this will work as expected.

7 Responses to “Virtuemart discount tax calculation fix


  • In Color
    July 7th, 2009 06:17
    1

    Thank you so much for this. I was pulling my hair out trying to fix this problem, and your patch did the trick.

  • VirtueMart 1.1.4 发布了! | 中文专业网店Magento开发服务
    October 16th, 2009 17:44
    2

    [...] added the fix for order tax calculation when coupon discounts are used http://www.nandebayo.org/blog/?p=80 [...]

  • Frank Beier
    November 9th, 2009 22:26
    3

    found a coupon error with the latest vm update to 1.1.4 – coupons discounts are getting doubled and deducted. No matter what you do, coupon values double in value. Where should I look for code abnormalities with this one?

  • admin
    November 10th, 2009 22:23
    4

    @Frank:

    I am not sure in what reference you are asking me this question. VM code isn’t a couple of lines for me to take a guess.

    As far as this fix is concerned, it is already in place in the latest release (1.1.4) so you shouldn’t have had to modify anything.

  • andrea
    December 2nd, 2009 11:44
    5

    I cant use this hack because my customers need to see products with the tax included.

  • Aaron
    December 8th, 2009 02:06
    6

    Hi there,

    you state above that this issue is not present for vendor based tax orders. However I have found this is not the case.

    Not being a coder myself could this code be adapted for vendor based orders?

    I would really appreciate a response as this is how I earn a living of my store and really need to give coupons to my customers.

  • Richard Webber
    February 5th, 2010 00:55
    7

    I\’m running 1.1.4 and still see this issue, or an issue like it. When using a coupon (and I\’m using the product based coupon patch, though that doesn\’t seem to make a difference), the order total shown is equal to the tax total.

    Interestingly, before a user enters his login details, Virtuemart assumes \”Vendor based tax calculation\”, but the issue is still seen once the user has confirmed their address. The coupon I\’ve used is called \”newtest\” which gives a 50% discount. I\’ve also turned debug on to see what is going on, but it hasn\’t helped!

Leave a Reply

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word