0

On the checkout page of my WooCommerce based site, users will have a list of shipping methods to choose from depending on what they are purchasing

This is the list I want to capture:

This is the list I want to capture


Things like

  • “Free Shipping” for orders over a certain price
  • “Freight Shipping” for certain items, and so on.

My goal, is to display ALL available methods for each specific order, and display it on the “Edit Order / Order Details” page in the Admin view.

A small feature that would help us be able to quickly identify what option people are choosing more often, depending on the choices that they have available.

This is what I have so far:

add_action( 'woocommerce_checkout_update_order_meta', 'save_available_shipping_methods' );
 
function save_available_shipping_methods( $order_id ) {
    $shippingmethods = WC()->cart->get_shipping_methods();
    update_post_meta( $order_id, '_shipping_methods', $shippingmethods );
}

add_action( 'woocommerce_admin_order_data_after_shipping_address', 'get_available_shipping_methods', 10, 1 );

function get_available_shipping_methods($order){
    $order = wc_get_order( $order_id );
    if ( $order ) {
        echo '<p><strong>'.__('Available Shipping Methods: ').'</strong> ' . get_post_meta($order->get_shipping_methods(), '_shipping_field_value', true ) . '</p>';
    }
}

I'll attach a picture as well to maybe make things a little easier to follow.

This is where I would like to put it. The current hook places the field underneath the shipping address

This is where I would like to put it. The current hook places the field underneath the shipping address

7uc1f3r
  • 28,449
  • 17
  • 32
  • 50
Dalton
  • 59
  • 9
  • `$order` already contains all the information you need, see [Get orders shipping items details in WooCommerce 3](https://stackoverflow.com/a/46106700/11987538). so the `woocommerce_admin_order_data_after_shipping_address` hook is sufficient, there is no need to use `update_post_meta` – 7uc1f3r Jul 08 '20 at 17:58
  • Now that I have re-read your question, is it the intention to display the chosen shipping method by the customer? or would you like to list **ALL** available shipping methods for that specific order? – 7uc1f3r Jul 08 '20 at 18:17
  • I am wanting to display ALL available methods for each specific order – Dalton Jul 08 '20 at 19:00
  • [Link To Related Question](https://stackoverflow.com/questions/62819259/iterate-through-two-foreach-loops-at-once) – Dalton Jul 09 '20 at 16:21

2 Answers2

2
  • In the woocommerce_checkout_update_order_meta hook, the available shipping packages are stored via update_post_meta
  • Comments with explanation added in the code
function action_woocommerce_checkout_update_order_meta( $order_id ) {
    // Get shipping packages
    $packages = WC()->shipping()->get_packages();
    
    // Set array
    $rate_labels = array();
    
    // Loop trough packages
    foreach ( $packages as $key => $package ) {
        // Loop through package rates
        foreach( $package['rates'] as $rate_id => $rate ) {
            // Push to array
            $rate_labels[] = $rate->get_label();
        }
    }

    // NOT empty
    if ( ! empty ( $rate_labels ) ) {
        // Update post meta
        update_post_meta( $order_id, '_available_shipping_methods', $rate_labels );
    }
}
add_action( 'woocommerce_checkout_update_order_meta', 'action_woocommerce_checkout_update_order_meta', 10, 1 ); 

// Display on the order edit page (backend)
function action_woocommerce_admin_order_data_after_shipping_address( $order ) {
    // Get meta
    $rate_labels = $order->get_meta( '_available_shipping_methods' );
    
    // True
    if ( $rate_labels ) {
        // Loop trough rate labels
        foreach( $rate_labels as $rate_label ) {
            // Output
            echo '<p>' . $rate_label . '</p>';
        }
    }
}
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'action_woocommerce_admin_order_data_after_shipping_address', 10, 1 );
7uc1f3r
  • 28,449
  • 17
  • 32
  • 50
  • Works like a charm! Thanks a bunch! Now id like to see if I could add the prices that we quoted each method for. Any suggestions on that? – Dalton Jul 08 '20 at 21:01
  • Yes, in the foreach 'loop through package rates' you could use something like `$rate_cost = $rate->get_cost();`. See [Class WC_Shipping_Rate](https://docs.woocommerce.com/wc-apidocs/class-WC_Shipping_Rate.html). - Get started and if you don't get there, feel free to ask a new question, with a possible reference to this question Regards – 7uc1f3r Jul 08 '20 at 21:14
  • Appreciate the help. Thanks! – Dalton Jul 08 '20 at 21:15
  • So ive added references to the costs in the foreach loop, the update_post_meta function, and echo, and it seems to only return 0.00 across the board. Am I missing a piece? Thanks again. – Dalton Jul 08 '20 at 21:49
  • Just to test this without taking other factors into account, what if you replace `$rate_labels[] = $rate->get_label();` with `$rate_labels[] = $rate->get_cost();` in my answer. What do you get as a result? – 7uc1f3r Jul 09 '20 at 07:38
  • ok, then it's just a matter of adding this cost to an array. Can be done via a multiarray, 2 arrays, concatenating the values ​​as a string in the already existing array,... as you can see, the prices are processed correctly. As I mentioned before, if you cannot find a solution, do not hesitate to open a new question. Regards – 7uc1f3r Jul 09 '20 at 15:26
  • Ive posted a more revised question here: https://stackoverflow.com/questions/62819259/iterate-through-two-foreach-loops-at-once . Thanks for your help! – Dalton Jul 09 '20 at 16:18
1

In case anyone is wondering, this is the final result. It will loop through each order to find the available shipping methods at the time, along with how much it was quoted for.

 // Capture the available shipping methods, and costs: 
      function action_woocommerce_checkout_update_order_meta( $order_id ) {
      // Get shipping packages
         $packages = WC()->shipping()->get_packages();
        
    // Set array
    $rate_labels = array();
    $rate_costs = array();
    
    // Loop trough packages
    foreach ( $packages as $key => $package ) {
        // Loop through package rates
        foreach( $package['rates'] as $rate_id => $rate ) {
            // Push to array
            $rate_labels[] = $rate->get_label();
            $rate_costs[] = $rate->get_cost();
        }
    }

    // NOT empty
    if ( ! empty ( $rate_labels ) ) {
        // Update post meta
        update_post_meta( $order_id, '_available_shipping_methods', $rate_labels );
        update_post_meta( $order_id, '_available_shipping_method_cost', $rate_costs );
    }
}
add_action( 'woocommerce_checkout_update_order_meta', 'action_woocommerce_checkout_update_order_meta', 10, 1 ); 

// Make it display on the edit order page:
function action_woocommerce_admin_order_data_after_shipping_address( $order ) {
    // Get meta
    $rate_labels = $order->get_meta( '_available_shipping_methods' );
    $rate_costs = $order->get_meta( '_available_shipping_method_cost' );
    
    $methods = array ( $rate_labels, $rate_costs );
    
    // True
    if ( $rate_labels ) {
        // Loop
        echo '<p><strong>Shipping Methods: </strong>';
        foreach(array_combine($rate_labels, $rate_costs) as $rate_label => $rate_cost) {
             echo '<p>' . $rate_label . ' - $' . $rate_cost . '</p>';
        }
    }
    
}
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'action_woocommerce_admin_order_data_after_shipping_address', 10, 1 );
Dalton
  • 59
  • 9