skip to Main Content

We would like to prevent shop manager from changing order status, we found a help here in the link below Restrict user role to change only some order statuses in Woocommerce

But the issue here that it limits certain role ( shop Manager ) to some order statuses, we need to deny the shop manager from changing the order status completely not limit it to some order statuses.

Also the snippet we mentioned remove the the order statuses from the bulk action drop down & the order details here: https://prnt.sc/mpfl3b, we need to remove the statuses too from the quick action column here https://snipboard.io/B6SYHb.jpg

Simply we try to have the shop manager to when he try to change order status from bulk, order details page, or actions column to find there is no order statuses to select to change it or disable it completely.

Best Regards

2

Answers


  1. As you can see in the example code the conditions of the statuses are determined in the if statement, because you want to apply this without a limit, it’s just a matter of removing that if statement and returning empty arrays

    p.s; if you mark my answer as the solution, then also vote for @LoicTheAztec original answer if you have not already done this, since his code just about contained the solution.

    // Admin orders list: bulk order status change dropdown
    function filter_dropdown_bulk_actions_shop_order( $actions ) {
        // Targeting shop_manager
        if( current_user_can( 'shop_manager' ) ) {
            $actions = (array) null;
        }
    
        return $actions;
    }
    add_filter( 'bulk_actions-edit-shop_order', 'filter_dropdown_bulk_actions_shop_order', 20, 1 );
    
    // Admin orders list: quick action
    function filter_order_actions( $actions, $order ) {
        // Targeting shop_manager
        if( current_user_can( 'shop_manager' ) ) {
            $actions = (array) null;
        }
    
        return $actions;
    }
    add_filter( 'woocommerce_admin_order_actions', 'filter_order_actions', 10, 2 );
    
    // Admin order pages: order status dropdown
    function filter_order_statuses( $order_statuses ) { 
        global $post, $pagenow;
    
        if( $pagenow === 'post.php' || $pagenow === 'post-new.php' ) {
            // Get ID
            $order_id = $post->ID;
    
            // Get an instance of the WC_Order object
            $order = wc_get_order( $order_id );
    
            // TRUE
            if ( $order ) { 
                // Get current order status
                $order_status = 'wc-' . $order->get_status();
    
                // New order status
                $new_order_statuses = array();
    
                foreach ($order_statuses as $key => $option ) {
                    // Targeting "shop_manager"
                    if( current_user_can('shop_manager') && $key == $order_status ) {
                        $new_order_statuses[$key] = $option;
                    }
                }
    
                if( sizeof($new_order_statuses) > 0 ) {
                    return $new_order_statuses;
                }
            }
        }
        return $order_statuses;
    }
    add_filter('wc_order_statuses', 'filter_order_statuses', 10, 1 );
    
    Login or Signup to reply.
  2. //Since the suggested answer apparently causes some new issues and doesn’t solve the original issue in a couple of other cases, there are options to hide elements according to user type, something like the below – which is a bit of kludge, but might serve:

    First, to load an admin style sheet applying only to Shop Managers:

    /**
     * SHOP MANAGER STYLES 
     * Front (Optional) and Back End stylesheet 
     * Style interface for users logged in with'shop_manager' role
     * Add to theme functions.php
     */
    add_action('admin_enqueue_scripts', 'shop_manager_styles');
    //if front end stylesheet needs to be added to cover admin bar:
    //add_action('wp_enqueue_scripts', 'shop_manager_styles' ) ; 
    
    function shop_manager_styles() {  
    
        $user = wp_get_current_user() ;
    
        //uncomment following and remove next if not confined to admin  
        //if ( $user && in_array( 'shop_manager', $user->roles )  ) { 
        if ( in_array( 'shop_manager', $user->roles ) ) {
    
            //time() as stylesheeet version to help bust caching - may not be necessary but doesn't hurt:
            wp_enqueue_style( 
                'shop_manager_styles', get_stylesheet_directory_uri() 
                . '/css/shop_manager_styles.css', array(), time() 
            ); 
    
        } 
    
    }
    

    …and the css to hide the order-status label and menu completely, as well as related columns in shop_order sub-pages:

    /** HIDE ORDER STATUS LABEL, SELECTION MENU IN ORDER EDIT
      * AND RELATED COLUMNS IN shop_order SUB-PAGE
      */
    .wc-order-status, 
    .column-order_status,
    .column-wc_actions {
        display: none;
    }
    

    You’d save that in your theme css folder in a new shop_manager_styles.css.

    Now, you may have some need to show the order status to shop managers without their being able to edit it. That would also be doable with CSS, if also (even more) a kludge. It may be that you have other peculiarities in your installation that will prevent the above code or a minimally customized variation of it from working, but, even if it is a little less clean than removing the option via function, this kind of thing usually will work in a pinch.

    (Edited to provide option to add stylesheet on front end – in case relevant options appearing in admin bar, otherwise no need to enqueue extra non-admin script.)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search