Search code examples
phpwordpresswoocommerceproduct

Custom formatted min price including tax for specific WooCommerce Variable Product


I'm trying to change the price for a specific product so that it shows the price with VAT (as opposed to other products where the price is shown without VAT)

I have managed to get this to work with the variable products themselves, by using the following code from https://tomjesch.com/display-woocommerce-products-with-and-without-tax/

function edit_selected_variation_price( $data, $product, $variation ) {
    if(is_singular('product') && $product->get_id() == 68719 ) {
    $price = $variation->price;
    $price_incl_tax = $price + round($price * ( 20 / 100 ), 2);  
    $price_incl_tax = number_format($price_incl_tax, 2, ",", ".");
    $price = number_format($price, 2, ",", ".");
        $display_price = '<span class="price">';
        $display_price .= '<span class="amount">£ ' . $price_incl_tax .'<small class="woocommerce-price-suffix"> incl VAT</small></span>';
        $display_price .= '</span>';
    $data['price_html'] = $display_price;
    }
    return $data;
}
add_filter( 'woocommerce_available_variation', 'edit_selected_variation_price', 10, 3);

This works when an option is chosen. However, before an option is chosen, there is a price that says FROM: £xxx which I now also want to change to say "FROM: £xxx inc VAT"

However, I can't seem to do anything to change it. So I have added the following to setup the html for the price:

function cw_change_product_html( $price_html, $product ) {
 if ( $product->get_id() == 68719 ) {
     $price_incl_tax = $product->price + round($price * ( 20 / 100 ), 2);  
    $price_incl_tax = number_format($price_incl_tax, 2, ",", ".");
 $price_html = '<span class="amount">From ' . $price_incl_tax . 'incl VAT</span>';
 }
 echo $price_html;
}

And then I tried using these three different hooks.

add_filter( 'woocommerce_get_price_html_from_to', 'cw_change_product_html', 10, 2 );
add_filter( 'woocommerce_get_price_html', 'cw_change_product_html', 10, 2 );
add_filter('woocommerce_variable_price_html', 'cw_change_product_html', 10, 2);

Only the second one seems to trigger the code but then it outputs all of the prices for all the different variants.

Do I need to use a different hook or is there a way I can run the above code once?


Solution

  • There are some mistakes in your code. woocommerce_variable_price_html is best hook to be used. Also instead of using custom tax calculations, you can use WC_Tax methods to get dynamically the tax amount. Finally wc_price() is the formatted price function to be used in WooCommerce.

    The code:

    add_filter( 'woocommerce_variable_price_html', 'filter_wc_variable_price_html', 10, 2 );
    function filter_wc_variable_price_html( $price_html, $product ) {
        // only for variable product 68719
        if( $product->get_id() != 68719 )
            return $price_html;
    
        $min_price = $product->get_variation_price( 'min' );
        $tax_rates = WC_Tax::get_rates( $product->get_tax_class() );
        $taxes     = WC_Tax::calc_tax( $min_price, $tax_rates, false );
    
        return sprintf(
            __( 'From %s %s', 'woocommerce' ),
            wc_price( $min_price + array_sum( $taxes ) ),
            '<small class="woocommerce-price-suffix">' . __( 'incl VAT', 'woocommerce' ) . '</small>'
        );
    }
    

    As your other code is a bit outdated and complicated, you can try the following instead:

    add_filter( 'woocommerce_available_variation', 'filter_wc_available_variation_price_html', 10, 3);
    function filter_wc_available_variation_price_html( $data, $product, $variation ) {
        // only for variable product 68719
        if( $product->get_id() != 68719 )
            return $data;
    
        $price     = $data['display_price'];
        $tax_rates = WC_Tax::get_rates( $variation->get_tax_class() );
        $taxes     = WC_Tax::calc_tax( $price, $tax_rates, false );
    
        $data['price_html'] = sprintf( '%s %s',
            wc_price( $price + array_sum( $taxes ) ),
            '<small class="woocommerce-price-suffix">' . __( 'incl VAT', 'woocommerce' ) . '</small>'
        );
    
        return $data;
    }
    

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