Is there a way to change the order of the shipping services? I have several flat rate services and i'd like to change the order.

Files: 

Comments

Are you talking about the order in the backend?

Are you talking about the order in the backend?

Version:7.x-2.0-beta1» 7.x-2.x-dev

I too would like the ability to change the order the shipping services appear in on the checkout form.

I have two shipping options, standard and express. As the standard option is cheaper, I'd like it to appear first as the default, but it seems they're listed in alphabetical order and so standard appears last...

Adding those drag 'n drop weight things (found on most other Drupal forms) to the form from the screenshot above would be perfect.

Status:Active» Postponed (maintainer needs more info)

Have you tried using the rules weight system to do sorting?

Status:Postponed (maintainer needs more info)» Active

I looked for some weights in Rules to change originally (and again just now), but I can't seem to find anything... There's only one Rule for shipping, and the two shipping services (express and standard) are implemented as Rules Components which don't have weights...

Could you help point me in the right direction?

Assigned:Unassigned» rszrama

Sounds like this is a flaw in the way the 2.x branch has organized the Rules, since this is possible in the 1.x. I'll assign Ryan to this, since he made the most of this and knows why it was built the way it was.

Hi,
What I can see that the services are placed in alphabet from a-z as a workaround for now.
Off course +1 for Weight possibility on Shipping Services!

Greetings, Martijn

Hi people, if anyone has large amount of services here is a link to make them in a select box. Plus an incomplete (i'm not a programmer so i can't figure it out how to complete the sort function) code of a callback sort function.

Component:User interface» Code
Assigned:rszrama» Unassigned
Category:support» feature

As with the core Tax module, the Shipping 2.x branch abstracts the calculation of shipping services for an order through a single rule with an action that collects all the available rates for services of each method. If you look at your Rules list, you'll see the Collect rates: [Shipping method] rules in there for each shipping method module you've enabled. The action on that rule will loop over all shipping services for the given method and manually execute the rule components for each one to determine if it should be on the order or not. Inside that action, we can't change the execution order of components, as they're governed by the service's weight, but what could happen is you simply remove the default action and replace it with the necessary actions to manually call your various service rules components.

That said, on testing, it didn't matter if I split it out, flat rate services were still ordered alphabetically. What we could do is change the checkout form code to respect the order these things were added to the array, but I'm not sure that's the easiest solution. It seems it would be easier to add a "sort order" weight to flat rate services, which would be a simple feature request to that module rather than something the Shipping module itself needs to take care of. Perhaps a hybrid approach would be the best, as it would be most flexible.

So the task for this issue:

Update the checkout pane so it displays shipping services in the order in which they were added to the order's data array.

Ryan,

I agree with you. We have the same problem here, as we have 7 different shipping services. Adding a sort order "weight" to flat rate services would be very helpfull. It would allow to present them to the client in a particular order.

Thanks a lot for your work. There are many of us using your insights and comments.

Cheers.
juan

Hi, guys!
I have faced with the same problem, that I couldn't sort shipping services in the way Id like to. I've read all above comments and didn't understand clearly what means update checkout pane (what to change there). Then I started to experiment and I found out the order is being changed if to write machine names of the shipping services in alphabetical order. So I deleted all my services and added them again with respect to machine's names alphabetical order. I had to delete them first since I couldnt edit machine names. So it can help to those who cant programm and write sorting functions!

Project:Commerce Shipping» Commerce Flat Rate
Version:7.x-2.x-dev» 7.x-1.x-dev

By the time the shipping services are passed to hook_commerce_shipping_service_info_alter, they have been assigned a 'weight' property. This weight appears to be based solely on the order the various modules return their methods (commerce_shipping_services() steps through each module that implements the hook, then each of the shipping services, and sets each weight to "$weight++"). I guess this means the 'Commerce Shipping' part of this issue, as described by Ryan in #9 above, is complete. I'm moving it over to Commerce Flat Rate so we can actually tackle the issue eswiderski originally raised.

FWIW it looks like this should be fairly trivial - just add a 'weight' integer field to the commerce_flat_rate_service table, create some way of editing those weights (either on individual forms or using the tabledrag method), and respect those weights inside the commerce_flat_rate_commerce_shipping_service_info function instead of just 'SELECT * FROM {commerce_flat_rate_service}'.

In the meantime I've used this hook to re-order my shipping rates manually by simply overriding the weight property:

<?php
/**
* Implements hook_commerce_shipping_service_info_alter().
*/
function mymodule_commerce_shipping_service_info_alter(&$shipping_services) {
  if (isset(
$shipping_services['my_flat_rate'])) {
   
$shipping_services['my_flat_rate']['weight'] = -10;
  }
}
?>

what if we have more than 20 rates? how to order them properly as weight is only from -10 to 10.

I have many shipment rates as there is no module (known to me) for HK post and I am setting up a shop for worldwide shipment and the weight base rule is not suitable, I end up having one rate for each country and each 500g section from 0 to 20kg. I do not want to take any shortcut as I do not want my customer to get over charged for transportation.

Thanks

In that case you'd need to alter them via code I suppose. Weights don't have to be integers, but only integers can be set via the UI.

i am also in the middle of the limitation. I need to run a Shipping calculation after another 2 shipping calculation..

kingandy, where exactly did you add the hook?

Thanks,

Update: I really don't like hacking modules but, to get my preferred shipping set as the selected default, I added: 'weight' => -10, to line 70 of...

\profiles\commerce_kickstart\profiles\commerce_kickstart\modules\commerce_kickstart\commerce_kickstart_product\commerce_kickstart_product.features.inc

Of coarse this only works for Commerce Kickstart but, you can search your flat rate module for express_shipping to find what you may be looking for.

+1 for being able to reorder within flat shipping rates. I currently have premium listed before standard shipping which is quite inconvenient for the visitor...

@Infinitee, I think I made a new module just to introduce the hook. Either that or I used an existing custom "site-specific utilities" type of module...

This seems to be an issue for the FedEx shipping module as well (http://drupal.org/node/1955574) It seems to me that this ability to sort the displayed rates by price should probably be a feature in the overall Commerce Shipping module rather than in some of the various shipping method modules. Thoughts?

Used the approach in #13 as well, thanks for sharing!

As I see it there are two distinct goals discussed in this thread:

1. Sort services by name.
2. Sort services by price.

The two don't necessarily work together, since in many cases the rates depend on the order contents.

iwant2fly (post #20) sponsored a solution to #2. I'm posting it here for feedback and in case it is of use to others. In words the approach is to fetch the rates from the $order object, and then use that array to sort the $options displayed on the checkout pane.

<?php
/**
* Implements hook_commerce_shipping_service_rate_options_alter()
*/
function [module_name]_commerce_shipping_service_rate_options_alter(&$options, $order) {
   
// If there is more than one shipping service available, sort them by line item unit price
   
if (count($order->shipping_rates) > 1) {
       
// Collect rates from line items
       
$service_prices = array();
        foreach (
$order->shipping_rates as $service => $line_item) {
           
$line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $line_item);
           
$unit_price = $line_item_wrapper->commerce_unit_price->value();
         
$service_prices[$service] = $unit_price['amount'];
        }
       
// array_multisort can be used here because $options and $order->shipping_rates contain the same number of elements (i.e. services).
       
array_multisort($service_prices, SORT_NUMERIC, SORT_ASC, $options);
    }
}
?>

This could be integrated into the commerce shipping module by adding a toggle switch somewhere in the UI to turn this sorting on/off.

Issue summary:View changes

Nice one MEsch. Exactly what I was looking for.

#22 Works for me. Using only Flat Rate shipping services, and shipping options are listed by price now.

Being able to assign weights to the shipping options would definitely give greater control but ultimately I simply wanted the options ordered by price so I think this is a great solution.

#22 is working for me as well. I would second the request to assign weights for more control. (In my case, I'd like to show all USPS options first, sorted by price, then all UPS options, sorted by price.)