'Remove percent coupon if discounted price of product is more than 10%

I need to remove / disable the coupon effect for products discounted by more than 10%. At the moment I have something like this:

function action_woocommerce_before_calculate_totals( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) return;
    // Specific categories: the term name/term_id/slug. Several could be added, separated by a comma
    $excluded_categories = array( 'prod_category_name' );
    // Initialize
    $coupon_flag = false;
    // Loop through applied coupons
    foreach ( $cart->get_applied_coupons() as $coupon_code ) {
        // Get an instance of the WC_Coupon Object
        $coupon = new WC_Coupon( $coupon_code );
        // Only for certain types, several can be added, separated by a comma
        if ( in_array( $coupon->get_discount_type(), array( 'percent', 'percent_product' ) ) ) {
            $coupon_flag = true;
            break;
        }
    }
    foreach( $cart->get_applied_coupons() as $coupon_code ) {
        // Get the WC_Coupon object
        $coupon = new WC_Coupon($coupon_code);
        $coupon_amount = $coupon->get_amount(); // Get coupon amount
    }

    if ( $coupon_flag ) {
        // Loop through cart items
        foreach ( $cart->get_cart() as $cart_item ) {
            // Get product ID in
            $product_id = $cart_item['product_id'];
            // NOT contains the definite term
            if ( ! has_term( $excluded_categories, 'product_cat', $product_id ) ) {
                // Get regular price
                $regular_price = $cart_item['data']->get_regular_price();
                // Get promo price
                $promo_price = $cart_item['data']->get_price();
                // Zniżka
                $discount = 100 - (($promo_price * 100) / $regular_price);

                $percentage = 10;
                $percent_price = $regular_price - ($regular_price * ($percentage / 100));
                if ($discount > $coupon_amount ) {
                    //$coupon->set_amount(0);
                    $cart->remove_coupon( 'coupon_name' );
                }
                if ( $percent_price < $promo_price ) {
                    $cart_item['data']->set_price( $regular_price );
                } else {
                    $cart_item['data']->set_price( $promo_price ); 
                }
            }
        }
    }
}

At the moment, the code removes the coupon for the entire cart:

$cart->remove_coupon( 'coupon_name' );

Is there an option to remove the discount for the selected product from the cart? I need something like:

$cart_item['data']->remove_coupon( 'coupon_name' );

Thank you so much!



Solution 1:[1]

Ok I added filter and it works perfect =)

add_filter( 'woocommerce_coupon_is_valid_for_product', 'exclude_product_from_product_promotions_frontend', 9999, 4 );

function exclude_product_from_product_promotions_frontend( $valid, $product, $coupon, $values ) {
    $regular_price = $product->get_regular_price();
    $promo_price = $product->get_price();
    $discount = 100 - (($promo_price * 100) / $regular_price);
    $coupon_amount = 10;
    if ($discount > $coupon_amount ) {
        $valid = false;
    }
    return $valid;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Giacomo