Search code examples
phpwordpresswoocommercecart

Hide and unhide a specific shipping methods based on shipping class in WooCommerce


i have a cart that has three method standard delivery(0-10kg), standard delivery(11-20kg) and next day delivery(0-20kg), my problem is when i a product with a frozen food shipping class to the cart the shipping method should only be the next day delivery and if there is now shipping class on the cart it only has the standard delivery, my problem is when a add the product with a shipping class and a products with no shipping class it will not go to the condition that i make.

add_filter( 'woocommerce_package_rates', 'custom_hide_shipping_methods', 10, 2 );
function custom_hide_shipping_methods( $rates, $package ) {
    foreach( WC()->cart->get_cart() as $cart_item  ) {
        $product = $cart_item[ 'data' ]; // The WC_Product object
        if( $product->get_shipping_class_id() == 149 ) { // <== ID OF MY SHIPPING_CLASS
            unset( $rates['shipping_by_rules:16'] ); // standard delivery
             wc_add_notice( sprintf( __( '1', 'woocommerce' ), $weight ), 'error' );
        }else if($product->get_shipping_class_id() == NULL){
            unset( $rates['shipping_by_rules:15'] ); // next day delivery
             wc_add_notice( sprintf( __( '2', 'woocommerce' ), $weight ), 'error' );
        }else if($product->get_shipping_class_id() !=  || $product->get_shipping_class_id() == 149){
            unset( $rates['shipping_by_rules:16'] ); // standard delivery
             wc_add_notice( sprintf( __( '3', 'woocommerce' ), $weight ), 'error' );
        }
        break; // we stop the loop
    }
    return $rates;
}

Solution

  • Updated 2: There are many errors and mistakes in your code…

    THERE IS A MISSING SHIPPING METHOD IN YOUR CODE as you only have 2:

    • 'shipping_by_rules:16' ==> Standard delivery(0-10kg)
    • 'shipping_by_rules:15' ==> Next day delivery

    But what about standard delivery(11-20kg)

    You should try the following:

    add_filter( 'woocommerce_package_rates', 'custom_hide_shipping_methods', 20, 2 );
    function custom_hide_shipping_methods( $rates, $package ) {
        $targeted_class_id = 149;  // <== ID OF MY SHIPPING_CLASS
        $has_class = $has_no_class = false;
        
        // Loop through cart items
        foreach( WC()->cart->get_cart() as $cart_item  ) {
            $shipping_class = $cart_item['data']->get_shipping_class_id();
            # $weight = $cart_item['data']->get_weight();
            
            if( $shipping_class == $targeted_class_id ) 
                $has_class = true;
            elseif( empty( $shipping_class ) )
                $has_no_class = true;
        }
        // Unseting shipping methods
        if( $has_class ) 
        { // CASE 1 and 3
            unset( $rates['shipping_by_rules:16'] ); // standard delivery
            # wc_add_notice( sprintf( __( '1 | %s', 'woocommerce' ), $weight ), 'error' );
        }
        elseif( ! $has_class && $has_no_class )
        { // CASE 2
            unset( $rates['shipping_by_rules:15'] ); // next day delivery
            # wc_add_notice( sprintf( __( '2 | %s', 'woocommerce' ), $weight ), 'error' );
        }
        elseif( $has_class && $has_no_class ) // ==> Optional (You may not neeed it)
        { // CASE 3
            unset( $rates['shipping_by_rules:16'] ); // standard delivery
            # wc_add_notice( sprintf( __( '3 | %s', 'woocommerce' ), $weight ), 'error' );
        }
        return $rates;
    }
    

    Code goes in function.php file of the active child theme (or active theme).

    It should works.