Add a custom order status “Shipped” in Woocommerce

2020-03-01 00:42发布

I am developing an e-commerce site using Woocommerce and I would like to a custom order status "Shipped".

So this is how the flow would go: Customer places an order gets an email saying order has been confirmed, current status is processing, admin gets the tracking ID from its courier and can paste it in a new section and change the order status to shipped. That would fire another email with tracking id to the customer.

Is there any custom code which will help me achieve this functionality?

Any help would be greatly appreciated.

1条回答
够拽才男人
2楼-- · 2020-03-01 01:41

The following code will add a new custom "shipped" order status to Woocommerce orders:

// Register a custom order status
add_action('init', 'register_custom_order_statuses');
function register_custom_order_statuses() {
    register_post_status('wc-shipped ', array(
        'label' => __( 'Shipped', 'woocommerce' ),
        'public' => true,
        'exclude_from_search' => false,
        'show_in_admin_all_list' => true,
        'show_in_admin_status_list' => true,
        'label_count' => _n_noop('Shipped <span class="count">(%s)</span>', 'Shipped <span class="count">(%s)</span>')
    ));
}


// Add a custom order status to list of WC Order statuses
add_filter('wc_order_statuses', 'add_custom_order_statuses');
function add_custom_order_statuses($order_statuses) {
    $new_order_statuses = array();

    // add new order status before processing
    foreach ($order_statuses as $key => $status) {
        $new_order_statuses[$key] = $status;
        if ('wc-processing' === $key) {
            $new_order_statuses['wc-shipped'] = __('Shipped', 'woocommerce' );
        }
    }
    return $new_order_statuses;
}


// Adding custom status 'awaiting-delivery' to admin order list bulk dropdown
add_filter( 'bulk_actions-edit-shop_order', 'custom_dropdown_bulk_actions_shop_order', 50, 1 );
function custom_dropdown_bulk_actions_shop_order( $actions ) {
    $new_actions = array();

    // add new order status before processing
    foreach ($actions as $key => $action) {
        if ('mark_processing' === $key)
            $new_actions['mark_shipped'] = __( 'Change status to shipped', 'woocommerce' );

        $new_actions[$key] = $action;
    }
    return $new_actions;
}

// Add a custom order status action button (for orders with "processing" status)
add_filter( 'woocommerce_admin_order_actions', 'add_custom_order_status_actions_button', 100, 2 );
function add_custom_order_status_actions_button( $actions, $order ) {
    // Display the button for all orders that have a 'processing', 'pending' or 'on-hold' status
    if ( $order->has_status( array( 'on-hold', 'processing', 'pending' ) ) ) {

        // The key slug defined for your action button
        $action_slug = 'shipped';

        // Set the action button
        $actions[$action_slug] = array(
            'url'       => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce_mark_order_status&status='.$action_slug.'&order_id='.$order->get_id() ), 'woocommerce-mark-order-status' ),
            'name'      => __( 'Shipped', 'woocommerce' ),
            'action'    => $action_slug,
        );
    }
    return $actions;
}

// Set styling for custom order status action button icon and List icon
add_action( 'admin_head', 'add_custom_order_status_actions_button_css' );
function add_custom_order_status_actions_button_css() {
    $action_slug = "shipped"; // The key slug defined for your action button
    ?>
    <style>
        .wc-action-button-<?php echo $action_slug; ?>::after {
            font-family: woocommerce !important; content: "\e029" !important;
        }
    </style>
    <?php
}

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

You will get something like this:

In admin order list:

enter image description here

In admin order edit pages:

enter image description here


To remove a specific action from the dropdown orders bulk actions

For example we want to remove "On hold" status change:

add_filter( 'bulk_actions-edit-shop_order', 'remove_a_bulk_order_action', 20, 1 );
function remove_a_bulk_order_action( $actions ) {
    unset($actions['mark_on-hold']);

    return $actions;
}

All statuses change keys start with mark_ + the status slug (without wc-).

查看更多
登录 后发表回答