I'm working on a bit of custom Woocommerce functionality for a client. They use the BACS payment gateway to handle manual payments.
However, the gateway currently reduces the stock too early for our needs, ie, when the order is "On Hold". I would like to ONLY reduce the stock when the order is marked "Processing" or "Complete" (avoiding duplicate reductions).
I have manged to prevent the stock from reducing itself while "on hold" with the following snippet:
function wcs_do_not_reduce_onhold_stock( $reduce_stock, $order ) {
if ( $order->has_status( 'on-hold' ) ) {
$reduce_stock = false;
}
return $reduce_stock;
}
add_filter( 'woocommerce_can_reduce_order_stock', 'wcs_do_not_reduce_onhold_stock', 10, 2 );
I'm not too sure how to proceed though. While the above code works, adding the following condition does not:
else if ( $order->has_status( 'processing' ) || $order->has_status( 'completed' ) ) {
$reduce_stock = true;
}
In short, I'd ideally like the stock to change depending on the following stock statuses:
Any help is much appreciated!
Using a custom function hooked in woocommerce_order_status_changed
you will be able to target 'processing' and 'completed' order statuses change reducing order items stock.
I have added in your function a condition to target only "BACS" payment gateway on orders.
add_filter( 'woocommerce_can_reduce_order_stock', 'wcs_do_not_reduce_onhold_stock', 10, 2 );
function wcs_do_not_reduce_onhold_stock( $reduce_stock, $order ) {
if ( $order->has_status( 'on-hold' ) && $order->get_payment_method() == 'bacs' ) {
$reduce_stock = false;
}
return $reduce_stock;
}
add_action( 'woocommerce_order_status_changed', 'order_stock_reduction_based_on_status', 20, 4 );
function order_stock_reduction_based_on_status( $order_id, $old_status, $new_status, $order ){
// Only for 'processing' and 'completed' order statuses change
if ( $new_status == 'processing' || $new_status == 'completed' ){
$stock_reduced = get_post_meta( $order_id, '_order_stock_reduced', true );
if( empty($stock_reduced) && $order->get_payment_method() == 'bacs' ){
wc_reduce_stock_levels($order_id);
}
}
}
Code goes in function.php file of the active child theme (or active theme).
Tested and works
The accepted answer did not work for me. The first part did but not the second, this is how I modified it:
// This is the same as the accepted answer
add_filter( 'woocommerce_can_reduce_order_stock', 'wcs_do_not_reduce_onhold_stock', 10, 2 );
function wcs_do_not_reduce_onhold_stock( $reduce_stock, $order ) {
if ( $order->has_status( 'on-hold' ) && $order->get_payment_method() == 'bacs' ) {
$reduce_stock = false;
}
return $reduce_stock;
}
// This is what I changed
add_action( 'woocommerce_order_status_processing', 'reduce_stock_on_bacs_order_status_change', 10, 1 );
add_action( 'woocommerce_order_status_completed', 'reduce_stock_on_bacs_order_status_change', 10, 1 );
function reduce_stock_on_bacs_order_status_change( $order_id ) {
// Get the order object
$order = wc_get_order( $order_id );
// Check if the order was paid using BACS
if ( 'bacs' == $order->get_payment_method() ) {
// Check if the stock reduction has already been done for this order
$stock_reduction_done = get_post_meta( $order_id, '_stock_reduction_done', true );
if ( ! $stock_reduction_done ) {
// Iterate over the order items
foreach( $order->get_items() as $item_id => $item ) {
// Reduce stock for each item
$product = $item->get_product();
$qty = $item->get_quantity();
$product->reduce_stock( $qty );
}
// Mark the stock reduction as done for this order
update_post_meta( $order_id, '_stock_reduction_done', true );
}
}
}
This will not reduce the stock for BACS
payments until the order is marked as processing
or completed
.
can someone support please i have custom status wich named "wc-packed" and "wc-shipped" i need the stock level reduce when i choose one of them and not effective by any other status
and even i change from those status to another the stock level restored
and i have another custom status called "WC-RTRN"
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.