PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Tuesday, January 18, 2022

[FIXED] Reduce stock only for specific order statuses and payment method in Woocommerce

 January 18, 2022     orders, php, stock, woocommerce, wordpress     No comments   

Issue

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, i.e., 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:

  • On Hold - Does nothing
  • Completed or Processing - Reduce Stock (Only once)
  • Cancelled - Increase Stock (Only if initially reduced)

Any help is much appreciated!


Solution

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



Answered By - LoicTheAztec
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing