Change WordPress user roles and capabilities Forums How to or FAQ Restrict Role from Processing Refunds in WooCommerce

This topic contains 8 replies, has 2 voices, and was last updated by  AGB 1 year, 4 months ago.

Viewing 9 posts - 1 through 9 (of 9 total)
  • Author
    Posts
  • #2723

    AGB
    Participant

    Hi Vladimir,
    We have internal roles, such as Sales team, who need to be able to create/edit Orders in WooCom but Not be able to issue Refunds. How can I hide/block the Refunds capability for a role?

    I first looked in the Meta Boxes area and saw a Shop_order_refund listed there; however there’s nothing under it to block (aside from the ure_content_view_restrictions_meta_box). Is this Meta Boxes module where we can achieve what we need? Do we need to Add a capability?

    (Note: for payment methods we are using this PayPal for WooCommerce plugin.)

    I appreciate your help.

    #2726

    Vladimir
    Keymaster

    Hi,

    The only way to hide “Refunds” button from order edit form is to change HTML page CSS via JavaScript. Add code below to the active theme functions.php file or setup it as a must-use plugin. It is executed for the ‘orders-manager’ role only. Replace it with you own role ID.

    
    add_action('admin_head', 'hide_wc_refund_button');
    
    function hide_wc_refund_button() {
    
        global $post;
    
        if (!current_user_can('orders-manager')) {
            return;
        }
        if (strpos($_SERVER['REQUEST_URI'], 'post.php?post=') === false) {
            return;
        }
    
        if (empty($post) || $post->post_type != 'shop_order') {
            return;
        }
    ?>
        <script>
          jQuery().ready(function () {
                jQuery('.refund-items').hide();
            });
        </script>
        <?php
    
    }
    
    #2729

    AGB
    Participant

    Thank you Vladimir for consistently providing such great support! That worked perfectly to hide the Refund button from showing for the role (sales) we specified in the code. However, in General Details part of order edit form, that role still has the ability to set the Order Status to be “Refunded”, which when saving order will proceed to change the order details, reflecting a full refund for whole order (products + shipping).

    Is it also possible to hide (or block ability to select) the “Refunded” status from the Order Status drop-down in order edit form, for this particular role?

    Thanks again.

    #2730

    Vladimir
    Keymaster

    Try this updated version:

    
    add_action('admin_head', 'hide_wc_refund_button');
    
    function hide_wc_refund_button() {
    
        global $post;
    
        if (!current_user_can('sales')) {
            return;
        }
        if (strpos($_SERVER['REQUEST_URI'], 'post.php?post=') === false) {
            return;
        }
    
        if (empty($post) || $post->post_type != 'shop_order') {
            return;
        }
    ?>
        <script>
          jQuery(function () {
                jQuery('.refund-items').hide();
                jQuery('.order_actions option[value=send_email_customer_refunded_order]').remove();
            });
        </script>
        <?php
    
    }
    
    #2731

    AGB
    Participant

    Thank you – that was successful hiding the Resend Order Emails option “Refunded Order”, in the Order Actions drop-down.

    However the role can still select “Refunded” in the Order Status drop-down. Then if the role saves order, it will update order totals as being fully refunded.

    Now I wonder though: if I did hide that “Refunded” order status option for role, then would it cause problem if role was viewing an old order that was previously refunded – meaning would its order status be missing/show blank?

    I want to keep using your code above… Then instead of also trying to hide Refunded order status from drop-down… is it better or possible to restrict role from Saving the order IF he has “Refunded” as selected status option? So if he tried to save with that status, he’d get the message popup that he doesn’t have the permissions. I think that’d be ideal.

    I really appreciate your help on this.

    #2732

    Vladimir
    Keymaster

    Thanks for the clarification. I missed ‘Order status’ field yesterday. Try this version. It removes dropdown list of statuses if order was refunded already and just shows “Refunded” text and removes ‘Refunded’ item from the dropdown list options in other cases:

    
    add_action('admin_head', 'hide_wc_refund_button');
    
    function hide_wc_refund_button() {
    
        global $post;
    
        if (!current_user_can('sales')) {
            return;
        }
        if (strpos($_SERVER['REQUEST_URI'], 'post.php?post=') === false) {
            return;
        }
    
        if (empty($post) || $post->post_type != 'shop_order') {
            return;
        }
    ?>
        <script>
          jQuery(function () {
                jQuery('.refund-items').hide();
                jQuery('.order_actions option[value=send_email_customer_refunded_order]').remove();
                if (jQuery('#original_post_status').val()=='wc-refunded') {
                    jQuery('#s2id_order_status').html('Refunded');
                } else {
                    jQuery('#order_status option[value=wc-refunded]').remove();
                }
            });
        </script>
        <?php
    
    }
    
    #2733

    AGB
    Participant

    YES! This is perfect – thank you so much. One last question, regarding syntax: to apply this to multiple roles (‘sales’ role and also ‘shipping’ role), do I simply use a comma as the separator? Or would that make it apply to someone who had both sales & shipping role?

    For example would this line be correct for applying to each of the two roles:
    if (!current_user_can(‘sales’,’shipping’))

    #2734

    Vladimir
    Keymaster

    You have to call current_user_can() for every role you wish to check, e.g.:

    
    if (current_user_can('role_1') || current_user_can('role_2')) {
      ...
    }
    

    This means “if current user have role_1 or current user have role_2”.

    For our code:

    
    if (!current_user_can('sales') && !current_user_can('shipping')) {
        return;
    }
    

    That is ‘do not execute code below if user does not have role ‘sales’ and user does not have role ‘shipping’.

    #2735

    AGB
    Participant

    Got it! I appreciate the clarification – all is working great now. Thanks for your prompt replies!

Viewing 9 posts - 1 through 9 (of 9 total)

You must be logged in to reply to this topic.