Jump to content

Sort carriers by price


Recommended Posts

  • 1 month later...

I am looking for this as well!

 

I have been pouring over code for several hours now! I think it has something to do with the getDeliveryPriceByPrice and getDeliveryPriceByWeight functions in cart.php.

 

Will post more when/if I figure it out!

 

EDIT: No that's not it! I think that has to do with manually entered shipping costs, but nothing to do with module shipping that goes and retrieves live rates.

Link to comment
Share on other sites

Ok, I found where you can modify the sort order...

 

In Prestashop v1.4.4.0 look in the /controllers/ParentOrderController.php around line 364 in the function _assignCarrier()

 

You can then take the $carriers array and sort it on whatever criteria you want (like [price], [price_tac_exc], [name], [external_module_name])

 

Put your mods AFTER this line:

$carriers = Carrier::getCarriersForOrder($id_zone, $customer->getGroups());

 

And BEFORE these lines:

self::$smarty->assign(array(
 'checked' => $this->_setDefaultCarrierSelection($carriers),
 'carriers' => $carriers,
 'default_carrier' => (int)(Configuration::get('PS_CARRIER_DEFAULT'))
));

 

I do not have any code written yet that actually does the sorting, but at least we know where to look now!

 

I have posted a feature request in the bug tracker to have a new hook added so you could create a module to do the sorting and would not have to modify core code:

http://forge.prestashop.com/browse/PSCFI-3047

  • Like 1
Link to comment
Share on other sites

  • 3 weeks later...

At the moment, you may as a replacement modify each carrier *in the same order* you want to see them displayed : go in each carrier screen in Shipping > Carriers. By clicking Save each time, the carrier ID will be reincremented, making it possible to re-sort them the right way.

Link to comment
Share on other sites

  • 5 weeks later...

I whipped up the following class override today to sort the carriers based on price ascending. To use this, save it as "/overrides/classes/Carrier.php". Should be transparent as far as I can tell and does not require making any modifications to core files.

 

<?php

class Carrier extends CarrierCore
{

public static function getCarriersForOrder($id_zone, $groups = NULL)
{
 $carriers=array();

 $result=parent::getCarriersForOrder($id_zone, $groups);
 if($result)
 {
  if(count($result)>0)
  {
$sort=array();
foreach($result AS $k=>$v)
{
 $sort['_'.$k]=$v['price'];
}
asort($sort,SORT_NUMERIC);
foreach(array_keys($sort) AS $k)
{
 $carriers[]=$result[(substr($k,1))];
}
  }
 }
 return $carriers;
}
}
?>

 

Cheers

  • Like 1
Link to comment
Share on other sites

  • 5 months later...

I whipped up the following class override today to sort the carriers based on price ascending. To use this, save it as "/overrides/classes/Carrier.php". Should be transparent as far as I can tell and does not require making any modifications to core files.

 

<?php

class Carrier extends CarrierCore
{

public static function getCarriersForOrder($id_zone, $groups = NULL)
{
 $carriers=array();

 $result=parent::getCarriersForOrder($id_zone, $groups);
 if($result)
 {
  if(count($result)>0)
  {
$sort=array();
foreach($result AS $k=>$v)
{
 $sort['_'.$k]=$v['price'];
}
asort($sort,SORT_NUMERIC);
foreach(array_keys($sort) AS $k)
{
 $carriers[]=$result[(substr($k,1))];
}
  }
 }
 return $carriers;
}
}
?>

 

Cheers

 

 

Thank you for this. Is it possible to order Carriers alphabeticaly? PS 1.4.7

 

Thank you in advance,

Lukas

Link to comment
Share on other sites

Hi Lukas,

 

I think to sort alphabetically you would need to make the following modifications (untested):

 

@Codegrunt: Thanks! Extremely helpful code snippet

 

<?php
class Carrier extends CarrierCore
{
public static function getCarriersForOrder($id_zone, $groups = NULL)
{
	$carriers=array();
	$result=parent::getCarriersForOrder($id_zone, $groups);
	if($result){
		if(count($result)>0){
			$sort=array();
			foreach($result AS $k=>$v){
				$sort['_'.$k]=$v['name']; //change from 'price' to 'name'
			}
			asort($sort,SORT_STRING); //change from SORT_NUMERIC to SORT_STRING
			foreach(array_keys($sort) AS $k){
				$carriers[]=$result[(substr($k,1))];
			}
		}
	}
	return $carriers;
}
}

  • Like 2
Link to comment
Share on other sites

WORKS like a charm!

Thank you very much!

 

Hi Lukas,

 

I think to sort alphabetically you would need to make the following modifications (untested):

 

@Codegrunt: Thanks! Extremely helpful code snippet

 

<?php
class Carrier extends CarrierCore
{
public static function getCarriersForOrder($id_zone, $groups = NULL)
{
	$carriers=array();
	$result=parent::getCarriersForOrder($id_zone, $groups);
	if($result){
		if(count($result)>0){
			$sort=array();
			foreach($result AS $k=>$v){
				$sort['_'.$k]=$v['name']; //change from 'price' to 'name'
			}
			asort($sort,SORT_STRING); //change from SORT_NUMERIC to SORT_STRING
			foreach(array_keys($sort) AS $k){
				$carriers[]=$result[(substr($k,1))];
			}
		}
	}
	return $carriers;
}
}

Link to comment
Share on other sites

  • 1 month later...

I think little bit cleaner solution for override Carrier.php would be something like code below. In this case we just get data from parent function and sort it after that by one of the function.

One is for sorting by price and second for sorting by name.

To switch from sortByPrice to sortByName simply change row

usort($resultsArray, array("Carrier", "sortByPrice"));

to

usort($resultsArray, array("Carrier", "sortByName "));

 

<?php
class Carrier extends CarrierCore
{
	static function sortByPrice($f1,$f2,$precision = 2)
	{
			$e = pow(10,$precision);
			return (intval($f1['price'] * $e) - intval($f2['price'] * $e));
	}

	static function sortByName($a1, $a2){
			return strcmp($a2['name'], $a1['name']);
	}
	public static function getCarriersForOrder($id_zone, $groups = null)
	{
			$resultsArray = parent::getCarriersForOrder($id_zone, $groups);
			usort($resultsArray, array("Carrier", "sortByPrice"));
			return $resultsArray;
	}
}

Link to comment
Share on other sites

  • 2 months later...

i think this is the right way to do this kind of sort

<?php
class Carrier extends CarrierCore
{
   public static function sortBySubValue($a,$subkey)
   {
    foreach($a as $k=>$v) {
	    $b[$k] = strtolower($v[$subkey]);
    }
    asort($;
    foreach($b as $k=>$v) {
	    $c[] = $a[$k];
    }
    return $c;
   }
   public static function getCarriersForOrder($id_zone, $groups = NULL)
   {
    $carriers=array();
    $result=parent::getCarriersForOrder($id_zone, $groups);
    $result_sorted = self::sortBySubValue($result,'name');
    return $result_sorted;
   }
}
?>

Link to comment
Share on other sites

  • 4 weeks later...

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