Better error messages for when coupon are held in other transactions.

Earlier, we were just showing an "Usage limit reached message", however in some cases, specially when user is logged in, we can also ask them to go to MyAccount page and cancel order if they'd like to (to free up the coupon). This will hopefully make for a better user experience.
This commit is contained in:
vedanshujain 2020-12-16 15:19:40 +05:30
parent 507e7a27b2
commit 6b550ffb23
3 changed files with 35 additions and 5 deletions

View File

@ -1005,7 +1005,7 @@ class WC_Coupon extends WC_Legacy_Coupon {
}
break;
case self::E_WC_COUPON_USAGE_LIMIT_COUPON_STUCK_GUEST:
$err = __( 'Coupon usage limit has been reached. If you were trying to use this coupon just now, please try again after some time or contact us for help.', 'woocommerce' );
$err = __( 'Coupon usage limit has been reached. Please try again after some time, or contact us for help.', 'woocommerce' );
break;
case self::E_WC_COUPON_EXCLUDED_PRODUCTS:
// Store excluded products that are in cart in $products.

View File

@ -599,11 +599,40 @@ class WC_Discounts {
* @return bool
*/
protected function validate_coupon_usage_limit( $coupon ) {
if ( $coupon->get_usage_limit() > 0 && $coupon->get_usage_count() >= $coupon->get_usage_limit() ) {
throw new Exception( __( 'Coupon usage limit has been reached.', 'woocommerce' ), 106 );
if ( ! $coupon->get_usage_limit() ) {
return true;
}
return true;
$usage_count = $coupon->get_usage_count();
$data_store = $coupon->get_data_store();
$tentative_usage_count = is_callable( array( $data_store, 'get_tentative_usage_count' ) ) ? $data_store->get_tentative_usage_count( $coupon->get_id() ) : 0;
if ( $usage_count + $tentative_usage_count < $coupon->get_usage_limit() ) {
// All good.
return true;
}
// Coupon usage limit is reached. Let's show as informative error message as we can.
if ( 0 === $tentative_usage_count ) {
// No held coupon, usage limit is indeed reached.
$error_code = WC_Coupon::E_WC_COUPON_USAGE_LIMIT_REACHED;
} elseif ( is_user_logged_in() ) {
$recent_pending_orders = wc_get_orders(
array(
'limit' => 1,
'post_status' => array( 'wc-failed', 'wc-pending' ),
'customer' => get_current_user_id(),
'return' => 'ids',
)
);
if ( count( $recent_pending_orders ) > 0 ) {
// User logged in and have a pending order, maybe they are trying to use the coupon.
$error_code = WC_Coupon::E_WC_COUPON_USAGE_LIMIT_COUPON_STUCK;
} else {
$error_code = WC_Coupon::E_WC_COUPON_USAGE_LIMIT_REACHED;
}
} else {
// Maybe this user was trying to use the coupon but got stuck. We can't know for sure (performantly). Show a slightly better error message.
$error_code = WC_Coupon::E_WC_COUPON_USAGE_LIMIT_COUPON_STUCK_GUEST;
}
throw new Exception( $coupon->get_coupon_error( $error_code ), $error_code );
}
/**

View File

@ -422,6 +422,7 @@ class WC_Coupon_Data_Store_CPT extends WC_Data_Store_WP implements WC_Coupon_Dat
$this->get_tentative_usage_query( $coupon_id )
);
}
/**
* Get the number of uses for a coupon by user ID.
*