In WooCommerce we have set flat_rate
shipping amount to 4.95€ and free_shipping
shows up for a minimal total amount of 45€.
Now, if a customer has a cart with - let`s say 48€ - he does not have to pay shipping costs, as he has reached the order total amount to apply free_shipping.
If he does apply now a 10% coupon, he ends up having 43.20€ order total amount and therefore has to pay shipping fees again.
We would like to still offer free shipping to that customer, after he applied the coupon and "landed" below the free_shipping amount. Otherwise its not very attractive using a 10% coupon (4.80€ in our case) but must pay 4.95€ shipping again.
Based on Applied coupons disable Free shipping conditionally in Woocommerce answer code, here is my code attempt:
add_filter( 'woocommerce_package_rates', 'coupons_removes_free_shipping', 10, 2 );
function coupons_removes_free_shipping( $rates, $package ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return $rates;
$shipping_counrtry = WC()->customer->get_shipping_country();
if ($shipping_counrtry == 'DE') : $min_subtotal = 45;
endif;
$shipping_counrtry = WC()->customer->get_shipping_country();
if ($shipping_counrtry == 'AT') : $min_subtotal = 75;
endif;
// Get needed cart subtotals
$subtotal_excl_tax = WC()->cart->get_subtotal();
$subtotal_incl_tax = $subtotal_excl_tax + WC()->cart->get_subtotal_tax();
$discount_excl_tax = WC()->cart->get_discount_total();
$discount_incl_tax = $discount_total + WC()->cart->get_discount_tax();
// Calculating the discounted subtotal including taxes
$discounted_subtotal_incl_taxes = $subtotal_incl_tax - $discount_incl_tax;
$applied_coupons = WC()->cart->get_applied_coupons();
if( sizeof($applied_coupons) > 0 && $discounted_subtotal_incl_taxes > $min_subtotal ){
foreach ( $rates as $rate_key => $rate ){
// Targeting "Free shipping"
if( 'free_shipping' != $rate->method_id ){
// SET THE RATE HERE; but how
}
}
}
return $rates;
}
Updated
First in your shipping settings for Free shipping, you will need to set the minimal amount to 0 (zero). Then the following code will handle cart item non discounted subtotal for a "Free shipping" minimal amount (that will solve your issue):
add_filter( 'woocommerce_package_rates', 'conditional_free_shipping', 10, 2 );
function conditional_free_shipping( $rates, $package ){
$shipping_country = WC()->customer->get_shipping_country(); // Get shipping country
$free_shipping = $other_rates = array(); // Initializing
if ($shipping_country === 'DE') {
$min_subtotal = 45;
} elseif ($shipping_country === 'AT') {
$min_subtotal = 75;
}
// Get subtotal incl tax (non discounted) for the current shipping package
$items_subtotal = array_sum( wp_list_pluck( $package['contents'], 'line_subtotal' ) );
$items_subtotal += array_sum( wp_list_pluck( $package['contents'], 'line_subtotal_tax' ) );
// Loop through shipping rates for current shipping package
foreach ( $rates as $rate_key => $rate ){
if( 'free_shipping' === $rate->method_id ){
$free_shipping[$rate_key] = $rate;
} else
$other_rates[$rate_key] = $rate;
}
}
return isset($min_subtotal) && $items_subtotal >= $min_subtotal ? $free_shipping : $other_rates;
}
Code goes in functions.php file of the active child theme (or active theme). It should work.
Don't forget to empty your cart to refresh shipping cached data.