问题
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:
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:
- Hide other shipping methods when FREE SHIPPING is available
- WooCommerce - Hide other shipping methods when FREE SHIPPING is available
来源:https://stackoverflow.com/questions/38928973/shipping-methods-local-pickup-option-not-available-when-flat-rate-is-hidden