Jump to content

Shipping Carrier dependent on category


Recommended Posts

Hi all,

I would like to be able to limit which carriers are used depending on the category the item is in.

 

For example, most items can be shipped by normal post or registered post whichever the client prefers, however a category with more expensive items, I would like that the only option for shipping is the registered/ trackable post.

 

How can I do this?

Thanks in advance!

Link to comment
Share on other sites

Not possible out of the box. You could maybe simulate it using some twisted logic by weight ranges and giving those items in that special category artificial weights that does not coincide with the weights of any other item in any other category, then specify that the carrier only available within that weight range. Details depens on how the rest of the shiping is setup.

Link to comment
Share on other sites

  • 1 year later...
  • 1 year later...

PrestaShop has changed its design - great. How about making something useful for a change? Like ability to change shipping Carrier dependent on category? It's been 3 years and shipping options in PS are still in the medieval ages.

Link to comment
Share on other sites

  • 4 weeks later...
  • 4 weeks later...

Well i have some good news for you all.

I'm almost done with a module that is capable of this. It has many configuration options that i think covers all posibilities

 

I'll have to do some minor enhancements and write a manual. After that the module will be available on addons.prestashop.com.

 

I think it will be there next week.

Compatibility 1.6.x and higher

  • Like 1
Link to comment
Share on other sites

The module is being reviewed by Prestashop now so hopefully it will be available soon.

 

While it's being reviewed you can play with the module over here:



 


password: demodemo

 


 

Please don't make a mess :)

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

That is some great news.

 

"With this module you can overrule or add carriers based on the products category."

 

So basically it's the same as I would assign carrier to each product , right? Well, it saves time, but still it won't help one of my clients.

He wants to assign different rules for chosen category within 1 carrier that is common for all products.

It's a bad idea to have multiple carriers in PrestaShop because if there are multiple products in cart that require multiple carriers client can't choose the carrier for each product. It's probably the biggest disadvantage of PrestaShop and I'm aware that it's complicated and won't be easy for anyone to fix...

Link to comment
Share on other sites

No, you can overrule/override the carrier with this module

A client of ours had the following issue:
Bikes MUST be delivered bij Carrier 1 wich shippingcost is €25

But if you get to the carrierlist all carriers were shown. So the customer had 7 carriers to choose from. 4 of them  didn't need to be shown.

You think : "Well. just add a carrier for that product then". Yeah you could do that.
If i only have BIKE in my cart only the 3 carrier options are shown. But as soon as i add the bell all 7 carriers are shown again (maybe a bug in their Prestashop, didn't look at the version).

 

This module will allow you to avoid that kind of behaviour and it's configurable so i think it suits everybodies needs. Our client uses an automated import for the products too. So adding carriers to each product manually isn't an option. 

BTW since Prestashop 1.6 multishipping is gone and not supported anymore.


I'm trying to understand you: So basicly you want to choose a carrier by EACH product in the cart instead of override/overrule to the cheapest or most expensive one ?
I'm trying to understand the logic on this one, but so far i can't so please  explain further. Maybe i can find or program a solution but i need some more information ( with some examples )

 

 

Link to comment
Share on other sites

BTW since Prestashop 1.6 multishipping is gone and not supported anymore.

I'm trying to understand you: So basicly you want to choose a carrier by EACH product in the cart instead of override/overrule to the cheapest or most expensive one ?

I'm trying to understand the logic on this one, but so far i can't so please  explain further. Maybe i can find or program a solution but i need some more information ( with some examples )

 

 

Yes, client should be able to choose himself the carrier for each product separately (well, at least that was the plan at the beginning, later I was forced to create dirty workarounds).

 

Thanks to your info about multi shipping feature I went to Google and found a module which brings multi shipping back.

 

It appears it enables not only choosing addresses for each product, but also carriers, so I thought I found the solution. But unfortunately this module has some major disadvantages:

1. Works only with 5-steps order, in 1-page order the option was gone.

2. Client can choose carrier for each product only if he created multiple addresses.

 

Perhaps nr 1 is not a big issue, but it is essential to enable client to choose carrier for each product event if he has 1 address.

Link to comment
Share on other sites

It would be perfect if that would be that easy, but this module is solely a 1 overriden tpl file with JS code only.

So that "address count" code part must lay elsewhere in core PrestaShop files, at the moment I'm trying to find it.

 

Edit: I've found something but changing it doesn't help >.>

classes/Cart.php :

public function isMultiAddressDelivery()
{
static $cache = null;


if (is_null($cache))
{
$sql = new DbQuery();
$sql->select('count(distinct id_address_delivery)');
$sql->from('cart_product', 'cp');
$sql->where('id_cart = '.(int)$this->id);


$cache = Db::getInstance()->getValue($sql) > 1;
}
return true;
// return $cache;
}
Edited by Hasher (see edit history)
Link to comment
Share on other sites

I searched too and i think your issue will be fixed by overruling the following class

 

Class : Cart

Function : public function isMultiAddressDelivery()

As far as i can see in the Prestashop code involving multishipping this is the function you should override.

 

Why:
Because Prestashop set multishipping to NO if !$this->context->cart->isMultiAddressDelivery()
( see Prestashop 1.6.0.13 OrderController line 314)

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

After some debugging I've found it. Problem lies in last step of getPackageList() function, because it merges delivery options by their delivery address:

// Step 5 : Reduce depth of $package_list
$final_package_list = array();
foreach ($package_list as $id_address_delivery => $products_in_stock_list)
{
	if (!isset($final_package_list[$id_address_delivery]))
		$final_package_list[$id_address_delivery] = array();

	foreach ($products_in_stock_list as $key => $warehouse_list)
		foreach ($warehouse_list as $id_warehouse => $products_grouped_by_carriers)
			foreach ($products_grouped_by_carriers as $data)
			{
				$final_package_list[$id_address_delivery][] = array(
					'product_list' => $data['product_list'],
					'carrier_list' => $data['carrier_list'],
					'warehouse_list' => $data['warehouse_list'],
					'id_warehouse' => $id_warehouse,
					);
			}
		}

$cache[(int)$this->id.'_'.(int)$this->id_address_delivery] = $final_package_list;
return $final_package_list;

Now I need to figure out how to rewrite it in safe way.

Link to comment
Share on other sites

Well you have to fake an id_address_delivery:
 

$final_package_list[$id_address_delivery][]

 
To:

$final_package_list[][]

The cache needs to be changed too.

But you allready knew that. or create an extra sub array. You won't get away that easily, you'll have to override another class to read that foreign array.
I haven't got much time atm to help you debugging. I'm sorry :( I will try to help you as soon as i can find some time

Link to comment
Share on other sites

I was inaccurate - the problem lies behind these particular lines of getPackageList() function:

// Step 3 : grouped product from grouped_by_warehouse by available carriers
		$grouped_by_carriers = array();
		foreach ($grouped_by_warehouse as $id_address_delivery => $products_in_stock_list)
		{
			if (!isset($grouped_by_carriers[$id_address_delivery]))
				$grouped_by_carriers[$id_address_delivery] = array(
					'in_stock' => array(),
					'out_of_stock' => array(),
					);

If product is related to $id_address_delivery that exists in $grouped_by_carriers already another delivery option is not created - instead product's delivery info is merged into existing $grouped_by_carriers[$id_address_delivery]. This is the very moment when we loose the second delivery option.

 

And since id_address_delivery are real ids from database I can't override them in order to force adding another delivery option. Or perhaps there is a way that would spare me the need of rewriting half of the Presta's core code?

Edited by Hasher (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...