php - Show single product prices with and without VAT in WooCommerce

I'm trying to show price with and without VAT on every Single Product page in a WooCommerce store.

I already done it for variable products with the script below, thanks to the WooCommerce_available_variation hook:

add_filter( 'woocommerce_available_variation', 'my_variation', 10, 3);
function my_variation( $data, $product, $variation ) {
    $data['price_html'] = "<bdi><span class='inc-vat-price'></span>" . woocommerce_price($variation->get_price_including_tax()) . "</bdi><br>";
    $data['price_html'] .= "<bdi><span class='ex-vat-price'>Tax Free - </span>". woocommerce_price($variation->get_price_excluding_tax()) . "</bdi>" ;
    return $data;
}

Instead, for a Single Product, I haven't found any solution.

By modifying the Price.php file of the Single Product in WooCommerce, the price without Vat is repeated also in the variable products. In this case I have used the code:

$product->get_price_excluding_tax()

What is a possible solution to this problem?

Answer

Solution:

Your actual code for WooCommerce_available_variation is really outdated since a while:

  • The function woocommerce_price() is replaced by wc_price() function
  • The method get_price_including_tax() is replaced by wc_get_price_including_tax() function
  • The method get_price_excluding_tax() is replaced by wc_get_price_excluding_tax() function

Now you could have instead a unique function for simple products, variable products and product variations html formatted prices, that will handle also on sale price, displaying prices with and without taxes.

So the following will replace your code and will work for simple products, variable products and product variations displaying including and excluding prices in a custom formatting way (as you did on your code), on single product pages only:

add_filter('woocommerce_get_price_html', 'display_prices_incl_and_excl_taxes', 100, 2 );
function display_prices_incl_and_excl_taxes( $price_html, $product ) {
    global $woocommerce_loop;

    // On single product pages only (and not on any product loop)
    if( isset($woocommerce_loop['total']) && $woocommerce_loop['total'] == 0
    && isset($woocommerce_loop['total']) && empty($woocommerce_loop['name']) ) {

        // For simple products and products variations
        if( $product->is_type('simple') || $product->is_type('variation') ) {
            // On sale products
            if( $product->is_on_sale() ) {
                $regular_price_incl_tax = wc_get_price_including_tax( $product, array( 'price' => $product->get_regular_price() ) );
                $price_incl_tax_html    = wc_format_sale_price( $regular_price_incl_tax, wc_get_price_including_tax( $product ) );
                $regular_price_excl_tax = wc_get_price_excluding_tax( $product, array( 'price' => $product->get_regular_price() ) );
                $price_excl_tax_html    = wc_format_sale_price( $regular_price_excl_tax, wc_get_price_excluding_tax( $product ) );
            }
            // Not on sale
            else {
                $price_incl_tax_html = wc_price( wc_get_price_including_tax( $product ) );
                $price_excl_tax_html = wc_price( wc_get_price_excluding_tax( $product ) );
            }
        }
        // variable pproducts
        elseif( $product->is_type('variable') ) {
            $prices = $product->get_variation_prices( true );

            if ( ! empty( $prices['price'] ) ) {
                $act_keys = array_keys($prices['price']);
                $reg_keys = array_keys($prices['regular_price']);

                $min_price_incl_tax = wc_get_price_including_tax( wc_get_product(reset($act_keys)));
                $max_price_incl_tax = wc_get_price_including_tax( wc_get_product(end($act_keys)));

                $min_price_excl_tax = wc_get_price_excluding_tax( wc_get_product(reset($act_keys)));
                $max_price_excl_tax = wc_get_price_excluding_tax( wc_get_product(end($act_keys)));

                $min_reg_price_jncl_tax = wc_get_price_including_tax( wc_get_product(reset($reg_keys)));
                $max_reg_price_incl_tax = wc_get_price_including_tax( wc_get_product(end($reg_keys)));

                $min_reg_price_excl_tax = wc_get_price_excluding_tax( wc_get_product(reset($reg_keys)));
                $max_reg_price_excl_tax = wc_get_price_excluding_tax( wc_get_product(end($reg_keys)));

                if ( $min_price_excl_tax !== $max_price_excl_tax ) {
                    $price_incl_tax_html = wc_format_price_range( $min_price_incl_tax, $max_reg_price_incl_tax );
                    $price_excl_tax_html = wc_format_price_range( $min_price_excl_tax, $max_reg_price_excl_tax );
                }
                elseif ( $product->is_on_sale() && $min_reg_price_excl_tax === $max_reg_price_excl_tax ) {
                    $price_incl_tax_html = wc_format_sale_price( wc_price( $max_reg_price_incl_tax ), wc_price( $min_price_incl_tax ) );
                    $price_excl_tax_html = wc_format_sale_price( wc_price( $max_reg_price_excl_tax ), wc_price( $min_price_excl_tax ) );
                }
                else {
                    $price_incl_tax_html = wc_price( $min_price_incl_tax );
                    $price_excl_tax_html = wc_price( $min_price_excl_tax );
                }
            }
        }
        if ( isset($price_incl_tax_html) && isset($price_excl_tax_html) ) {
            $price_html  = '<bdi><span class="inc-vat-price"></span>' . $price_incl_tax_html . '<bdi><br>';
            $price_html .= '<bdi><span class="ex-vat-price">'. __("Tax Free") . ' - </span>' . $price_excl_tax_html . '<bdi><br>';
            $price_html .= $product->get_price_suffix();
        }
    }
    return $price_html;
}

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


This code will not handle variable product price range.

Source