s01*_*420 1 methods woocommerce
我发现 woocommerce 只会显示排序在列表顶部(最窄)的配送区域的配送方式,而这种默认设置使得配送区域功能变得非常有限。
我有 2 个承运商供客户选择,UPS 和 EMS。UPS和EMS有不同的价格规则和不同的运输区域设置。
显示两种运输方式 I
我需要创建 3 种类型的区域:
这意味着我需要创建至少 30 多个运输区域。大多数人喜欢将一个国家创建为一个航运区,这意味着航运区毫无用处。
我还发现有人和我有同样的问题: https://wordpress.org/support/topic/intersecting-shipping-zones-not-displayed-on-checkout/
如果 woocommerce 可以在不同的运输区域上显示两种运输方式,那就太好了。我可以添加任何代码以使其正常工作吗?
非常感谢。
我在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)