Search code examples
phpwordpresswoocommerceuser-rolesdiscount

Show possible discount to unlogged users for WooCommerce discount based on user roles


I used the Apply a discount for a specific user role in Woocommerce solution to create two snippets that will give my customers and wholesalers a discount this Black Friday.

However, the discount for customers only shows when they login. Is there a way to display the customer discount before the customer logs in?

// Apply Discount for Customer

add_action( 'woocommerce_cart_calculate_fees', 'discount_based_on_customer', 20, 1 );
function discount_based_on_customer( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( ! current_user_can('customer') )
        return;

    $percentage = 50;

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

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

// Apply Discount for Wholesaler

add_action( 'woocommerce_cart_calculate_fees', 'discount_based_on_wholesaler', 10, 1 );
function discount_based_on_wholesaler( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( ! ( current_user_can('default_wholesaler') || current_user_can('wholesaler-non-vat-registered') ) )
        return;

    $percentage = 10;

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

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


Solution

  • First, instead of using multiple snippets on the same hook you can merge them in a unique hooked function to handle all required user roles.

    Then for unlogged users, you can print a notice on cart and checkout page that will display the discount amount and percentage that user can get if they are logged in (displaying also a login link on the right side of the notice)

    enter image description here

    The complete revisited code:

    // User roles discount percentage
    add_action( 'woocommerce_cart_calculate_fees', 'discount_percentage_based_on_user_roles' );
    function discount_percentage_based_on_user_roles( $cart ) {
        if ( is_admin() && ! defined( 'DOING_AJAX' ) )
            return;
    
        // Logged in users only
        if ( is_user_logged_in() ) {
            $text_domain = 'woocommerce'; // Text domain for translations
            $percentage  = 0;  // Initializing
            $user_obj    = wp_get_current_user(); // Get the WP_User Object
    
            // 1. Customer user role
            if ( in_array('customer', $user_obj->roles ) ) {
                $percentage = 50;
                $label_text = sprintf( __("Black Friday Discount (%s)", $text_domain), $percentage.'%');
            }
    
            // 2. Wholesalers users roles
            elseif ( array_intersect( array('default_wholesaler', 'wholesaler-non-vat-registered'), $user_obj->roles ) ) {
                $percentage = 10;
                $label_text = sprintf( __("Black Friday Reseller Discount (%s)", $text_domain), $percentage.'%');
            }
    
            // THE DISCOUNT
            if ( $percentage > 0 ) {
                $discount = $cart->get_subtotal() * $percentage / 100; // Calculation
    
                $cart->add_fee( $label_text, -$discount, true ); // Apply calculated discount
            }
        }
    }
    
    // For unlogged Users: display a notice with the discount percentage and the loging link (cart and checkout pages)
    add_action( 'woocommerce_before_checkout_form', 'discount_percentage_notice_for_unlogged_users' );
    add_action( 'woocommerce_before_cart_table', 'discount_percentage_notice_for_unlogged_users' );
    function discount_percentage_notice_for_unlogged_users() {
        if ( ! is_user_logged_in() ) {
            $text_domain = 'woocommerce'; // Text domain for translations
            $percentage  = 50;
            $login_link  = get_permalink( wc_get_page_id( 'myaccount' ) );
            $login_text  = __("Login / Register", $text_domain);
    
            wc_print_notice( sprintf(
                __('You could get %s off on Black Friday Discount (%s).%s', $text_domain),
                '<strong>' . wc_price(WC()->cart->subtotal * $percentage / 100) . '</strong>',
                $percentage . '%',
                '<a href="' . $login_link . '" class="button" style="float:right;">' . $login_text . '</a>'
            ), 'notice' );
        }
    }
    

    Code goes in functions.php file of the active child theme (or active theme). Tested and works.


    Or if you want to apply the discount for "customer" user role to guest users (unlogged), you will use instead this:

    // User roles and guests discount percentage
    add_action( 'woocommerce_cart_calculate_fees', 'discount_percentage_based_on_user_roles' );
    function discount_percentage_based_on_user_roles( $cart ) {
        if ( is_admin() && ! defined( 'DOING_AJAX' ) )
            return;
            
        $text_domain = 'woocommerce'; // Text domain for translations
        $percentage  = 0;  // Initializing
        $user_obj    = wp_get_current_user(); // Get the WP_User Object
    
        // 1. Wholesalers user roles
        if ( array_intersect( array('default_wholesaler', 'wholesaler-non-vat-registered'), $user_obj->roles ) ) {
            $percentage = 10;
            $label_text = sprintf( __("Black Friday Reseller Discount (%s)", $text_domain), $percentage.'%');
        }
        // 2. Customer user role and guest users
        elseif ( in_array('customer', $user_obj->roles ) || ! is_user_logged_in() ) {
            $percentage = 50;
            $label_text = sprintf( __("Black Friday Discount (%s)", $text_domain), $percentage.'%');
        }
    
        // THE DISCOUNT
        if ( $percentage > 0 ) {
            $discount = $cart->get_subtotal() * $percentage / 100; // Calculation
    
            $cart->add_fee( $label_text, -$discount, true ); // Apply calculated discount
        }
    }
    

    Code goes in functions.php file of the active child theme (or active theme). Tested and works.