I would like to get some hints as to how I would go about changing some WooCommerce functionality.
Background
I am using WooCommerce 3.5.4 which allows one to mark a product as "disabled for coupons" (a great feature btw.). If one were to add such a product to an otherwise empty cart and tried to apply a coupon afterward, they would receive an error message. That is great as the user gets feedback on why there are no changes to the price. Thus, if all the products in the cart are marked as "disabled for coupons" everything works like I would want it to.
My Problem
My problem arises if there are some products in the cart, on which the coupon can be applied. In this case, the price would be calculated correctly (the coupon would be applied only to those products which it is applicable to) but the user would receive no message that it was not applied to some of the products. Thus they may wonder why the new price does not meet their expectations.
On the WooCommerce side
The Class that - among other things - handles the discount by coupons is WC_Discounts which can be found in
woocommerce/includes/class-wc-discounts.php
The Method that is responsible for the error message I like is this:
protected function validate_coupon_excluded_items( $coupon ) {
$items = $this->get_items_to_validate();
if ( ! empty( $items ) && $coupon->is_type( wc_get_product_coupon_types() ) ) {
$valid = false;
foreach ( $items as $item ) {
if ( $item->product && $coupon->is_valid_for_product( $item->product, $item->object ) ) {
$valid = true;
break;
}
}
if ( ! $valid ) {
throw new Exception( __( 'Sorry, this coupon is not applicable to selected products.', 'woocommerce' ), 109 );
}
}
return true;
}
It checks all items in the cart and throws an exception only if the coupon in question is applicable to none of the items.
The exception in turn is catched by another method which will only apply the coupon (e.g. calculate some discount off the original price) if there are no exceptions:
public function is_coupon_valid( $coupon ) {
try {
$this->validate_coupon_exists( $coupon );
$this->validate_coupon_usage_limit( $coupon );
$this->validate_coupon_user_usage_limit( $coupon );
$this->validate_coupon_expiry_date( $coupon );
$this->validate_coupon_minimum_amount( $coupon );
$this->validate_coupon_maximum_amount( $coupon );
$this->validate_coupon_product_ids( $coupon );
$this->validate_coupon_product_categories( $coupon );
$this->validate_coupon_excluded_items( $coupon );
$this->validate_coupon_eligible_items( $coupon );
if ( ! apply_filters( 'woocommerce_coupon_is_valid', true, $coupon, $this ) ) {
throw new Exception( __( 'Coupon is not valid.', 'woocommerce' ), 100 );
}
} catch ( Exception $e ) {
/**
* Filter the coupon error message.
*
* @param string $error_message Error message.
* @param int $error_code Error code.
* @param WC_Coupon $coupon Coupon data.
*/
$message = apply_filters( 'woocommerce_coupon_error', is_numeric( $e->getMessage() ) ? $coupon->get_coupon_error( $e->getMessage() ) : $e->getMessage(), $e->getCode(), $coupon );
return new WP_Error( 'invalid_coupon', $message, array(
'status' => 400,
) );
}
return true;
}
My Question
My question would be if anyone could give me an idea on how to show an error message (some kind of feedback) to a user, if a coupon is not applicable to all the products in the cart. I would like a customer to know, if and why for example a 10% discount is not being applied to all the items in their cart.