2
votes

I'm using WooCommerce version 3.0+ as well as a price by user roles plugin which gives a % discount against prices.

We have an item in the shop which is £89.55. With a 30% discount applied this becomes £62.685. If you order 6 then the value is £376.11.

The final figure is correct.

However as I have WC settings set to 2dp, the item price shows as £62.69. Therefore invoices are incorrect showing as £62.69 x 6 = £376.11.

I've thought about using woocommerce_before_calculate_totals like from here:

Dynamic cart item pricing not working on orders in WooCommerce 3.0+

My code is:

add_action( 'woocommerce_before_calculate_totals', 'adding_custom_price', 10, 1);
function adding_custom_price( $cart_obj ) {

if ( is_admin() && ! defined( 'DOING_AJAX' ) )
    return;

 foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
     $new_price = round($cart_item['data']->price,2,PHP_ROUND_HALF_UP);
     $cart_item['data']->set_price($new_price);
     #echo $new_price;
 }

}

The output from the echo $new_price is 62.69. But it seems set_price isn't working as the values in the cart are still showing as for 62.685.

So for example if I do 62.69 x 2 the subtotal is 125.37.

Any idea why set_price isn't working? I saw this:

Woocommerce: $cart_item['data']->set_price is not working inside custom plugin

But the answer on there doesn't work either.

Any help much appreciated.

1

1 Answers

4
votes

First you need to use WC_Product method get_price() as $cart_item['data'] is an instance of WC_Simple_Product.

Also you have to beware as the displayed prices in cart are already rounded by WooCommerce specific formatting functions.

So your functional code for WC 3.0+ will be:

add_action( 'woocommerce_before_calculate_totals', 'adding_custom_price', 10, 1);
function adding_custom_price( $cart ) {

    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;

    foreach ( $cart->get_cart() as $cart_item ) {
        $product_price = $cart_item['data']->get_price(); // get the price
        $rounded_price = round( $product_price, 2, PHP_ROUND_HALF_UP );
        $cart_item['data']->set_price(floatval($rounded_price));
    }
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.


You can check (test) by adding to the product price (cart item) a very little float number. You will see that the cart prices are really updated, replacing for example in the function:

$cart_item['data']->set_price( floatval( $rounded_price ) );

By

$cart_item['data']->set_price( floatval( $rounded_price + 0.2 ) );