phpwordpresswoocommerceshipping-method

WooCommerce custom shipping costs for min required subtotal with tax calculations


I have set some Shipping methods with taxable option enabled in WooCommerce. I use this code to set up different shipping cost if spend over X amount:

// Extra discount on shipping for orders of values of above 150 or 100.
function custom_adjust_shipping_rate( $rates ) {
    $cart_subtotal = WC()->cart->subtotal;

    // Check if the subtotal is greater than value specified
    if ( $cart_subtotal >= 29.99 ) {

        // Loop through each shipping rate
        foreach ( $rates as $rate ) {

            // Store the previous cost in $cost
            $cost = $rate->cost;

            // Adjust the cost as needed
            // original shipping greater than 6 discount by 5 
            if ( $cost == 7.38 ) {
                // discount rate by 5
                $rate->cost = $cost - 2.54;
            }
            // Optional discount for other shipping rates 
            if ( $cost == 4.10 ) {
                $rate->cost = $cost - 5;
            }
        }
    }
    return $rates;
}
add_filter( 'woocommerce_package_rates', 'custom_adjust_shipping_rate', 10 );

But the problem is the tax calculations. My code doesn't handle taxes.

How can I adjust taxes from custom shipping cost?

How to enable taxes in cost calculations?

Any advice is appreciated.


Solution

  • To enable shipping taxes calculations in your code, use the following revisited code instead:

    add_filter( 'woocommerce_package_rates', 'adjust_shipping_rates_cost', 10, 2 );
    function adjust_shipping_rates_cost( $rates, $package ) {
        $min_subtotal  = 30; // Set min subtotal
        $cart_subtotal = 0; // Initializing
            
        // Loop through cart items to get items total for the current shipping package 
        foreach( $package['contents'] as $item ) {
            $cart_subtotal += $item['line_subtotal'] + $item['line_subtotal_tax'];
            // $cart_subtotal += $item['line_subtotal']; // Or without taxes
        }
    
        // Check if the subtotal is greater than specified value
        if ( $cart_subtotal < $min_subtotal ) {
            return $rates; // Exit
        }
    
        // Loop through shipping rates
        foreach ( $rates as $rate_key => $rate ) {
            $has_taxes = false; // Initializing
            $taxes     = array(); // Initializing
            $new_cost = $initial_cost = $rate->cost; // grab initial cost
    
            if ( $initial_cost == 7.38 ) {
                $new_cost -= 2.54;
            } elseif ( $initial_cost == 4.10 ) {
                $new_cost -= 5;
            }
            $rates[$rate_key]->cost = $new_cost; // Set new rate cost
    
            // Loop through taxes array (change taxes rate cost if enabled)
            foreach ($rate->taxes as $key => $tax){
                if( $tax > 0 ){
                    // Get the tax rate conversion
                    $tax_rate    = $tax / $initial_cost;
    
                    // Set the new tax cost in the array
                    $taxes[$key] = $new_cost * $tax_rate;
                    $has_taxes   = true; // Enabling tax changes
                }
            }
            // set array of shipping tax cost
            if( $has_taxes ) {
                $rates[$rate_key]->taxes = $taxes;
            }
        }
        return $rates;
    }
    

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

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