4

I have 3 shipping methods in my cart that should become zero prices as soon as your customer enters Free Shipping coupon.

I know how to add a filter in functions.php to detect the coupon but is someone know a snippet to set shipping methods visibles in cart (radio button) to ZERO for this order?

My deliveries methods are companies like UPS, FedEx...

I activated the free shipping option in order it can be managed with coupon.

The list of choice of deliveries methods for the customers is calculated according to my products shipping class and order total weight.

Shipping class are not calculated but set by product and i use TABLE RATE PLUGIN to calculate the weight.

Daniel Widdis
  • 8,424
  • 13
  • 41
  • 63
  • thanks but that's the contrary that i want...if my coupon enable a free shipping method i can't let the choice to the customer of de delivery method.. –  Feb 07 '18 at 08:29
  • when shipping methods are displayed in cart, inviting customer to choose one with radio button, i need to set all their price to 0 if a coupon is applied –  Feb 07 '18 at 10:08

2 Answers2

5

First free shipping method has to be enabled with option "A valid free shipping coupon"…

Then you need to set the desired coupon codes with option "Allow free shipping" enabled.

The following code will set all shipping methods costs to zero when a valid coupon code (with option "Allow free shipping" enabled) will be applied.

Update: Hide "Free shipping" method and append shipping label titles with "(free)"

add_filter( 'woocommerce_package_rates', 'coupon_free_shipping_customization', 20, 2 );
function coupon_free_shipping_customization( $rates, $package ) {
    $has_free_shipping = false;

    $applied_coupons = WC()->cart->get_applied_coupons();
    foreach( $applied_coupons as $coupon_code ){
        $coupon = new WC_Coupon($coupon_code);
        if($coupon->get_free_shipping()){
            $has_free_shipping = true;
            break;
        }
    }

    foreach( $rates as $rate_key => $rate ){
        if( $has_free_shipping ){
            // For "free shipping" method (enabled), remove it
            if( $rate->method_id == 'free_shipping'){
                unset($rates[$rate_key]);
            }
            // For other shipping methods
            else {
                // Append rate label titles (free)
                $rates[$rate_key]->label .= ' ' . __('(free)', 'woocommerce');

                // Set rate cost
                $rates[$rate_key]->cost = 0;

                // Set taxes rate cost (if enabled)
                $taxes = array();
                foreach ($rates[$rate_key]->taxes as $key => $tax){
                    if( $rates[$rate_key]->taxes[$key] > 0 )
                        $taxes[$key] = 0;
                }
                $rates[$rate_key]->taxes = $taxes;
            }
        }
    }
    return $rates;
}

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

Tested and works. It should works also for you.

Sometimes, you should may be need to refresh shipping methods:
1) Empty cart first.
2) Go to shipping Zones settings, then disable/save and re-enable/save the related shipping methods.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
-1

If you want to achieve the same but whenever there is a free shipping method available (not only applied coupon, but also cart total is above certain price), you can use this:

add_filter( 'woocommerce_package_rates', 'wc_apply_free_shipping_to_all_methods', 10, 2 );
function wc_apply_free_shipping_to_all_methods( $rates, $package ) {
  if( isset( $rates['free_shipping:11'] ) ) { 
    unset( $rates['free_shipping:11'] );
    foreach( $rates as $rate_key => $rate ) { 
                // Append rate label titles (free)
                $rates[$rate_key]->label .= ' ' . __('(free)', 'woocommerce');

                // Set rate cost
                $rates[$rate_key]->cost = 0;

                // Set taxes rate cost (if enabled)
                $taxes = array();
                foreach ($rates[$rate_key]->taxes as $key => $tax){
                    if( $rates[$rate_key]->taxes[$key] > 0 )
                        $taxes[$key] = 0;
                }
                $rates[$rate_key]->taxes = $taxes;
    }   
  }
  return $rates;
}

Notice, that after free_shipping there is a :11. Prior to WooCommerce 2.6, the details of shipping method "Free Shipping" were stored under array element $rates['free_shipping']. Now, however, it is stored as $rates['free_shipping:shipping_zone_instance_id'] where shipping_zone_instance_id is the shipping zone instance id of the shipping method. You can check the instance id of the shipping method by inspecting the "Free Shipping" in admin panel, or opening it in new tab and looking at the url http://prntscr.com/jd2zjy.

IKavanagh
  • 6,089
  • 11
  • 42
  • 47
  • This is not a way to thank for a snippet… Your answer is not answering the initial question here and should be removed. It's strictly based on my code without the coupon part, which was asked in this question. That is really not fair. You should have asked a new question instead… – LoicTheAztec May 04 '18 at 13:38
  • @LoicTheAztec, I'd thought that someone would appreciate the more universal solution. Isn't it obvious that this is your code but tweaked? Do you want me to tag you in my answer? I really don't mean any disrespect – Michał Burda May 04 '18 at 13:50
  • You asked in a deleted answer here: **"thanks for this cool snippet! Could you tell me how to edit this code to work with free shipping above certain cart total price too?"** So this is answering your question… but it's not answering the question asked in this thread… `if( isset( $rates['free_shipping:11'] ) ) { unset( $rates['free_shipping:11'] );` is not universal and it's related to your specific problem… – LoicTheAztec May 04 '18 at 14:04