'WooCommerce coupon usage restriction by allowed user roles

we need to make an automatic discount coupon to be applied if the current user role is ( vendor ), we achieved that by creating a normal coupon then used the snippet below to automatic apply the coupon .. but we need to limit the usage of that coupon to user role (vendor) only .. if another user role even administrators use it they get a message invalid coupon

    add_action( 'woocommerce_before_cart', 'apply_matched_coupons' );

function apply_matched_coupons() {
    global $woocommerce;

    $coupon_code = 'freeee'; // coupon code

    if ( $woocommerce->cart->has_discount( $coupon_code ) ) return;

if ( current_user_can('yith_vendor') ) {
        $woocommerce->cart->add_discount( $coupon_code );
        wc_print_notices();
    }

}

what we need to achieve now is to limit that coupon usage to user role ( vendors ) only and if another user role even administrator tried to use it they get a message invalid coupon.



Solution 1:[1]

The following code adds a new field to the usage restriction tab where you can add allowed user roles.

// Add new field - usage restriction tab
function action_woocommerce_coupon_options_usage_restriction( $coupon_get_id, $coupon ) {
    woocommerce_wp_text_input( array( 
        'id' => 'customer_user_role',  
        'label' => __( 'User role restrictions', 'woocommerce' ),  
        'placeholder' => __( 'No restrictions', 'woocommerce' ),  
        'description' => __( 'List of allowed user roles. Separate user roles with commas.', 'woocommerce' ),  
        'desc_tip' => true,  
        'type' => 'text',  
    )); 
}
add_action( 'woocommerce_coupon_options_usage_restriction', 'action_woocommerce_coupon_options_usage_restriction', 10, 2 );

// Save
function action_woocommerce_coupon_options_save( $post_id, $coupon ) {
    // Isset
    if ( isset ( $_POST['customer_user_role'] ) ) {
        $coupon->update_meta_data( 'customer_user_role', sanitize_text_field( $_POST['customer_user_role'] ) );
        $coupon->save();
    }
}
add_action( 'woocommerce_coupon_options_save', 'action_woocommerce_coupon_options_save', 10, 2 );

// Valid
function filter_woocommerce_coupon_is_valid( $valid, $coupon, $discount ) {
    // Get meta
    $customer_user_role = $coupon->get_meta('customer_user_role');

    // NOT empty
    if( ! empty( $customer_user_role ) ) {
        // Convert string to array
        $customer_user_role = explode( ', ', $customer_user_role );

        // Get current user role
        $user = wp_get_current_user();
        $roles = ( array ) $user->roles;

        // Compare
        $compare = array_diff( $roles, $customer_user_role );

        // NOT empty
        if ( ! empty ( $compare ) ) {           
            $valid = false;
            
            if ( ! $valid ) {
                throw new Exception( __( 'My custom error message', 'woocommerce' ), 109 );
            }
        }
    }

    return $valid;
}
add_filter( 'woocommerce_coupon_is_valid', 'filter_woocommerce_coupon_is_valid', 10, 3 );

enter image description here


EDIT:

To automatically apply the coupon on the CART page and hide the delete coupon link (based on user role)

function action_woocommerce_before_calculate_totals( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;
    
   if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;
    
    // Only cart
    if( ! is_cart() )
        return;
    
    /* SETTINGS */
    
    // Coupon code
    $coupon_code = 'test';
    
    // Allowed user role
    $allowed_user_role = 'administrator';
    
    /* END SETTINGS */
    
    // check current user role
    $user = wp_get_current_user();
    $user_roles = ( array ) $user->roles;
    
    // ADD js
    $add_js = false;

    // In array user roles
    if ( in_array( $allowed_user_role, $user_roles ) ) {        
        // Format
        $coupon_code = wc_format_coupon_code( $coupon_code );

        // Applied coupons
        $applied_coupons = $cart->get_applied_coupons();

        // Is applied
        $is_applied = in_array( $coupon_code, $applied_coupons );

        // NOT applied
        if ( ! $is_applied ) {
            // Apply
            $cart->apply_coupon( $coupon_code );
            
            // True
            $add_js = true;
        } elseif ( $is_applied ) {
            // True
            $add_js = true;
        }
        
        // True
        if ( $add_js ) {
            ?>
            <script type="text/javascript">
            jQuery( function($) {               
                // Hide remove link
                $( '.woocommerce-remove-coupon' ).hide();
            });
            </script>
            <?php
        }
    }
}
add_action( 'woocommerce_before_calculate_totals', 'action_woocommerce_before_calculate_totals', 10, 1 );

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1