I am trying to exclude any products where any coupon code is applied, from my custom discount code, on the checkout page.
In my code, I am applying a discount to the order when x amount of products are added to the cart, with a specific variation taxonomy. I am trying to make this code work, so no discount may be given on items where ANY coupon code is used.
The discount code should only apply on products where no other coupon code has been applied/is active.
add_action( 'woocommerce_cart_calculate_fees','wc_cart_item_quantity_discount' );
function wc_cart_item_quantity_discount( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// INITIALIZING VARIABLES
$discount = $items_count = $percent = $items_subtotal = 0;
$taxonomy = 'pa_variant'; // Taxonomy
$term_slugs = array('flaske'); // Term/terms
$couponcode = WC()->cart->get_applied_coupons(); // check for any coupon code
// Loop through cart items
foreach( $cart->get_cart() as $cart_item_key => $cart_item ) {
$product = $cart_item['data'];
// Product variations
if( $product->is_type('variation') ) {
// Loop through variation attributes
foreach ($cart_item['variation'] as $attribute => $term_slug) {
if ($attribute === 'attribute_' . $taxonomy && in_array($term_slug, $term_slugs)) {
$items_count += $cart_item['quantity'];
$items_subtotal += $cart_item['line_subtotal'];
}
}
}
// Simple products
elseif ( $product->is_type('simple') ) {
$attributes = $product->get_attributes();
if( ! empty($attributes) && array_key_exists($taxonomy, $attributes) ) {
$terms = (array) $attributes[$taxonomy]->get_terms(); // array of WP_Term objects
$slugs = array_map(function($term) { return $term->slug; }, $terms); // Extract only the term slugs
if (count( array_intersect($slugs, $term_slugs) ) > 0 ) {
$items_count += $cart_item['quantity'];
$items_subtotal += $cart_item['line_subtotal'];
}
}
}
}
// CONDITIONAL PERCENTAGE
if ($items_count >= 6 && ! $couponcode ) { // CHECK COUPON
$percent = 15;
}
// DISCOUNT (TAXABLE)
if ($items_count > 0 ) {
// Calculation
$discount -= ($items_subtotal / 100) * $percent;
$cart->add_fee(__("Mix & Match rabat - $percent%", "woocommerce"), $discount, true);
}
}
What I have tried
I thought this could easily be done by checking if a coupon has been applied to cart, using WC()->cart->get_applied_coupons().
However, if ($items_count >= 6 && ! $couponcode ) {
removes the discount completely when a coupon code is applied. I only want to exclude products with coupons active, from the discounted calculations.
Is there any way to achieve this?
Reference:
Check if a coupon is applied to cart in WooCommerce
You need something a bit different, optimized in a simpler way.
get_attribute()
, to target only specific cart items (works with simple products and product variations).So your code will be:
add_action( 'woocommerce_cart_calculate_fees', 'wc_cart_item_quantity_discount' );
function wc_cart_item_quantity_discount( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$discount = $items_count = $percent = $items_subtotal = 0; // Initializing variables
$taxonomy = 'pa_variant'; // Attribute taxonomy (or taxonomy label name too)
$term_name = 'Flaske'; // Attribute term NAME
// Loop through cart items
foreach( $cart->get_cart() as $item ) {
$product = $item['data'];
// Targeting undiscounted items that have a specific product attribute value
if ( $product->get_attribute($taxonomy) === $term_name
&& $item['line_subtotal'] === $item['line_total'] ) {
$items_count += $item['quantity'];
$items_subtotal += $item['line_subtotal'];
}
}
// Discount percentage based on item count
if ($items_count >= 6 ) {
$percent = 15; // Discount percentage
$discount -= $items_subtotal * $percent / 100; // Calculation
$cart->add_fee( __('Mix & Match rabat', 'woocommerce') . " - {$percent}%", $discount );
}
}
Code goes in functions.php file of your child theme (or in a plugin). Tested and works.
Note: Using a fee with a negative amount to get a discount, is a trick, and in this case, it is always taxable even if you set the
$taxable
argument asfalse
.