如何在WooCommerce中根据购物车数量和产品属性对可变和单品应用折扣?

huangapple go评论67阅读模式
英文:

How to apply discount on variable and single products, based on cart quantity and product attribute in WooCommerce?

问题

我正在尝试根据购物车中具有特定产品属性的产品数量来应用百分比折扣。

更具体地说,我的目标是对具有属性“flaske”的至少6件产品的订单应用15%的折扣。

我已经成功地为具有设置变体属性的可变产品实现了这一目标,但似乎无法针对单个/简单产品进行操作。

我的代码如下(从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;

    // 初始化变量
    $min_item_amount = 6; // 最小数量
    $discount = $items_count = $percent = $items_subtotal = 0;
    $taxonomy = 'pa_variant'; // 分类法
    $term_slugs = array('flaske'); // 术语/术语
    // 循环购物车项目
    foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
        // 循环变量
        foreach ($cart_item['variation'] as $attribute => $term_slug) {
            // 仅计算大于6且具有属性的项目
            if ($cart_item['data']->get_price() >= $min_item_amount && $attribute === 'attribute_' . $taxonomy && in_array($term_slug, $term_slugs)) {
                $items_count += $cart_item['quantity'];
                $items_subtotal += $cart_item['line_subtotal'];
            }
        }
    }
    // 条件百分比
    if ($items_count >= 6) {
        $percent = 15;
    }
    // 折扣(应税)
    if ($items_count > 0) {
        // 计算
        $discount -= ($items_subtotal / 100) * $percent;
        $cart->add_fee(__('Mix & Match rabat - $percent%', 'woocommerce'), $discount, true);
    }
}

我的当前代码非常适用于可变产品(变体),但似乎不影响单个产品,即使我将单个产品赋予与可变产品相同的属性也是如此。

我怀疑这与foreach循环foreach ($cart_item['variation'] as $attribute => $term_slug)有关。

如何使这个代码普遍适用,以便它也适用于具有相同属性“flaske”的单个/简单产品?

将不适用于这些产品的部分删除或注释掉,可能会导致它适用于所有产品。希望对你有所帮助。

英文:

I am trying to apply a percentage discount based on quantity of products with a specific product attribute, in cart.

More precisely my goal is to apply 15% discount on orders of minimum 6 products with the attribute flaske.

I have managed to achieve this for variable products with variation attributes set, but I can't seem to target the single/simple products.

My code so far (borrowed from Condition for Quantity and Price for Woocommerce):

// Discount based on product quantity and attribute in cart
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
    $min_item_amount = 6; // Min quantity
    $discount = $items_count = $percent = $items_subtotal = 0;
    $taxonomy   = 'pa_variant'; // Taxonomy
    $term_slugs = array('flaske'); // Term/terms
    // Loop through cart items
    foreach( $cart->get_cart() as $cart_item_key => $cart_item ) {
      // Loop through variation
      foreach( $cart_item['variation'] as $attribute => $term_slug ) {
        // Only counting items that are above 6 and has attribute
        if( $cart_item['data']->get_price() >= $min_item_amount && $attribute === 'attribute_'.$taxonomy && in_array( $term_slug, $term_slugs ) ) {
            $items_count += $cart_item['quantity'];
            $items_subtotal += $cart_item['line_subtotal'];
        }
      }
    }
    // CONDITIONAL PERCENTAGE
    if ($items_count >= 6 ) {
        $percent = 15;
    }
    // DISCOUNT (TAXABLE)
    if( $items_count > 0 ) {
        // Calculation
        $discount -= ($items_subtotal / 100) * $percent;
        $cart->add_fee( __( "Mix & Match rabat - $percent%", "woocommerce" ), $discount, true);
    }
}

My current code works very well for variable products (the variants), but it doesn't seem to affect single products, even if I give the single products the same attributes as the variable product.

I suspect it has to do with the foreach loop foreach( $cart_item['variation'] as $attribute => $term_slug )

How can I make this work in general, so it also applies for single/simple products with same attribute flaske?

Any help and advice would be appreciated.

Other useful references:

Woocommerce percentage discount per item based on quantity

Exclude variations with 2 specific attribute terms from coupon usage in Woocommerce

答案1

得分: 1

以下是翻译好的代码部分:

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) {
        $product = $cart_item['data'];

        // 产品变体
        if ($product->is_type('variation')) {
            // 循环遍历变体属性
            foreach ($cart_item['variation'] as $attribute => $term_slug) {
                // 只计算数量大于6且具有属性的项目
                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(); // WP_Term对象数组
                $slugs = array_map(function($term) { return $term->slug; }, $terms); // 仅提取术语slug

                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) {
        // 计算
        $discount -= ($items_subtotal / 100) * $percent;
        $cart->add_fee(__("Mix & Match rabat - $percent%", "woocommerce"), $discount, true);
    }
}

它应该可以正常工作。

英文:

You don't get the product attributes set in simple or variable products, in the same way as for product variations.

The following revisited code should also handle simple products (untested):

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
    // 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) {
                // Only counting items that are above 6 and has attribute
                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) {
        $percent = 15;
    }
    // DISCOUNT (TAXABLE)
    if ($items_count > 0) {
        // Calculation
        $discount -= ($items_subtotal / 100) * $percent;
        $cart->add_fee(__("Mix & Match rabat - $percent%", "woocommerce"), $discount, true);
    }
}

It should work.

huangapple
  • 本文由 发表于 2023年7月18日 01:30:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/76706825.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定