siomosp Posted November 11, 2012 Share Posted November 11, 2012 (edited) Hello eveybody. I am looking for a solution for overiding free shipping in specific products or categories , PS 1.5.2. For example, I have set a free shipping starting at 50 €. I need, If a customer adds a product with additional shipping cost enabled , this cost is added to cart, even the cart sum is over 50€. Any suggestions? Edited November 11, 2012 by siomosp (see edit history) Link to comment Share on other sites More sharing options...
bellini13 Posted November 11, 2012 Share Posted November 11, 2012 I searched the 1.5.2 code for the configuration name "PS_SHIPPING_FREE_PRICE". This is the name of the field in the back office related to your free shipping starting at 50 € There are only 2 places in the code that use it, which are Cart.php and AdminShippingController.php You can ignore AdminShippingController.php since that is the configuration page where you entered 50 € In Cart.php there is a function called getPackageShippingCost which has the following code // Free fees $free_fees_price = 0; if (isset($configuration['PS_SHIPPING_FREE_PRICE'])) $free_fees_price = Tools::convertPrice((float)$configuration['PS_SHIPPING_FREE_PRICE'], Currency::getCurrencyInstance((int)$this->id_currency)); $orderTotalwithDiscounts = $this->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING, null, null, false); if ($orderTotalwithDiscounts >= (float)($free_fees_price) && (float)($free_fees_price) > 0) { Cache::store($cache_id, $shipping_cost); return $shipping_cost; } It would seem you could override this code to introduce your custom logic, so that instead of returning zero if the free shipping price is met, that you would instead return the correct rate. Now I have to admit, I am having a hard time believing that this is the only area of the code that needs to change. I would suggest taking baby steps, start with this code change and test it and see how it works. 1 Link to comment Share on other sites More sharing options...
siomosp Posted November 11, 2012 Author Share Posted November 11, 2012 It seems that you guide me to the right way I am not a programmer, but .... For products with additional price enabled , adding to cart.php code, the "$product['additional_shipping_cost'] <= 0" seems to do the trick! // Free fees $free_fees_price = 0; if (isset($configuration['PS_SHIPPING_FREE_PRICE'])) $free_fees_price = Tools::convertPrice((float)$configuration['PS_SHIPPING_FREE_PRICE'], Currency::getCurrencyInstance((int)$this->id_currency)); $orderTotalwithDiscounts = $this->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING, null, null, false); if ($product['additional_shipping_cost'] <= 0 && $orderTotalwithDiscounts >= (float)($free_fees_price) && (float)($free_fees_price) > 0 ) { Cache::store($cache_id, $shipping_cost); return $shipping_cost; } ( i am not marking it "solved" yet, before furter testing ) Link to comment Share on other sites More sharing options...
mouse1 Posted May 10, 2014 Share Posted May 10, 2014 Hi everyone. The above mentioned solution does not work for me. :-( Any other ideas? Link to comment Share on other sites More sharing options...
mouse1 Posted May 13, 2014 Share Posted May 13, 2014 (edited) I think I found the solution. I'm not a programmer and haven't tested it properly yet, but so far it seems to be working... in classes/Cart.php there is the following code: // Additional Shipping Cost per product foreach ($products as $product) if (!$product['is_virtual']) $shipping_cost += $product['additional_shipping_cost'] * $product['cart_quantity']; I edited the code as follows (added && $shipping_cost > 0) // Additional Shipping Cost per product foreach ($products as $product) if (!$product['is_virtual'] && $shipping_cost > 0) $shipping_cost += $product['additional_shipping_cost'] * $product['cart_quantity']; Now if the price range for free shipping is reached in the cart, additional price per item will not be added. In other words, it will only be added if shipping cost is higher than zero. Another thing is - if you do not want the additional shipping per item to be added multiple times, delete * $product['cart_quantity'] from the code. Let me know how this works for you. And don't forget to backup just in case. ;-) PS: I'm using Prestashop 1.5.4.0 Edited May 14, 2014 by mouse1 (see edit history) Link to comment Share on other sites More sharing options...
kadapawn Posted June 2, 2014 Share Posted June 2, 2014 (edited) nice! The code is working but there is a problem, when you add another product in the same cart with the product with extra shipping cost, the value of the extra shipping disappear and the free shipping appear. Any way to bypass that? Edited June 2, 2014 by kadapawn (see edit history) Link to comment Share on other sites More sharing options...
mouse1 Posted July 3, 2016 Share Posted July 3, 2016 To kadapawn: Have you solved the problem? If not, check your general free shipping rules in your shop. In my case, if I add any number of products with extra shipping in the cart, free shipping won't appear until the limit for free shipping is reached. However, I found another problem. The solution from my post #5 only applies on the quantities of the same product. If another product with extra shippping is added in the cart, extra shipping is multiplied. Example: Cart 1:Product A (with extra shipping) - Qty 2: extra shipping is charged only once Cart 2: Product A (with extra shipping) - Qty 2 - extra shipping is charged once Product B (with extra shipping) - Qty 1 - extra shipping is charged again, so twice in total What I needed was to charge my customers only one additional shipping fee per cart, doesn't matter how many products with extra shipping are added. This is the code I used (classes - Cart.php): foreach ($products as $product) if (!$product['is_virtual'] && $shipping_cost > 0) $shipping_cost += $product['additional_shipping_cost']; and just removed: foreach ($products as $product) Now, only 1 extra shipping is charged per cart. Hope this helps someone else as well. Good luck with your shops. ;-) Link to comment Share on other sites More sharing options...
mouse1 Posted September 1, 2016 Share Posted September 1, 2016 A very weird problem occured. I am using the above mentioned solution (post #7). When I add two products in the cart - 1 product with extra shipping and 1 product without extra shipping - the extra shipping is only calculated correctly if the second product was added in the shop BEFORE the product with extra shipping. Any product added in the shop AFTER the product with extra charge removes the extra charge from the cart. Any ideas what could be causing this? It is so weird. Example: shipping is 5 USD, extra shipping set individually in BO for a specific product is 1 USD Cart 1:Product A (with extra shipping) Product B (product without extra shipping, added in the shop BEFORE product A) Shipping TOTAL: 6 USD (extra shipping is applied) Cart 2: Product A (with extra shipping) Product B (product without extra shipping, added in the shop AFTER product A) Shipping TOTAL: 5 USD (the total is wrong, it should be 6 USD = extra shipping is not applied) Link to comment Share on other sites More sharing options...
GrandMa90 Posted November 14, 2017 Share Posted November 14, 2017 (edited) I know this is an old thread but i managed to make this work. The fix works on 1.6.x. We have specific products that have special shipping costs applied to them (due to their weight and the extra money the carrier charges us for them). We needed a way to keep the shipping if under X $, and add the additional shipping fees, but if the order is greater than X $, only the additional shipping fees will count as shipping. Because the first situation is default in prestashop, i found a way to override the second situation (because PS always disregarded the additional shipping fees if shipping is free). In cart.php, where the Free Fee is set, go ahead and replace the whole chunk of code to: // Free fees $free_fees_price = 0; if (isset($configuration['PS_SHIPPING_FREE_PRICE'])) { $free_fees_price = Tools::convertPrice((float)$configuration['PS_SHIPPING_FREE_PRICE'], Currency::getCurrencyInstance((int)$this->id_currency)) ; } $orderTotalwithDiscounts = $this->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING, null, null, false); if ($orderTotalwithDiscounts >= (float)($free_fees_price) && (float)($free_fees_price) > 0) { Cache::store($cache_id, $shipping_cost); foreach ($products as $product) { //added line $shipping_cost = $shipping_cost + ($product['additional_shipping_cost'] * $product['cart_quantity']); //added line } //added line return $shipping_cost; } Scroll down, where you will find // Additional Shipping Cost per product, edit the whole chunk of code with: // Additional Shipping Cost per product foreach ($products as $product) { if (!$product['is_virtual'] && $product['additional_shipping_cost']) { if ($shipping_cost > 0){ $shipping_cost += $product['additional_shipping_cost'] * $product['cart_quantity']; } else $shipping_cost = $product['additional_shipping_cost'] * $product['cart_quantity']; } } Then go up the the function getCarrierCost, edit the last part of it (i pasted the whole function here for convinience): public function getCarrierCost($id_carrier, $useTax = true, Country $default_country = null, $delivery_option = null) { if (is_null($delivery_option)) { $delivery_option = $this->getDeliveryOption($default_country); } $total_shipping = 0; $delivery_option_list = $this->getDeliveryOptionList(); foreach ($delivery_option as $id_address => $key) { if (!isset($delivery_option_list[$id_address]) || !isset($delivery_option_list[$id_address][$key])) { continue; } if (isset($delivery_option_list[$id_address][$key]['carrier_list'][$id_carrier])) { if ($useTax) { $total_shipping += $delivery_option_list[$id_address][$key]['carrier_list'][$id_carrier]['price_with_tax']; } else { $total_shipping += $delivery_option_list[$id_address][$key]['carrier_list'][$id_carrier]['price_without_tax']; } } } // loop products in the cart to find the addition cost of each foreach ($products as $product) { // find the additional shopping price of products if (!$product['is_virtual'] && $product['additional_shipping_cost']) { // if shipping exists, then add additional fees to it (reduntant) if ($total_shipping > 0){ $shipping_cost += $product['additional_shipping_cost'] * $product['cart_quantity']; // if shipping is free, just add the additional shipping fees as shipping price } else $shipping_cost = $product['additional_shipping_cost'] * $product['cart_quantity']; } } // increment the shipping total $total_shipping += $shipping_cost; return $total_shipping; } I've tested the situation and it works regardless of the combinations of products you have in the cart. Free shipping, no free shipping, one or multiple products with additional shipping cost. EDIT: Please note that the block of code below can also be inputed into the carrier.php to override the free shipping stuff PS does. $shipping_cost + self::$price_by_price[$cache_key]; $price_by_price = Hook::exec('actionDeliveryPriceByPrice', array('id_carrier' => $id_carrier, 'order_total' => $order_total, 'id_zone' => $id_zone)); if (is_numeric($price_by_price)) { self::$price_by_price[$cache_key] = $price_by_price; } //from here foreach ($products as $product) { $shipping_cost = $shipping_cost + ($product['additional_shipping_cost'] * $product['cart_quantity']); } $shipTax = $shipping_cost + self::$price_by_price[$cache_key]; return $shipTax; Edited November 20, 2017 by GrandMa90 (see edit history) Link to comment Share on other sites More sharing options...
realloyalist Posted September 19, 2018 Share Posted September 19, 2018 I can confirm the method listed here by GrandMa90 still works for PS 1.7. I don't know why Prestashop hasn't made this the default behavior. One addendum I must add is that if you are using a carrier that is free shipping overall you must add some code in another spot. In the Cart.php file edit the small if statement labeled under // Free fees if free carrier. Find this code: // Free fees if free carrier if ($carrier->is_free == 1) { Cache::store($cache_id, 0); return 0; } Replace with this: // Free fees if free carrier if ($carrier->is_free == 1) { Cache::store($cache_id, 0); $shipping_cost = 0; foreach ($products as $product) { $shipping_cost = $shipping_cost + ($product['additional_shipping_cost'] * $product['cart_quantity']); //added line } return $shipping_cost; } Link to comment Share on other sites More sharing options...
ruisonika Posted April 8, 2019 Share Posted April 8, 2019 Sorry this dont work for me And i need it badly ... Can someone give me some lights? My version is 1.6.1.17 Link to comment Share on other sites More sharing options...
Nico1982 Posted November 30, 2020 Share Posted November 30, 2020 On 11/14/2017 at 11:55 AM, GrandMa90 said: I know this is an old thread but i managed to make this work. The fix works on 1.6.x. We have specific products that have special shipping costs applied to them (due to their weight and the extra money the carrier charges us for them). We needed a way to keep the shipping if under X $, and add the additional shipping fees, but if the order is greater than X $, only the additional shipping fees will count as shipping. Because the first situation is default in prestashop, i found a way to override the second situation (because PS always disregarded the additional shipping fees if shipping is free). In cart.php, where the Free Fee is set, go ahead and replace the whole chunk of code to: // Free fees $free_fees_price = 0; if (isset($configuration['PS_SHIPPING_FREE_PRICE'])) { $free_fees_price = Tools::convertPrice((float)$configuration['PS_SHIPPING_FREE_PRICE'], Currency::getCurrencyInstance((int)$this->id_currency)) ; } $orderTotalwithDiscounts = $this->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING, null, null, false); if ($orderTotalwithDiscounts >= (float)($free_fees_price) && (float)($free_fees_price) > 0) { Cache::store($cache_id, $shipping_cost); foreach ($products as $product) { //added line $shipping_cost = $shipping_cost + ($product['additional_shipping_cost'] * $product['cart_quantity']); //added line } //added line return $shipping_cost; } Scroll down, where you will find // Additional Shipping Cost per product, edit the whole chunk of code with: // Additional Shipping Cost per product foreach ($products as $product) { if (!$product['is_virtual'] && $product['additional_shipping_cost']) { if ($shipping_cost > 0){ $shipping_cost += $product['additional_shipping_cost'] * $product['cart_quantity']; } else $shipping_cost = $product['additional_shipping_cost'] * $product['cart_quantity']; } } Then go up the the function getCarrierCost, edit the last part of it (i pasted the whole function here for convinience): public function getCarrierCost($id_carrier, $useTax = true, Country $default_country = null, $delivery_option = null) { if (is_null($delivery_option)) { $delivery_option = $this->getDeliveryOption($default_country); } $total_shipping = 0; $delivery_option_list = $this->getDeliveryOptionList(); foreach ($delivery_option as $id_address => $key) { if (!isset($delivery_option_list[$id_address]) || !isset($delivery_option_list[$id_address][$key])) { continue; } if (isset($delivery_option_list[$id_address][$key]['carrier_list'][$id_carrier])) { if ($useTax) { $total_shipping += $delivery_option_list[$id_address][$key]['carrier_list'][$id_carrier]['price_with_tax']; } else { $total_shipping += $delivery_option_list[$id_address][$key]['carrier_list'][$id_carrier]['price_without_tax']; } } } // loop products in the cart to find the addition cost of each foreach ($products as $product) { // find the additional shopping price of products if (!$product['is_virtual'] && $product['additional_shipping_cost']) { // if shipping exists, then add additional fees to it (reduntant) if ($total_shipping > 0){ $shipping_cost += $product['additional_shipping_cost'] * $product['cart_quantity']; // if shipping is free, just add the additional shipping fees as shipping price } else $shipping_cost = $product['additional_shipping_cost'] * $product['cart_quantity']; } } // increment the shipping total $total_shipping += $shipping_cost; return $total_shipping; } I've tested the situation and it works regardless of the combinations of products you have in the cart. Free shipping, no free shipping, one or multiple products with additional shipping cost. EDIT: Please note that the block of code below can also be inputed into the carrier.php to override the free shipping stuff PS does. $shipping_cost + self::$price_by_price[$cache_key]; $price_by_price = Hook::exec('actionDeliveryPriceByPrice', array('id_carrier' => $id_carrier, 'order_total' => $order_total, 'id_zone' => $id_zone)); if (is_numeric($price_by_price)) { self::$price_by_price[$cache_key] = $price_by_price; } //from here foreach ($products as $product) { $shipping_cost = $shipping_cost + ($product['additional_shipping_cost'] * $product['cart_quantity']); } $shipTax = $shipping_cost + self::$price_by_price[$cache_key]; return $shipTax; I tested this solution on PS 1.7.5 and it works for the cart but when completing order, in the success page where you see order summary, I don't see additional shipping fee for single product, instead I see free shipping if order subtotal is greater than threshold set for free shipping. Perhaps I have to add other changes in other classes, I don't know (I'm not a Prestashop programmer). Can you indicate if there are other sections in Prestashop classes where to check? Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now