我在 WooCommerce 中使用以下代码根据用户角色添加折扣:
//DISCOUNT
add_filter('woocommerce_add_cart_item_data', 'add_items_default_price_as_custom_data', 20, 3 );
function add_items_default_price_as_custom_data( $cart_item_data, $product_id, $variation_id ){
if ( !is_user_logged_in() ) { return;}
$product_id = $variation_id > 0 ? $variation_id : $product_id;
//get discount from role
$user = wp_get_current_user();
$user_role = $user->roles[0];
$page = jet_engine()->options_pages->registered_pages['shop-opt'];
// give a discount depending on the role
switch ($user_role) {
case 'customer':
$discount_percentage = 0;
break;
case 'discount1':
$discount_percentage = $page->get( 'diskont-riven-1' );
break;
case 'discount2':
$discount_percentage = $page->get( 'diskont-riven-2' );
break;
case 'discount3':
$discount_percentage = $page->get( 'diskont-riven-3' );
break;
}
// The WC_Product Object
$product = wc_get_product($product_id);
$price = (float) $product->get_price();
// Set the Product default base price as custom cart item data
$cart_item_data['base_price'] = $price;
// Only for non on sale products
if( ! $product->is_on_sale() ){
// Set the Product discounted price as custom cart item data
$cart_item_data['new_price'] = $price * (100 - $discount_percentage) / 100;
// Set the percentage as custom cart item data
$cart_item_data['percentage'] = $discount_percentage;
}
if( $product->is_on_sale() ){
// Set the Product discounted price as custom cart item data
$cart_item_data['new_price'] = $price;
}
return $cart_item_data;
}
// Display the product name with the discount percentage
add_filter( 'woocommerce_cart_item_name', 'append_percetage_to_item_name', 20, 3 );
function append_percetage_to_item_name( $product_name, $cart_item, $cart_item_key ){
if ( !is_user_logged_in() ) { return;}
if( isset($cart_item['percentage']) && isset($cart_item['base_price']) ) {
if( $cart_item['data']->get_price() != $cart_item['base_price'] )
$product_name .= ' <em>(' . $cart_item['percentage'] . '% discount)</em>';
}
return $product_name;
}
add_action( 'woocommerce_before_calculate_totals', 'custom_discounted_cart_item_price', 20, 1 );
function custom_discounted_cart_item_price( $cart ) {
if ( !is_user_logged_in() ) { return;}
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
## ----- YOUR SETTING ----- ##
$targeted_qty = 2; // Targeted quantity
// Loop through cart items
foreach ( $cart->get_cart() as $cart_item ) {
// Set cart item discounted price
$cart_item['data']->set_price($cart_item['new_price']);
}
}
// CHECK/ADD ROLE after buuing
add_action( 'woocommerce_order_status_completed', 'order_completed', 1);
function order_completed($order_id) {
$order = wc_get_order( $order_id );
$user_id = $order->get_customer_id();
if ( $user_id == ''){return ;}
$user = new WP_User( $user_id);
$user_role = $user->roles[0];
switch ($user_role) {
case 'customer':
$user->set_role( 'discount1' );
break;
case 'discount1':
$user->set_role( 'discount2' );
break;
case 'discount2':
$user->set_role( 'discount3' );
break;
}
}
一切都很好,但有时,我得到空订单....我设置记录器:
看来当客人将一些产品添加到购物车,去结账时发现他可以在第一次订购后获得折扣,但需要登录时,就会发生问题。
客人在商店登记,走到购物车前,购物车就空了。我收到一个空订单,没有电子邮件、姓名和产品。
首先,您应该在结帐页面启用注册,以避免此类问题。此问题可能属于您添加的其他一些自定义代码或某些干扰的第 3 方插件。
现在,您当前的代码存在一些错误和复杂性。
尝试以下修改和优化的代码替换(已注释):
// Add discounted price as custom cart item data conditionally
add_filter( 'woocommerce_add_cart_item_data', 'add_discounted_price_as_custom_cart_item_data', 20, 3 );
function add_discounted_price_as_custom_cart_item_data( $cart_item_data, $product_id, $variation_id ) {
global $current_user;
if ( !$current_user ) {
return; // Exit if not logged
}
$product = wc_get_product($variation_id > 0 ? $variation_id : $product_id); // The WC_Product Object
if ( ! $product->is_on_sale() ) {
return; // Exit if product is on sale
}
$page = jet_engine()->options_pages->registered_pages['shop-opt'];
// Define each option for a user role in an array
$discount_for_role = array(
'discount1' => $page->get('diskont-riven-1'),
'discount2' => $page->get('diskont-riven-2'),
'discount3' => $page->get('diskont-riven-3'),
);
$discount_percentage = 0; // Initialize
// Loop through options for user roles array
foreach ( $discount_for_role as $user_role => $option_percentage ) {
// Check user role
if ( wc_current_user_has_role($user_role) ) {
$discount_percentage = (float) $option_percentage; // Define discount percentage
break;
}
}
$price = (float) $product->get_price(); // Get product active price
if ( $discount_percentage > 0 && $price > 0 ) {
$cart_item_data['base_price'] = $price;
$cart_item_data['percentage'] = $discount_percentage;
$cart_item_data['new_price'] = $price * (100 - $discount_percentage) / 100; // New Price
}
return $cart_item_data;
}
// Display the discount percentage conditionally
add_filter( 'woocommerce_cart_item_name', 'append_discount_percentage_to_cart_item_name', 20, 3 );
function append_discount_percentage_to_cart_item_name($product_name, $cart_item, $cart_item_key) {
if (!is_user_logged_in()) {
return;
}
if ( isset($cart_item['percentage']) ) {
$product_name .= ' <em>(' . $cart_item['percentage'] . '% discount)</em>';
}
return $product_name;
}
// Discount cart item price conditionally
add_action( 'woocommerce_before_calculate_totals', 'custom_discounted_cart_item_price', 20 );
function custom_discounted_cart_item_price( $cart ) {
if ( !is_user_logged_in() ) {
return;
}
if ( is_admin() && ! defined('DOING_AJAX') ) {
return;
}
if (did_action('woocommerce_before_calculate_totals') >= 2) {
return;
}
// Loop through cart items
foreach ($cart->get_cart() as $item) {
// Check for discounted price
if ( isset($item['new_price']) ) {
$item['data']->set_price($item['new_price']); // Set discounted price
}
}
}
// Check and change user role after a purchase
add_action( 'woocommerce_order_status_completed', 'alter_user_role_on_order_completed', 10, 2 );
function alter_user_role_on_order_completed( $order_id, $order ) {
if ( !$order->get_user_id() ) {
return;
}
// Array of user roles transitions
$role_transition = array(
'customer' => 'discount1',
'discount1' => 'discount2',
'discount2' => 'discount3',
);
$user = $order->get_user(); // Get The WP_User object
// Loop through role transition array
foreach ( $role_transition as $role_from => $role_to ) {
// Check user role
if ( wc_user_has_role( $order->get_user(), $role_from ) ) {
$user->set_role( $role_to ); // set new user role
break; // Stop the loop
}
}
}
应该可以。
您不应删除“客户”用户角色,因为 WooCommerce 需要有效的用户角色。相反,您应该添加折扣角色作为附加角色。
理想的解决方案是将允许的折扣添加作为自定义用户元数据,而不是更改用户角色。
这是修改后的代码版本,添加“折扣用户角色”而不是替换“客户”角色。
将最后一个函数替换为以下内容:
// Check and add/update user discount role after a purchase
add_action( 'woocommerce_order_status_completed', 'define_discount_user_role_on_order_completed', 10, 2 );
function define_discount_user_role_on_order_completed( $order_id, $order ) {
if ( !$order->get_user_id() ) {
return;
}
// Array of user roles transitions
$discount_roles = array( 'discount1', 'discount2', 'discount3' );
$user = $order->get_user(); // Get The WP_User object
// If user has already 'discount3' user role we exit
if ( wc_user_has_role( $order->get_user(), end($discount_roles) ) ) {
return; // Exit
}
// No discount role has been added
if ( ! array_intersect( $discount_roles, $user->roles) ) {
$user->add_role( reset($discount_roles) ); // add the first role
}
// A discount role exist already
else {
// Loop through discount roles
foreach ( $discount_roles as $key => $role ) {
// Check role
if ( wc_user_has_role( $order->get_user(), $role ) ) {
$user->remove_role( $role ); // Remove current discount role
$user->add_role( $discount_roles[$key+1] ); // Add the next discount role
break; // Stop the loop
}
}
}
}
应该可以。