Get tax rate separately for every cart and order items in Woocommerce

5.5k Views Asked by At

I'd like to modify the cart display (and later the invoice) so that there is another column showing the tax and tax rate for each product. I have not found a function or a getter for the tax rate as a number, only the name, with $_product->get_tax_class(). I was looking for a function like $_product->get_tax_rate() but found none. So I wrote a terrible workaround in woocommerce/templates/cart/cart.php.

After the easy part of adding

<th class="product-tax"><?php esc_html_e( 'Tax', 'woocommerce' ); ?></th>

in Line 35, I added from Line 121:

$tax_name = apply_filters( 'woocommerce_cart_item_tax', $_product->get_tax_class(), $cart_item, $cart_item_key );
if ($tax_name == "reduced-tax-rate") $tax_rate= 7; else $tax_rate= 19;                      
$with_tax = $_product->get_price( $_product ); 
$without_tax = $with_tax/((100+$tax_rate)/100);
$tax = $with_tax-$without_tax;
$tax = $tax*$cart_item['quantity'];
$tax = number_format($tax, 2, '.', '')." €";
echo "  ".$tax." (".$tax_rate."%)";

This works for now, but only in Germany, and it would of course not survive for a very long time. So, what is the better way to do this?

Thanks!

UPDATE

Just found half of the solution:

$tax_name = apply_filters( 'woocommerce_cart_item_tax', $_product->get_tax_class(), $cart_item, $cart_item_key );
if ($tax_name == "reduced-tax-rate") $tax_rate= 7; else $tax_rate= 19;                      
echo "  ".$cart_item['line_subtotal_tax']." (".$tax_rate."%)";

$cart_item['line_subtotal_tax'] holds the value I was trying to get by calculation. Now just the name is missing..."19%" or "7%"...

1

There are 1 best solutions below

0
LoicTheAztec On

2020 October Update (removed some mistakes - Tested on WooCommerce 4.5.x version)

I suppose that woocommerce_cart_item_tax is a custom hook as I didn't find it…

The taxes depends on your settings which are one or multiple tax classes and for each tax classes:

  • all countries or/and by countries
  • all states of a country or/and by state
  • all postcodes of a country or/and by postcode
  • one or multiple tax rates.
  • (and other settings)

Now to handle taxes in a correct way you will use the WC_Tax object Class and all related methods. We will use here only country based tax rates:

 // Getting an instance of the WC_Tax object
 $wc_tax = new WC_Tax();

// Get User billing country
$billing_country = WC()->customer->get_billing_country();

// Get the item tax class (your code)
$tax_class = apply_filters( 'woocommerce_cart_item_tax', $_product->get_tax_class(), $cart_item, $cart_item_key );

// Get the related Data for Germany and "default" tax class
$tax_data = $wc_tax->find_rates( array('country' => $billing_country, 'tax_class' => $tax_class ) );

// Get the rate (percentage number)
if( ! empty($tax_data) ) {
    $tax_rate = reset($tax_data)['rate'];

    // Display it
    printf( '<span class="tax-rate">' . __("The tax rate is %s", "woocommerce") . '</span>',  $tax_rate . '%' );
}

Tested and works.


For orders (pdf invoice) it should be something very similar, where you will need to replace this line:

// Get the item tax class (your code)
$tax_class = apply_filters( 'woocommerce_cart_item_tax', $_product->get_tax_class(), $cart_item, $cart_item_key );

by something like (where $item is the instance of the WC_Order_Item_Product object):

// Get the WC_Product Object instance
$_product = $item->get_product();

// Get the item tax class
$tax_class = $_product->get_tax_class();