1

I'm building a Woocommerce store and I need to get all the prices with tax included to end in zero (For example, if the original price with tax included is 1234, then I round it to 1240).

Products are imported to my website in bulk (+2800 products) but they have the price without tax. I configured the tax in woocommerce settings and I display prices with tax included in the store.

To fix the "ending in 0" problem, I created a method to change the tax value so the final price ends in 0:

// Calculate tax
function filter_woocommerce_calc_tax( $taxes, $price, $rates, $price_includes_tax, $suppress_rounding ) { 
    $key = array_search('IVA', array_column_keys($rates, 'label')); // find tax with label "IVA"
    $tax = $taxes[$key]; // get the current tax
    $subtotal = $price + $tax; // get the total
    $final = ceil($subtotal / 10) * 10; // modify the total so it ends in 0
    $new_tax = $final - $price; // calculate new tax price
    $taxes[$key] = $new_tax; // update tax in array
    return $taxes; // return new calculated taxes
};
add_filter( 'woocommerce_calc_tax', 'filter_woocommerce_calc_tax', 10, 5 ); 

It works really good, but I figured that if I change the tax price, I'm actually changing the tax rate (%) and I can't do that for legal reasons.

That's why I wanted to change the price of the product without tax instead.

I can use the same method:

$final = ceil($subtotal / 10) * 10; // modify the total so it ends in 0
$new_price = $final - $tax; // new price without tax

But I don't know what hook to use to achieve this.

Is is possible to change the price with hooks and filters?

JCAguilera
  • 944
  • 1
  • 13
  • 32

1 Answers1

1

I finally got a solution, first I created a method to calculate the prices without tax:

function get_net_sales_price($price, $tax_rate = 0) {
    $subtotal = $price + (1+$tax_rate);
    $final = ceil($subtotal / 10) * 10;
    $new_price = $final / (1+$tax_rate);
    return $new_price;
}

Then I got the taxes based on the product and customer location (thanks to this answer):

function get_tax_rates($product) {
    // Get an instance of the WC_Tax object
    $tax_obj = new WC_Tax();
    // Get the tax data from customer location and product tax class
    return $tax_obj->find_rates(array(
        'country'   => WC()->customer->get_shipping_country() ? WC()->customer->get_shipping_country() : WC()->customer->get_billing_country(),
        'state'     => WC()->customer->get_shipping_state() ? WC()->customer->get_shipping_state() : WC()->customer->get_billing_state(),
        'city'      => WC()->customer->get_shipping_city() ? WC()->customer->get_shipping_city() : WC()->customer->get_billing_city(),
        'postcode'  => WC()->customer->get_shipping_city() ? WC()->customer->get_shipping_city() : WC()->customer->get_billing_city(),
        'tax_class' => $product->get_tax_class()
    ));
}

And finally I use a hook to return the correct price for the product (woocommerce then adds the tax when needed):

function filter_woocommerce_price($price, $product) {
    $rates = get_tax_rates($product);
    // Finally we get the tax rate and calculare net sales price:
    if( ! empty($rates) ) {
        $key = array_search('IVA', array_column_keys($rates, 'label'));
        return get_net_sales_price($price, $rates[$key]['rate'] / 100);
    } else {
        return get_net_sales_price($price);
    }
}
add_filter('woocommerce_product_get_price', 'filter_woocommerce_price', 99, 2 );
add_filter('woocommerce_product_get_regular_price', 'filter_woocommerce_price', 99, 2 );
add_filter('woocommerce_product_variation_get_regular_price', 'filter_woocommerce_price', 99, 2 );
add_filter('woocommerce_product_variation_get_price', 'filter_woocommerce_price', 99, 2 );

Now I'm getting the right tax amount, and also all the product prices end in 0.

JCAguilera
  • 944
  • 1
  • 13
  • 32