I have a custom order status called 'cancel-by-admin' which is set when an order is cancelled by site admin for some reason.
Now we need to increase/adjust the produce stock count when the order is cancelled. WooCommerce has already provided 'cancel' order status and when it is set the stock count get adjusted by existing code. We need to implement the same functionality for 'cancel-by-admin' status.
How to achieve that? I am using Woocommerce 6.3.1.
Someone suggested to use the function wc_update_product_stock()
. Also this link: https://stackoverflow.com/a/51940564/696680
But I am note sure what would be the best approach. Note that a customer can order multiple products in a single order, hence when the admin cancel the order, all the associated product quantity need to be adjusted.
To add the custom order status I use the following code:
add_action( 'init', 'register_custom_order_statuses', 20 );
function register_custom_order_statuses() {
register_post_status( 'wc-cancelled-by-us', array(
'label' => _x( 'CancelledByAdmin', 'Order status', 'woocommerce' ),
'public' => true,
'exclude_from_search' => false,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true,
'label_count' => _n_noop( 'CancelledByAdmin <span >(%s)</span>', 'CancelledByAdmin <span >(%s)</span>', 'woocommerce' )
) );
}
And my code attempt, where I could use some advice on how to proceed:
add_action('woocommerce_order_status_changed', 'func_status_changed', 10, 4 );
function func_status_changed( $order_id, $old_status, $new_status, $order ){
if ( $new_status == 'cancelled-by-us' ) {
// Stock update operation goes here
}
}
CodePudding user response:
To add a custom order status I rewritten your code because:
- The
init
hook has been replaced withwoocommerce_register_shop_order_post_statuses
to register custom order statuses. wc_order_statuses
is added to show the order status in the dropdown @ single orderbulk_actions-edit-shop_order
is added to show order status in the dropdown @ bulk actions
// Register order status
function filter_woocommerce_register_shop_order_post_statuses( $order_statuses ) {
// Status must start with "wc-"
$order_statuses['wc-cancelled-by-us'] = array(
'label' => _x( 'Cancelled by admin', 'Order status', 'woocommerce' ),
'public' => false,
'exclude_from_search' => false,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true,
/* translators: %s: number of orders */
'label_count' => _n_noop( 'Cancelled by admin <span >(%s)</span>', 'Cancelled by admin <span >(%s)</span>', 'woocommerce' ),
);
return $order_statuses;
}
add_filter( 'woocommerce_register_shop_order_post_statuses', 'filter_woocommerce_register_shop_order_post_statuses', 10, 1 );
// Show order status in the dropdown @ single order
function filter_wc_order_statuses( $order_statuses ) {
$new_order_statuses = array();
// Add new order status after cancel
foreach ( $order_statuses as $key => $status ) {
$new_order_statuses[ $key ] = $status;
if ( 'wc-cancelled' === $key ) {
// Status must start with "wc-"
$new_order_statuses['wc-cancelled-by-us'] = _x( 'Cancelled by admin', 'Order status', 'woocommerce' );
}
}
return $new_order_statuses;
}
add_filter( 'wc_order_statuses', 'filter_wc_order_statuses', 10, 1 );
// Show order status in the dropdown @ bulk actions
function filter_bulk_actions_edit_shop_order( $bulk_actions ) {
// Note: "mark_" must be there instead of "wc"
$bulk_actions['mark_cancelled-by-us'] = __( 'Cancelled by admin', 'woocommerce' );
return $bulk_actions;
}
add_filter( 'bulk_actions-edit-shop_order', 'filter_bulk_actions_edit_shop_order', 10, 1 );
To answer your question, it is best to look at which functionality is applied for the existing 'cancel'
order status and then reproduce it.
In wc-stock-functions.php we can see that the function wc_maybe_increase_stock_levels()
is called for both the 'cancel'
status and the 'pending'
status
To reproduce it we can use the woocommerce_order_status_' . $status_transition['to']
composite hook that can be used with any custom order status.
So you get:
// Maybe increase stock levels
add_action( 'woocommerce_order_status_cancelled-by-us', 'wc_maybe_increase_stock_levels' );