phpwoocommercecartdiscount

Change WooCommerce cart item tax rate based on the item discounted price


I want to calculate the tax based on the item price after discount.

I have two tax rates: 5% GST and 12% GST.

For products with price after discount that is less than 1000, I want to apply a tax rate of 5%.

For products with price after discount that is more than up to 1000, I want to apply a tax rate of 12%.

I have used the following code, but it doesn't alter the tax rate after applying discounts.

add_action( 'woocommerce_before_calculate_totals', 'change_cart_items_prices', 10, 1 );
function change_cart_items_prices( $cart ) {

    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;

    foreach ( $cart->get_cart() as $cart_item ) {
        // get product price
        $price = $cart_item['data']->get_price();

        // Set conditionaly based on price the tax class
        if ( $price <= 999 )
            $cart_item['data']->set_tax_class( '5% GST' ); // below 999
        if ( $price > 999 )
            $cart_item['data']->set_tax_class( '12% GST' ); // Above 999
    }
}

Solution

  • You need first to get the tax rate slugs, but not the tax name as you are actually using "5% GST" and "12% GST" which are tax names.

    The following function will display only for "administrator" user role, the correct tax rate(s) slug(s) to be used:

    add_action('wp_footer', 'display_all_tax_rates_slugs_in_the_footer', 10);
    function display_all_tax_rates_slugs_in_the_footer() {
        // Displayed only to administrator user role
        if( ! current_user_can('administrator') ) 
            return;
    
        echo '<div style="max-width:450px;">
        
        <table style="border:solid 1px #000;">
            <thead><tr><th colspan="2"><h4>Tax rates</h4></th><tr></thead>
            <tbody><tr><th>Name</th><th>Slug <i><small>(to be used)</small></i></th><tr>';
    
        foreach ( wc_get_product_tax_class_options() as $tax_rate_slug => $tax_rate_label_name ) {
            echo "<tr><td>'{$tax_rate_label_name}'</td><td><code>'{$tax_rate_slug}'</code></td></tr>"; 
        }
        echo '</tbody></table></div>';
    }
    

    something like:

    enter image description here

    Once you get the correct tax rate slug(s) remove this function.


    The following code uses the discounted item subtotal to get the item discounted price, to set different tax rate based on this item discounted price:

    add_action( 'woocommerce_before_calculate_totals', 'change_cart_items_prices', 10, 1 );
    function change_cart_items_prices( $cart ) {
    
        if ( is_admin() && ! defined( 'DOING_AJAX' ) )
            return;
    
        if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
            return;
    
        foreach ( $cart->get_cart() as $item ) {
            // Get discounted item price excluding taxes
            $price = $item['line_total'] / $item['quantity'];
    
            // Set conditionally item tax class based on discounted item price
            $item['data']->set_tax_class( $price < 1000 ? 'reduced-rate' : '' ); 
        }
    }
    

    Code goes in functions.php file of your theme (or in a plugin). Tested and works.

    Related: Set different Tax rates conditionally based on cart item prices in WooCommerce