Reputation: 157
In WooCommerce I can only enter the shipping price excluding tax. How can I make the given price including tax?
The settings to show 'prices including tax' only applies to the products.
So for example if I enter in the settings shipping €1,00 It shows on the checkout €1,21 (0,21 = tax)
It should be €1,00 (incl. 0,21 tax) (Don't care about the calculation here, it's just an example)
Thanks if anybody has a solution or function for this.
Upvotes: 6
Views: 10521
Reputation: 101
As others have mentioned WooCommerce devs have hardcoded the calculation of shipping tax to be exclusive of tax. To change this, first adjust the shipping tax by using the woocommerce_calc_shipping_tax
:
function calculateShippingInclusiveOfTax($taxes, $shippingPrice, $taxRates)
{
// If site-wide configuration is inclusive of taxes calculate taxes as such
if (wc_prices_include_tax()) {
return WC_Tax::calc_inclusive_tax($shippingPrice, $taxRates);
}
// Reaching this point means side-wide configuration is exclusive of tax, therefore return shipping taxes
// as such
return $taxes;
}
add_filter('woocommerce_calc_shipping_tax', 'calculateShippingInclusiveOfTax', 10, 3);
After doing this, the Shipping Taxes will display correctly on the Cart. However, WooCommerce internally uses Shipping cost without Tax + Calculated Tax (either from inclusive price or exclusive price)
to come up with the Shipping Tax Total, and up until now, we haven't changed the Shipping cost without Tax value anywhere. Because of this, our total will still be incorrect. So we have to either change the "Shipping cost without Tax" value or just remove the Total Shipping Tax from the Cart Total once everything has been summed. As you can see, the latter is easier, so we do that by using the woocomerce_calculated_total
hook:
function fixCartTotalAmountCalculationDueToMakingShippingInclusiveOfTax($total, $cart)
{
if (wc_prices_include_tax()) {
$total -= $cart->shipping_tax_total;
}
return $total;
}
add_filter('woocommerce_calculated_total', 'fixCartTotalAmountCalculationDueToMakingShippingInclusiveOfTax', 10, 2);
Refer to line 865 of wp-content/plugins/woocommerce/includes/class-wc-cart-totals.php
for more information.
First, the woocommerce_calculate_totals
hook is an action instead of a filter. Modifying values is not the intended use of an action, a filter should be used instead.
Putting that aside, the error is that the Cart Totals have already been calculated at the point where the action is executed based on the sum Shipping cost without Tax + Calculated Tax
, so the correct operation would be $cart->total - $cart->shipping_tax_total
.
Upvotes: 0
Reputation: 5932
A possible alternative solution is to manually adjust the pricing for shipping so it becomes VAT exclusive. I.e. if shipping incl 20% tax is 6 EUR, adjust it to 5 EUR. Note that this only works if your tax rate is the same for all shipping destinations.
Upvotes: 1
Reputation: 638
A year after the original question I just hit the same problem and there is not a lot out there to help.
On investigation this turns out to be a problem with the shipping tax calculation from "class-wc-tax.php" which as you can see below hard codes shipping to be tax exclusive.
/**
* Calculate the shipping tax using a passed array of rates.
*
* @param float Price
* @param array Taxation Rate
* @return array
*/
public static function calc_shipping_tax( $price, $rates ) {
$taxes = self::calc_exclusive_tax( $price, $rates );
return apply_filters( 'woocommerce_calc_shipping_tax', $taxes, $price, $rates );
}
It turns out that for some reason that woo have pushed this assumption of shipping being tax exclusive through their down stream tax calculations so you will need to add a couple of filters to your functions.php in order to fix things.
1) The first to calculate the inclusive tax
function yourname_fix_shipping_tax( $taxes, $price, $rates) {
if(wc_prices_include_tax()){
return WC_Tax::calc_inclusive_tax( $price, $rates );
}
return $taxes;
}
add_filter( 'woocommerce_calc_shipping_tax', 'yourname_fix_shipping_tax',10,3);
Careful that you don't forget the 10,3 at the end of add_filter. The 10 is the priority which I have left at the default. The 3 is the number of arguments. You really need this one - the filter displays behavioral problems if you leave it out.
2) The second filter is to fix the totals in downstream calculations.
function yourname_fix_totals( $cart) {
if(wc_prices_include_tax()){
$cart->shipping_total -= $cart->shipping_tax_total;
}
}
add_filter( 'woocommerce_calculate_totals', 'yourname_fix_totals');
The first filter is fairly straight forward - it simply recalculates the tax in the inclusive case.
The second filter is to deal with woo pushing the assumption of exclusive tax further into their tax calculations.
Around line 1396 of 'class-wc-cart.php' we have the following.
// Grand Total - Discounted product prices, discounted tax, shipping cost + tax
$this->total = max( 0, apply_filters( 'woocommerce_calculated_total', round( $this->cart_contents_total + $this->tax_total + $this->shipping_tax_total + $this->shipping_total + $this->fee_total, $this->dp ), $this ) );
What this wants to do is add the shipping tax to the shipping total which we don't want it to do - and they have hard coded it in......
What we will do is use the conveniently located 'woocommerce_calculate_totals' filter() a few lines above around line 1392 to subtract the shipping tax from the total before it all gets added up using the second filter above.
// Allow plugins to hook and alter totals before final total is calculated
do_action( 'woocommerce_calculate_totals', $this );
In an earlier cut of this post from a few weeks back I was worried that this would be a can of worms - and it is turning out to be just that now that I can test things.
So huge caveat here. Test your final tax totals and subtotals thoroughly - this is no longer possibly a risk. Woo have made the assumption of tax exclusive shipping and have pushed it through their downstream calculations. Unfortunately you will have to pay tax to your respective governments even if there was a bug in you code.
Remember also when testing that when you change from exclusive to inclusive taxes in woocommerce settings that old prices are not affected, so you may need to use clean test data.
With all that said so far it is looking ok for me, but in my scenario I am bypassing large amounts of woo - I am not using any of their front end code which means I may not have found other places impacted by the assumption of tax exclusive shipping.
Upvotes: 7