问题
I have a number of shipping classes with prices set in multiple shipping zones. Is it possible to detect if ANY product within the cart belongs to a specific shipping class, and if so set the shipping cost to 0 and display a message?
I would like to use this mechanism for products which require special handling and would be shipped via freight. So if a customer's order contains any of these products the shipping quote would be provided manually post-sale.
Thanks for the help.
回答1:
The following code will set all shipping cost to zero, when a specific defined shipping method is found in cart items and will display a custom notice.
The second hooked function is optional and will display the custom notice in checkout page.
You will have to temporarily "Enable debug mode" in Shipping settings under Shipping options (tab).
In the code bellow define in each function your shipping class slug and your custom notice:
// Null shipping costs for a specific shipping class and display a message
add_filter('woocommerce_package_rates', 'shipping_class_null_shipping_costs', 10, 2);
function shipping_class_null_shipping_costs( $rates, $package ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return $rates;
// HERE set your shipping class slug
$shipping_class_slug = 'extra';
$found = false;
// Loop through cart items and checking for the specific defined shipping class
foreach( $package['contents'] as $cart_item ) {
if( $cart_item['data']->get_shipping_class() == $shipping_class_slug )
$found = true;
}
// Set shipping costs to zero if shipping class is found
if( $found ){
foreach ( $rates as $rate_key => $rate ){
$has_taxes = false;
// Targetting "flat rate" and local pickup
if( 'flat_rate' === $rate->method_id || 'local_pickup' === $rate->method_id ){
// Set the cost to zero
$rates[$rate_key]->cost = 0;
// Taxes rate cost (if enabled)
foreach ($rates[$rate_key]->taxes as $key => $tax){
if( $rates[$rate_key]->taxes[$key] > 0 ){
$has_taxes = true;
// Set taxes cost to zero
$taxes[$key] = 0;
}
}
if( $has_taxes )
$rates[$rate_key]->taxes = $taxes;
}
}
// Clear duplicated notices
wc_clear_notices();
// Add a custom notice to be displayed
wc_add_notice( __('My custom shipping message here.', 'woocommerce'), 'notice' );
}
return $rates;
}
add_action( 'woocommerce_before_checkout_form', 'display_custom_shipping_message_in_checkout' );
function display_custom_shipping_message_in_checkout(){
// HERE set your shipping class slug
$shipping_class_slug = 'extra';
$found = false;
// Loop through cart items and checking for the specific defined shipping class
foreach( WC()->cart->get_cart() as $cart_item ) {
if( $cart_item['data']->get_shipping_class() == $shipping_class_slug )
$found = true;
}
if( $found ){
// Display a custom notice
wc_print_notice( __('My custom shipping message here.', 'woocommerce'), 'notice' );
}
}
Code goes in function.php file of your active child theme (or active theme). It should works.
Don't forget to disable "debug mode" in shipping settings once this has been tested once.
回答2:
Set up a Shipping Class and Shipping Method for Free Shipping, assign that Class to the product you want to offer free shipping for, and then ensure that Free Shipping Method is set at the default shipping method.
Good Luck!
来源:https://stackoverflow.com/questions/50936025/override-all-shipping-costs-for-a-specific-shipping-class-in-woocommerce