简体   繁体   中英

Conditionally Hide WooCommerce Shipping methods based on shipping class

Using WooCommerce v3.2.4 on This site (here) (WP v4.9) and 11 products with the shipping class of Overweight/Oversize that have a flat rate applied to them:
$20 to Canada and $25 to the US.

All other products have flat rate shipping of $10 (Canada) and $15 (US), unless the order is over $100 , then free shipping is applied automatically.

My client wants free shipping to be disabled if there are any overweight/oversize items in the cart. The problem is that the cart says there are no shipping methods available when there are a mix of regular and oversize items in the cart, and no shipping methods are applied.

I'm using XAdapter Woocommerce Shipping Table Rate plugin to apply the higher cost to the "Overweight" Shipping Classes.

UPDATE

I deactivated this plugin, as I realized I could just use the WooCommerce Shipping Zone settings to set a flat rate for specific shipping classes. See screenshot below: 其中一个送货区域的统一费率设置

I am using some code to:

  • hide the free shipping and flat rates when the "Overweight" Shipping Class exists in the cart
  • hide the "Overweight" Shipping Method if that class does not exist (163 being the id of the Shipping Class)

Here is that code:

add_filter('woocommerce_package_rates', 'wf_hide_shipping_method_based_on_shipping_class', 100, 2);

function wf_hide_shipping_method_based_on_shipping_class($available_shipping_methods, $package){
    $hide_when_shipping_class_exist = array(
        163 => array(
            'flat_rate:1',
            'flat_rate:2',
            'free_shipping:3',
            'free_shipping:5'
        )
    );

    $hide_when_shipping_class_not_exist = array(
        163 => array( 'wf_woocommerce_shipping_pro:overweightoversizeoverweight')
    );

    $shipping_class_in_cart = array();
    foreach(WC()->cart->cart_contents as $key => $values) {
       $shipping_class_in_cart[] = $values['data']->get_shipping_class_id();
    }

    foreach($hide_when_shipping_class_exist as $class_id => $methods) {
        if(in_array($class_id, $shipping_class_in_cart)){
            foreach($methods as & $current_method) {
                unset($available_shipping_methods[$current_method]);
            }
        }
    }

    foreach($hide_when_shipping_class_not_exist as $class_id => $methods) {
        if(!in_array($class_id, $shipping_class_in_cart)){
            foreach($methods as & $current_method) {
                unset($available_shipping_methods[$current_method]);
            }
        }
    }
    return $available_shipping_methods;
}

EDIT

Here is a list of IDs of the rates per shipping zone:

Canada

  • Regular Flat rate | ID: flat_rate:1
  • Free Shipping | ID: free_shipping:3
  • Local Pickup | ID: local_pickup:4

USA

  • Regular Flat rate | ID: flat_rate:2
  • Free Shipping | ID: free_shipping:5

UPDATE 2: (Without any plugin need, just settings and code)

The function below will always show "Local pickup" shipping for canada and will:

  1. Hide free shipping methods when "Oversize" shipping class is in cart items. For the "Flat rate" Shipping Methods, the cost will be the one set for "Oversize" shipping class.
  2. if "Oversize" Shipping Class is not set in cart items:
    • If cart amount is less than the target free shipping amount: Hide "Free shipping".
    • If cart amount is over the target free shipping amount: Hide "Flat rate" Shipping Methods.

Here is that code:

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

    // Defining & Initializing variables
    $free_shipping_rates = array(
        'free_shipping:3',
        'free_shipping:5'
    );

    // Defining & Initializing variables
    $shipping_class_id = 163;
    $free = array();
    $over_found = $has_free = false;

    // Check if "Oversize" shipping class (163) is in cart items
    foreach(WC()->cart->get_cart() as $key => $cart_item){
        if($cart_item['data']->get_shipping_class_id() == $shipping_class_id ){
            $over_found = true;
            break;
        }
    }

    // 1. Hiding free shipping but always show Local pickup for Canada
    if( $over_found ){
        foreach($free_shipping_rates as $rate_id) {
            unset( $rates[$rate_id] );
        }
    }
    // 2. Hiding Flat rate OR Free shipping --> depending on cart amount
    //   (but always show Local pickup for Canada)
    else {
        foreach ( $rates as $rate_id => $rate ) {

            // Hide all "Flat rates" when "Free Shipping" is available
            if ( 'free_shipping' === $rate->method_id ) {
                $free[ $rate_id ] = $rate;
                $has_free = true;
            } elseif ( 'local_pickup' === $rate->method_id ) {
                $free[ $rate_id ] = $rate;
            }
        }
        return $has_free ? $free : $rates;
    }
    return $rates;
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

Tested on WooCommerce 3 and works.


Refresh the shipping caches (needed sometimes) :
1) First empty your cart.
2) This code is already saved on your function.php file.
3) Go in a shipping zone settings and disable one "flat rate" (for example) and "save". Then re-enable that "flat rate" and "save". You are done and you can test it.

This is possible by using Woocommerce Shipping Table Rate , You just need to add the extra rules. You need to add 7 shipping rules, You can see the shipping rules in the below image: Image contains the shipping rule you need to add

For the above rules, you will get the desired results at a cart page. I have attached some screenshot of the cart page in different cases for your references: Note: Shipping class of Hat: Regular & Hoodie: Over weight.

Regular and overweight product ordered together

Over wight product with orders over $100

Free shipping for orders amount over $100 with regular items

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM