Shipping methods - Local Pickup option not availab

2019-07-30 04:48发布

Based on this answer (code below), I successfully can hide flat rate from particular product category and local delivery option is available. This is working perfect.

The problem: local pickup option is NOT available for that particular category.

How can I make the local pickup option available to this special category?

This is the code that I use:

function custom_shipping_methods( $rates ){

    // Define/replace here your correct category slug (!)
    $cat_slug = 'your_category_slug';
    $prod_cat = false;

    // Going through each item in cart to see if there is anyone of your category        
    foreach ( WC()->cart->get_cart() as $values ) {
        $item = $values['data'];

        if ( has_term( $cat_slug, 'product_cat', $item->id ) )
            $prod_cat = true;
    }

    $rates_arr = array();

    if ( $prod_cat ) {
        foreach($rates as $key => $rate) {
            if ('free_shipping' === $rate->method_id || 'local_pickup' === $rate->method_id || 'local_delivery' === $rate->method_id) {
                $rates_arr[ $rate_id ] = $rate;
                break;
            }
        }
    }
    return !empty( $rates_arr ) ? $rates_arr : $rates;
}
add_filter( 'woocommerce_package_rates', 'custom_shipping_methods', 100);

One more thing: Is it possible to show local delivery and local pickup for that special category depending on location?

Currently in my store local Pickup or Delivery is setup only for one location.

1条回答
一夜七次
2楼-- · 2019-07-30 05:40

Advice: ONLY for WooCommerce version 2.6.x (added compatibility for WC 3+)

After many tests… You will need to change 2 little things in your code:

add_filter( 'woocommerce_package_rates', 'custom_shipping_methods', 100, 2 );
function custom_shipping_methods( $rates, $package ){

    // Define/replace here your correct category slug (!)
    $cat_slug = 'posters';
    $prod_cat = false;

    // Going through each item in cart to see if there is anyone of your category
    foreach ( WC()->cart->get_cart() as $values ) {
        $product = $values['data'];

        // compatibility with WC +3
        $product_id = method_exists( $product, 'get_id' ) ? $product->get_id() : $product->id;

        if ( has_term( $cat_slug, 'product_cat', $product_id ) )
            $prod_cat = true;
    }

    $rates_arr = array();

    if ( $prod_cat ) {
        foreach($rates as $rate_id => $rate) { // <== There was a mistake here

            if ('free_shipping' === $rate->method_id || 'local_pickup' === $rate->method_id || 'local_delivery' === $rate->method_id) {
                $rates_arr[ $rate_id ] = $rate;
                // break; // <========= Removed this to avoid stoping the loop
            }
        }
    }
    return !empty( $rates_arr ) ? $rates_arr : $rates;
}

There was 2 mistakes:

  • One in the foreach loop with a bad variable name that I have replace it.
  • Removed break; avoiding stoping the foreach loop when one condition match.

This code goes on function.php file of your active child theme or theme.

This code is tested and fully functional (it will work if you have correctly set your shipping zones).

You will need to refresh shipping cached data: disable, save and enable, save related shipping methods for the current shipping zone, in woocommerce shipping settings.


References:

查看更多
登录 后发表回答