dressmylegs.ie Posted March 3, 2014 Share Posted March 3, 2014 Hi, I'm having problems with how the shipping rate is applied at the checkout and would like some imput from the experts. I'm currently offering free shipping on orders over €35 and €1.95 for orders under €35. However, if there is a promotion (for example, 3 for 2) the shipping cost is still being calculated based on the original cart total, not the final figure. For example: Now: customer buys 3 products, €15 each, on 3 for 2 promotion. The product total before promotion is €45, so the free shipping is added to the order. Then the cart shows a deduction of €15 on 3 for 2, so the order total is now €30 (and this is what the customer pays) but the shipping is still free. Should be: As the final payment amount is below the free shipping threashold, the €1.95 charge must be added. Basically, I need to configure the shipping cost so that it's added last, after applications of discounts, vouchers, promotions, etc. Any help is greatly appreciated! 1 Link to comment Share on other sites More sharing options...
mathidla Posted April 16, 2014 Share Posted April 16, 2014 I'm having the same issue. Somebody plz help! 1 Link to comment Share on other sites More sharing options...
mouse1 Posted May 12, 2014 Share Posted May 12, 2014 Same here :-( I cannot find any solution. 1 Link to comment Share on other sites More sharing options...
mtporter Posted July 14, 2014 Share Posted July 14, 2014 Same here Link to comment Share on other sites More sharing options...
hatak Posted December 18, 2014 Share Posted December 18, 2014 I think I figured it out in ps 1.6 this modification takes a total price of products with discounts for calculating range of shipping it's not nice solution but works classes/cart.php at about 2561 line after this // Order total in default currency without fees $order_total = $this->getOrderTotal(true, Cart::ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING, $product_list); you need add $order_dis = $this->getOrderTotal(true, Cart::ONLY_DISCOUNTS, $product_list); $order_total = $order_total - $order_dis; have fun 1 Link to comment Share on other sites More sharing options...
deli00 Posted May 10, 2015 Share Posted May 10, 2015 I think I figured it out in ps 1.6 this modification takes a total price of products with discounts for calculating range of shipping it's not nice solution but works classes/cart.php at about 2561 line after this // Order total in default currency without fees $order_total = $this->getOrderTotal(true, Cart::ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING, $product_list); you need add $order_dis = $this->getOrderTotal(true, Cart::ONLY_DISCOUNTS, $product_list); $order_total = $order_total - $order_dis; have fun I added it and now all my pages load blank... any ideas? Link to comment Share on other sites More sharing options...
mir-aus Posted May 18, 2015 Share Posted May 18, 2015 I think I figured it out in ps 1.6 this modification takes a total price of products with discounts for calculating range of shipping it's not nice solution but works classes/cart.php at about 2561 line after this // Order total in default currency without fees $order_total = $this->getOrderTotal(true, Cart::ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING, $product_list); you need add $order_dis = $this->getOrderTotal(true, Cart::ONLY_DISCOUNTS, $product_list); $order_total = $order_total - $order_dis; have fun it's working for me Link to comment Share on other sites More sharing options...
CJV Posted May 21, 2015 Share Posted May 21, 2015 It´s working for me too. Thanks!!! Link to comment Share on other sites More sharing options...
aka_ys Posted May 27, 2015 Share Posted May 27, 2015 Hi, that not work, you try to create a voucher code with a free shipping, this will return a error. Link to comment Share on other sites More sharing options...
mir-aus Posted May 28, 2015 Share Posted May 28, 2015 Hi, that not work, you try to create a voucher code with a free shipping, this will return a error. which error do you have? Link to comment Share on other sites More sharing options...
aka_ys Posted May 28, 2015 Share Posted May 28, 2015 which error do you have? if you create this voucher (cart rule), return a maximum execution time error. Because prestashop calls 8 times this function (getpackageshippingcost) and this function calls getOrderTotal 2 times, every time. Link to comment Share on other sites More sharing options...
CJV Posted May 28, 2015 Share Posted May 28, 2015 Hi Aka_ys and mir-aus Same problem here... I can´t create any cart rule with free shipping. If I select this option then the shop crash when the customer selects this voucher and then the only option is to delete the cart (in backoffice) and then the customer can start from the beginning. Please help. (Sorry my english) Link to comment Share on other sites More sharing options...
mir-aus Posted May 29, 2015 Share Posted May 29, 2015 (edited) Hi Aka_ys and mir-aus Same problem here... I can´t create any cart rule with free shipping. If I select this option then the shop crash when the customer selects this voucher and then the only option is to delete the cart (in backoffice) and then the customer can start from the beginning. Please help. (Sorry my english) HI, but for me is working OK, I have price range( for example anything over than $95.00 with AUSpost shows free shipping) I never use free shipping option in cart rule. If I use free shipping in cart rule then it doesn't work for me as well. Edited May 29, 2015 by mir-aus (see edit history) Link to comment Share on other sites More sharing options...
mir-aus Posted May 29, 2015 Share Posted May 29, 2015 I think If we can add some code which said that, IF discount code use freeshipping option use same code as before. or in simple way: after: // Order total in default currency without fees $order_total = $this->getOrderTotal(true, Cart::ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING, $product_list) we need code : if discount code use free shipping option do same as before if discount code doesn't use freeshipping option and use the price range for shipping then do this: $order_dis = $this->getOrderTotal(true, Cart::ONLY_DISCOUNTS, $product_list); $order_total = $order_total - $order_dis; I am not web-developer to type the new code if anyone knows that will help us. Link to comment Share on other sites More sharing options...
aka_ys Posted June 2, 2015 Share Posted June 2, 2015 (edited) Hi Aka_ys and mir-aus Same problem here... I can´t create any cart rule with free shipping. If I select this option then the shop crash when the customer selects this voucher and then the only option is to delete the cart (in backoffice) and then the customer can start from the beginning. Please help. (Sorry my english) no problem. follow steps: (the problem occurs when use function getOrderTotal with ONLY_DISCOUNTS when the discount is free shipping) Overriding class Cart.php You need create your own method. 1) Create function to get vouchers of this cart. public function getVoucher_(){ $cart_id = Context::getContext()->cart->id; $cart = New Cart($cart_id); $cr = $this->getRealDisc($cart_id); return $cr; } 2) Create second function calling from getVoucher_ public function getRealDisc($cart_id) { return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' SELECT `id_cart_rule` FROM `'._DB_PREFIX_.'cart_cart_rule` cr WHERE cr.`id_cart` = '.(int)$cart_id); } 3) Create other function that return if this cart_rule is free_shipping public function existFreeRule($id_cart_rule) { $result = Db::getInstance()->getValue(' SELECT `free_shipping` FROM `'._DB_PREFIX_.'cart_rule` cr WHERE cr.id_cart_rule = '.(int)$id_cart_rule.' AND cr.date_from < "'.date('Y-m-d H:i:s').'" AND cr.date_to > "'.date('Y-m-d H:i:s').'"'); return $result; } 4) And finally modify prestashop function getPackageShippingCost like after. Add this lines after // Order total in default currency without fees and before of // Start with shipping cost at 0 $shipping_cost = 0; // Order total in default currency without fees $order_total = $this->getOrderTotal(true, Cart::ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING, $product_list); //recalculate shipping cost $free_s = false; $cr = $this->getVoucher_(); if(count($cr) > 0){ foreach ($cr as $crr) { $exist = $this->existFreeRule($crr['id_cart_rule']); if ($exist == 1){ $free_s = true; break; } } } if(!$free_s){ $order_dis = $this->getOrderTotal(true, Cart::ONLY_DISCOUNTS, $product_list); $order_total = $order_total - $order_dis; } // Start with shipping cost at 0 $shipping_cost = 0; From this way, you only run this function getOrderTotal(true, Cart::ONLY_DISCOUNTS, $product_list); when there are no free shipping discounts in cart Edited June 2, 2015 by aka_ys (see edit history) Link to comment Share on other sites More sharing options...
CJV Posted June 8, 2015 Share Posted June 8, 2015 Hi aka_ys, It works!! Thank you very much! Genius!! The only problem is that I´ve just detected that prestashop doesn´t apply automatically the "free shipping" option to a new cart rule generated after using it partially to pay an order. I mean with the "partial use" option applied. So I have to manually apply the option "free shipping" to each new cart rule generated after each use... :-( (sorry my english) Link to comment Share on other sites More sharing options...
hyChemira Posted July 22, 2015 Share Posted July 22, 2015 I added it and now all my pages load blank... any ideas? Same problem to me.... anyone can help on this? Link to comment Share on other sites More sharing options...
annoyingusername Posted October 15, 2015 Share Posted October 15, 2015 (edited) Hi, here is another (dirty) workaround that is working in a prestashop 1.6.1.1 with a huge amount of products, without blank page or "out of memory" error. just replace $order_total from $orderTotalwithDiscounts in lines 2965 and 2972 classes/Cart.php // Get shipping cost using correct method if ($carrier->range_behavior) { if (!isset($id_zone)) { // Get id zone if (isset($this->id_address_delivery) && $this->id_address_delivery && Customer::customerHasAddress($this->id_customer, $this->id_address_delivery)) { $id_zone = Address::getZoneById((int)$this->id_address_delivery); } else { $id_zone = (int)$default_country->id_zone; } } if (($shipping_method == Carrier::SHIPPING_METHOD_WEIGHT && !Carrier::checkDeliveryPriceByWeight($carrier->id, $this->getTotalWeight(), (int)$id_zone)) || ($shipping_method == Carrier::SHIPPING_METHOD_PRICE && !Carrier::checkDeliveryPriceByPrice($carrier->id, $total_package_without_shipping_tax_inc, $id_zone, (int)$this->id_currency) )) { $shipping_cost += 0; } else { if ($shipping_method == Carrier::SHIPPING_METHOD_WEIGHT) { $shipping_cost += $carrier->getDeliveryPriceByWeight($this->getTotalWeight($product_list), $id_zone); } else { // by price //WORKAROUND //$shipping_cost += $carrier->getDeliveryPriceByPrice($order_total, $id_zone, (int)$this->id_currency); $shipping_cost += $carrier->getDeliveryPriceByPrice($orderTotalwithDiscounts, $id_zone, (int)$this->id_currency); } } } else { if ($shipping_method == Carrier::SHIPPING_METHOD_WEIGHT) { $shipping_cost += $carrier->getDeliveryPriceByWeight($this->getTotalWeight($product_list), $id_zone); } else { //WORKAROUND //$shipping_cost += $carrier->getDeliveryPriceByPrice($order_total, $id_zone, (int)$this->id_currency); $shipping_cost += $carrier->getDeliveryPriceByPrice($orderTotalwithDiscounts, $id_zone, (int)$this->id_currency); } } Edited October 15, 2015 by annoyingusername (see edit history) 2 Link to comment Share on other sites More sharing options...
hyChemira Posted October 21, 2015 Share Posted October 21, 2015 Hi, here is another (dirty) workaround that is working in a prestashop 1.6.1.1 with a huge amount of products, without blank page or "out of memory" error. just replace $order_total from $orderTotalwithDiscounts in lines 2965 and 2972 classes/Cart.php // Get shipping cost using correct method if ($carrier->range_behavior) { if (!isset($id_zone)) { // Get id zone if (isset($this->id_address_delivery) && $this->id_address_delivery && Customer::customerHasAddress($this->id_customer, $this->id_address_delivery)) { $id_zone = Address::getZoneById((int)$this->id_address_delivery); } else { $id_zone = (int)$default_country->id_zone; } } if (($shipping_method == Carrier::SHIPPING_METHOD_WEIGHT && !Carrier::checkDeliveryPriceByWeight($carrier->id, $this->getTotalWeight(), (int)$id_zone)) || ($shipping_method == Carrier::SHIPPING_METHOD_PRICE && !Carrier::checkDeliveryPriceByPrice($carrier->id, $total_package_without_shipping_tax_inc, $id_zone, (int)$this->id_currency) )) { $shipping_cost += 0; } else { if ($shipping_method == Carrier::SHIPPING_METHOD_WEIGHT) { $shipping_cost += $carrier->getDeliveryPriceByWeight($this->getTotalWeight($product_list), $id_zone); } else { // by price //WORKAROUND //$shipping_cost += $carrier->getDeliveryPriceByPrice($order_total, $id_zone, (int)$this->id_currency); $shipping_cost += $carrier->getDeliveryPriceByPrice($orderTotalwithDiscounts, $id_zone, (int)$this->id_currency); } } } else { if ($shipping_method == Carrier::SHIPPING_METHOD_WEIGHT) { $shipping_cost += $carrier->getDeliveryPriceByWeight($this->getTotalWeight($product_list), $id_zone); } else { //WORKAROUND //$shipping_cost += $carrier->getDeliveryPriceByPrice($order_total, $id_zone, (int)$this->id_currency); $shipping_cost += $carrier->getDeliveryPriceByPrice($orderTotalwithDiscounts, $id_zone, (int)$this->id_currency); } } This is working!!! Thank you very much!!! Link to comment Share on other sites More sharing options...
malawi11 Posted October 30, 2015 Share Posted October 30, 2015 Thank you annoyingusername , your solution works Link to comment Share on other sites More sharing options...
brrt Posted June 5, 2016 Share Posted June 5, 2016 (edited) I think this is the regarding github-issue: [*] Calculate carrier price on the real order price #4402 the suggested solution is even simpler: instead of "ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING": $order_total = $this->getOrderTotal(true, Cart::ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING, $product_list); use "BOTH_WITHOUT_SHIPPING" : $order_total = $this->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING, $product_list); Edited June 5, 2016 by brrt (see edit history) 4 2 Link to comment Share on other sites More sharing options...
ajensen27 Posted August 31, 2016 Share Posted August 31, 2016 I think this is the regarding github-issue: [*] Calculate carrier price on the real order price #4402 the suggested solution is even simpler: instead of "ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING": $order_total = $this->getOrderTotal(true, Cart::ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING, $product_list); use "BOTH_WITHOUT_SHIPPING" : $order_total = $this->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING, $product_list); This didn't work for me in 1.6.2. Any ideas why? I cleared the cache after I made the changes. Emptied my cart, and re-added a product and voucher code. Still doesn't work. Link to comment Share on other sites More sharing options...
Rissinko Posted November 15, 2016 Share Posted November 15, 2016 I tried use this in a new function in cart.php and echo the output but it return this error : Fatal error: Using $this when not in object context in Maybe this is why it didn't work for you because it's not correct. Link to comment Share on other sites More sharing options...
ozdemir Posted December 8, 2016 Share Posted December 8, 2016 I think this is the regarding github-issue: [*] Calculate carrier price on the real order price #4402 the suggested solution is even simpler: instead of "ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING": $order_total = $this->getOrderTotal(true, Cart::ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING, $product_list); use "BOTH_WITHOUT_SHIPPING" : $order_total = $this->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING, $product_list); Its working on my system (1.6.1.6). Thanks a lot. Link to comment Share on other sites More sharing options...
swz3000 Posted July 31, 2017 Share Posted July 31, 2017 I think this is the regarding github-issue: [*] Calculate carrier price on the real order price #4402 the suggested solution is even simpler: instead of "ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING": $order_total = $this->getOrderTotal(true, Cart::ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING, $product_list); use "BOTH_WITHOUT_SHIPPING" : $order_total = $this->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING, $product_list); This worked for me on 1.6.1.12, perfect solucion!!!!!!!!!! Link to comment Share on other sites More sharing options...
Recommended Posts