phpwordpresswoocommerceshipping-method

Set specific taxable shipping rate cost to 0 based on cart subtotal in WooCommerce


With following code I'm able for specific shipping rate method (here 'easypack_parcel_machines') to set the cost to 0, when cart subtotal is up to a specific amount (here 150 PLN):

function override_inpost_cost( $rates, $package ) {
    // Make sure paczkomaty is available
    if ( isset( $rates['easypack_parcel_machines'] ) ) {
        // Current value of the shopping cart
        $cart_subtotal = WC()->cart->subtotal;
        // Check if the subtotal is greater than 150pln
        if ( $cart_subtotal >= 150 )    {
            // Set the cost to 0pln
            $rates['easypack_parcel_machines']->cost = 0;

        }
    }
    
    return $rates;
}

add_filter( 'woocommerce_package_rates', 'override_inpost_cost', 10, 2 );

But the problem is that shipping tax original cost remains, even if 'easypack_parcel_machines' shipping method rate cost is set to zero its original cost (as it is taxable).

How to change the code so if 'easypack_parcel_machines' shipping method rate cost is set to 0 the tax will also be set to zero?


Solution

  • Note: As cart can be split into multiple shipping packages by some plugins or some custom code, the correct way is to get the subtotal of related cart items included in the current shipping package.

    What is missing in your code, is to set the taxes to zero as follows:

    add_filter( 'woocommerce_package_rates', 'override_inpost_shipping_method_cost', 10, 2 );
    function override_inpost_shipping_method_cost( $rates, $package ) {
        $targeted_shipping_rate_id = 'easypack_parcel_machines'; // <== Define shipping method rate Id
        
        // Make sure that our shipping rate is available
        if ( isset( $rates[$targeted_shipping_rate_id] ) ) {
            $cart_subtotal_incl_tax = 0; // Initializing
    
            // Get cart items subtotal for the current shipping package
            foreach( $package['contents'] as $cart_item ) {
                $cart_subtotal_incl_tax += $cart_item['line_subtotal'] + $cart_item['line_subtotal_tax'];
            }
            
            // Check if the subtotal is greater than 150pln
            if ( $cart_subtotal_incl_tax >= 150 )    {
                // Set the cost to 0pln
                $rates[$targeted_shipping_rate_id]->cost = 0;
    
                $taxes = array(); // Initializing
    
                // Loop through the shipping method rate taxes array
                foreach( $rates[$targeted_shipping_rate_id]->taxes as $key => $tax_cost ) {
                    $taxes[$key] = 0; // Set each tax to Zero
                }
    
                if ( ! empty($taxes) ) {
                    $rates[$targeted_shipping_rate_id]->taxes = $taxes; // Set back "zero" taxes array
                }
            }
        }
    
        return $rates;
    }
    

    Code goes in functions.php file of the active child theme (or active theme). It should works.

    Note: Don't forget to empty your cart to refresh shipping cached data.