Reputation: 157
In WooCommerce, is it possible to automatically apply free shipping to any product that is on sale?
Every month we have different products on sale, and all sale products automatically qualify for free shipping. For sale products I currently have to manually change the shipping class to "free shipping" and then back to "standard shipping" when the sale is over. I would like to automate this so any product that is on sale automatically qualifies the order for free shipping.
I can apply free shipping per product ID, but I have not been able to figure out applying this to sale products.
function wcs_my_free_shipping( $is_available ) {
global $woocommerce;
// set the product ids that are eligible
$eligible = array( '360' );
// get cart contents
$cart_items = $woocommerce->cart->get_cart();
// loop through the items looking for one in the eligible array
foreach ( $cart_items as $key => $item ) {
if( in_array( $item['product_id'], $eligible ) ) {
return true;
}
}
// nothing found return the default value
return $is_available;
}
add_filter( 'woocommerce_shipping_free_shipping_is_available', 'wcs_my_free_shipping', 20 );
Upvotes: 3
Views: 959
Reputation: 29614
To make free shipping available, you could use is_on_sale();
function filter_woocommerce_shipping_free_shipping_is_available( $is_available, $package, $shipping_method ) {
// Loop through cart items
foreach( $package['contents'] as $cart_item ) {
// On sale
if ( $cart_item['data']->is_on_sale() ) {
// True
$is_available = true;
// Notice
$notice = __( 'free shipping', 'woocommerce' );
// Break loop
break;
}
}
// Display notice
if ( isset( $notice ) ) {
wc_add_notice( $notice, 'notice' );
}
// Return
return $is_available;
}
add_filter( 'woocommerce_shipping_free_shipping_is_available', 'filter_woocommerce_shipping_free_shipping_is_available', 10, 3 );
Optional: Hide other shipping methods when free shipping is available
function filter_woocommerce_package_rates( $rates, $package ) {
// Empty array
$free = array();
// Loop trough
foreach ( $rates as $rate_id => $rate ) {
if ( $rate->method_id === 'free_shipping' ) {
$free[ $rate_id ] = $rate;
// Break loop
break;
}
}
return ! empty( $free ) ? $free : $rates;
}
add_filter( 'woocommerce_package_rates', 'filter_woocommerce_package_rates', 10, 2 );
Upvotes: 3