Check for max discount to be -ve to prevent overwriting fee.

When we refund fee and some other line item whose value is more than fee in a single requst, value of line item will overwrite refund fee.

This is because where we check to make sure that we do not discount more than total possible value (to prevent negative total), we do not account for the fact that sometimes the cart could contain refund items. In those cases max_discount * -1 will always be larges then fees total.

This commit adds a check to make sure that max discount * -1 is indeed negative before overwriting fee total.
This commit is contained in:
vedanshujain 2019-08-07 02:13:01 +05:30
parent 3685171c52
commit 6f2d64dcb4
2 changed files with 56 additions and 1 deletions

View File

@ -1534,7 +1534,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
if ( 0 > $fee_total ) {
$max_discount = round( $cart_total + $fees_total + $shipping_total, wc_get_price_decimals() ) * -1;
if ( $fee_total < $max_discount ) {
if ( $fee_total < $max_discount && 0 > $max_discount ) {
$item->set_total( $max_discount );
}
}

View File

@ -1272,6 +1272,61 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$this->assertEquals( $expected, $orders );
}
/**
* Test create refund when additional fee is also refunded.
*
* @link https://github.com/woocommerce/woocommerce/issues/24238
*/
public function test_wc_create_refund_24238() {
$order = new WC_Order();
$order->add_product( WC_Helper_Product::create_simple_product(), 10 );
$fee = new WC_Order_Item_Fee();
$fee->set_props(
array(
'name' => 'Some Fee',
'tax_status' => 'taxable',
'total' => '10',
'tax_class' => '',
)
);
$order->add_item( $fee );
$order->calculate_totals( true );
$order->save();
$this->assertEquals( 110, $order->get_total() );
$products = $order->get_items( 'line_item' );
$this->assertCount( 1, $products );
$product_id = array_keys( $products )[0];
$fee_items = $order->get_items( 'fee' );
$this->assertCount( 1, $fee_items );
$fee_id = array_keys( $fee_items )[0];
$args = array(
'amount' => 55,
'order_id' => $order->get_id(),
'line_items' => array(
$fee_id => array(
'refund_total' => 5,
),
$product_id => array(
'qty' => 5,
'refund_total' => 50,
),
),
);
$refund_obj = wc_create_refund( $args );
$refunded_fee_items = $refund_obj->get_items( 'fee' );
$this->assertCount( 1, $refunded_fee_items );
$refunded_fee = array_values( $refunded_fee_items )[0];
$this->assertEquals( -5, $refunded_fee->get_total() );
}
/**
* Test wc_sanitize_order_id().
*/