2

I need help in woocommerce shipping options, I want to hide flat rate for a particular product category, where I only want to show local delivery or local pickup options.

For all others categories all options should work.

I have try to do it with that code (added in function.php file of my theme):

function cart_has_product_with_orange_cats() {

    global $woocommerce;
    $product_in_cart = false;

    // start of the loop that fetches the cart items
    foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
        $_product = $values['data'];
        $terms = get_the_terms( $_product->id, 'product_cat' );
        // second level loop search, in case some items have several categories

        if($terms){

            foreach ($terms as $term) {
                $_categoryid = $term->term_id;

                if ( $_categoryid == 16 ) {
                    //category is in cart!
                    $product_in_cart = true;
                }
            }   
        }
    }
    return $product_in_cart;
}

// add filter and function to hide method

add_filter( 'woocommerce_available_shipping_methods', 'custom_shipping_methods' , 10, 1 );

function custom_shipping_methods( $available_methods ){

    if ( cart_has_product_with_orange_cats() ) {

        foreach($available_methods as $key => $method){
            if( $key == 'local_delivery' || $key == 'local_pickup'){
                continue;
            }
            unset($available_methods[$key]);

        }
        // remove the rate you want
    }
    // return the available methods without the one you unset.
    return $available_methods;
}

But it isn't working for me, maybe because outdated code for latest WooCommerce version or any other issue.

How can I achieve this?

starball
  • 20,030
  • 7
  • 43
  • 238
Zahid Iqbal
  • 134
  • 3
  • 10

1 Answers1

4

Update (Compatible with WC 3+ and works with variable products too)

The fully functional tested and corrected code for this answer is located on another thread:
Shipping methods - Local Pickup option not available when Flat Rate is hidden


Important:
woocommerce_available_shipping_methods hook is deprecated since WC version 2.1+ and you will need to use instead woocommerce_package_rates filter hook.

WooCommerce version 2.6+ introduce NEW shipping zones. So all WooCommerce prior version's code related to shipping rates is outdated and will not work anymore.

For info:
global $woocommerce;** with $woocommerce->cart has been replaced by WC()->cart.
You will use instead WC()->cart->get_cart()

We will not need anymore your custom conditional function, because there is already a conditional function that exist in WordPress, that you can target for WooCommerce product categories. This function accept the term ID, the term slug or the term name:

has_term( 'your_category', 'product_cat', $post_id )

So we can use has_term() conditional function in this code:

add_filter( 'woocommerce_package_rates', 'conditional_hide_shipping_methods', 100, 2 );    
function conditional_hide_shipping_methods( $rates, $package ){

    // Define/replace here your correct category slug (!)
    $product_category = 'your_category';
    $prod_cat = false;

    // Going through each item in cart to see if there is anyone of your category        
    foreach ( WC()->cart->get_cart() as $cart_item ) {
        $product_id = $cart_item['product_id'];
        if ( has_term( $product_category, 'product_cat', $product_id ) ){
            $prod_cat = true;
        }
    }

    $rates_arr = array();

    if ( $prod_cat ) {
        foreach($rates as $key => $rate) {
            if ('free_shipping' === $rate->method_id || 'local_pickup' === $rate->method_id || 'local_delivery' === $rate->method_id) {
                $rates_arr[ $rate_id ] = $rate;
                break;
            }
        }
    }
    return !empty( $rates_arr ) ? $rates_arr : $rates;
}

Before adding the snippet, make sure you clear your WooCommerce cache (WooCommerce > System Status > Tools > WC Transients > Clear transients), as shipping methods are cached.

This code goes on function.php file of your active child theme or theme.

This code should work if you have correctly set your shipping zones…


References:

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • Hi, thanks for your great answer, its working but only one issue, local pickup option is not available now. It is showing only Local Delivery. I want to show local pickup as well. Thank you. – Zahid Iqbal Aug 13 '16 at 02:44
  • @LoicTheAztec This is an amazing solution! Worked perfectly! One question - is there any way to show the full set of shipping options again when a product from a different category is added? We have a Gift Card product with Smart Coupons and don't need shipping if it's the only item in the cart, but if they add another product, then shipping methods would apply again. – Nalakira May 22 '18 at 19:25
  • @Nalakira Yes it is possible… But it will change a bit this code… You could ask a new question for it, adding in your question the customized code that you get for now. – LoicTheAztec May 22 '18 at 19:57
  • @LoicTheAztec Here's the new question, if you want to take a crack at it! https://stackoverflow.com/questions/50475753/woocommerce-removing-flat-rate-shipping-for-category-bringing-it-back-when-an – Nalakira May 22 '18 at 20:11