在我的 WooCommerce 网站上,每个产品都有四个属性(尺寸、颜色、季节和品牌)。尺寸和颜色属性用于变化,而季节和品牌不用于变化。
我设置了 3 种送货方式:无最低订单要求的免费送货 (ID 17)、最低订单为 100 欧元的免费送货 (ID 8),最后是 9.99 欧元的付费送货 (ID 1)。
当购买 S24 季节的产品时,我希望最低订单为 100 欧元免运费 (ID 17) 和付费运费 (ID 1) 9.99 欧元,而如果您购买 F23 季节的产品,则免费必须激活最低订单为 100 欧元的运费 (ID 8) 和 9.99 欧元的付费运费 (ID 1)。在最后一种情况下,如果您购买了至少一件 S24 赛季的产品和至少一件 F23 赛季的产品,则必须激活无最低订购量的免运费(ID 17)。
这是起始代码,但它仅适用于用于变体的属性:
add_filter( 'woocommerce_package_rates', 'hide_shipping_method_based_on_product_attribute', 10, 2 );
function hide_shipping_method_based_on_product_attribute( $rates, $package ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Product Attribute taxonomy (start always with "pa_")
$taxonomy = 'pa_season'; // Example for "Season"
// Array of Shipping method rate ID and term(s) slug(s) pairs
$data_array = array(
'free_shipping:8' => array('s24'),
'free_shipping:17' => array('f23'),
'flat_rate:1' => array('f23'),
);
// Loop through items in the current shipping package
foreach( $package['contents'] as $item ){
// Get the parent variable product if it's a product variation
$product = $item['variation_id'] > 0 ? wc_get_product($item['product_id']) : $item['data'];
// Loop through our data array
foreach( $data_array as $rate_id => $term_slugs ) {
// loop through product attributes
foreach($product->get_attributes() as $attribute ) {
if( $attribute->get_taxonomy() === $taxonomy && isset($rates[$rate_id])
&& count( array_intersect($attribute->get_slugs(), $term_slugs) ) > 0 ) {
unset($rates[$rate_id]);
}
}
}
}
return $rates;
}
以下将处理您所需的所有案例:
重要提示:您需要从两种免费送货方式设置中删除,即最小订单金额限制,因为它是在代码中处理的。
尝试以下操作:
add_filter( 'woocommerce_package_rates', 'hide_shipping_method_based_on_product_attribute', 10, 2 );
function hide_shipping_method_based_on_product_attribute( $rates, $package ) {
$free_min_subtotal = 100; // Set the minimal amount for free shipping
$taxonomy = 'pa_season'; // Product Attribute taxonomy (start always with "pa_")
$has_s24 = $has_f23 = false; // Initializing
$cart_subtotal = $package['cart_subtotal']; // Or use $package['contents_cost'] to exclude taxes
error_log('cart_subtotal: '.$package['cart_subtotal'].' | contents_cost: '.$package['contents_cost']);
// Loop through items in the current shipping package
foreach( $package['contents'] as $item ){
// Get the parent variable product if it's a product variation
$product = $item['variation_id'] > 0 ? wc_get_product($item['product_id']) : $item['data'];
// Loop through product attributes
foreach($product->get_attributes() as $attribute ) {
// Check for "Season" PA
if( $attribute->get_taxonomy() === $taxonomy ) {
$has_s24 = in_array( 's24', $attribute->get_slugs() );
$has_f23 = in_array( 'f23', $attribute->get_slugs() );
}
}
}
// Case 1 (term "s24" found)
if ( isset($rates['free_shipping:17']) && isset($rates['flat_rate:1']) && $has_s24 && ! $has_f23 ) {
if ( isset($rates['free_shipping:8']) ) {
unset($rates['free_shipping:8']); // remove Free Shipping 8
}
// Handle minimum cart amount for free shipping
if ( isset($rates['free_shipping:17']) && floatval($cart_subtotal) < $free_min_subtotal ) {
unset($rates['free_shipping:17']); // remove Free Shipping 17 (required subtotal is lower)
}
}
// Case 2 (term "f23" found)
elseif ( isset($rates['free_shipping:8']) && isset($rates['flat_rate:1']) && $has_f23 && ! $has_s24 ) {
if ( isset($rates['free_shipping:17']) ) {
unset($rates['free_shipping:17']); // remove Free Shipping 17
}
// Handle minimum cart amount for free shipping
if ( isset($rates['free_shipping:8']) && floatval($cart_subtotal) < $free_min_subtotal ) {
unset($rates['free_shipping:8']); // remove Free Shipping 8 (required subtotal is lower)
}
}
// Case 3 (terms "s24" and "f23" found)
elseif ( isset($rates['free_shipping:17']) && $has_s24 && $has_f23 ) {
if ( isset($rates['free_shipping:8']) ) {
unset($rates['free_shipping:8']); // remove Free Shipping 8
}
if ( isset($rates['flat_rate:1']) ) {
unset($rates['flat_rate:1']); // remove Flat rate 1
}
}
// Fallback: For security regarding free shipping and minimal required subtotal
elseif ( floatval($cart_subtotal) < $free_min_subtotal ) {
if ( isset($rates['free_shipping:8']) ) {
unset($rates['free_shipping:8']); // remove Free Shipping 8
}
if ( isset($rates['free_shipping:17']) ) {
unset($rates['free_shipping:17']); // remove Free Shipping 17
}
}
return $rates;
}
代码位于子主题的functions.php 文件中(或插件中)。应该可以。
注意:不要忘记清空购物车,以刷新运输缓存数据。