Override all shipping costs for a specific shippin

2019-06-06 02:07发布

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.

2条回答
兄弟一词,经得起流年.
2楼-- · 2019-06-06 02:24

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.

查看更多
爱情/是我丢掉的垃圾
3楼-- · 2019-06-06 02:44

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!

查看更多
登录 后发表回答