Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Free shipping depending on weight and on minimal cart amount

With WooCommerce, I need to have Free Shipping over certain amount of 250 except the heavy products that are included in the cart.

Does anyone know what i should do?

Thanks.

like image 671
spy Avatar asked Oct 18 '22 17:10

spy


1 Answers

This custom code will keep free shipping method and will hide other shipping methods when the cart amount is up to 250 and if products are not heavy (less than 20 kg here)… To not allow Free shipping for orders less than 250, you can set this in woocommerce (see at the end).

First you will have to sure that the weight is set in each heavy product (for simple or variables products (in each variations). The cart subtotal here is Excluding taxes (and you can change it to Including taxes easily).

enter image description here

Then here is that custom hooked function in woocommerce_package_rates filter hook:

add_filter( 'woocommerce_package_rates', 'conditionally_hide_other_shipping_based_on_items_weight', 100, 1 );
function conditionally_hide_other_shipping_based_on_items_weight( $rates ) {

    // Set HERE your targeted weight (here is 20 kg) <== <== <== <== <==
    $targeted_product_weight = 20;
    
    // Set HERE your targeted cart amount (here is 250)  <== <== <== <== <==
    $targeted_cart_amount = 250;
    // For cart subtotal amount EXCLUDING TAXES
    $passed = WC()->cart->subtotal_ex_tax >= $targeted_cart_amount ? true : false;
    // For cart subtotal amount INCLUDING TAXES (replace by this):
    // $passed = WC()->cart->subtotal >= $targeted_cart_amount ? true : false;
    $light_products_only = true; // Initializing

    // Iterating trough cart items to get the weight for each item
    foreach( $package['contents'] as $cart_item ){
        // Getting the product weight
        $product_weight = $cart_item['data']->get_weight();

        if( !empty($product_weight) && $product_weight >= $targeted_product_weight ){
            $light_products_only = false;
            break;
        }
    }

    // If 'free_shipping' method is available and if products are not heavy
    // and cart amout up to the target limit, we hide other methods
    $free = array();
    foreach ( $rates as $rate_id => $rate ) {
        if ( 'free_shipping' === $rate->method_id && $passed && $light_products_only ) {
            $free[ $rate_id ] = $rate;
            break;
        }
    }

    return ! empty( $free ) ? $free : $rates;
}

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

This code is tested and it works for simple and variable products…

You Will also have to in WooCommerce settings > Shipping, for each shipping zone and for the "Free Shipping" method your minimum order amount:

enter image description here

You will need to refresh shipping cached data: disable, save and enable, save related shipping methods for the current shipping zone, in woocommerce shipping settings.

like image 194
LoicTheAztec Avatar answered Oct 27 '22 11:10

LoicTheAztec