Jump to content

[SOLVED] Can I change free shipping for one zone and one carrier?


Recommended Posts

Hello

I have different zones and different carriers. I want to give free shipping for one zone for more €300 pay. But that can do only one carrier. If I give Free shipping starts at:300 all zones and all carriers show "delivery free"

Is it possible to do this? I can't success

Thank you

Link to comment
Share on other sites

It's not possible without modifying code. Try changing line 833 of classes/Cart.php from:

if ($orderTotalwithDiscounts >= floatval($free_fees_price) AND floatval($free_fees_price) > 0)
   return $shipping_cost;



to:

if ($orderTotalwithDiscounts >= floatval($free_fees_price) AND floatval($free_fees_price) > 0 AND $id_zone == 1)
   return $shipping_cost;



Change 1 to the ID of the zone you want to have free shipping over €300.

Link to comment
Share on other sites

Thank you Rocky

I find this solution http://www.prestashop.com/forums/viewthread/21663/P0/general_discussion/modhacktip_free_shipping_on_one_carrier_only_dot_

and try to test and modify. After code /Ion Cannon/ I put one more operator "AND" "$id_zone==1" and now I have solution.
He look like AND $id_carrier==1 AND $id_zone==1

My local numbers is 51 and 15, but is different for all.

Thanks all and regards

Link to comment
Share on other sites

  • 3 months later...
  • 3 months later...

Thanks Rocky for the code modification. I used it exactly as you have written, just changing my zone id to "6" since that was the zone I wanted to offer free shipping and it worked perfectly. Thanks a lot for the fix! Great.

Kind regards,
Lisa

I am using PrestaShop version 1.3.2.3

Link to comment
Share on other sites

  • 3 months later...

Hi Rocky,

Is it possible to give each carrier an individual FREE shipping price?

EXAMPLE:

Carrier 1 = FREE Shipping starts at £50
Carrier 2 = FREE Shipping starts at £350

Regards


It's not possible without modifying code. Try changing line 833 of classes/Cart.php from:

if ($orderTotalwithDiscounts >= floatval($free_fees_price) AND floatval($free_fees_price) > 0)
   return $shipping_cost;



to:

if ($orderTotalwithDiscounts >= floatval($free_fees_price) AND floatval($free_fees_price) > 0 AND $id_zone == 1)
   return $shipping_cost;



Change 1 to the ID of the zone you want to have free shipping over €300.

Link to comment
Share on other sites

You will need to override the getOrderShippingCost function in classes/Cart.php and change lines 1064-1067 (in PrestaShop v1.4.1) from:

// 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)));



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)));*/
if ((int)$carrier->id == 1)
   $free_fees_price = Tools::convertPrice(50, Currency::getCurrencyInstance((int)($this->id_currency)));
elseif ((int)$carrier->id == 2)
   $free_fees_price = Tools::convertPrice(350, Currency::getCurrencyInstance((int)($this->id_currency)));

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

Hi Rocky,

Thanks for your response!

I am using prestashop 1.3.2.3 so my code i slightly different:

// Free fees
       $free_fees_price = 0;
       if (isset($configuration['PS_SHIPPING_FREE_PRICE']))
           $free_fees_price = Tools::convertPrice(floatval($configuration['PS_SHIPPING_FREE_PRICE']), new Currency(intval($this->id_currency)));

$orderTotalwithDiscounts = $this->getOrderTotal(true, 4);
       if ($orderTotalwithDiscounts >= floatval($free_fees_price) AND $id_zone==7 AND floatval($free_fees_price) > 0)
           return $shipping_cost;
       if (isset($configuration['PS_SHIPPING_FREE_WEIGHT']) AND $id_zone==7 AND $this->getTotalWeight() >= floatval($configuration['PS_SHIPPING_FREE_WEIGHT']) AND floatval($configuration['PS_SHIPPING_FREE_WEIGHT']) > 0)
           return $shipping_cost;




Could you please confirm that the changes need are:

// Free fees
       $free_fees_price = 0;

if ((int)$carrier->id == 1)
   $free_fees_price = Tools::convertPrice(50, Currency::getCurrencyInstance((int)($this->id_currency)));
elseif ((int)$carrier->id == 2)
   $free_fees_price = Tools::convertPrice(350, Currency::getCurrencyInstance((int)($this->id_currency)));

$orderTotalwithDiscounts = $this->getOrderTotal(true, 4);
       if ($orderTotalwithDiscounts >= floatval($free_fees_price) AND $id_zone==7 AND floatval($free_fees_price) > 0)
           return $shipping_cost;
       if (isset($configuration['PS_SHIPPING_FREE_WEIGHT']) AND $id_zone==7 AND $this->getTotalWeight() >= floatval($configuration['PS_SHIPPING_FREE_WEIGHT']) AND floatval($configuration['PS_SHIPPING_FREE_WEIGHT']) > 0)
           return $shipping_cost;




Thanks for your help!

Link to comment
Share on other sites

Hi Rocky,

The code works! .... kind of ????

When signed in as a GROUP2 £350 customer which has CARRIER2 £350 assigned to it and add something for example £30 to cart it still shows the P+P charge for GROUP1 £50 CARRIER1 £50 in the shopping cart summary & blockcart? It shows the £2.49 GROUP1 CARRIER1 charge instead of the £8.99 GROUP2 CARRIER2 charge?

While going through the checkout steps, step4 shipping changes the P+P to £8.99 GROUP2 CARRIER2 P+P which is correct, all of the checkout methods bill the correct P+P.

So the code does indeed work but the shopping cart summary & blockcart does not reflect the true charges until reaching & passing step 4 shipping??

This could be confusing to the customer..... have you any ideas why this could be happening?

Thanks for all your help with this, i very much appreciate it!.

Regards

Adam

Looks right to me.
Link to comment
Share on other sites

It might have something to do with the default carrier. Before a carrier has been selected, the default carrier on the Shipping > Carriers tab is used for the calculation. Once the real carrier has been selected, the shipping cost changes to that carrier. Would you rather have the default shipping cost display as $0 until a carrier is selected? Perhaps you can create another carrier with no shipping cost that isn't available in any zones, and make it the default carrier?

Link to comment
Share on other sites

Thanks for explaining.

I think it may be best to leave as is because if i make the changes you propose i assume GROUP1 CARRIER1 (retail) will show as £0 P+P too until they pass step 4 of checkout process ??

I agree that this would solve but i would prefer the retail customers to see the P+P costs before going through checkout process.

My trade customers have terms and conditions stating the P+P charges so they are aware even if the website display is incorrect until checkout.

Thank you so much for help, this has been driving me crazy!!!

Regards

It might have something to do with the default carrier. Before a carrier has been selected, the default carrier on the Shipping > Carriers tab is used for the calculation. Once the real carrier has been selected, the shipping cost changes to that carrier. Would you rather have the default shipping cost display as $0 until a carrier is selected? Perhaps you can create another carrier with no shipping cost that isn't available in any zones, and make it the default carrier?
Link to comment
Share on other sites

Just a thought:

Would it be possible to override prestashop to dynamically choose the carrier used for calculation based on logged in customer group?

For example:

{if}

If the logged in customer is in GROUP1 select CARRIER1 for calculation
(as this will be the only carrier available anyway)

{elseif}

If the logged in customer is in GROUP2 select CARRIER2 for calculation
(as this will be the only carrier available anyway)

{else}

If the customer is not logged in select CARRIER1 for calculation as the fall back?

{/if}


This would solve my problem completely!

Regards

Link to comment
Share on other sites

Try changing lines 780-798 of classes/Cart.php (in PrestaShop v1.3.2) from:

// If no carrier, select default one
if (!$id_carrier)
   $id_carrier = $this->id_carrier;
if (empty($id_carrier))
{
   if ((Configuration::get('PS_SHIPPING_METHOD') AND (Carrier::checkDeliveryPriceByWeight(intval(Configuration::get('PS_CARRIER_DEFAULT')), $this->getTotalWeight(), $id_zone)))
   OR (!Configuration::get('PS_SHIPPING_METHOD') AND (Carrier::checkDeliveryPriceByPrice(intval(Configuration::get('PS_CARRIER_DEFAULT')), $this->getOrderTotal(true, 4), $id_zone))))
       $id_carrier = intval(Configuration::get('PS_CARRIER_DEFAULT'));
}
if (empty($id_carrier))
{
   if (intval($this->id_customer))
   {
       $customer = new Customer(intval($this->id_customer));
       $result = Carrier::getCarriers(intval(Configuration::get('PS_LANG_DEFAULT')), true, false, intval($id_zone), $customer->getGroups());
       unset($customer);
   }
   else
       $result = Carrier::getCarriers(intval(Configuration::get('PS_LANG_DEFAULT')), true, false, intval($id_zone));



to:

// If no carrier, select customer group carrier if logged in or default carrier if logged out
if (!$id_carrier)
   $id_carrier = $this->id_carrier;
if (empty($id_carrier))
{
   if (intval($this->id_customer))
   {
       $customer = new Customer(intval($this->id_customer));
       $result = Carrier::getCarriers(intval(Configuration::get('PS_LANG_DEFAULT')), true, false, intval($id_zone), $customer->getGroups());
       unset($customer);
   }
   elseif ((Configuration::get('PS_SHIPPING_METHOD') AND (Carrier::checkDeliveryPriceByWeight(intval(Configuration::get('PS_CARRIER_DEFAULT')), $this->getTotalWeight(), $id_zone)))
   OR (!Configuration::get('PS_SHIPPING_METHOD') AND (Carrier::checkDeliveryPriceByPrice(intval(Configuration::get('PS_CARRIER_DEFAULT')), $this->getOrderTotal(true, 4), $id_zone))))
       $id_carrier = intval(Configuration::get('PS_CARRIER_DEFAULT'));
   else
       $result = Carrier::getCarriers(intval(Configuration::get('PS_LANG_DEFAULT')), true, false, intval($id_zone));



I haven't tested this code, but hopefully, it will get the customer group carrier if logged in and the default carrier if not logged in.

Link to comment
Share on other sites

Rocky,

Since i have changed my code to the ones you provided above i have been getting some php errors in cart.php

The error is:

PHP Warning:  Invalid argument supplied for foreach() in /home/sites/XXXXXX/public_html/classes/Cart.php on line 807



The snippet of code from cart.php is as follows:

788:          // If no carrier, select customer group carrier if logged in or default carrier if logged out
789:          if (!$id_carrier)
790:              $id_carrier = $this->id_carrier;
791:          if (empty($id_carrier))
792:          {
793:              if (intval($this->id_customer))
794:              {
795:                  $customer = new Customer(intval($this->id_customer));
796:                  $result = Carrier::getCarriers(intval(Configuration::get('PS_LANG_DEFAULT')), true, false, intval($id_zone), $customer->getGroups());
797:                          unset($customer);
798:                      }
799:                      elseif ((Configuration::get('PS_SHIPPING_METHOD') AND (Carrier::checkDeliveryPriceByWeight(intval(Configuration::get('PS_CARRIER_DEFAULT')), $this->getTotalWeight(), $id_zone)))
800:                          OR (!Configuration::get('PS_SHIPPING_METHOD') AND (Carrier::checkDeliveryPriceByPrice(intval(Configuration::get('PS_CARRIER_DEFAULT')), $this->getOrderTotal(true, 4), $id_zone))))
801:                                  $id_carrier = intval(Configuration::get('PS_CARRIER_DEFAULT'));
802:                              else
803:                                  $result = Carrier::getCarriers(intval(Configuration::get('PS_LANG_DEFAULT')), true, false, intval($id_zone));
804:                         
805:        
806:             $resultsArray = array();
807:                     foreach ($result AS $k => $row)
808:                     {
809:                         if ($row['id_carrier'] == Configuration::get('PS_CARRIER_DEFAULT'))
810:                             continue;
811:                         if (!isset(self::$_carriers[$row['id_carrier']]))
812:                             self::$_carriers[$row['id_carrier']] = new Carrier(intval($row['id_carrier']));
813:                         $carrier = self::$_carriers[$row['id_carrier']];
814:                         // Get only carriers that are compliant with shipping method
815:                         if ((Configuration::get('PS_SHIPPING_METHOD') AND $carrier->getMaxDeliveryPriceByWeight($id_zone) === false)
816:                         OR (!Configuration::get('PS_SHIPPING_METHOD') AND $carrier->getMaxDeliveryPriceByPrice($id_zone) === false))
817:                         {
818:                             unset($result[$k]);
819:                             continue ;
820:                         }
821:         



Any ideas about this error?

The code works just the way i want it too but i keep getting a log full of these errors??

Any help would be greatly appreciated.

Regards

Link to comment
Share on other sites

  • 1 year later...

Try changing lines 780-798 of classes/Cart.php (in PrestaShop v1.3.2) from:

 

let's bring this up again. does this still work in 1.4.8.2? I cannot get the free shipping to work for 1 specific country with the options provided in the BO...

Link to comment
Share on other sites

  • 3 months later...

Hi Rocky.

 

The code works great in my PS 1.3.2.

 

I was wondering if it's possible to avoid free shipping if a virtual product is added to the cart. Or better, if the price of the virtual product does not count to the free shipping.

 

Many thanks!

 

I think that if I can add, somehow, the total value of virtual products in cart to line 441 of order.php:

 

$total_free_ship =  $free_ship - ($summary['total_products_wt'] + $summary['total_discounts'] /* Add virtual products total! */);

 

... I could avoid virtual products from being count for free shipping.

 

Any ideas?

Edited by ilovekutchi.com (see edit history)
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...