I am working on a dynamic pricing system on my Wordpress store. I have set it up so users who have certain roles (right now, subscriber or admin - for testing purposes) get a 15% discount (price*0.85). However, I need to also exclude specific product categories from the discount rule.
Right now I have:
function add_cart_item_data( $cart_item_data, $product_id, $variation_id ) {
//if admin || subscriber
$role = get_user_role(); /* I know that isn't the default get user role. I made a shortened version of it in functions.php because I used it a lot in other functions */
if (in_array("admin", $role) || in_array("subscriber", $role)){
$product = wc_get_product( $product_id );
// ==> Start: Needed product category check HERE
$price = $product->get_price();
$cart_item_data['RefPrice'] = $price * 0.85;
// ==> End of product category check
}
return $cart_item_data;
}
add_filter( 'woocommerce_add_cart_item_data', 'add_cart_item_data', 10, 2 );
function before_calculate_totals( $cart_obj ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
return;
}
// Iterate through each cart item
foreach( $cart_obj->get_cart() as $key=>$value ) {
if( isset( $value['RefPrice'] ) ) {
$price = $value['RefPrice'];
$value['data']->set_price( ( $price ) );
}
}
}
add_action( 'woocommerce_before_calculate_totals', 'before_calculate_totals', 10, 1 );
This is working to modify the price by * 0.85
for certain roles, but I've hit a brick wall trying to exclude a product category from it. The product category ID is 978 (or its name is "last minute gifts").
How can I add in this check for each cart item?
Updated… Here is the way to exclude product categories from your custom dynamic pricing making small changes in your 1st hooked function.
It use has_term()
WordPress conditional function to exclude product categories, this way:
function get_user_roles(){
global $current_user;
return $current_user->roles;
}
add_filter( 'woocommerce_add_cart_item_data', 'add_cart_item_data', 10, 2 );
function add_cart_item_data( $cart_item_data, $product_id ) {
// For administrator or subscriber user roles
if ( count( array_intersect(array('administrator', 'subscriber'), get_user_roles() ) ) > 1 ) {
// Excluded product categories in this array (Can be IDs, slugs or names)
$excl_cats = array( 978 );
$product = wc_get_product( $product_id );
// Excluding product categories
if( ! has_term( $excl_cats, 'product_cat', $product_id ) ){
$cart_item_data['ref_price'] = $product->get_price() * 0.85;
// Every add to cart action is set as a unique line item
$cart_item_data['unique_key'] = md5( microtime().rand() );
}
}
return $cart_item_data;
}
add_action( 'woocommerce_before_calculate_totals', 'before_calculate_totals', 10, 1 );
function before_calculate_totals( $cart ) {
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 $cart_item ) {
if( isset( $cart_item['ref_price'] ) ) {
$cart_item['data']->set_price( floatval($cart_item['ref_price']) );
}
}
}
Code goes in function.php file of your active child theme (or active theme).
Tested and works