Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Woocommerce prevent negative variation stock with backorder

Im allowing backorders in my store, but i don't want the stock quantity to be negative.

I tried to fix this using this :

add_action('woocommerce_variation_set_stock', 'avoid_negative_stock', 10, 1);
function avoid_negative_stock( $product ) {
    if ( did_action( 'woocommerce_variation_set_stock' ) >= 2 )
        return;
    if($product->get_stock_quantity() < 0){
        $product->set_stock_quantity(0);
        $product->save();
    }
}

But it doesn't work :/

Can anyone help me up with that ?

Regards

like image 919
Arès Avatar asked Dec 12 '25 12:12

Arès


2 Answers

You can use the woocommerce_update_product_stock_query hook.
In this answer you can find a solution.

Keep in mind that it's not a good idea to force product inventory management.

I'll give you an example:

  1. You have enabled backorders for a product that has a stock of 1 quantity.
  2. A customer places an order for that product by purchasing 3 quantities.
  3. With your rule the product will have the stock quantity at zero (instead of -2)
  4. The order is canceled or refunded and the product stock quantity is reset to 3 (instead of 1)

This is multiplied by all orders of the same product which for any reason are canceled and/or refunded. The product stock quantity will no longer be reliable.

Just be aware of it.

That said, you can disable negative stock quantity like this:

// disables the negative product stock quantity
add_filter( 'woocommerce_update_product_stock_query', 'disable_negative_stock_quantity', 10, 4 );
function disable_negative_stock_quantity( $sql, $product_id_with_stock, $new_stock, $operation ) {

    global $wpdb;

    // if the new stock quantity is negative, it sets zero
    if ( $new_stock < 1 ) {
        $new_stock = 0;
    }

    // generates SQL with the stock quantity at zero
    $sql = $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_value = %f WHERE post_id = %d AND meta_key='_stock'", wc_stock_amount( $new_stock ), $product_id_with_stock );
    
    return $sql;

}

The code has been tested and works. Add it to your active theme's functions.php.

like image 117
Vincenzo Di Gaetano Avatar answered Dec 15 '25 06:12

Vincenzo Di Gaetano


You can use update_product_stock and read_stock_quantity Try below code.

add_action('woocommerce_variation_set_stock', 'avoid_negative_stock', 10, 1);
function avoid_negative_stock( $product ) {
    
    if ( did_action( 'woocommerce_variation_set_stock' ) >= 2 )
        return;

    $product_id_with_stock = $product->get_stock_managed_by_id();
    $product_with_stock    = $product_id_with_stock !== $product->get_id() ? wc_get_product( $product_id_with_stock ) : $product;
    $data_store            = WC_Data_Store::load( 'product' );
    $stock_quantity        = $product->get_stock_quantity();

    if( $stock_quantity < 1 ){

        $stock_quantity = 0;

        // Update the database.
        $new_stock = $data_store->update_product_stock( $product_id_with_stock, $stock_quantity, 'set' );

        // Update the product object.
        $data_store->read_stock_quantity( $product_with_stock, $new_stock );
    
        $product->save();
    }

}
like image 43
Bhautik Avatar answered Dec 15 '25 06:12

Bhautik