Use update_coupon_usage_counts to avoid double count. (#31147)

Previously we were increasing coupon usage count on every apply_coupon method. This was causing double usages because, we would also increase on order save callback.

We instead now call `wc_update_coupon_usage_counts` in apply_method itself, which would increase the usage and also set the `_recorded_coupon_usage_counts` order meta.

Additional, we also manually call $couon->increase_usage_count if `_recorded_coupon_usage_counts` is because in this case, we are likely applying more than one coupon to the order. And `_recorded_coupon_usage_counts` meta would have already been set by the first coupon. This is not a good solution, ideally we should revamp how we store the coupon recorded information to support multiple coupon information from the get-go.
This commit is contained in:
Vedanshu Jain 2021-11-17 02:53:24 +05:30 committed by GitHub
parent 742fffff79
commit 78e7039944
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 68 additions and 1 deletions

View File

@ -1166,7 +1166,12 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
$used_by = $this->get_billing_email();
}
$coupon->increase_usage_count( $used_by );
$order_data_store = $this->get_data_store();
if ( $order_data_store->get_recorded_coupon_usage_counts( $this ) ) {
$coupon->increase_usage_count( $used_by );
}
wc_update_coupon_usage_counts( $this->get_id() );
return true;
}

View File

@ -184,4 +184,66 @@ class WC_Abstract_Order_Test extends WC_Unit_Test_Case {
$this->assertEquals( 1234, $order_item->passed_props['total'] );
$this->assertEquals( 1234, $order_item->passed_props['subtotal'] );
}
/**
* Test get coupon usage count across statuses.
*/
public function test_apply_coupon_across_status() {
$coupon_code = 'coupon_test_count_across_status';
$coupon = WC_Helper_Coupon::create_coupon( $coupon_code );
$this->assertEquals( 0, $coupon->get_usage_count() );
$order = WC_Helper_Order::create_order();
$order->set_status( 'pending' );
$order->save();
$order->apply_coupon( $coupon_code );
$this->assertEquals( 1, ( new WC_Coupon( $coupon_code ) )->get_usage_count() );
// Change order status to anything other than cancelled should not change coupon count.
$order->set_status( 'processing' );
$order->save();
$this->assertEquals( 1, ( new WC_Coupon( $coupon_code ) )->get_usage_count() );
// Cancelling order should reduce coupon count.
$order->set_status( 'cancelled' );
$order->save();
$this->assertEquals( 0, ( new WC_Coupon( $coupon_code ) )->get_usage_count() );
}
/**
* Test get multiple coupon usage count across statuses.
*/
public function test_apply_coupon_multiple_across_status() {
$coupon_code_1 = 'coupon_test_count_across_status_1';
$coupon_code_2 = 'coupon_test_count_across_status_2';
$coupon_code_3 = 'coupon_test_count_across_status_3';
WC_Helper_Coupon::create_coupon( $coupon_code_1 );
WC_Helper_Coupon::create_coupon( $coupon_code_2 );
WC_Helper_Coupon::create_coupon( $coupon_code_3 );
$order = WC_Helper_Order::create_order();
$order->set_status( 'pending' );
$order->save();
$order->apply_coupon( $coupon_code_1 );
$order->apply_coupon( $coupon_code_2 );
$order->apply_coupon( $coupon_code_3 );
$this->assertEquals( 1, ( new WC_Coupon( $coupon_code_1 ) )->get_usage_count() );
$this->assertEquals( 1, ( new WC_Coupon( $coupon_code_2 ) )->get_usage_count() );
$this->assertEquals( 1, ( new WC_Coupon( $coupon_code_3 ) )->get_usage_count() );
// Change order status to anything other than cancelled should not change coupon count.
$order->set_status( 'processing' );
$order->save();
$this->assertEquals( 1, ( new WC_Coupon( $coupon_code_1 ) )->get_usage_count() );
$this->assertEquals( 1, ( new WC_Coupon( $coupon_code_2 ) )->get_usage_count() );
$this->assertEquals( 1, ( new WC_Coupon( $coupon_code_3 ) )->get_usage_count() );
// Cancelling order should reduce coupon count.
$order->set_status( 'cancelled' );
$order->save();
$this->assertEquals( 0, ( new WC_Coupon( $coupon_code_1 ) )->get_usage_count() );
$this->assertEquals( 0, ( new WC_Coupon( $coupon_code_2 ) )->get_usage_count() );
$this->assertEquals( 0, ( new WC_Coupon( $coupon_code_3 ) )->get_usage_count() );
}
}