Search code examples
phpwordpresswoocommerceproduct

Use a product custom field as discount percentage for specific user role in WooCommerce


I want to display and apply a percentual discount on products, based on user role 'clubmember' and a percentage filled in a meta box 'clubmember_price'.

I used the code below for the percentual discount (on the cart, not the products) which works fine.

/* discount clubmembers */
add_action( 'woocommerce_cart_calculate_fees', 'discount_based_on_user_role', 20, 1 );
function discount_based_on_user_role( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return; // Exit
    
    // only for 'clubmember' role
    if ( ! current_user_can('clubmember') )
        return; // Exit

    // Kortings percentage
    $percentage = 10
    
    $discount = $cart->get_subtotal() * $percentage / 100; // Calculation
    
    // Applying discount
    $cart->add_fee( sprintf( __("Clubmember discount (%s)", "woocommerce"), $percentage . '%'), -$discount, true );
}

It shows the message 'clubmember discount' on the checkout, which looks good. My problem now is, that the code above applies discount on the total cart.

I want the discount on the product itself, but ONLY if a meta box 'clubmember_price' is filled. For that, I replaced the code with this code:

/* Custom prices by user role */
add_filter('woocommerce_product_get_price', 'custom_price_assign', 10, 2);
add_filter('woocommerce_product_variation_get_price', 'custom_price_assign', 10, 2); // For product variations (optional)

function custom_price_assign( $price, $product ) {
    // Check if the user has a role of wholesaler
    if ( current_user_can('clubmember') && $clubmember_price = $product->get_meta('clubmember_price') ){
        return $price * (100 - $clubmember_price) / 100;
    }
    return $price;
}

Now, the problem is, that I can't see the discount anywhere. So the user's won't see they have a 'reduced' price, the snippet just changes the price.

I want to display the normal price, and show the discounted on the product page, and on the cart / checkout.

I tried to combine the two code's in any way, but since I'm new to PHP I cannot get it working. I have the feeling I need to use an 'if' between 2 functions, but I can't figure out how or if this is possible.

I am really trying to understand how this works and be able to write these snippets myself in the future. If anybody can explain where I'm missing out, that would be great!


Solution

  • To make a visible discount at product level based for a specific user role, you will need to add the following to make prices on sale:

    add_filter('woocommerce_product_get_sale_price', 'custom_sale_price_assign', 10, 2);
    add_filter('woocommerce_product_variation_get_sale_price', 'custom_sale_price_assign', 10, 2); 
    function custom_sale_price_assign( $price, $product ) {
        // only for 'clubmember' role and with a 'clubmember_price' custom field
        if ( current_user_can('clubmember') && $product->get_meta('clubmember_price') ){
            $price = $product->get_price();
        }
        return $price;
    }
    

    Now all related "Clubmember" discounted product prices will be on sale, displaying the old price amount (crossed out), with the new discounted price.

    Then, following those threads (and others), you will be able to customize things just as you would like, displaying also for example the discounted percentage or the saving amount, with some custom text, for every "Clubmember" discounted product prices.