Jump to content

Limit free shipping weight in the AdminShipping controller


aptivus

Recommended Posts

Hi everyone,

I was trying to configure a free shipment directive, so I went to

Admin-> Shipment and set:

Handling Fees = 0Euro

Free shipment starts at 39.99 Euros

Free shipment starts at 0 kg

 

I would like to add a directive like:

Free shipment ends at 5 kg.

 

Is there any hack to achieve that?

Honestly I am not sure where I am supposed to write some code to make Prestashop behave like I need.

Any suggestion would be highly appreciated

 

Thank you very much.

 

Link to comment
Share on other sites

Before we try to fix it in the code, would just adding a shipping carrier where you add it, work for you, or do you have some special carrier in use?

 

pascal

Hi, no special carrier.

Just ordinary carriers module configured with weight ranges and costs.

It works fine like so.

No special requirement in matter of carriers at the moment.

Just the free shipping MAXIMUM weight.

Thank you very much.

Link to comment
Share on other sites

Hi Aptivus,

Can you show me the carrier range steps you use at the moment?

 

I can imagine you can just add something like this:

 

range step 1: 0kg  - 5kg   0$

range step 2: 5kg  - 10kg  5$

range step 3: 10kg - 15kg  8$ etc etc

 

Hope this helps,

pascal.

Link to comment
Share on other sites

Hi Aptivus,

Can you show me the carrier range steps you use at the moment?

 

I can imagine you can just add something like this:

 

range step 1: 0kg  - 5kg   0$

range step 2: 5kg  - 10kg  5$

range step 3: 10kg - 15kg  8$ etc etc

 

Hope this helps,

pascal.

Nope.

I have something like

range 1 = 0kg to 5kg  -> 5Euros

range 2 = 5kg to 10kg  -> 10Euros

and so on.

 

Free shipment must be the result of 2 conditions.

First: the amount of the order must be greater than 39.99Euros

Second: the total weight must be WITHIN 5 kg (so, lesser than 5).

 

If the first condition is not satisfied, shipping fee applies and it is 5Euros according the schema above mentioned.

Any clue?

Thank you very much

Link to comment
Share on other sites

  • 2 weeks later...

OK, If I understand well, you need the following:

 

1) You want a max weight for free shipping, like free shipping only when total order weight below 5kg.

2) If you add a min price, BOTH conditions must be met before the free shipping is given (Like min order price > 39.99$ AND max order weight < 5kg)

 

I added one more option, to make it complete/more logic:

3) when both min price and min weight are added, both conditions must be met before the free shipping is given. (When the max weight is given (i.e. max weight value > 0 ), this is taken into account as well).

 

So example:

product X: price 10$, weight 2kg.

 

min free shipping price: 15$ 

min free shipping weight: 5kg

max free shipping weight: 8kg

 

carrier range:

0-5 kg: 5$

5-10kg: 8$

10-20kg: 11$

 

Then for 1,2,3,4,5 products in cart:

1: 10$, 2kg : free price not met, free weight not met -> carrier step 1 = 5$

2: 20$, 4kg:  free price met, free weight not yet met -> carrier step 1 = 5$

3: 30$, 6kg:  free price met, free weight met, weight not more than max weight -> free shipping

4: 40$, 8kg:  free price met, free weight met, weight not more than max weight (weight exactly max value)-> free shipping

5: 50$,10kg: free price met, free weight met, but weight more than max weight! -> carrier step 3: 11$

 

(N.B.) if only min price and NOT min weight was given (i.e. min weight = 0 ), step 2 would give free shipping already)

 

 

If this is what you need, then make the following changes: (N.B. Sample code is from PS 1.5.6.2 !!)

 

In file: /controllers/admin/AdminShippingController.php (make backup!)

add the following code:

 

 

                                               ...  ,             <-- Don't forget this comma!!

                        'PS_SHIPPING_FREE_WEIGHT_MAX' => array(
                        'title' => $this->l('Free shipping ends at'),
                        'suffix' => Configuration::get('PS_WEIGHT_UNIT'),
                        'cast' => 'floatval',
                        'type' => 'text',
                        'validation' => 'isUnsignedFloat')

 

 

like in sample code below

		$this->fields_options = array(
			'handling' => array(
				'title' =>	$this->l('Handling'),
				'icon' => 'delivery',
				'fields' =>	array(
					'PS_SHIPPING_HANDLING' => array(
						'title' => $this->l('Handling charges'),
						'suffix' => $this->context->currency->getSign().' '.$this->l('(tax excl.)'),
						'cast' => 'floatval',
						'type' => 'text',
						'validation' => 'isPrice'),
					'PS_SHIPPING_FREE_PRICE' => array(
						'title' => $this->l('Free shipping starts at'),
						'suffix' => $this->context->currency->getSign(),
						'cast' => 'floatval',
						'type' => 'text',
						'validation' => 'isPrice'),
					'PS_SHIPPING_FREE_WEIGHT' => array(
						'title' => $this->l('Free shipping starts at'),
						'suffix' => Configuration::get('PS_WEIGHT_UNIT'),
						'cast' => 'floatval',
						'type' => 'text',
						'validation' => 'isUnsignedFloat'),
					'PS_SHIPPING_FREE_WEIGHT_MAX' => array(
						'title' => $this->l('Free shipping ends at'),
						'suffix' => Configuration::get('PS_WEIGHT_UNIT'),
						'cast' => 'floatval',
						'type' => 'text',
						'validation' => 'isUnsignedFloat')
				),

This will add a new field to the shipping admin page, just below free shipping starts at : _____ kg, where you can add the max order weight for free shipping (value inclusive)

post-455771-0-18128000-1404079508_thumb.png

 

 

Then edit file: classes/Cart.php (Make backup!!)

and change code: (search (Ctrl-F/Cmd-F) for string: PS_SHIPPING_FREE_PRICE to easily find this piece of code)

		$configuration = Configuration::getMultiple(array(
			'PS_SHIPPING_FREE_PRICE',
			'PS_SHIPPING_HANDLING',
			'PS_SHIPPING_METHOD',
			'PS_SHIPPING_FREE_WEIGHT'
		));

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

		if (isset($configuration['PS_SHIPPING_FREE_WEIGHT'])
			&& $this->getTotalWeight() >= (float)$configuration['PS_SHIPPING_FREE_WEIGHT']
			&& (float)$configuration['PS_SHIPPING_FREE_WEIGHT'] > 0)
		{
			Cache::store($cache_id, $shipping_cost);
			return $shipping_cost;
		}

		// Get shipping cost using correct method

into:

		$configuration = Configuration::getMultiple(array(
			'PS_SHIPPING_FREE_PRICE',
			'PS_SHIPPING_HANDLING',
			'PS_SHIPPING_METHOD',
			'PS_SHIPPING_FREE_WEIGHT',
			'PS_SHIPPING_FREE_WEIGHT_MAX'
		));

		// Free fees
		$free_fees_price = 0;
		if (!isset($configuration['PS_SHIPPING_FREE_WEIGHT_MAX']) ||
 				((float)$configuration['PS_SHIPPING_FREE_WEIGHT_MAX'] <= 0) ||
				((float)$configuration['PS_SHIPPING_FREE_WEIGHT_MAX'] > 0
				&& $this->getTotalWeight() <= (float)$configuration['PS_SHIPPING_FREE_WEIGHT_MAX']))
		{
			if (isset($configuration['PS_SHIPPING_FREE_PRICE']) && (!isset($configuration['PS_SHIPPING_FREE_WEIGHT']) || (float)$configuration['PS_SHIPPING_FREE_WEIGHT'] <= 0 || $this->getTotalWeight() >= (float)$configuration['PS_SHIPPING_FREE_WEIGHT']))
				$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;
			}

			if (isset($configuration['PS_SHIPPING_FREE_WEIGHT'])
				&& $this->getTotalWeight() >= (float)$configuration['PS_SHIPPING_FREE_WEIGHT']
				&& (float)$configuration['PS_SHIPPING_FREE_WEIGHT'] > 0 && (!isset($configuration['PS_SHIPPING_FREE_PRICE']) || $configuration['PS_SHIPPING_FREE_PRICE'] <= 0))
			{
				Cache::store($cache_id, $shipping_cost);
				return $shipping_cost;
			}
		}

		// Get shipping cost using correct method

What happens:

1) we add the max weight value to the $configuration variable:

 

2): we check if the max weight value is used, or not. If it is > 0, then we check if the order weight <=max value. If not, the normal carrier value is used

 

3) if max weight isn't used, or if the order weight <= max weight value, then we check if:

 

3a) if the min price value is used and and the order price >= min price and either the min weight is not used or the order weight >= min weight, we give free shipping

3b) if the min weight value is used and the order weight >= min weight and min price is not used then free shipping is given

 

 

That should do the trick.

 

Hope this helps,

pascal.

  • Like 3
Link to comment
Share on other sites

  • 6 months later...
  • 1 month later...
  • 10 months later...
I've got a problem with this solution.. It works in my 5 steps cart only in the first step, it displays everything fine but after redirecting to shipping step I have only personal collection. I writing about case when cost of products are greater than free shipping limit and weight are bigger than free shipping limit.

Perhaps you can give me a hint how to fix it?

I would be really grateful

Link to comment
Share on other sites

  • 4 weeks later...
  • 1 year later...

OK, If I understand well, you need the following:

 

1) You want a max weight for free shipping, like free shipping only when total order weight below 5kg.

2) If you add a min price, BOTH conditions must be met before the free shipping is given (Like min order price > 39.99$ AND max order weight < 5kg)

 

I added one more option, to make it complete/more logic:

3) when both min price and min weight are added, both conditions must be met before the free shipping is given. (When the max weight is given (i.e. max weight value > 0 ), this is taken into account as well).

 

So example:

product X: price 10$, weight 2kg.

 

min free shipping price: 15$ 

min free shipping weight: 5kg

max free shipping weight: 8kg

 

carrier range:

0-5 kg: 5$

5-10kg: 8$

10-20kg: 11$

 

Then for 1,2,3,4,5 products in cart:

1: 10$, 2kg : free price not met, free weight not met -> carrier step 1 = 5$

2: 20$, 4kg:  free price met, free weight not yet met -> carrier step 1 = 5$

3: 30$, 6kg:  free price met, free weight met, weight not more than max weight -> free shipping

4: 40$, 8kg:  free price met, free weight met, weight not more than max weight (weight exactly max value)-> free shipping

5: 50$,10kg: free price met, free weight met, but weight more than max weight! -> carrier step 3: 11$

 

(N.B.) if only min price and NOT min weight was given (i.e. min weight = 0 ), step 2 would give free shipping already)

 

 

If this is what you need, then make the following changes: (N.B. Sample code is from PS 1.5.6.2 !!)

 

In file: /controllers/admin/AdminShippingController.php (make backup!)

add the following code:

 

 

                                               ...  ,             <-- Don't forget this comma!!

                        'PS_SHIPPING_FREE_WEIGHT_MAX' => array(

                        'title' => $this->l('Free shipping ends at'),

                        'suffix' => Configuration::get('PS_WEIGHT_UNIT'),

                        'cast' => 'floatval',

                        'type' => 'text',

                        'validation' => 'isUnsignedFloat')

 

 

like in sample code below

		$this->fields_options = array(
			'handling' => array(
				'title' =>	$this->l('Handling'),
				'icon' => 'delivery',
				'fields' =>	array(
					'PS_SHIPPING_HANDLING' => array(
						'title' => $this->l('Handling charges'),
						'suffix' => $this->context->currency->getSign().' '.$this->l('(tax excl.)'),
						'cast' => 'floatval',
						'type' => 'text',
						'validation' => 'isPrice'),
					'PS_SHIPPING_FREE_PRICE' => array(
						'title' => $this->l('Free shipping starts at'),
						'suffix' => $this->context->currency->getSign(),
						'cast' => 'floatval',
						'type' => 'text',
						'validation' => 'isPrice'),
					'PS_SHIPPING_FREE_WEIGHT' => array(
						'title' => $this->l('Free shipping starts at'),
						'suffix' => Configuration::get('PS_WEIGHT_UNIT'),
						'cast' => 'floatval',
						'type' => 'text',
						'validation' => 'isUnsignedFloat'),
					'PS_SHIPPING_FREE_WEIGHT_MAX' => array(
						'title' => $this->l('Free shipping ends at'),
						'suffix' => Configuration::get('PS_WEIGHT_UNIT'),
						'cast' => 'floatval',
						'type' => 'text',
						'validation' => 'isUnsignedFloat')
				),

This will add a new field to the shipping admin page, just below free shipping starts at : _____ kg, where you can add the max order weight for free shipping (value inclusive)

attachicon.gifshipping ends at field.png

 

 

Then edit file: classes/Cart.php (Make backup!!)

and change code: (search (Ctrl-F/Cmd-F) for string: PS_SHIPPING_FREE_PRICE to easily find this piece of code)

		$configuration = Configuration::getMultiple(array(
			'PS_SHIPPING_FREE_PRICE',
			'PS_SHIPPING_HANDLING',
			'PS_SHIPPING_METHOD',
			'PS_SHIPPING_FREE_WEIGHT'
		));

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

		if (isset($configuration['PS_SHIPPING_FREE_WEIGHT'])
			&& $this->getTotalWeight() >= (float)$configuration['PS_SHIPPING_FREE_WEIGHT']
			&& (float)$configuration['PS_SHIPPING_FREE_WEIGHT'] > 0)
		{
			Cache::store($cache_id, $shipping_cost);
			return $shipping_cost;
		}

		// Get shipping cost using correct method

into:

		$configuration = Configuration::getMultiple(array(
			'PS_SHIPPING_FREE_PRICE',
			'PS_SHIPPING_HANDLING',
			'PS_SHIPPING_METHOD',
			'PS_SHIPPING_FREE_WEIGHT',
			'PS_SHIPPING_FREE_WEIGHT_MAX'
		));

		// Free fees
		$free_fees_price = 0;
		if (!isset($configuration['PS_SHIPPING_FREE_WEIGHT_MAX']) ||
 				((float)$configuration['PS_SHIPPING_FREE_WEIGHT_MAX'] <= 0) ||
				((float)$configuration['PS_SHIPPING_FREE_WEIGHT_MAX'] > 0
				&& $this->getTotalWeight() <= (float)$configuration['PS_SHIPPING_FREE_WEIGHT_MAX']))
		{
			if (isset($configuration['PS_SHIPPING_FREE_PRICE']) && (!isset($configuration['PS_SHIPPING_FREE_WEIGHT']) || (float)$configuration['PS_SHIPPING_FREE_WEIGHT'] <= 0 || $this->getTotalWeight() >= (float)$configuration['PS_SHIPPING_FREE_WEIGHT']))
				$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;
			}

			if (isset($configuration['PS_SHIPPING_FREE_WEIGHT'])
				&& $this->getTotalWeight() >= (float)$configuration['PS_SHIPPING_FREE_WEIGHT']
				&& (float)$configuration['PS_SHIPPING_FREE_WEIGHT'] > 0 && (!isset($configuration['PS_SHIPPING_FREE_PRICE']) || $configuration['PS_SHIPPING_FREE_PRICE'] <= 0))
			{
				Cache::store($cache_id, $shipping_cost);
				return $shipping_cost;
			}
		}

		// Get shipping cost using correct method

What happens:

1) we add the max weight value to the $configuration variable:

 

2): we check if the max weight value is used, or not. If it is > 0, then we check if the order weight <=max value. If not, the normal carrier value is used

 

3) if max weight isn't used, or if the order weight <= max weight value, then we check if:

 

3a) if the min price value is used and and the order price >= min price and either the min weight is not used or the order weight >= min weight, we give free shipping

3b) if the min weight value is used and the order weight >= min weight and min price is not used then free shipping is given

 

 

That should do the trick.

 

Hope this helps,

pascal.

 

You sir are a genious! problem solved in 5 minutes. this is perfect!

 

1.6.0.14

Link to comment
Share on other sites

  • 1 year later...

Hello and thank you for your solution! :)

Let's say we have the following shipping costs:

  • 3€ for orders below 3Kg
  • and +1€ for each extra Kg
  • Free shipping starts at 30€ for orders below 3Kg.
  • If an order is over 30€ and above 3Kg then the shipping cost is 1€ per extra Kg. The customer wont pay for the base shipping price but will have to pay for the 1€/Kg, over 3Kg.

EXAMPLE

Order price: 40€ 
Order weight: 5Kg
Total shipping: 2€   (free base shipping price + 1€ for each Kg above 3Kg)

Any ideas on how to achieve this?

1.6.1.17

Edited by marpand (see edit history)
Link to comment
Share on other sites

  • 2 years later...
  • 1 year later...

For people who have set the "Free Shipping Starts at 'x' amount" and want that free shipping canceled when the cart products total weight is over 'x' kg:

In PrestaShop 1.7.8.8 in /classes/Cart.php at Line number 3758, change:

if ($orderTotalwithDiscounts >= (float) ($free_fees_price) && (float) ($free_fees_price) > 0)

to:

if ($orderTotalwithDiscounts >= (float) ($free_fees_price) && (float) ($free_fees_price) > 0 && $this->getTotalWeight() <= (float) 10.0)

I have it set to 10kg, change 10 to whatever weight you want.

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...