You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WooCommerce:如何仅给未应用优惠券的特定属性商品添加折扣

问题:让自定义折扣排除已应用优惠券的商品

我希望在结账页面实现:自定义折扣代码排除所有已应用优惠券的商品。

目前我的代码逻辑是:当购物车中添加了指定数量、属于特定变体分类的商品时,为订单应用折扣。需要调整代码,使已使用任何优惠券的商品无法享受该折扣,仅未应用优惠券的商品可享受此折扣。

当前代码

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);
    }
}

现有问题

我尝试通过WC()->cart->get_applied_coupons()判断购物车是否有优惠券,但当前代码中if ($items_count >= 6 && ! $couponcode )的逻辑会在有优惠券时完全取消折扣,而我只想排除那些已应用优惠券的商品,其余符合条件的商品仍可享受折扣。


解决方案

核心思路是逐个检查购物车商品是否被优惠券覆盖,只对未被优惠券应用的符合条件商品计算折扣,而非全局关闭所有折扣。

修改后的完整代码

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;
    $taxonomy   = 'pa_variant'; // 目标商品属性分类法
    $term_slugs = array('flaske'); // 目标属性别名

    // 遍历购物车中的每个商品
    foreach( $cart->get_cart() as $cart_item_key => $cart_item ) {
        // 检查当前商品是否有优惠券应用,有则跳过该商品的折扣计算
        if( ! empty( wc_get_coupon_ids_applied_to_item( $cart_item_key, $cart ) ) ) {
            continue;
        }

        $product = $cart_item['data'];
        // 处理变体商品
        if( $product->is_type('variation') ) {
            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'];
                }
            }
        } 
        // 处理简单商品
        elseif ( $product->is_type('simple') ) {
            $attributes = $product->get_attributes();

            if( ! empty($attributes) && array_key_exists($taxonomy, $attributes) ) {
                $terms = (array) $attributes[$taxonomy]->get_terms();
                $slugs = array_map(function($term) { return $term->slug; }, $terms);

                if (count( array_intersect($slugs, $term_slugs) ) > 0 ) {
                    $items_count += $cart_item['quantity'];
                    $items_subtotal += $cart_item['line_subtotal'];
                }
            }
        }
    }
    // 满足数量条件时设置折扣比例
    if ($items_count >= 6 ) { 
        $percent = 15;
    }
    // 应用折扣(仅当有符合条件的商品且折扣比例生效时)
    if ($items_count > 0 && $percent > 0 ) {
        $discount -= ($items_subtotal / 100) * $percent;
        $cart->add_fee(__("Mix & Match 折扣 - $percent%", "woocommerce"), $discount, true);
    }
}

关键改动说明

  1. 逐个商品检查优惠券状态:使用wc_get_coupon_ids_applied_to_item()函数判断当前商品是否被优惠券覆盖,若已应用优惠券则跳过该商品的计数和小计累加。
  2. 移除全局优惠券判断:删除原代码中! $couponcode的全局判断逻辑,不再因为购物车有优惠券就完全取消所有折扣。
  3. 精准计算折扣范围:折扣仅基于未被优惠券应用的、符合属性分类条件的商品数量和小计。
  4. 优化折扣应用条件:确保只有在有符合条件的商品且折扣比例生效时,才添加折扣费用,避免无效的0金额折扣显示。

内容的提问来源于stack exchange,提问作者Richard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 16:24:57