Merge pull request #28069 from woocommerce/fix/issue-27504

Fix stock reducing incorrect amount when order item is deleted after …
This commit is contained in:
Roy Ho 2020-11-11 14:05:37 -08:00 committed by GitHub
commit 5dd19658f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 225 additions and 0 deletions

View File

@ -218,6 +218,14 @@ function wc_maybe_adjust_line_item_product_stock( $item, $item_quantity = -1 ) {
$refunded_item_quantity = $order->get_qty_refunded_for_item( $item->get_id() );
$diff = $item_quantity + $refunded_item_quantity - $already_reduced_stock;
/*
* 0 as $item_quantity usually indicates we're deleting the order item.
* We need to perform different calculations for this case.
*/
if ( 0 === $item_quantity ) {
$diff = min( absint( $refunded_item_quantity ), $already_reduced_stock ) * -1;
}
if ( $diff < 0 ) {
$new_stock = wc_update_product_stock( $product, $diff * -1, 'increase' );
} elseif ( $diff > 0 ) {

View File

@ -69,4 +69,221 @@ class WC_Admin_Functions_Test extends \WC_Unit_Test_Case {
$this->assertEquals( 990, $product->get_stock_quantity() );
}
/**
* Test adjust line item function when order item is deleted after a full refund with restock.
*
* @link https://github.com/woocommerce/woocommerce/issues/27504.
*/
public function test_admin_delete_order_item_after_full_refund_restock() {
$product = WC_Helper_Product::create_simple_product();
$product->set_manage_stock( true );
$product->set_stock_quantity( 100 );
$product->set_price( 100 );
$product->set_regular_price( 100 );
$product->save();
$order = WC_Helper_Order::create_order();
$order->set_status( 'on-hold' );
$order_item_id = $order->add_product( $product, 10 );
$order_item = new WC_Order_Item_Product( $order_item_id );
// Stocks have not reduced yet.
$product = wc_get_product( $product->get_id() );
$this->assertEquals( 100, $product->get_stock_quantity() );
wc_maybe_adjust_line_item_product_stock( $order_item );
$product = wc_get_product( $product->get_id() );
$this->assertEquals( 90, $product->get_stock_quantity() );
$args = array(
'amount' => 10,
'order_id' => $order->get_id(),
'line_items' => array(
$order_item_id => array(
'qty' => 10,
'refund_total' => 0,
),
),
'refund_payment' => false,
'restock_items' => true,
);
wc_create_refund( $args );
$order->remove_item( $order_item_id );
$order->save();
$order_item->delete_meta_data( '_reduced_stock' );
wc_maybe_adjust_line_item_product_stock( $order_item, 0 );
$product = wc_get_product( $product->get_id() );
// Stocks should have been increased back to original level.
$this->assertEquals( 100, $product->get_stock_quantity() );
}
/**
* Test adjust line item function when order item is deleted after a full refund with no restock.
*
* @link https://github.com/woocommerce/woocommerce/issues/27504.
*/
public function test_admin_delete_order_item_after_full_refund_no_restock() {
$product = WC_Helper_Product::create_simple_product();
$product->set_manage_stock( true );
$product->set_stock_quantity( 100 );
$product->set_price( 100 );
$product->set_regular_price( 100 );
$product->save();
$order = WC_Helper_Order::create_order();
$order->set_status( 'on-hold' );
$order_item_id = $order->add_product( $product, 10 );
$order_item = new WC_Order_Item_Product( $order_item_id );
// Stocks have not reduced yet.
$product = wc_get_product( $product->get_id() );
$this->assertEquals( 100, $product->get_stock_quantity() );
wc_maybe_adjust_line_item_product_stock( $order_item );
$product = wc_get_product( $product->get_id() );
$this->assertEquals( 90, $product->get_stock_quantity() );
$args = array(
'amount' => 10,
'order_id' => $order->get_id(),
'line_items' => array(
$order_item_id => array(
'qty' => 10,
'refund_total' => 0,
),
),
'refund_payment' => false,
'restock_items' => false,
);
wc_create_refund( $args );
$order->remove_item( $order_item_id );
$order->save();
wc_maybe_adjust_line_item_product_stock( $order_item, 0 );
$product = wc_get_product( $product->get_id() );
// Stocks should have been increased back to original level.
$this->assertEquals( 100, $product->get_stock_quantity() );
}
/**
* Test adjust line item function when order item is deleted after a partial refund with restock.
*
* @link https://github.com/woocommerce/woocommerce/issues/27504.
*/
public function test_admin_delete_order_item_after_partial_refund_restock() {
$product = WC_Helper_Product::create_simple_product();
$product->set_manage_stock( true );
$product->set_stock_quantity( 100 );
$product->set_price( 100 );
$product->set_regular_price( 100 );
$product->save();
$order = WC_Helper_Order::create_order();
$order->set_status( 'on-hold' );
$order_item_id = $order->add_product( $product, 10 );
$order_item = new WC_Order_Item_Product( $order_item_id );
// Stocks have not reduced yet.
$product = wc_get_product( $product->get_id() );
$this->assertEquals( 100, $product->get_stock_quantity() );
wc_maybe_adjust_line_item_product_stock( $order_item );
$product = wc_get_product( $product->get_id() );
$this->assertEquals( 90, $product->get_stock_quantity() );
$args = array(
'amount' => 10,
'order_id' => $order->get_id(),
'line_items' => array(
$order_item_id => array(
'qty' => 5,
'refund_total' => 0,
),
),
'refund_payment' => false,
'restock_items' => true,
);
wc_create_refund( $args );
$order->remove_item( $order_item_id );
$order->save();
$order_item->update_meta_data( '_reduced_stock', 5 );
wc_maybe_adjust_line_item_product_stock( $order_item, 0 );
$product = wc_get_product( $product->get_id() );
// Stocks should have been increased back to original level.
$this->assertEquals( 100, $product->get_stock_quantity() );
}
/**
* Test adjust line item function when order item is deleted after a partial refund with no restock.
*
* @link https://github.com/woocommerce/woocommerce/issues/27504.
*/
public function test_admin_delete_order_item_after_partial_refund_no_restock() {
$product = WC_Helper_Product::create_simple_product();
$product->set_manage_stock( true );
$product->set_stock_quantity( 100 );
$product->set_price( 100 );
$product->set_regular_price( 100 );
$product->save();
$order = WC_Helper_Order::create_order();
$order->set_status( 'on-hold' );
$order_item_id = $order->add_product( $product, 10 );
$order_item = new WC_Order_Item_Product( $order_item_id );
// Stocks have not reduced yet.
$product = wc_get_product( $product->get_id() );
$this->assertEquals( 100, $product->get_stock_quantity() );
wc_maybe_adjust_line_item_product_stock( $order_item );
$product = wc_get_product( $product->get_id() );
$this->assertEquals( 90, $product->get_stock_quantity() );
$args = array(
'amount' => 10,
'order_id' => $order->get_id(),
'line_items' => array(
$order_item_id => array(
'qty' => 5,
'refund_total' => 0,
),
),
'refund_payment' => false,
'restock_items' => false,
);
wc_create_refund( $args );
$order->remove_item( $order_item_id );
$order->save();
$order_item->update_meta_data( '_reduced_stock', 5 );
wc_maybe_adjust_line_item_product_stock( $order_item, 0 );
$product = wc_get_product( $product->get_id() );
// Stocks should have been increased to orignal amount minus the partially refunded stock.
$this->assertEquals( 95, $product->get_stock_quantity() );
}
}