Home > Net >  Add a fee for specific user roles when "Ship to a different address?" has been checked on
Add a fee for specific user roles when "Ship to a different address?" has been checked on

Time:12-03

I have a wholesale site with different user roles & want to allow employees to start ordering online from here also.

I want to only add a $5 fee if the user roles 'team' and 'team2' select ship to a different address (they get free shipping if sent to their billing address).

No other user role should see the fee if selecting the ship to a different address.

This is the closest solution I've found to make this happen but need help configuring this code to apply to only those two user roles and no one else.

// send as gift for Team & Team2 role add $5 fee
add_filter( 'woocommerce_form_field' , 'remove_order_comments_optional_fields_label', 10, 4 );
function remove_order_comments_optional_fields_label( $field, $key, $args, $value ) {
    // Only on checkout page for Order notes field
    if( 'ship_to_different_address' === $key && is_checkout() ) {
        $optional = '&nbsp;<span >(' . esc_html__( 'optional', 'woocommerce' ) . ')</span>';
        $field = str_replace( $optional, '', $field );
    }
    return $field;
}

// Ajax / jQuery script
add_action( 'wp_footer', 'ship_to_different_address_script' );
function ship_to_different_address_script() {
    // On checkoutpage
    if( ( is_checkout() && ! is_wc_endpoint_url() ) ) :
        ?>
        <script type="text/javascript">
            jQuery( function($){
                if (typeof woocommerce_params === 'undefined')
                    return false;

                console.log('defined');

                $('input[name=ship_to_different_address]').click( function(){
                    var fee = $(this).prop('checked') === true ? '1' : '';

                    $.ajax({
                        type: 'POST',
                        url: woocommerce_params.ajax_url,
                        data: {
                            'action': 'ship_to_different_address',
                            'ship_to_different_address': fee,
                        },
                        success: function (result) {
                            $('body').trigger('update_checkout');
                            console.log(result);
                        },
                    });
                });
            });
        </script>
    <?php
    endif;
}

// Get the ajax request and set value to WC session
add_action( 'wp_ajax_ship_to_different_address', 'get_ajax_ship_to_different_address' );
add_action( 'wp_ajax_nopriv_ship_to_different_address', 'get_ajax_ship_to_different_address' );
function get_ajax_ship_to_different_address() {
    if ( isset($_POST['ship_to_different_address']) ) {
        WC()->session->set('ship_to_different_address', ($_POST['ship_to_different_address'] ? '1' : '0') );
        echo WC()->session->get('ship_to_different_address');
    }
    die();
}

// Add / Remove a custom fee
add_action( 'woocommerce_cart_calculate_fees', 'add_remove_ship_to_different_address', 10, 1 );
function add_remove_ship_to_different_address( $cart )
{
    // Only on checkout
    if ((is_admin() && !defined('DOING_AJAX')) || is_cart())
        return;

    $fee_amount = 5.00;

    if (WC()->session->get('ship_to_different_address'))
        $cart->add_fee(__('Shipping fee', 'woocommerce'), $fee_amount);
}

CodePudding user response:

Your code contains some mistakes, missing pieces, and unnecessary steps.

This answer shows (without any user restrictions) how to add a fee when "Ship to a different address?" has been checked:

// The jQuery Ajax request
function action_wp_footer() {
    // Only checkout page
    if ( is_checkout() && ! is_wc_endpoint_url() ) :

    // Remove "ship_different" custom WC session on load
    if ( WC()->session->get( 'ship_different' ) ) {
        WC()->session->__unset( 'ship_different' );
    }
    
    // jQuery Ajax code below
    ?>
    <script type="text/javascript">
    jQuery( function($) {
        if ( typeof wc_checkout_params === 'undefined' )
            return false;

        var a = '#ship-to-different-address-checkbox', b = '';

        // Ajax function
        function triggerSTDA( value ) {
             $.ajax({
                type: 'POST',
                url: wc_checkout_params.ajax_url,
                data: {
                    'action': 'ship_different_address',
                    'ship_different': value,
                },
                success: function (result) {
                    $( 'body' ).trigger( 'update_checkout' );
                    // console.log( result ); // For testing (to be removed)
                }
            });
        }

        $( a ).on( 'change', function() {
            b = $( this ).prop('checked') === true ? 'yes' : 'no';
            triggerSTDA( b );
        });
    });
    </script>
    <?php
    endif;
}
add_action( 'wp_footer', 'action_wp_footer' );

// The Wordpress Ajax PHP receiver
function get_ajax_ship_different_address() {
    if ( isset( $_POST['ship_different'] ) ) {
        WC()->session->set( 'ship_different', esc_attr( $_POST['ship_different'] ) );
        echo $_POST['ship_different'];
    }
    
    die();
}
add_action( 'wp_ajax_ship_different_address', 'get_ajax_ship_different_address' );
add_action( 'wp_ajax_nopriv_ship_different_address', 'get_ajax_ship_different_address' );

// Add / remove a custom fee
function action_woocommerce_cart_calculate_fees( $cart ) {
    // Only on checkout
    if ( ( is_admin() && ! defined( 'DOING_AJAX' ) ) || is_cart() )
        return;

    $fee_amount = 5;

    if ( WC()->session->get( 'ship_different' ) == 'yes' ) {
        $cart->add_fee( __( 'Shipping fee', 'woocommerce'), $fee_amount );
    }
}
add_action( 'woocommerce_cart_calculate_fees', 'action_woocommerce_cart_calculate_fees', 10, 1 );

However, your question was to only apply this based on certain user roles:

So you get:

// The jQuery Ajax request
function action_wp_footer() {
    // Only for logged in users
    if ( ! is_user_logged_in() )
        return;
    
    // Only checkout page
    if ( is_checkout() && ! is_wc_endpoint_url() ) :

    // Remove "ship_different" custom WC session on load
    if ( WC()->session->get( 'ship_different' ) ) {
        WC()->session->__unset( 'ship_different' );
    }
    
    // jQuery Ajax code below
    ?>
    <script type="text/javascript">
    jQuery( function($) {
        if ( typeof wc_checkout_params === 'undefined' )
            return false;

        var a = '#ship-to-different-address-checkbox', b = '';

        // Ajax function
        function triggerSTDA( value ) {
             $.ajax({
                type: 'POST',
                url: wc_checkout_params.ajax_url,
                data: {
                    'action': 'ship_different_address',
                    'ship_different': value,
                },
                success: function (result) {
                    $( 'body' ).trigger( 'update_checkout' );
                    // console.log( result ); // For testing (to be removed)
                }
            });
        }

        $( a ).on( 'change', function() {
            b = $( this ).prop('checked') === true ? 'yes' : 'no';
            triggerSTDA( b );
        });
    });
    </script>
    <?php
    endif;
}
add_action( 'wp_footer', 'action_wp_footer' );

// The Wordpress Ajax PHP receiver
function get_ajax_ship_different_address() {
    if ( isset( $_POST['ship_different'] ) ) {
        WC()->session->set( 'ship_different', esc_attr( $_POST['ship_different'] ) );
        echo $_POST['ship_different'];
    }
    
    die();
}
add_action( 'wp_ajax_ship_different_address', 'get_ajax_ship_different_address' );
add_action( 'wp_ajax_nopriv_ship_different_address', 'get_ajax_ship_different_address' );

// Add / remove a custom fee
function action_woocommerce_cart_calculate_fees( $cart ) {
    // Only on checkout
    if ( ( is_admin() && ! defined( 'DOING_AJAX' ) ) || is_cart() )
        return;
    
    // Only for logged in users
    if ( ! is_user_logged_in() )
        return;

    // Get current WP_User Object
    $user = wp_get_current_user();
    
    // Roles to check, adapt to your specific needes
    $roles_to_check = array( 'team', 'team2', 'administrator' );
    
    // User roles
    $roles = ( array ) $user->roles;
    
    // Compare
    $compare = array_diff( $roles, $roles_to_check );

    // Result is empty
    if ( empty ( $compare ) ) {
        // Amount
        $fee_amount = 5;

        if ( WC()->session->get( 'ship_different' ) == 'yes' ) {
            $cart->add_fee( __( 'Shipping fee', 'woocommerce'), $fee_amount );
        }
    }
}
add_action( 'woocommerce_cart_calculate_fees', 'action_woocommerce_cart_calculate_fees', 10, 1 );

Partly used in this answer

  • Related