Edited my question for better understanding
A woocommerce has the following two shipping methods:
- Free shipping
- Advance shipping ($3)
In addition, I have two rules to decide if I will give free shipping or advance shipping.
- A simple one. If the cart total is above $50.
A complex one. Let's say that is checked based on the following function
function complex_rule() { //simplified example
if ( get_current_user_id() < 50 ) { return true; else { return false; } }
My first try that didn't work is the following:
function enable_free_shipping( $cart_object ) {
if( WC()->cart->get_subtotal() > 50 || complex_rule() ) {
WC()->session->set('chosen_shipping_methods', array( 'free_shipping' ) );
}
}
add_action( 'woocommerce_before_calculate_totals', 'enable_free_shipping', 99 );
Unfortunately, it doesn't work. I don't have a specific error. It just ignores both rules.
Based on the following answer, I tried this as well, but to simplify the problem and to be sure that there isn't any problem at all on the complex_rule()
function, I kept only the minimum amount rule.
This is the code:
add_filter( 'woocommerce_package_rates', 'conditional_free_shipping', 100, 2 );
function conditional_free_shipping( $rates, $package ) {
// Set the min Order amount for free shipping
$min_order_amount = 50;
$cart_subtotal = (float) WC()->cart->get_subtotal(); // Subtotal excl. taxes
$free = array();
$free_key = '';
// Loop through shipping rates
foreach ( $rates as $rate_id => $rate ) {
if ( 'free_shipping' === $rate->method_id ) {
// Your conditions goes bellow
if ( $cart_subtotal >= $min_order_amount ) {
$free[ $rate_id ] = $rate;
}
$free_key = $rate_id;
break;
}
}
// No free shipping (Other shipping methods only)
if( empty( $free ) ) {
unset($rates[$free_key]);
return $rates;
}
// Only free shipping
else
return $free;
}
With the above, I get the desired result (free shipping method only) above the minimum amount, but the problem is in cases below that amount.
Expected result: Get the Advance shipping method
What I get: No shipping options were found for
All those were tested in a new Woocommerce installation with an empty child theme (no other code in functions.php)