我正在尝试在 Woocommerce 中应用复杂的运输规则。
我有基本产品:
消费 | 运费 |
---|---|
少于300 | 30$ |
300个以上 | 免费 |
但我也有一些大件产品和有特殊交货要求的产品
产品 | 运输等级 | 成本 |
---|---|---|
大盒子 | 带起重机的卡车 | 1000$ |
大盒子 | 仅限卡车 | 200$ |
Gazebo(选择1:仅限外卖) | 交付与组装 | 200$ |
Gazebo(选择2:送货及组装) | 交付与组装 | 350$ |
以下是我的运送方式
对于基本产品,一切正常,
对于大盒子也适用,如标准运输中所示。
但是,当我添加(组装运输)运输方式时,即使购物车中没有此类产品,它仍然显示为选择。
我只需要它仅在 Gazebo 位于购物车时才出现
add_filter( 'woocommerce_package_rates', 'hide_shipping_when_class_is_in_cart', 100, 2 );
函数 hide_shipping_when_class_is_in_cart( $rates, $package ) {
$free_shipping_method = 'free_shipping:13';
$shipping_classes = array('truck-crane','large-furniture','furniture-assembly');
$class_exists = false;
$cart_classes = array();
$shipping_methods = $shipping_zone->get_shipping_methods();
foreach( $package['contents'] as $cart_item )
$cart_item_class = $cart_item['data']->get_shipping_class();
if( in_array($cart_item_class , $shipping_classes ) ) {//Check if any shipping class exist
array_push($cart_classes,$cart_item_class); //push cart classes to array
$class_exists = true;
//break;
}
foreach($shipping_methods as $method){
$method_classes = $method->get_shipping_classes();
//Here i want to unset shipping methods which has no avaiable class in cart items
}
if( $class_exists )
unset( $rates[$free_shipping_method] );
return $rates;
}
我最终添加了“组装”等服务作为产品附带的选项
我的代码如下
/**
** Display Fields
*/
add_action('woocommerce_product_options_shipping', 'woocommerce_product_custom_product_service');
function woocommerce_product_custom_product_service()
{
global $woocommerce, $post;
echo '<div class="product_custom_field"><span class="wrap">';
woocommerce_wp_text_input(
array(
'id' => '_custom_product_service_label',
'placeholder' => 'Service Label',
'label' => __('Custom Service', 'woocommerce'),
)
);
woocommerce_wp_text_input(
array(
'id' => '_custom_product_service_fees',
'placeholder' => 'Service Fees',
'type' => 'number',
'custom_attributes' => array(
'step' => 'any',
'min' => '0'
)
)
);
echo '</span></div>';
}
/**
** Save Fields
*/
add_action('woocommerce_process_product_meta', 'woocommerce_product_custom_product_service_save');
function woocommerce_product_custom_product_service_save($post_id)
{
$woocommerce_custom_product_service_label = $_POST['_custom_product_service_label'];
$woocommerce_custom_product_service_fees = $_POST['_custom_product_service_fees'];
if (!empty($woocommerce_custom_product_service_label) && !empty($woocommerce_custom_product_service_fees)){
update_post_meta($post_id, '_custom_product_service_label', esc_attr($woocommerce_custom_product_service_label));
update_post_meta($post_id, '_custom_product_service_fees', esc_attr($woocommerce_custom_product_service_fees));
}elseif(empty($woocommerce_custom_product_service_label) && empty($woocommerce_custom_product_service_fees)){
update_post_meta($post_id, '_custom_product_service_label', '');
update_post_meta($post_id, '_custom_product_service_fees', '');
}
}
/**
** Product page form
*/
add_action('woocommerce_single_product_summary','add_custom_product_service_to_single_product', 2 );
function add_custom_product_service_to_single_product(){
global $product;
if( !$product->get_meta( '_custom_product_service_label' ) && !$product->get_meta( '_custom_product_service_fees' )) return;
add_action('woocommerce_before_add_to_cart_button', 'add_custom_product_service_option', 30 );
}
function add_custom_product_service_option(){
global $product;
$active_price = (float) $product->get_price();
$service_label = $product->get_meta( '_custom_product_service_label' );
$service_price = (float) $product->get_meta( '_custom_product_service_fees' );
$service_price_html = strip_tags( wc_price( wc_get_price_to_display( $product, array('price' => $service_price ) ) ) );
$active_price_html = wc_price( wc_get_price_to_display( $product ) );
$disp_price_sum_html = wc_price( wc_get_price_to_display( $product, array('price' => $active_price + $service_price ) ) );
echo '<div class="hidden-field">
<p class="form-row form-row-wide" id="service_option_field" data-priority="">
<span class="woocommerce-input-wrapper"><label class="checkbox"> ' .$service_label.' '.__("Service:", "Woocommerce") .
' <input type="checkbox" class="input-checkbox " name="service_option" id="service_option" value="1"> +' . $service_price_html .
'</label></span></p>
<input type="hidden" name="service_price" value="' . $service_price . '">
<input type="hidden" name="active_price" value="' . $active_price . '"></div>';
// Jquery: Update displayed price
?>
<script type="text/javascript">
jQuery(function($) {
var cb = 'input[name="service_option"]'
pp = 'p.price';
// On change / select a variation
$('form.cart').on( 'change', cb, function(){
if( $(cb).prop('checked') === true )
$(pp).html('<?php echo $disp_price_sum_html.__("(Assembly Included)", "Woocommerce"); ?>');
else
$(pp).html('<?php echo $active_price_html; ?>');
})
});
</script>
<?php
}
/**
** Add to Cart
*/
add_filter('woocommerce_add_cart_item_data', 'add_custom_product_service_data', 10, 3);
function add_custom_product_service_data( $cart_item_data, $product_id, $variation_id ) {
if (isset($_POST['service_option']) && !empty($_POST['service_option'])) {
$cart_item_data['new_price'] = (float) ($_POST['active_price'] + $_POST['service_price']);
$cart_item_data['service_price'] = (float) $_POST['service_price'];
$cart_item_data['active_price'] = (float) $_POST['active_price'];
foreach(WC()->cart->get_cart() as $cart_item){
if(($product_id == $cart_item['product_id']) && !empty($cart_item['service_price'])){
$unique_key = $cart_item['unique_key'];
break;
}
}
if(!empty($unique_key)){
$cart_item_data['unique_key'] = $unique_key;
}else{
$cart_item_data['unique_key'] = md5(microtime().rand());
}
return $cart_item_data;
}}
/**
** Set the new calculated cart item price
*/
add_action('woocommerce_before_calculate_totals', 'add_custom_product_service_custom_price', 20, 1);
function add_custom_product_service_custom_price($cart) {
if (is_admin() && !defined('DOING_AJAX'))
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
foreach($cart->get_cart() as $cart_item) {
if (isset($cart_item['new_price']))
$cart_item['data']->set_price((float) $cart_item['new_price']);
}
}
/**
** Display in Cart
*/
add_filter('woocommerce_get_item_data', 'display_custom_product_service_item_data', 10, 2);
function display_custom_product_service_item_data($cart_item_data, $cart_item) {
$_product = new WC_Product( $cart_item['product_id'] );
$service_label = $_product->get_meta( '_custom_product_service_label' );
if (isset($cart_item['service_price'])) {
//$service_label = get_post_meta( $cart_item['product_id'], '_custom_product_service_label' );
$cart_item_data[] = array(
'name' => $service_label .__(" Service Fees", "woocommerce"),
'value' => strip_tags( '+ ' . wc_price( wc_get_price_to_display( $cart_item['data'], array('price' => $cart_item['service_price'] ) ) ) )
);
}elseif(!empty($service_label)){
$cart_item_data[] = array(
'name' => $service_label .__(" Service Not Included", "woocommerce"),
'value' => strip_tags( '+ ' . wc_price( wc_get_price_to_display( $cart_item['data'], array('price' => $cart_item['service_price'] ) ) ) )
);
}
return $cart_item_data;
}