英文:
WooCommerce shipping methods based on user roles and subtotal amount
问题
我需要根据购买者的角色添加两种不同的运费,取决于用户的角色。我有一个角色是 'wholesale_customer',不应支付运费。但是,如果购物车的小计等于或小于90欧元,则必须阻止购买并在结账时添加一条消息(请记住必须达到90欧元的金额)。
另一种选择是所有其他WordPress角色,如果他们的购物车小计为40欧元或更少,则必须支付5欧元的运费。
我已经在WooCommerce中配置了运费,创建了两种免费运费方式,一个是40欧元,另一个是90欧元的最低订单金额。
问题是,当拥有 'wholesale_customer' 角色的用户达到40欧元时,也会启用该免费运费方式,这不应该发生,因为对于这个用户角色('wholesale_customer')来说,如果购买超过90欧元的最低金额,则运费是免费的。
我已经按以下方式在WooCommerce中配置了运费,创建了2种运费方式:
- 一个具有 90欧元的 "所需最低数量"
- 另一个具有40欧元的 "所需最低数量"
- 一个运费为0欧元。
我尝试添加以下函数以获取所需的内容,但所有运费方式始终处于启用状态,因此 "最低40欧元免运费" 的零售运费方式也会激活给具有 'wholesale_customer' 角色的用户。这不应该发生,因为这些用户角色将受益于不属于他们的福利。
我展示了一些我用来尝试做我想要的事情的代码,因为我进行了很多测试。唯一的问题是我没有找到添加到 'wholesale_customer' 角色的演示中提到的文本的方法。
function custom_shipping_methods_visibility( $available_methods ) {
$subtotal = WC()->cart->subtotal;
$user = wp_get_current_user();
$user_roles = $user->roles;
// 检查用户角色和购物车小计以显示/隐藏运费方式
if ( in_array( 'wholesale_customer', $user_roles ) && $subtotal <= 70 ) {
unset( $available_methods['flat_rate:13'] );
} elseif ( $subtotal <= 30 ) {
unset( $available_methods['flat_rate:9'] );
}
return $available_methods;
}
add_filter( 'woocommerce_package_rates', 'custom_shipping_methods_visibility', 10, 1 );
// 添加一个自定义函数来根据购物车角色和小计筛选运费方式
function custom_shipping_methods( $available_methods ) {
// 获取购物车小计
$subtotal = WC()->cart->subtotal;
// 获取当前用户的角色
$user = wp_get_current_user();
$user_roles = $user->roles;
// 检查用户角色和购物车小计以调整运费方式
if ( in_array( 'wholesale_customer', $user_roles ) && $subtotal < 70 ) {
foreach ( $available_methods as $method_id => $method ) {
// 如果用户是批发商且小计小于70欧元,则隐藏运费方式
unset( $available_methods[ $method_id ] );
}
// 显示警告消息
wc_add_notice( '你必须达到70欧元的购物车最低金额才能下订单。', 'error' );
}
return $available_methods;
}
add_filter( 'woocommerce_package_rates', 'custom_shipping_methods', 10, 1 );
配置图:
英文:
I need to add two different shipping rates, depending on the role of the user making the purchase. I have a role that is 'wholesale_customer' and should not pay shipping costs. However, the purchase must be prevented and a message added at Checkout if the subtotal of the cart is equal to or less than €90. (remember that you must reach the amount of €90)
The other option is all other WordPress roles, who are required to pay €5 shipping if their cart subtotal is €40 or less.
I have configured shipping in WooCommerce, I have created two free shipping methods with a minimum order amount, one of €40 and another of €90.
The problem is that the user with the 'wholesale_customer' role, when he reaches the amount of €40, is also enabled for that free shipping method, which should not happen, since for this user role ('wholesale_customer ' ) shipping is free, if the purchase exceeds the minimum of €90.
I have configured the shipments in WooCommerce in the following way, creating 2 Shipping Methods:
- one has "Minimum Quantity Required" at €90
-
another has "Minimum Quantity Required" at €40
-
and one of shipping costs at €0.
I have tried to add the following function to add to get what I need, but all the shipping methods are always enabled, so the retail shipping method of "Minimum €40 for free shipping", is also activated for the user with the role wholesale_customer' This should not happen, as users with this role would benefit from benefits that are not theirs.
I'm showing some of the code I've used to try to do what I'm looking for, since I did a lot of testing. Only I have not had the way to add the text that I mention in the presentation for the role 'wholesale_customer'
Show images of WooCommerce setup
function custom_shipping_methods_visibility( $available_methods ) {
$subtotal = WC()->cart->subtotal;
$user = wp_get_current_user();
$user_roles = $user->roles;
// Check user role and cart subtotal to show/hide shipping methods
if ( in_array( 'wholesale_customer', $user_roles ) && $subtotal <= 70 ) {
unset( $available_methods['flat_rate:13'] );
} elseif ( $subtotal <= 30 ) {
unset( $available_methods['flat_rate:9'] );
}
return $available_methods;
}
add_filter( 'woocommerce_package_rates', 'custom_shipping_methods_visibility', 10, 1 );
////////////////////
// Adds a custom function to filter shipping methods based on cart role and subtotal
function custom_shipping_methods( $available_methods ) {
// Get cart subtotal
$subtotal = WC()->cart->subtotal;
// Gets the role of the current user
$user = wp_get_current_user();
$user_roles = $user->roles;
//Check user role and cart subtotal to adjust shipping methods
if ( in_array( 'wholesale_customer', $user_roles ) && $subtotal < 70 ) {
foreach ( $available_methods as $method_id => $method ) {
// Hide the shipping methods if the user is a wholesaler and the subtotal is less than €70
unset( $available_methods[ $method_id ] );
}
// Show a warning message
wc_add_notice( 'Debes alcanzar un mínimo de 70€ en tu carrito para realizar el pedido.', 'error' );
}
return $available_methods;
}
add_filter( 'woocommerce_package_rates', 'custom_shipping_methods', 10, 1 );
config-1
Config-2 :
Config-3 :
答案1
得分: 4
// 条件函数:用户是否为批发客户
function is_a_wholesale_customer() {
if ( ! is_user_logged_in() ) return false;
return (bool) in_array( 'wholesale_customer', wp_get_current_user()->roles );
}
// 条件函数:用户是否为(普通)顾客
function is_a_normal_customer() {
if ( ! is_user_logged_in() ) return false;
return (bool) in_array( 'customer', wp_get_current_user()->roles );
}
// 条件函数:是否允许“批发客户”下订单
function is_wholesale_customer_allowed_to_order() {
// 检查“批发客户”用户角色和所需小计
return is_a_wholesale_customer() && WC()->cart->subtotal < 90 ? false : true;
}
// 提示文本(针对“批发客户”)
function wholesale_customer_text_error_notice(){
return __('请记住,您必须达到90欧元的金额', 'woocommerce');
}
// 基于所需小计的提示提醒(针对“批发客户”)
add_action( 'woocommerce_before_cart', 'check_cart_subtotal_wholesale_customer' ); // 购物车
add_action( 'woocommerce_before_checkout_form', 'check_cart_subtotal_wholesale_customer' ); // 结账
function check_cart_subtotal_wholesale_customer() {
if ( ! is_wholesale_customer_allowed_to_order() ) {
wc_print_notice( wholesale_customer_text_error_notice() );
}
}
// 基于所需小计的结账验证(针对“批发客户”)
add_action( 'woocommerce_checkout_process', 'wholesale_customer_checkout_validation' );
function wholesale_customer_checkout_validation() {
if ( ! is_wholesale_customer_allowed_to_order() ) {
wc_add_notice( wholesale_customer_text_error_notice(), 'error' ); // 显示错误提示
}
}
// 显示/隐藏送货方式的代码
add_filter( 'woocommerce_package_rates', 'filter_shipping_package_rates', 10, 2 );
function filter_shipping_package_rates( $rates, $package ) {
// 设置
$free_rate_ids = array(
'wholesale_customer' => 'free_shipping:2', // 在此设置批发用户的免费送货费率ID
'customer_or_unlogged' => 'free_shipping:3', // 在此设置普通顾客或未登录用户的免费送货费率ID
);
$error_data['all_rates'] = array_keys($rates);
// “批发”用户角色
if ( is_a_wholesale_customer() ) {
$key = 'wholesale_customer';
// 仅在免费送货可用时显示“批发”免费送货
if( isset($rates[$free_rate_ids[$key]]) ) {
return array( $free_rate_ids[$key] => $rates[$free_rate_ids[$key]] );
}
// 隐藏所有送货方式(没有免费送货可用)
else {
return array();
}
}
// “顾客”用户角色或未登录用户
else {
$key = 'customer_or_unlogged';
// 仅在免费送货可用时显示“普通”免费送货
if( isset($rates[$free_rate_ids[$key]]) ) {
return array( $free_rate_ids[$key] => $rates[$free_rate_ids[$key]] );
}
}
return $rates;
}
这段代码用于在购物网站上根据用户角色和购物车的小计金额来显示/隐藏送货方式。根据用户角色,当购物车小计金额达到一定数额时,会显示特定的免费送货方式,并隐藏其他送货方式。
英文:
Updated
First, to prevent "wholesale_customer" user placing an order if cart subtotal is less than €90, the following code will:
- display a related reminder notice on cart and checkout pages,
- display an error notice on checkout validation process, avoiding any purchase.
// Conditional function: Is user a Wholesale Customer
function is_a_wholesale_customer() {
if ( ! is_user_logged_in() ) return false;
return (bool) in_array( 'wholesale_customer', wp_get_current_user()->roles );
}
// Conditional function: Is user a (normal) Customer
function is_a_normal_customer() {
if ( ! is_user_logged_in() ) return false;
return (bool) in_array( 'customer', wp_get_current_user()->roles );
}
// Conditional function: Is "wholesale_customer" allowed to order
function is_wholesale_customer_allowed_to_order() {
// Check "wholesale_customer" user role and required subtotal
return is_a_wholesale_customer() && WC()->cart->subtotal < 90 ? false : true;
}
// The notice text (for "wholesale_customer")
function wholesale_customer_text_error_notice(){
return __('Please remember that you must reach an amount of €90', 'woocommerce');
}
// Notice reminder based on required subtotal (for "wholesale_customer")
add_action( 'woocommerce_before_cart', 'check_cart_subtotal_wholesale_customer' ); // cart
add_action( 'woocommerce_before_checkout_form', 'check_cart_subtotal_wholesale_customer' ); // checkout
function check_cart_subtotal_wholesale_customer() {
if ( ! is_wholesale_customer_allowed_to_order() ) {
wc_print_notice( wholesale_customer_text_error_notice() );
}
}
// Checkout validation based on required subtotal (for "wholesale_customer")
add_action( 'woocommerce_checkout_process', 'wholesale_customer_checkout_validation' );
function wholesale_customer_checkout_validation() {
if ( ! is_wholesale_customer_allowed_to_order() ) {
wc_add_notice( wholesale_customer_text_error_notice(), 'error' ); // Displays an error notice
}
}
> For the shipping methods, your settings are correct.
The following code will show / hide shipping methods based on your user roles ("wholesale_customer" and "customer" (adding unlogged users too) and a minimum cart subtotal amount for free shipping.
> Update: The code works now with unlogged user (just as "customer" user role)
For the "wholesale_customer" all shipping methods will be disabled, until cart subtotal reaches €90.
When free shipping will be available, all other shipping methods will be hidden.
For each of your 2 free shipping methods, you will need to get the correct shipping rate ID. <br>
With a cart subtotal higher than €90, on your checkout page shipping section, inspect the displayed radio buttons for each free shipping displayed option (see the screenshot below):
Now you can set in the code below both of your 2 free shipping methods rate IDs:
// showing / Hidding shipping methods
add_filter( 'woocommerce_package_rates', 'filter_shipping_package_rates', 10, 2 );
function filter_shipping_package_rates( $rates, $package ) {
// Settings
$free_rate_ids = array(
'wholesale_customer' => 'free_shipping:2', // Here set the free shipping rate ID for wholesale user
'customer_or_unlogged' => 'free_shipping:3', // Here set the free shipping rate ID for customer or unlogged user
);
$error_data['all_rates'] = array_keys($rates);
// "Wholesale" user role
if ( is_a_wholesale_customer() ) {
$key = 'wholesale_customer';
// show only "Wholesale" free shipping when available
if( isset($rates[$free_rate_ids[$key]]) ) {
return array( $free_rate_ids[$key] => $rates[$free_rate_ids[$key]] );
}
// Hide all shipping methods (no free shipping available)
else {
return array();
}
}
// "Customer" user role or unlogged users
else {
$key = 'customer_or_unlogged';
// show only "Normal" free shipping when available
if( isset($rates[$free_rate_ids[$key]]) ) {
return array( $free_rate_ids[$key] => $rates[$free_rate_ids[$key]] );
}
}
return $rates;
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
> Once the code is saved, to refresh shipping methods cached data, don't forget to empty your cart (or disable, save and enable, save related shipping methods for the current shipping zone, in Woocommerce shipping settings).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论