-1

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)

Tasos
  • 7,325
  • 18
  • 83
  • 176
  • I've answered analogical question about this issue. There is a woocommerce bug/feature https://stackoverflow.com/a/62825182/11173494 – 123 Jul 09 '20 at 23:33

1 Answers1

-1

From what I understand you are trying to to make free shipping selected in the checkout when it is over a certain amount.

You can run a filter like the function below. This will hide the other shipping methods and select free shipping when it available.

<?php 
  function site_my_hide_shipping_when_free_is_available( $rates ) { 
      $free = array(); 
      foreach ( $rates as $rate_id => $rate ) { 
          if ( 'free_shipping' === $rate->method_id ) { 
              $free[ $rate_id ] = $rate; 
              break; 
          } 
      } 
      return ! empty( $free ) ? $free : $rates; 
  } 
  add_filter( 'woocommerce_package_rates', 'site_my_hide_shipping_when_free_is_available', 100 );
?>
  • I have already done that. What I try to do is to apply the free_shipping below that amount under specific conditions. Like a combination of products in the cart. While in general the free shipping wasn't available in that cart total. – Tasos Apr 18 '19 at 09:36