Search code examples
phpwordpresswoocommercehook-woocommerceorders

Hide order statuses in dropdown based on order status in WooCommerce edit order page


I want to hide order statuses in the WooCommerce order status dropdown under specific scenarios:

  • If status is pending payment hide completed
  • If status is processing hide pending payment

I still want to display all these order statuses in the order overview list.

All I can find is to unset an order status completely:

function so_39252649_remove_processing_status ($statuses) {
    if (isset($statuses['wc-processing'])) {
        unset($statuses['wc-processing']);
    }
    return $statuses;
}
add_filter('wc_order_statuses', 'so_39252649_remove_processing_status');

But this will of course also remove it from the order overview list, I just want to hide it in the dropdown on the order edit page, but I cant find a hook for this.

Is jQuery my only choice for this?


Solution

  • You can use the following, comments with explanations added in the code.

    So you get:

    // Admin order edit page: order status dropdown
    function filter_wc_order_statuses( $order_statuses ) {  
        global $post, $pagenow;
    
        // Target edit pages
        if( $pagenow === 'post.php' && isset($_GET['post']) && $_GET['action'] == 'edit' && get_post_type($_GET['post']) === 'shop_order' ) {
            // Get ID
            $order_id = $post->ID;
    
            // Get an instance of the WC_Order object
            $order = wc_get_order( $order_id );
    
            // Is a WC order
            if ( is_a( $order, 'WC_Order' ) ) {
                // Get current order status
                $order_status = $order->get_status();
                
                // Compare
                if ( $order_status == 'pending' ) {
                    unset( $order_statuses['wc-completed'] );
                } elseif ( $order_status == 'processing' ) {
                    unset( $order_statuses['wc-pending'] );             
                } 
            }
        }
        
        return $order_statuses;
    }
    add_filter( 'wc_order_statuses', 'filter_wc_order_statuses', 10, 1 );