VirtueMart Forum

VirtueMart 2 + 3 + 4 => Plugins: Payment, Shipment and others => Topic started by: zanardi on October 18, 2012, 11:18:30 AM

Title: Coupon discount and free shipping
Post by: zanardi on October 18, 2012, 11:18:30 AM
VirtueMart 2.0.10 on Joomla 2.5

I would like a confirmation or clarifications about free shipping and coupon discounts.

I have a shipping method which gets free shipping over € 150. So if my total amount is, e.g., € 180, i get free shipping.
Now I use a coupon, e.g. a 50% coupon, that sets the total to € 90.
I still get free shipping, even if I am going to pay less than € 150.

Is that intended behaviour? Is it configurable?

Thank you for any suggestion.
Title: Re: Coupon discount and free shipping
Post by: zanardi on January 07, 2013, 14:46:23 PM
This (possible) issue is still there in VirtueMart 2.0.14. Free shipping threshold is checked against total price BEFORE coupon discount is calculated.
I see that in

  /plugins/vmshipment/weight_countries/weight_countries.php

there's a method

  plgVmShipmentWeight_countries::getCosts

which does the check:

  if ($method->free_shipment && $cart_prices['salesPrice'] >= $method->free_shipment) {

I changed that to

  if ($method->free_shipment && ( $cart->pricesUnformatted['billTotal'] >= $method->free_shipment ) ) {

to get the desired behaviour for free shipping.

Thank you for any opinion on this matter.
Title: Re: Coupon discount and free shipping
Post by: bytelord on January 07, 2013, 14:59:05 PM
Hello,

Please try with 2.0.16d. The coupon calculation have been changed, please test it.
Title: Re: Coupon discount and free shipping
Post by: zanardi on January 08, 2013, 09:35:52 AM
@bytelord:
no difference in 2.0.16d, the issue is still there.

Please note that I am not talking about a *coupon* issue, but about a *free shipping* issue. The coupon is only a condition that triggers the possibly unintended behaviour.

If you look at the code of the  plgVmShipmentWeight_countries::getCosts you will see that it still checks free shipping threshold against the "salesPrice" instead of the "billTotal" so of course the coupon discount is not taken into account.

In my previous post i suggest a possible solution (which I am actually using on a production site).
Title: Re: Coupon discount and free shipping
Post by: veeco on January 08, 2013, 13:22:48 PM
@zanardi, by common sense, i think you got the point right.. 
Title: Re: Coupon discount and free shipping
Post by: kermitfrog on February 13, 2013, 10:41:50 AM
Quote from: zanardi on January 07, 2013, 14:46:23 PM
This (possible) issue is still there in VirtueMart 2.0.14. Free shipping threshold is checked against total price BEFORE coupon discount is calculated.
I see that in

  /plugins/vmshipment/weight_countries/weight_countries.php

there's a method

  plgVmShipmentWeight_countries::getCosts

which does the check:

  if ($method->free_shipment && $cart_prices['salesPrice'] >= $method->free_shipment) {

I changed that to

  if ($method->free_shipment && ( $cart->pricesUnformatted['billTotal'] >= $method->free_shipment ) ) {

to get the desired behaviour for free shipping.

Thank you for any opinion on this matter.

Thanks zanardi, exactly what I was looking for - I Have the same problem.
Price: 18,70 Euro
Coupon: 20% off
-> 14,96 Euro
(Free Shipping when more than 15 Euro)
14,96 -> Free Shipping  :-\

But on my Joomla 2.5.9 and Virtuemart 2.0.18a 
$cart->pricesUnformatted['billTotal']    is not working. When I use this, the "if" never becomes true.

I'm not that good in php, but i tried  return $cart->pricesUnformatted['billTotal']; to check the value... the card showed nothing.
return $cart_prices['salesPrice']; correctly returns the amount (but without discount).

Adding $cart->pricesUnformatted['salesPriceCoupon']   also doesn't work for me (empty, too).

I also tried to solve this problem by adding another shipment method with the minimum amount 15 und shipping costs 0 ...
But the minumum / maximum amount for a shipping method is also not effected by the coupon amount.

Any ideas?
Thank a lot!
Title: Re: Coupon discount and free shipping
Post by: kermitfrog on February 14, 2013, 10:50:45 AM
Maybe I found why this is working in 2.0.14 and no longer in 2.0.18a...
cart.php  line 225  in the function setCartIntoSession()

in Version 2.0.18 pricesUnformatted is commented:
//$sessionCart->pricesUnformatted    = $this->pricesUnformatted;

in Version 2.0.14, this is without // comments...

I guess, it must have a reason why this is done. But this makes your trick impossible -.-
Title: Re: Coupon discount and free shipping
Post by: ArtRight on March 30, 2013, 22:06:43 PM
Thank you zanardi!  Your solution worked for me also, VM 2.0.2.
Title: Re: Coupon discount and free shipping
Post by: zanardi on April 11, 2013, 14:49:42 PM
Quote from: kermitfrog on February 14, 2013, 10:50:45 AM
Maybe I found why this is working in 2.0.14 and no longer in 2.0.18a...
cart.php  line 225  in the function setCartIntoSession()

in Version 2.0.18 pricesUnformatted is commented:
//$sessionCart->pricesUnformatted    = $this->pricesUnformatted;

Thank you for pointing that out.
I tried different methods but I can't find a different solution to get the final price from the available objects.
So the original issue remains and the proposed fix has been disabled. Great.
Title: Re: Coupon discount and free shipping
Post by: kermitfrog on June 07, 2013, 10:05:53 AM
This error also effects the payment method if you are using a min or max amount.

I tried to reactivate some lines in the code to make this solution work again. But the problem is, that the shopping card has to be manually reloaded after using a discount coupon.
Only after a manual reload (F5) the settings are correct. Seems that the Shipping and Payment methods are calculated before the total amount is calculated.

Well, I'm no good programmer - so I give up ;o)
Title: Re: Coupon discount and free shipping
Post by: zanardi on August 12, 2013, 19:26:00 PM
Wrote some code to work around the issue.

/plugins/vmshipment/weight_countries/weight_countries.php, change this code


/**
* @param VirtueMartCart $cart
* @param                $method
* @param                $cart_prices
* @return int
*/
function getCosts (VirtueMartCart $cart, $method, $cart_prices) {

  if ($method->free_shipment && $cart_prices['salesPrice'] >= $method->free_shipment) {
    return 0;
  } else {
    return $method->cost + $method->package_fee;
  }
}


to this



/**
* @param VirtueMartCart $cart
* @param                $method
* @param                $cart_prices
* @return int
*/
function getCosts (VirtueMartCart $cart, $method, $cart_prices) {

  if ($cart->couponCode) {
    $cart_prices['salesPrice'] = $this->applyCoupon($cart->couponCode, $cart_prices['salesPrice'] );
  }
  if ($method->free_shipment && $cart_prices['salesPrice'] >= $method->free_shipment) {
    return 0;
  } else {
    return $method->cost + $method->package_fee;
  }
}

/**
* Custom function to get total price with coupon applied
*
* @param string $couponcode
* @param float $salesprice
*/
private function applyCoupon($couponcode, $salesprice)
{
  require_once JPATH_VM_SITE.'/helpers/coupon.php';
  if (!($data = CouponHelper::getCouponDetails($couponcode))) {
    return $salesprice;
  }
  if ($data->percent_or_total == 'total') {
    return $salesprice - $data->coupon_value;
  }
  else {
    return $salesprice - ($salesprice * $data->coupon_value / 100);
  }



Basically, I have added a custom check for the presence of a coupon code, and then a custom method to get the coupon-discounted total.
Of course the "correct" way is not to hack the core plugin, but to create a custom plugin instead... but that is left as an exercise to the reader. This works and today it's already way too late.