Search code examples
phpwordpresswoocommercewoocommerce-subscriptions

Apply discount on products within specific category (WooCommerce)


I have this code which works perfectly and applies a 10% discount to users in the 'subscriber' category. Now I want to modify the code so that the discount is only applied to products that are in specific categories.

For example, I have three categories of products: 'products', 'exclusive-products', and 'subscriptions'. The discount should apply only to products that are in the first two categories, and not apply to the products within the 'subscriptions' category.

Can somebody help me modify this function to meet those requirements?

// Applying conditionally a discount for a specific user role
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 'subscriber' user role
    if ( ! current_user_can('subscriber') )
        return; // Exit

    // HERE define the percentage discount
    $percentage = 10;

    $discount = $cart->get_subtotal() * $percentage / 100; // Calculation

    // Applying discount
    $cart->add_fee( sprintf( __("Discount (%s)", "woocommerce"), $percentage . '%'), -$discount, true );
}

Solution

  • First of all current_user_can('subscriber') is a wrong way to check current user role. current_user_can should be only use for checking the capabilities not the user role.

    Second, You didn't explain your categories matching condition very well. I am not sure if you want to check if all products should have matching categories or one of them should have, or 1 just category with 1 product match is fine. You need to work on that on your own.

    Below code is checking if one of cart product has any of the matching category then condition will be valid.

    Note: code is not tested, if you find any critical or syntax error then please let me know I will fix the code. and Please make sure you have website backup and FTP access to make changes on files if there is any error after adding the code and you can't access the wordpress backend.

    /**
     * Applying conditionally a discount for a specific user role.
     */
    function discount_based_on_user_role() {
        if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
            return;
        }
    
        // Only for logged in users.
        if ( ! is_user_logged_in() ) {
            return;
        }
    
        $user = get_userdata( get_current_user_id() );
        // User or user roles not found.
        if ( ! $user || ! $user->roles ) {
            return;
        }
    
        // Only for 'subscriber' user role.
        if ( ! in_array( 'subscriber', (array) $user->roles, true ) ) {
            return;
        }
    
        // Get products from cart.
        $products_in_cart = WC()->cart->get_cart_contents();
    
        // Get product ids array from cart products.
        $product_ids_in_cart = array_column( array_values( $products_in_cart ), 'product_id' );
    
        // Define a flag for valid categories check.
        $has_valid_categories = false;
    
        // Define valid categories array.
        $valid_categories = array( 'products', 'exclusive-products' );
    
        // Loop through product ids.
        foreach ( $product_ids_in_cart as $product_id ) {
            // Check if product has any of the valid category.
            if ( has_term( $valid_categories, 'product_cat', $product_id ) ) {
                $has_valid_categories = true;
                break;
            }
        }
    
        // Valid categories not found.
        if ( ! $has_valid_categories ) {
            return;
        }
    
        // here define the percentage discount.
        $percentage = 10;
    
        $discount = WC()->cart->get_subtotal() * $percentage / 100; // Calculation.
    
        // Applying discount.
        WC()->cart->add_fee(
            sprintf(
                /* translators: %s Discount Value */
                __( 'Discount (%s)', 'woocommerce' ),
                $percentage . '%'
            ),
            -$discount,
            true
        );
    }
    add_action( 'woocommerce_cart_calculate_fees', 'discount_based_on_user_role', 20 );