3

I have a use case for a website and I can't figure out how to configure WooCommerce Shipping to do what I want.

Regarding shipping in that store:

  • There are products that can be delivered ONLY locally (for free). If someone is outside a defined the area, a message should notify him that this is a only local product.
  • Other products can be delivered locally (for free) or to outside areas.
  • Within these products that can be delivered to outside areas, different delivery rates apply (Product A is +$25 , but Product B is +$30, and Product C is +$10...)

I set up two Shipping zones:

  • Local (only a list of Zip codes) -> Free Rate,
  • Outside Area (everywhere) -> put a bunch of classes such as +10 , +20 , +25 ... and gave them rates

I have 2 main problems here:

  1. I dont know how to force some products to be local ONLY.
  2. when doing the setup above, the products that are on the outside area for which I gave a shipping class are not showing in local if someone is trying to checkout from a local Zip code.

How can this be solved?

starball
  • 20,030
  • 7
  • 43
  • 238
olim
  • 73
  • 1
  • 10
  • Hi Loic, I'm still testing your script as I'm tweaking it a little bit to match my use case. I'll accept it as soon as I'm done! I asked the new question as it was not answered here (and was also suggested by you). Thanks! – olim Aug 23 '17 at 02:00

2 Answers2

1

As you have enabled that free local shipping rate, you will need to set it the code below. It can be a "Free Shipping" method or a "Local Pickup" method (set with 0 cost and no tax).

You will have also to set in the function the array of products IDs that need this shipping method enabled (hiding all others).

add_filter( 'woocommerce_package_rates', 'conditionally_hide_shipping_methods', 10, 2 );
function conditionally_hide_shipping_methods( $rates, $package ) {

    // Set HERE the shipping method to use: 
    // It can be 'free_shipping' or 'local_pickup' (set with 0 cost and no tax) 
    $shipping_method_id = 'local_pickup';

    // Set HERE your "LOCAL free" product IDs
    $local_free_ids = array( 40, 37 );

    $found = false;

    foreach( WC()->cart->get_cart() as $cart_item  ) {
        if( in_array($cart_item[ 'product_id' ], $local_free_ids) ) { // <== ID OF MY SHIPPING_CLASS
            $found = true;
            break; // Stop the loop
        }
    }
    // If on of this product Ids are in cart we hide all other shipping methods
    if ( $found ){
        $local_free = array();
        foreach ( $rates as $rate_id => $rate ) {
            if ( $shipping_method_id === $rate->method_id ) {
                $local_free[ $rate_id ] = $rate;
                break;
            }
        }
        return ! empty( $local_free ) ? $local_free : $rates;
    } else {
        return $rates;
    }
}

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

Sometimes is necessary to refresh the shipping caches:
1) First your cart is empty.
2) The code is already saved on your function.php file.
3) Go in a shipping zone and disable one "flat rate" (for example) and "save". Then re-enable that "flat rate" and "save". You are done.

Based on: WooCommerce - Hide other shipping methods when FREE SHIPPING is available


To notify customers for Local products only, this should be asked in a new question...

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

These is somewhat debatable but you don't need to code to get this done. As I think you're already there.

I set up two Shipping zones:

Local (only a list of Zip codes) -> Free Rate, Outside Area (everywhere) -> put a bunch of classes such as +10 , +20 , +25 ... and gave them rates

In your Local and Everywhere should have same shipping classes but should have different values.

Let us say that in your settings be like this

Shipping Zone > Local

Zone regions: add list of zip codes or region.
Shipping methods: add a Flat Rate method

Flat Rate settings:
reigelgallarde.me

Shipping Zone > Everywhere

Zone regions: add list of zip codes or region or leave it blank.
Shipping methods: add a Flat Rate method

Flat Rate settings:
reigelgallarde.me

I have 2 main problems here:

  1. I dont know how to force some products to be local ONLY.
  2. when doing the setup above, the products that are on the outside area for which I gave a shipping class are not showing in local if someone is trying to checkout from a local Zip code.
  1. You don't. Just add the correct shipping class for the product and the shipping will do it itself.
  2. This is where you lost me. Here's a screenshot of my cart. Local vs Everywhere.

Local
reigelgallarde.me

Everywhere
reigelgallarde.me

Above two images are demonstrating a product that has a "Class A" shipping class.

Community
  • 1
  • 1
Reigel Gallarde
  • 64,198
  • 21
  • 121
  • 139
  • You can also name your flat rate in your Shipping Zone > Local as "Free Shipping" so it will show as Free Shipping on the cart. – Reigel Gallarde Aug 23 '17 at 02:27
  • Also, note that you should not apply a cost on your shipping methods. Only on the shipping classes. This way, if a product has no shipping class, this will leave a note that `There are no shipping methods available. Please double check your address, or contact us if you need any help.`. You can also use this for Local Only products. Might add classes "Local A", "Local B", "Local C"... and do the same as like shipping classes like Class A, B, C.. – Reigel Gallarde Aug 23 '17 at 02:49
  • Thank you for the answer. You actually got what I have in mind. As far as the point #2, I get the same results as you (See screenshots below for a "normal" product that can be both delivered locally and in an outside area): http://imgur.com/VsstRtY http://imgur.com/yoXxjlB Now, for point #1, I basically need to notify the customer that a product can't be delivered if he is in an outside area. Here are screenshots of a "local only" product. Notice how a customer can still check out even though he is in an outside area. http://imgur.com/VjsXqXN http://imgur.com/J1X3Njo – olim Aug 23 '17 at 02:56
  • P.S: I use a "Local Only" Shipping class to differentiate this product. It is set to $0 rate in "Local Area" Shipping Zone. and N/A in "Outside Area" Shipping zone. – olim Aug 23 '17 at 02:57
  • "Also, note that you should not apply a cost on your shipping methods. Only on the shipping classes. " This is what I was doing wrong this whole time. I was setting the default cost to 0. I left it blank .. and now all scenarios are working perfectly !!! Thank you so much @Reigel !! – olim Aug 23 '17 at 03:01