Recently an exasperated WooCommerce user contacted us as he was not able to differentiate between order items which have been shipped and delivered to a customer as opposed to items which have been shipped but not yet delivered.
On investigating, I realised it is a pretty basic requirement which made me wonder why it hasn’t been incorporated yet into WooCommerce. Never mind! I’m sure the developers of WooCommerce have their reasons. Let’s not get into that. Let’s just focus on how to add a shipped order status in WooCommerce.
To begin with, I did a recce of orders page and the single order page to identify exactly which sections of the pages required changes. Having done that I explored the hooks and filters offered by WooCommerce. Subsequently, I had the following tasks at hand to be able to fulfil the requirement of adding a shipped order status in WooCommerce.
- Register Shipped Order Status in WooCommerce
- Add ‘Shipped’ to Order Action Metabox on Single Order Page
- Add ‘Shipped’ to Order Status list on Single Order Page
- Create Callback Function if Order Status is Marked as Shipped
- Provide Feature to Change Order Status to Shipped for Multiple Orders
Steps to Add a Shipped Order status in WooCommerce
1. Register Shipped Order Status in WooCommerce
- The foremost step to carry out would be to register the shipped order status in WooCommerce. Only after this step has been fulfilled will it be possible to carry out the remaining steps.
- The code to add shipped order status in WooCommerce will have to be written on the ‘init’ hook and will be as below.
add_action( 'init', array($this,'wdm_register_shipped_order_status')); /* Register new status*/ function wdm_register_shipped_order_status() { register_post_status( 'wc-shipped', array( 'label' => _x('Shipped','wdm'), '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>' ) )); }
[space]
2. Add ‘Shipped’ to Order Actions Metabox on Order Page
- The next step would be to add the ‘Shipped’ order status to the order actions meta box on the single order page.
- When the admin selects the ‘shipped’ option in the order action meta box that particular order will be assigned the shipped status. This status will also be reflected on the order page. In order to do so the following code will have to be added.
add_action( 'woocommerce_order_actions', array( $this, 'wdm_add_order_meta_box_actions' ) ); /* Add Order action to Order action meta box */ function wdm_add_order_meta_box_actions($actions) { $actions['wdm_shipped'] = __( 'Shipped', 'wdm'); return $actions; }
- Once this has been done the ‘Order Actions’ drop down will look as below.
- An important thing to note here is that with this code ‘Shipped’ order status will be added to the drop down list. Read on to know how to incorporate the processing when the shipped order status is selected.
[space]
3. Add ‘Shipped’ to Order Status list on Single Order Page
- We will also have to add ‘Shipped’ to the order status drop down list in the single order page.It will be done as given below.
add_filter( 'wc_order_statuses', array($this,'add_shipped_to_order_statuses')); /* Adds new Order status - Shipped in Order statuses*/ function add_shipped_to_order_statuses($order_statuses) { $new_order_statuses = array(); // add new order status after Completed foreach ( $order_statuses as $key => $status ) { $new_order_statuses[ $key ] = $status; if ( 'wc-completed' === $key ) { $new_order_statuses['wc-shipped'] = __('Shipped','wdm'); } } return $new_order_statuses; }
- The following image is an example of how the order status dropdown will look once the ‘Shipped’ status has been added to it.
[space]
4. Create Callback Function if Order Status is Marked as Shipped
- Now that the ‘Shipped’ order status has been added to the required lists the next step would be to define the action that should be taken when the ‘Shipped’ value is selected in any of the above lists. For this callback functions will have to be written.
- The following function written on the ‘woocommerce_order_action_wdm_shipped’ hook will be called when ‘Shipped’ has been selected from the order actions drop-down list.
//Add callback if Shipped action called add_action( 'woocommerce_order_action_wdm_shipped', array( $this, 'wdm_order_shipped_callback' ),10,1); function wdm_order_shipped_callback($order) { //Here order object is sent as parameter //Add code for processing here }
- In the event in which ‘Shipped’ is selected from the order status drop down the following function which has been written on the ‘woocommerce_order_status_shipped’ hook will be called.
//Add callback if Status changed to Shipping add_action('woocommerce_order_status_shipped',array($this,'wdm_order_status_shipped_callback'),10,1); function wdm_order_status_shipped_callback($order_id) { //Here order id is sent as parameter //Add code for processing here }
[space]
5. Provide Feature to Change Order Status to Shipped for Multiple Orders
- Well, that is not it though. There could be an instance wherein you might want to change the order status of multiple orders to be shipped all at once.
- In order to effect this change, you will first need to add ‘Mark Shipped’ to the bulk actions drop down on the orders page.
- And here’s the icing on the cake. You can use the following code to change the status icon in the orders table on the order page.
//Add "Mark as Shipped" in Bulk action add_action( 'admin_footer', array( $this, 'wdm_add_shipped_in_bulk_action'),11); /* * Add "Mark as Shipped" in Bulk action dropdown */ function wdm_add_shipped_in_bulk_action() { global $post_type; if ( 'shop_order' == $post_type ) { wp_register_style('wdm_shipping_icon_css_handler',plugins_url('assets/css/wdm_shipping_icon.css',__FILE__)); wp_enqueue_style('wdm_shipping_icon_css_handler'); ?> <script type="text/javascript"> jQuery(function() { jQuery('<option>').val('mark_shipped').text('<?php _e( 'Mark shipped', 'woocommerce' )?>').appendTo("select[name='action']"); jQuery('<option>').val('mark_shipped').text('<?php _e( 'Mark shipped', 'woocommerce' )?>').appendTo("select[name='action2']"); //Add icon title_text = jQuery('.column-order_status .shipped').html() jQuery('.column-order_status .shipped').attr('alt',title_text); jQuery('.column-order_status .shipped').empty(); jQuery('.column-order_status .shipped').append('<icon class="icon-local-shipping"></icon>') jQuery('.column-order_status .shipped').css('text-indent','0'); }); </script> <?php } }//function ends - wdm_add_shipped_in_bulk_action
- Once this has been done you will now have to create a call back function which will be called when admin selects ‘Mark Shipped’ option from the bulk action drop-down.
//Add callback for Bulk action add_action( 'load-edit.php', array( $this, 'wdm_bulk_action_shipping_callback' ) ); /* Bulk action for Shop Order - Shipping selected*/ function wdm_bulk_action_shipping_callback() { $wp_list_table = _get_list_table( 'WP_Posts_List_Table' ); $action = $wp_list_table->current_action(); //wc-shipped switch ( $action ) { case 'mark_shipped' : $new_status = 'shipped'; $report_action = 'marked_shipped'; break; default : return; } $post_ids = array_map( 'absint', (array) $_REQUEST['post'] ); foreach ( $post_ids as $post_id ) { $order = wc_get_order( $post_id ); $order->update_status( $new_status, __( 'Order status changed by bulk edit:', 'woocommerce' ) ); $changed++; } $sendback = add_query_arg( array( 'post_type' => 'shop_order', $report_action => true, 'changed' => $changed, 'ids' => join( ',', $post_ids ) ), '' ); wp_redirect( $sendback ); exit(); }//function ends - wdm_bulk_action_shipping_callback
So, that was about adding a shipped order status in WooCommerce. I have covered all the points in detail and tried my best to make it simple for you. However, if you think you still have some doubts then connect with through the comments section and I shall be happy to help.
🙂
25 Responses
Great post, thank you for sharing! I’m going to try and implement this one.
So, if I understand correctly, this must be included into the function.php of the theme folder? In order to prevent this function to be lost after a Woo update?
Hi,
If you add the changes to the functions.php file of your current theme, the changes will not be lost when you update WooCommerce or WordPress. However, they will be lost when you update your theme. So, ideally, if it’s your own theme, or a child theme you’ve created, you could add the code to the functions.php file. Else, you should custom create a plugin, and add the code there.
not working for me ..i have added this code in my functions.php
Deep, could you give me some more information about the issue you are facing?
This is so awesome I am going to implement this. Can you make a plugin for this, i mean people who cant understand the poetry of code can benefit a lot from this.
Thanks for sharing. Keep it up.
Update: I tried adding and failed. Can you like give just one code to do this along with the what is already there. To be more precise one page of code that can be copied and pasted to the theme functions.php. 🙂
Please, help me: what file I have to change? I have read about “will have to be written on the ‘init’ hook” but where is this file located?
Hi Alexis,
You can add code in your theme’s ‘functions.php’ file or in a custom plugin.
Please help me, I want to make an email notification for customer if status “Shipped” being selected. Just like email notification when order is ‘Completed’. Please, i really need this.
Hi Lia,
The function ‘wdm_order_shipped_callback’ is called when the order status is set to Shipped. So you can add the email functionality in this function or add your own function on the ‘woocommerce_order_action_wdm_shipped’ hook
Hi,
How do I do add the e-mail functionality to the call back function? I am so lost in translation. Thank you in advanced for your assistance
Hi thanks for the article! I have tried adding the code to wp-content/themes/theme/functions.php but my back office stops working completely when I add it. Its not working 🙁 . I added it to the part of Assign Theme Specific Functions and right below : add_action( ‘after_setup_theme’, ‘thinkup_themesetup’ );
Please help 🙂
Hi, thanks for this awesome article. I have adding coding into functions.php as step 1 and 2 but it is not working 🙁 .
Kindly need your help. 🙂
Hello there !
Thank you and thank you for this post. Everything I was looking for, and it’s awesome. (WP 4.5.3 and WC 2.6.2)
I just made a little change to make it working fine :
i replace all the
add_action( ‘XXX’, array( $this, ‘YYY’ ) );
Only By
add_action( ‘XXX’, ‘YYY’ );
And it’s perfect !!
One last thing, could you explain what did you write in your css file ? Cause i still cannot change the icon… 🙁
Do you use a content=”e360″ thing, or a background=/wp-content/……./xxx.png ??
Thank you
Hi Thomas,
Regarding add_action( ‘XXX’, array( $this, ‘YYY’ ) );
‘$this’ refers to the current class object. We’d added the code in a custom class, therefore the format was as stated above.
In the CSS file, we’ve loaded the required icons by Icomoon -https://icomoon.io/. You can use the same as per your requirement.
Perfect solution. I am looking for this. I have similar shipping functionality. I hope I should share this.
Wonderful!
Just realized that the new order status is being ignored by the WooCommerce default reports. Is that a way to fix that?
Hi,
This has been a great solution for me so thank you! However I cant get the action to fire before the order status is changed? Is there a way to do that?
never mind I figured it out. (typo)
woocommerce admin panel order list ins not showing shipping detail
woocommerce admin panel order list isnot showing shipping detail
Hi sir,
I admire the work you did with the shipped status script which I found after a long search on the internet.
I am not an indepth developer, so the only thing which is an open question, is how to style the shipped icon, which is now blank.
You have a url to a css file called wdm_shipping_icon.css. Would it be possible to inform about the contents of this css? It would be highly appreciated.
Thanks in advance.
Thanks for the code. One major problem with the code is that it affects the sales report section as the order values of those with this new status are not considered in the calculation. Is there a fix for that?
It sounds ideal for my purposes.
Is there a way of it automatically adding an order note/comment (including a date stamp) when the status changes to shipped?
My functions.php is like below…
When i add the code…my site becomes unreachable
could u provide instructions where i need to add this code
root@ip-172-31-29-238:/opt/bitnami/apps/wordpress/htdocs/wp-content/themes/cspaced# cat functions.php
<?php
/*
* Load theme setup
* ******************************************************************* */
require_once( get_template_directory() . '/theme/theme-setup.php' );
/*
* Load framework
* ******************************************************************* */
require_once( get_template_directory() . '/framework/init.php' );
/*
* Load theme
* ******************************************************************* */