WooCommerce: autocomplete paid orders based on shipping method

情到浓时终转凉″ 提交于 2019-12-12 14:59:45

问题


I have a product that people can print directly (shipping method 1) or choose to get it via shipping service (shipping method 2). So the order should auto complete if they choose to print it directly (shipping method 2) ONLY.

Is it possible to extend that code snippet from WooCommerce?

From docs I found this

/**
 * Auto Complete all WooCommerce orders.
 */
add_action( 'woocommerce_thankyou', 'custom_woocommerce_auto_complete_order');
function custom_woocommerce_auto_complete_order( $order_id ) {
    if ( ! $order_id ) {
        return;
    }

    $order = wc_get_order( $order_id );
    $order->update_status( 'completed' );
}

Here is the working solution. BIG THANKS TO LoicTheAztec:

add_action( 'woocommerce_thankyou', 
'wc_auto_complete_paid_order_based_on_shipping_method', 20, 1 );
function wc_auto_complete_paid_order_based_on_shipping_method( $order_id ) {
if ( ! $order_id ) return;

// HERE define the allowed shipping methods IDs (can be names or slugs changing the code a bit)
$allowed_shipping_methods = array( '5' );

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

// Get the shipping related data for this order:
$shipping_item = $order->get_items('shipping');
$item = reset($shipping_item);
$item_data = $item->get_data();

// Get the shipping method name, rate ID and type slug
$method_rate_id = $item_data['instance_id'];  // Shipping method ID

// No updated status for orders delivered with Bank wire, Cash on 
delivery and Cheque payment methods.
$avoided_statuses = array( 'bacs', 'cod', 'cheque');
if ( in_array( $order->get_payment_method(), $avoided_statuses ) ){
return;
}
// update status to "completed" for paid Orders and a defined shipping 
method ID
elseif ( in_array( $method_rate_id, $allowed_shipping_methods ) ){
$order->update_status( 'completed' );
}
}

回答1:


First, get_post_meta($order_id, '_payment_method', true ) or $order->get_payment_method() are completely similar and do the same thing.
The difference is that the first one use a Wordpress function to access this data from wp_postmeta table and the 2nd one is a WC_Order method that will also access the same data from wp_postmeta table…
No one is better than the other.

New enhanced revisited code (see this thread for explanations).

What is the instance ID:
For example if the Shipping method rate Id is flat_rate:14, the instance Id is 14 (unique ID)

The new version code:

add_action( 'woocommerce_payment_complete_order_status', 'auto_complete_paid_order_based_on_shipping_method', 10, 3 );
function auto_complete_paid_order_based_on_shipping_method( $status, $order_id, $order ) {
    // HERE define the allowed shipping methods instance IDs
    $allowed_shipping_methods_instance_ids = array( '14', '19' );

    // Loop through order "shipping" items
    foreach ( $order->get_shipping_methods() as $shipping_method ) {
        if( in_array( $shipping_method->get_instance_id(), $allowed_shipping_methods_instance_ids ) ) {
            return 'completed';
        }
    }
    return $status;
}

Code goes in function.php file of the active child theme (or active theme). Tested and works.


Original answer:

The answer below comes from this similar answer I have maid some time ago:
WooCommerce: Auto complete paid orders

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

    // HERE define the allowed shipping methods IDs (can be names or slugs changing the code a bit)
    $allowed_shipping_methods = array( 'flat_rate:14', 'flat_rate:19' );

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

    // Get the shipping related data for this order:
    $shipping_item = $order->get_items('shipping');
    $item = reset($shipping_item);
    $item_data = $item->get_data();

    // Get the shipping method name, rate ID and type slug
    $shipping_name = $item_data['name']; // Shipping method name
    $method_rate_id = $item_data['method_id'];  // Shipping method ID
    $method_arr = explode( ':', $method_rate_id );
    $method_type = $method_arr[0];  // Shipping method type slug

    // No updated status for orders delivered with Bank wire, Cash on delivery and Cheque payment methods.
    $avoided_statuses = array( 'bacs', 'cod', 'cheque');
    if ( in_array( $order->get_payment_method(), $avoided_statuses ) ){
        return;
    }
    // update status to "completed" for paid Orders and a defined shipping method ID
    elseif ( in_array( $method_rate_id, $allowed_shipping_methods ) ){
        $order->update_status( 'completed' );
    }
}

Code goes in function.php file of the active child theme (or active theme).

Tested and works.




回答2:


I think what you're looking for is $order->has_shipping_method('name_of_method')

From: https://docs.woocommerce.com/wc-apidocs/class-WC_Abstract_Order.html#_has_shipping_method)




回答3:


That is my working solution (Thanks to LoicTheAztec):

add_action( 'woocommerce_thankyou', 
    'wc_auto_complete_paid_order_based_on_shipping_method', 20, 1 );
function wc_auto_complete_paid_order_based_on_shipping_method( $order_id ) {
    if ( ! $order_id ) return;

    // HERE define the allowed shipping methods IDs (can be names or slugs changing the code a bit)
    $allowed_shipping_methods = array( '5' );

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

    // Get the shipping related data for this order:
    $shipping_item = $order->get_items('shipping');
    $item = reset($shipping_item);
    $item_data = $item->get_data();

    // Get the shipping method name, rate ID and type slug
    $method_rate_id = $item_data['instance_id'];  // Shipping method ID

    // No updated status for orders delivered with Bank wire, Cash on delivery and Cheque payment methods.
    $avoided_statuses = array( 'bacs', 'cod', 'cheque');
    if ( in_array( $order->get_payment_method(), $avoided_statuses ) ){
        return;
    }
    // update status to "completed" for paid Orders and a defined shipping method ID
    elseif ( in_array( $method_rate_id, $allowed_shipping_methods ) ){
        $order->update_status( 'completed' );
    }
}


来源:https://stackoverflow.com/questions/48303688/woocommerce-autocomplete-paid-orders-based-on-shipping-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!