1

The idea here is that when an order comes in with an "express delivery" as Shipping Method, the order status is updated to On-Hold.

As there I have some different "express delivery" Shipping Method rates I thought that by using stristr() to see if the word 'express' appears anywhere in the formatted shipping method title. But I seem to be missing something as I don't get anything.

How can I check if the Order shipping method is an "express delivery" to be able to update the order status?

Here is the code that I have:

add_action( 'woocommerce_thankyou', 'express_orders_4865', 10, 1 );
function express_orders_4865( $order_id ) {
    global $woocommerce;

    $order = new WC_Order( $order_id );

    $shipping_method = $order->get_shipping_method();

    if (stristr($shipping_method, 'express') === TRUE) {
        $order->update_status('on-hold');
    } else {
        return;
    }
}

EDIT-----------------------------------------------------------

For anyone using Woocommerce Table Rate Shipping the get_method_id returns the table rate id so i used get_method_title instead as below, if there is a better way please comment...

add_action( 'woocommerce_thankyou', 'express_shipping_update_order_status', 10, 1 );
function express_shipping_update_order_status( $order_id ) {
    if ( ! $order_id ) return;

    $search = 'Express'; // The needle to search in the shipping method ID

    // Get an instance of the WC_Order object
    $order = wc_get_order( $order_id );

    // Get the WC_Order_Item_Shipping object data
    foreach($order->get_shipping_methods() as $shipping_item ){
        // When "express delivery" method is used, we change the order to "on-hold" status


        if( strpos( $shipping_item->get_method_title(), $search ) !== false ){
            $order->update_status('on-hold');
            break;
        }
    }
}
aynber
  • 22,380
  • 8
  • 50
  • 63
blackhill24
  • 422
  • 14
  • 30

3 Answers3

1

I prefer to use the faster and less memory intensive function strpos() instead as the shipping method ID is alway in lowercase (like a kind of slug).

So is better the get the WC_Order_Item_Shipping object data for this case, using the available methods.

So the code should be:

add_action( 'woocommerce_thankyou', 'express_shipping_update_order_status', 10, 1 );
function express_shipping_update_order_status( $order_id ) {
    if ( ! $order_id ) return;
    
    $search = 'express'; // The needle to search in the shipping method ID

    // Get an instance of the WC_Order object
    $order = wc_get_order( $order_id );

    // Get the WC_Order_Item_Shipping object data
    foreach($order->get_shipping_methods() as $shipping_item ){
        // When "express delivery" method is used, we change the order to "on-hold" status
        if( strpos( $shipping_item->get_method_title(), $search ) !== false && ! $order->has_status('on-hold')){
            $order->update_status('on-hold');
            break;
        }
    }
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

Tested and works…

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • Hi @LoicTheAztec, thank you for your answer, I'm unable to get this code to work for express orders? however, if I change !== false to true everything gets changed to on hold which to me would imply the issue is with using strpos. I've looked up the documentation for strpos and it only returns an interger, could this be the problem? Thanks again – blackhill24 Nov 20 '17 at 11:39
0

So the code above didn't work for me, i had someone in a FB group help me debug it and this was the final one that worked for me

add_action( 'woocommerce_thankyou', 'express_shipping_update_order_status', 10, 1 );
function express_shipping_update_order_status( $order_id ) {
    if ( ! $order_id ) return;

    $search = 'express'; // The needle to search in the shipping method ID

    // Get an instance of the WC_Order object
    $order = wc_get_order( $order_id );

    // Get the WC_Order_Item_Shipping object data
    foreach($order->get_shipping_methods() as $shipping_item ){
        // When "express delivery" method is used, we change the order to "on-hold" status
        if( strpos( $shipping_item->get_method_title(). $search ) !== false ){
            $order->update_status('on-hold');
            $order->save();
            break;
        }
    }
}
brasofilo
  • 25,496
  • 15
  • 91
  • 179
kili
  • 11
  • 1
  • 2
0

My solution assumes that the normal status for a new order is PROCESSING.

So when an order is changed to PROCESSING, check the shipping method and if it matches, then change it to ON-HOLD.

add_action('woocommerce_order_status_changed', 'jds_auto_change_status_by_shipping_method');
function jds_auto_change_status_by_shipping_method($order_id) {
    // If the status of an order is changed to PROCESSING and the shipping method contains specific text then change the status.
    if ( ! $order_id ) {
        return;
    }
    global $product;
    $order = wc_get_order( $order_id );
    if ($order->data['status'] == 'processing') { // if order status is processing
        $shipping_method = $order->get_shipping_method();
        if ( strpos($shipping_method, 'express') !== false ) { // if shipping method CONTAINS this text
            $order->update_status('on-hold'); // change status to this
        }
    }   
}

Note that $shipping_method returns the human readbale version of the shipping method that the customer sees, so you need to match exactly how the word 'express' appears to customer... is it 'express' or 'Express' or 'EXPRESS'

jsherk
  • 6,128
  • 8
  • 51
  • 83