如何为同一国家/地区设置不同的 woocommerce 运输区域并显示它们

s01*_*420 1 methods woocommerce

我发现 woocommerce 只会显示排序在列表顶部(最窄)的配送区域的配送方式,而这种默认设置使得配送区域功能变得非常有限。

我有 2 个承运商供客户选择,UPS 和 EMS。UPS和EMS有不同的价格规则和不同的运输区域设置。

显示两种运输方式 I

我需要创建 3 种类型的区域:

  1. 仅限 UPS 的县
  2. 仅县 EMS
  3. 重叠国家/地区同时使用 UPS 和 EMS 作为方法。

这意味着我需要创建至少 30 多个运输区域。大多数人喜欢将一个国家创建为一个航运区,这意味着航运区毫无用处。

我还发现有人和我有同样的问题: https://wordpress.org/support/topic/intersecting-shipping-zones-not-displayed-on-checkout/

如果 woocommerce 可以在不同的运输区域上显示两种运输方式,那就太好了。我可以添加任何代码以使其正常工作吗?

非常感谢。

Miz*_*ino 6

我在EMS和DHL的设置上也遇到了同样的问题,找不到合理的解决方案。因此,我不得不花一整天的时间手动编码。

我在这里将其发布给可能有需要的人。它将运输 ID 保存到数据存储区,并使用它们来计算和合并可选费率。

// Make and merge optional rates
add_filter( 'woocommerce_package_rates', function ( $rates, $package ){

$country           = strtoupper( wc_clean( $package['destination']['country'] ) );
$state             = strtoupper( wc_clean( $package['destination']['state'] ) );
$postcode          = wc_normalize_postcode( wc_clean( $package['destination']['postcode'] ) );
$cache_key         = WC_Cache_Helper::get_cache_prefix( 'shipping_zones' ) . 'wc_shipping_zones_' . md5( sprintf( '%s+%s+%s', $country, $state, $postcode ) );
$matching_zone_ids = wp_cache_get( $cache_key, 'shipping_zones_array' ); // get ids from the datastore cache
if ( false === $matching_zone_ids ) {
    $data_store = WC_Data_Store::load( 'shipping-zone' );
    $data_store->get_zone_id_from_package( $package );
    $matching_zone_ids = wp_cache_get( $cache_key, 'shipping_zones_array' );
}
if ( $matching_zone_ids ) : foreach ( $matching_zone_ids as $matching_zone_id ):
    $new_zone = new WC_Shipping_Zone( $matching_zone_id );
    foreach ( $new_zone->get_shipping_methods( true ) as $new_method ){
        $rates = $rates + $new_method->get_rates_for_package( $package ); // make and merge the optional rate
    }
endforeach; endif;

return  $rates;

}, 10, 2 );


add_filter( 'woocommerce_get_zone_criteria', function ( $criteria, $package, $postcode_locations ) { // set ids as array to the datastore cache 

global $wpdb;
$matching_zone_ids = array();
$matching_zones = $wpdb->get_results( "SELECT zones.zone_id FROM {$wpdb->prefix}woocommerce_shipping_zones as zones LEFT OUTER JOIN {$wpdb->prefix}woocommerce_shipping_zone_locations as locations ON zones.zone_id = locations.zone_id AND location_type != 'postcode' WHERE " . implode( ' ', $criteria ) . ' ORDER BY zone_order ASC, zones.zone_id ASC LIMIT 10' );
if ( $matching_zones ){
    foreach ( $matching_zones as $zone ){
        $matching_zone_ids[] = $zone->zone_id;
    }
}
$country           = strtoupper( wc_clean( $package['destination']['country'] ) );
$state             = strtoupper( wc_clean( $package['destination']['state'] ) );
$postcode          = wc_normalize_postcode( wc_clean( $package['destination']['postcode'] ) );
$cache_key         = WC_Cache_Helper::get_cache_prefix( 'shipping_zones' ) . 'wc_shipping_zones_' . md5( sprintf( '%s+%s+%s', $country, $state, $postcode ) );
wp_cache_set( $cache_key, $matching_zone_ids, 'shipping_zones_array' );

return $criteria;

}, 10, 3 );
Run Code Online (Sandbox Code Playgroud)