Within an order in my store some items are Heavy and some are light. I want my packers to pack items heaviest to light so that the light items are not squashed at the bottom.

I thought I could add a custom product attribute to each item then perhaps order the items in the order by that attribute but I can't seem to do it.

I do not want to effect the main store item order, just the confirmed orders ready for delivery.

Can anyone confirm if this is possible?


  • ok So after reading your question I have got one question. Do you want to change the order [Heavy to light ] in the admin panel, or do you have any other custom page for packers Commented Jul 13, 2021 at 7:22
  • @RajneeshTiwari Just change the order in the admin panel so the packing team pack items in the correct order (heavy to light). Thanks for the reply. Commented Jul 13, 2021 at 8:02
  • nice. glad to hear that. Commented Jul 17, 2021 at 4:45
  • you want to it for an order only using weight attribute which is already in woocommerce? Commented Jul 17, 2021 at 11:30

1 Answer 1


Using a clean wordpress install, woocommerce and storefront theme, I came up with this code.

It sorts regular products and variable products only. Only sorts in admin panel. Sorts by weight from hgih to low (you can see the commented section, you can uncomment the relevant option to you).

The code goes into functions.php

add_filter('woocommerce_order_get_items', 'bt_sort_woo_order_by_weight', 10, 3);
function bt_sort_woo_order_by_weight ($items, $_this, $types) {
    if (!is_admin()) return $items;
    if (isset($types[0]) && $types[0] !== 'line_item') return $items;

    $items_sorted_by_weight = [];

    foreach ($items as $item_id => $item) {
        // get variation or product id, starting with variation
        $id = !empty($item->get_variation_id()) ? $item->get_variation_id() : $item->get_product_id();

        // get product
        $product = wc_get_product($id);

        // in case the product/variation no longer exist OR product is not variable or simple
        if (empty($product) || !in_array($product->get_type(), ['variation', 'simple'])) {
            $items_sorted_by_weight[] = [
                'weight' => 0,
                'item'   => $item


        $items_sorted_by_weight[] = [
            'weight' => floatval($product->get_weight()),
            'item'   => $item

    // sort by weight
    usort($items_sorted_by_weight, function($a, $b) {
        //return $a['weight'] <=> $b['weight']; // low to high
        return $b['weight'] <=> $a['weight']; // high to low

    // set each sorted element to contain only the item, nothing else
    foreach ($items_sorted_by_weight as &$item) {
        $item = $item['item'];

    // in case nothing worked set the sorted variable to contain default items
    if (empty($items_sorted_by_weight)) $items_sorted_by_weight = $items;

    return $items_sorted_by_weight;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.