在WooCommerce中的折扣规则,不包括具有用户角色条件的类别。

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

Discount rules in WooCommerce excluding categories with user roles conditions

问题

我使用这段代码,根据特定金额范围为客户提供折扣,对于常规买家生成2%、4%、6%的折扣,对于角色为"vip"的客户生成3%、5%、7%的折扣。

代码还必须排除我添加的类别。如果客户将属于这些类别的产品放入购物车,它不应计算在内。目前,无论如何都会计算在内,我无法使其正常工作。

折扣步骤按预期工作,但不排除我指定要排除的产品。例如,当我放入一个绿色T恤时,它会计算在内,当我放入一个红色的排除T恤时,它仍然会计算在内,尽管不应该。

add_action('woocommerce_cart_calculate_fees', 'custom_discount_based_on_cart_total', 10, 1);
function custom_discount_based_on_cart_total($cart) {
    if (is_admin() && !defined('DOING_AJAX'))
        return;

    // 在此排除类别
    $excluded_categories = array('redshirt1', 'redshirt2', 'redshirt3', 'redshirt4');
    $discounted_total = 0;

    foreach ($cart->get_cart() as $cart_item) {
        $product = $cart_item['data'];
        $product_id = $product->get_id();
        $terms = get_the_terms($product_id, 'product_cat');

        $exclude = false;
        foreach ($terms as $term) {
            if (in_array($term->slug, $excluded_categories)) {
                $exclude = true;
                break;
            }
        }

        if (!$exclude) {
            $discounted_total += $cart_item['line_subtotal'];
        }
    }

    $discount = 0;
    $discount_text = "";

    // 检查用户是否属于角色'vip'
    $user = wp_get_current_user();
    $is_customer = in_array('vip', (array) $user->roles);

    if ($discounted_total >= 2000 && $discounted_total < 4000) {
        $discount = $discounted_total * ($is_customer ? 0.03 : 0.02); // 3% for vip, 2% for others
        $discount_text = 'Discount ' . ($is_customer ? '3%' : '2%');
    } else if ($discounted_total >= 4000 && $discounted_total < 6000) {
        $discount = $discounted_total * ($is_customer ? 0.05 : 0.04); // 5% for vip, 4% for others
        $discount_text = 'Discount ' . ($is_customer ? '5%' : '4%');
    } else if ($discounted_total >= 6000) {
        $discount = $discounted_total * ($is_customer ? 0.07 : 0.06); // 7% for vip, 6% for others
        $discount_text = 'Discount ' . ($is_customer ? '7%' : '6%');
    }

    if ($discount > 0) {
        $cart->add_fee(__($discount_text, 'woocommerce'), -$discount);
    }
}

add_action('woocommerce_before_cart', 'show_discount_message');
function show_discount_message() {
    $cart = WC()->cart;
    $total = $cart->subtotal;

    // 排除类别
    $excluded_categories = array('redshirt1', 'redshirt2', 'redshirt3', 'redshirt4');
    $discounted_total = $total;

    foreach ($cart->get_cart() as $cart_item) {
        $product = $cart_item['data'];
        $product_cats = wp_get_post_terms($product->get_id(), 'product_cat');

        foreach ($product_cats as $product_cat) {
            if (in_array($product_cat->slug, $excluded_categories)) {
                $discounted_total -= $cart_item['line_subtotal'];
                break;
            }
        }
    }

    // 检查用户是否属于角色'vip'
    $user = wp_get_current_user();
    $is_customer = in_array('vip', (array) $user->roles);

    $return_to = wc_get_page_permalink('shop');

    if ($discounted_total < 2000) {
        $difference = 2000 - $discounted_total;
        $added_text = 'you have ' . wc_price($difference) . ' untill you reach level 1 (' . ($is_customer ? '3%' : '2%') . ') on the discount!';
        $notice = sprintf('<a href="%s" class="button wc-forward">%s</a> %s', esc_url($return_to), 'Keep shopping', $added_text);
        wc_print_notice($notice, 'notice');
    } else if ($discounted_total >= 2000 && $discounted_total < 4000) {
        $difference = 4000 - $discounted_total;
        $added_text = 'you have ' . wc_price($difference) . ' untill you reach level 2 (' . ($is_customer ? '5%' : '4%') . ') on the discount!';
        $notice = sprintf('<a href="%s" class="button wc-forward">%s</a> %s', esc_url($return_to), 'Keep shopping', $added_text);
        wc_print_notice($notice, 'notice');
    } else if ($discounted_total >= 4000 && $discounted_total < 6000) {
        $difference = 6000 - $discounted_total;
        $added_text = 'you have ' . wc_price($difference) . ' untill you reach level 3 (' . ($is_customer ? '7%' : '6%') . ') on the discount!';
        $notice = sprintf('<a href="%s" class="button wc-forward">%s</a> %s', esc_url($return_to), 'Keep shopping', $added_text);
        wc_print_notice($notice, 'notice');
    }
}
英文:

I use this code which gives customers a discount based in speific amount ranges that generates discount of 2% 4% 6% for regular buyers and 3% 5% 7% for customers with the role "vip".

The code must also exclude the categories I added.
If a customer puts a product in the shopping cart that belongs to those products, it should not count with it/them. Right now it counts with them anyway and I can't get it to work.

The discount steps work as they should but not excluding products that are in the categories I specified to exclude. When i have example a green tshirt in it counts it and when i put one of the red excluded tshirts in it still counts it anyway even tough it shouldnt.

add_action( &#39;woocommerce_cart_calculate_fees&#39;, &#39;custom_discount_based_on_cart_total&#39;, 10, 1 );
function custom_discount_based_on_cart_total( $cart ) {
if ( is_admin() &amp;&amp; ! defined( &#39;DOING_AJAX&#39; ) )
return;
// excluding categories here
$excluded_categories = array( &#39;redshirt1&#39;, &#39;redshirt2&#39;, &#39;redshirt3&#39;, &#39;redshirt4&#39; );
$discounted_total = 0;
foreach ( $cart-&gt;get_cart() as $cart_item ) {
$product = $cart_item[&#39;data&#39;];
$product_id = $product-&gt;get_id();
$terms = get_the_terms( $product_id, &#39;product_cat&#39; );
$exclude = false;
foreach ( $terms as $term ) {
if ( in_array( $term-&gt;slug, $excluded_categories ) ) {
$exclude = true;
break;
}
}
if ( ! $exclude ) {
$discounted_total += $cart_item[&#39;line_subtotal&#39;];
}
}
$discount = 0;
$discount_text = &quot;&quot;;
// check if the user is in the role &#39;vip&#39;
$user = wp_get_current_user();
$is_customer = in_array( &#39;vip&#39;, (array) $user-&gt;roles );
if ( $discounted_total &gt;= 2000 &amp;&amp; $discounted_total &lt; 4000 ) {
$discount = $discounted_total * ($is_customer ? 0.03 : 0.02); // 3% for vip, 2% for others
$discount_text = &#39;Discount &#39; . ($is_customer ? &#39;3%&#39; : &#39;2%&#39;);
} else if ( $discounted_total &gt;= 4000 &amp;&amp; $discounted_total &lt; 6000 ) {
$discount = $discounted_total * ($is_customer ? 0.05 : 0.04); // 5% for vip, 4% for others
$discount_text = &#39;Discount &#39; . ($is_customer ? &#39;5%&#39; : &#39;4%&#39;);
} else if ( $discounted_total &gt;= 6000 ) {
$discount = $discounted_total * ($is_customer ? 0.07 : 0.06); // 7% for vip, 6% for others
$discount_text = &#39;Discount &#39; . ($is_customer ? &#39;7%&#39; : &#39;6%&#39;);
}
if ( $discount &gt; 0 ) {
$cart-&gt;add_fee( __( $discount_text, &#39;woocommerce&#39; ), -$discount );
}
}
add_action( &#39;woocommerce_before_cart&#39;, &#39;show_discount_message&#39; );
function show_discount_message() {
$cart = WC()-&gt;cart;
$total = $cart-&gt;subtotal;
// excluding categories
$excluded_categories = array( &#39;redshirt1&#39;, &#39;redshirt2&#39;, &#39;redshirt3&#39;, &#39;redshirt4&#39; );
$discounted_total = $total;
foreach ( $cart-&gt;get_cart() as $cart_item ) {
$product = $cart_item[&#39;data&#39;];
$product_cats = wp_get_post_terms( $product-&gt;get_id(), &#39;product_cat&#39; );
foreach ( $product_cats as $product_cat ) {
if ( in_array( $product_cat-&gt;slug, $excluded_categories ) ) {
$discounted_total -= $cart_item[&#39;line_subtotal&#39;];
break;
}
}
}
// check if the user is in role &#39;vip&#39;
$user = wp_get_current_user();
$is_customer = in_array( &#39;vip&#39;, (array) $user-&gt;roles );
$return_to = wc_get_page_permalink( &#39;shop&#39; );
if ( $discounted_total &lt; 2000 ) {
$difference = 2000 - $discounted_total;
$added_text = &#39;you have &#39; . wc_price( $difference ) . &#39; untill you reach level 1 (&#39; . ($is_customer ? &#39;3%&#39; : &#39;2%&#39;) . &#39;) on the discount!&#39;;
$notice = sprintf( &#39;&lt;a href=&quot;%s&quot; class=&quot;button wc-forward&quot;&gt;%s&lt;/a&gt; %s&#39;, esc_url( $return_to ), &#39;Keep shopping&#39;, $added_text );
wc_print_notice( $notice, &#39;notice&#39; );
} else if ( $discounted_total &gt;= 2000 &amp;&amp; $discounted_total &lt; 4000 ) {
$difference = 4000 - $discounted_total;
$added_text = &#39;you have &#39; . wc_price( $difference ) . &#39; untill you reach level 2 (&#39; . ($is_customer ? &#39;5%&#39; : &#39;4%&#39;) . &#39;) on the discount!&#39;;
$notice = sprintf( &#39;&lt;a href=&quot;%s&quot; class=&quot;button wc-forward&quot;&gt;%s&lt;/a&gt; %s&#39;, esc_url( $return_to ), &#39;Keep shopping&#39;, $added_text );
wc_print_notice( $notice, &#39;notice&#39; );
} else if ( $discounted_total &gt;= 4000 &amp;&amp; $discounted_total &lt; 6000 ) {
$difference = 6000 - $discounted_total;
$added_text = &#39;you have &#39; . wc_price( $difference ) . &#39; untill you reach level 3 (&#39; . ($is_customer ? &#39;7%&#39; : &#39;6%&#39;) . &#39;) on the discount!&#39;;
$notice = sprintf( &#39;&lt;a href=&quot;%s&quot; class=&quot;button wc-forward&quot;&gt;%s&lt;/a&gt; %s&#39;, esc_url( $return_to ), &#39;Keep shopping&#39;, $added_text );
wc_print_notice( $notice, &#39;notice&#39; );
}
}

答案1

得分: 2

在WooCommerce中,产品类别和标签不是由产品变体处理的,而是由父变体产品处理的。因此,对于变体购物车项目,您需要获取父产品的ID,以便能够针对特定的产品类别。还有一些其他错误。

以下是您的修订代码:

// 自定义排除产品类别的条件函数
function has_excluded_product_categories( $product ) {
    // 在这里设置您要排除的产品类别(别名)
    $excl_terms = array( 'redshirt1', 'redshirt2', 'redshirt3', 'redshirt4', 'hoodies' );
    // 重要提示:处理产品变体
    $product_id = $product->get_parent_id() ? $product->get_parent_id() : $product->get_id();
    // 简化:直接获取产品类别的别名数组
    $term_slugs = wp_get_post_terms( $product_id, 'product_cat', array( 'fields' => 'slugs' ) );
    // 使用array_intersect()在两个数组上而不是更重的foreach循环上
    return (bool) count( array_intersect($term_slugs, $excl_terms) ) > 0;
}

// 有条件地添加折扣
add_action( 'woocommerce_cart_calculate_fees', 'custom_discount_based_on_cart_total', 10, 1 );
function custom_discount_based_on_cart_total( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    // 初始化变量
    $discounted_total = 0; 
    $discount = 0; 
    $discount_text = __('Discount ', 'woocommerce');

    foreach ( $cart->get_cart() as $cart_item ) {
        if ( ! has_excluded_product_categories( $cart_item['data'] ) ) {
            $discounted_total += $cart_item['line_subtotal']; // 添加项目行小计
        }
    }

    $user = wp_get_current_user();  
    $is_customer = in_array( 'vip', (array) $user->roles ); // 检查用户是否属于“vip”角色

    if ( $discounted_total >= 2000 && $discounted_total < 4000 ) {
        $discount = $discounted_total * ($is_customer ? 0.03 : 0.02); // 对于vip客户为3%,其他为2%
        $discount_text .=  $is_customer ? '3%' : '2%';
    } else if ( $discounted_total >= 4000 && $discounted_total < 6000 ) {
        $discount = $discounted_total * ($is_customer ? 0.05 : 0.04); // 对于vip客户为5%,其他为4%
        $discount_text .= $is_customer ? '5%' : '4%';
    } else if ( $discounted_total >= 6000 ) {
        $discount = $discounted_total * ($is_customer ? 0.07 : 0.06); // 对于vip客户为7%,其他为6%
        $discount_text .= $is_customer ? '7%' : '6%';
    }

    if ( $discount > 0 ) {
        $cart->add_fee( $discount_text, -$discount );
    }
}

// 显示相关的折扣消息
add_action( 'woocommerce_before_cart', 'show_discount_message' );
function show_discount_message() {
    $discounted_total = 0; 

    foreach ( WC()->cart->get_cart() as $cart_item ) {
        if ( ! has_excluded_product_categories( $cart_item['data'] ) ) {
            $discounted_total = $cart_item['line_subtotal']; // 添加项目行小计
        }
    }

    // 检查用户是否属于角色“vip”
    $user = wp_get_current_user();
    $is_customer = in_array( 'vip', (array) $user->roles );
    $level = 0;
    $return_to = esc_url( wc_get_page_permalink( 'shop' ) );

    if ( $discounted_total < 2000 ) {
        $difference = 2000 - $discounted_total;
        $level = 1;
        $percentage = $is_customer ? '3%' : '2%';
    } else if ( $discounted_total >= 2000 && $discounted_total < 4000 ) {
        $difference = 4000 - $discounted_total;
        $level = 2;
        $percentage = $is_customer ? '5%' : '4%';
    } else if ( $discounted_total >= 4000 && $discounted_total < 6000 ) {
        $difference = 6000 - $discounted_total;
        $level = 3;
        $percentage = $is_customer ? '7%' : '6%';
    }

    if ( $level != 0 ) {
        $added_text = sprintf( __('You have %s until you reach level %d (%s) on the discount!', 'woocommerce'), 
            wc_price( $difference ), $level, $percentage );

        wc_print_notice( sprintf(  '<a href="%s" class="button wc-forward">%s</a> %s',  $return_to,
            __('Keep shopping', 'woocommerce'), $added_text  ), 'notice' );
    }
}

将此代码放入您的活动子主题(或活动主题)的functions.php文件中,经过测试,可以正常工作。

注意:我没有测试“vip”用户角色。

英文:

In WooCommerce product categories and tags are not handled by product variations, but by the parent variable product. So for variations cart items, you need to get the parent product ID to be able to target specific product categories. There was also some other mistakes.

Here is your revisited code:

// Custom conditional function for excluded product categories
function has_excluded_product_categories( $product ) {
// Set HERE your Excluded product categories (slugs)
$excl_terms = array( &#39;redshirt1&#39;, &#39;redshirt2&#39;, &#39;redshirt3&#39;, &#39;redshirt4&#39;, &#39;hoodies&#39; );
// IMPORTANT!!!: Handling Product variations 
$product_id = $product-&gt;get_parent_id() ? $product-&gt;get_parent_id() : $product-&gt;get_id();
// Simplifying: Get directly an array of product categories &quot;slugs&quot;
$term_slugs = wp_get_post_terms( $product_id, &#39;product_cat&#39;, array( &#39;fields&#39; =&gt; &#39;slugs&#39; ) );
// Using array_intersect() on 2 arrays instead of a heavier foreach loop
return (bool) count( array_intersect($term_slugs, $excl_terms) ) &gt; 0;
}
// Adding a discount conditionally
add_action( &#39;woocommerce_cart_calculate_fees&#39;, &#39;custom_discount_based_on_cart_total&#39;, 10, 1 );
function custom_discount_based_on_cart_total( $cart ) {
if ( is_admin() &amp;&amp; ! defined( &#39;DOING_AJAX&#39; ) )
return;
// Initializing variables
$discounted_total = 0; 
$discount = 0; 
$discount_text = __(&#39;Discount &#39;, &#39;woocommerce&#39;);
foreach ( $cart-&gt;get_cart() as $cart_item ) {
if ( ! has_excluded_product_categories( $cart_item[&#39;data&#39;] ) ) {
$discounted_total += $cart_item[&#39;line_subtotal&#39;]; // add item line subtotal
}
}
$user = wp_get_current_user();  
$is_customer = in_array( &#39;vip&#39;, (array) $user-&gt;roles ); // check if the user is in the role &#39;vip&#39;
if ( $discounted_total &gt;= 2000 &amp;&amp; $discounted_total &lt; 4000 ) {
$discount = $discounted_total * ($is_customer ? 0.03 : 0.02); // 3% for vip, 2% for others
$discount_text .=  $is_customer ? &#39;3%&#39; : &#39;2%&#39;;
} else if ( $discounted_total &gt;= 4000 &amp;&amp; $discounted_total &lt; 6000 ) {
$discount = $discounted_total * ($is_customer ? 0.05 : 0.04); // 5% for vip, 4% for others
$discount_text .= $is_customer ? &#39;5%&#39; : &#39;4%&#39;;
} else if ( $discounted_total &gt;= 6000 ) {
$discount = $discounted_total * ($is_customer ? 0.07 : 0.06); // 7% for vip, 6% for others
$discount_text .= $is_customer ? &#39;7%&#39; : &#39;6%&#39;;
}
if ( $discount &gt; 0 ) {
$cart-&gt;add_fee( $discount_text, -$discount );
}
}
// Display related discount message
add_action( &#39;woocommerce_before_cart&#39;, &#39;show_discount_message&#39; );
function show_discount_message() {
$discounted_total = 0; 
foreach ( WC()-&gt;cart-&gt;get_cart() as $cart_item ) {
if ( ! has_excluded_product_categories( $cart_item[&#39;data&#39;] ) ) {
$discounted_total = $cart_item[&#39;line_subtotal&#39;]; // add item line subtotal
}
}
// check if the user is in role &#39;vip&#39;
$user = wp_get_current_user();
$is_customer = in_array( &#39;vip&#39;, (array) $user-&gt;roles );
$level = 0;
$return_to = esc_url( wc_get_page_permalink( &#39;shop&#39; ) );
if ( $discounted_total &lt; 2000 ) {
$difference = 2000 - $discounted_total;
$level = 1;
$percentage = $is_customer ? &#39;3%&#39; : &#39;2%&#39;;
} else if ( $discounted_total &gt;= 2000 &amp;&amp; $discounted_total &lt; 4000 ) {
$difference = 4000 - $discounted_total;
$level = 2;
$percentage = $is_customer ? &#39;5%&#39; : &#39;4%&#39;;
} else if ( $discounted_total &gt;= 4000 &amp;&amp; $discounted_total &lt; 6000 ) {
$difference = 6000 - $discounted_total;
$level = 3;
$percentage = $is_customer ? &#39;7%&#39; : &#39;6%&#39;;
}
if ( $level != 0 ) {
$added_text = sprintf( __(&#39;You have %s untill you reach level %d (%s) on the discount!&#39;, &#39;woocommerce&#39;), 
wc_price( $difference ), $level, $percentage );
wc_print_notice( sprintf(  &#39;&lt;a href=&quot;%s&quot; class=&quot;button wc-forward&quot;&gt;%s&lt;/a&gt; %s&#39;,  $return_to,
__(&#39;Keep shopping&#39;, &#39;woocommerce&#39;), $added_text  ), &#39;notice&#39; );
}
}

Code goes in functions.php file of your active child theme (or active theme). Tested and works.

> Note: I didn't tested the "vip" user role

huangapple
  • 本文由 发表于 2023年6月19日 03:24:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/76502206.html
匿名

发表评论

匿名网友

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

确定