Jump to content

[Solved] total_price_tax_excl in ps_order_detail badly rounded


hakeryk2

Recommended Posts

Hello community,

I found out that in ps_order_detail  values in total_price_tax_excl column are not correct because they are rounded for 2 places after delimeter even that they are stored with 6 places after delimeter.
Example: bad values is 430.890000 (4 zeros) instead of proper one 430.894309.
Column structure is set to 6 places after delimeter but script is passing rounded only to 2.

It is bad for me because some modules are taking values from this column and if they are multiplied by tax values I received some weird roundings.
Anyone knows where I can the code responsible for this? Which function or file?

Prestashop 1.6.1.23

Edited by hakeryk2
Solved (see edit history)
Link to comment
Share on other sites

Thanks to some good guy from polish Prestashop group on facebook I menaged to fix it. There is an issue with Cart.php and getProducts function. Problem is that PS use _PS_PRICE_COMPUTE_PRECISION_ which is by default = 2. When we change that to 6 then it is ok. I don't know it is some serious bug to fix and forge it on github but it is kinda weird.

Change this:

            switch (Configuration::get('PS_ROUND_TYPE')) {
                case Order::ROUND_TOTAL:
                    $row['total'] = $row['price_with_reduction_without_tax'] * (int)$row['cart_quantity'];
                    $row['total_wt'] = $row['price_with_reduction'] * (int)$row['cart_quantity'];
                    break;
                case Order::ROUND_LINE:
                    $row['total'] = Tools::ps_round($row['price_with_reduction_without_tax'] * (int)$row['cart_quantity'], _PS_PRICE_COMPUTE_PRECISION_);
                    $row['total_wt'] = Tools::ps_round($row['price_with_reduction'] * (int)$row['cart_quantity'], _PS_PRICE_COMPUTE_PRECISION_);
                    break;

                case Order::ROUND_ITEM:
                default:
                    $row['total'] = Tools::ps_round($row['price_with_reduction_without_tax'], _PS_PRICE_COMPUTE_PRECISION_) * (int)$row['cart_quantity'];
                    $row['total_wt'] = Tools::ps_round($row['price_with_reduction'], _PS_PRICE_COMPUTE_PRECISION_) * (int)$row['cart_quantity'];
                    break;
            }

to this
 

switch (Configuration::get('PS_ROUND_TYPE')) {
                case Order::ROUND_TOTAL:
                    $row['total'] = $row['price_with_reduction_without_tax'] * (int)$row['cart_quantity'];
                    $row['total_wt'] = $row['price_with_reduction'] * (int)$row['cart_quantity'];
                    break;
                case Order::ROUND_LINE:
                    $row['total'] = Tools::ps_round($row['price_with_reduction_without_tax'] * (int)$row['cart_quantity'], 6);
                    $row['total_wt'] = Tools::ps_round($row['price_with_reduction'] * (int)$row['cart_quantity'], _PS_PRICE_COMPUTE_PRECISION_);
                    break;

                case Order::ROUND_ITEM:
                default:
                    $row['total'] = Tools::ps_round($row['price_with_reduction_without_tax'], 6) * (int)$row['cart_quantity'];
                    $row['total_wt'] = Tools::ps_round($row['price_with_reduction'], _PS_PRICE_COMPUTE_PRECISION_) * (int)$row['cart_quantity'];
                    break;
            }


 

Link to comment
Share on other sites

Well, but it is still not fixing tax_excl in ps_orders :( Anyone? 
--------------------
EDIT: Ok, to fix ps_orders total_paid_tax_excl and total_products we need to fix in getOrderTotal in Cart.php these lines - change _PS_PRICE_DISPLAY_PRECISION_ to  because this method is used in PaymentModule.php ValidateOrder class to compute prices but it is always passed with .00 .

 

Let's start.
In PaymentModule.php we need to change in ValidateOrder function this

 

$order->total_paid_tax_excl = (float)Tools::ps_round((float)$this->context->cart->getOrderTotal(false, Cart::BOTH, $order->product_list, $id_carrier), _PS_PRICE_COMPUTE_PRECISION_);

to this
 

$order->total_paid_tax_excl = (float)Tools::ps_round((float)$this->context->cart->getOrderTotal(false, Cart::BOTH, $order->product_list, $id_carrier), 6);



In Cart.php You need to change in getOrderTotal
 

$compute_precision = $configuration->get('_PS_PRICE_COMPUTE_PRECISION_');

to

$compute_precision = 6;


 and change change this part of getOrderTotal to be like this.
 

  switch ($ps_round_type) {
                case Order::ROUND_TOTAL:
                    $products_total[$id_tax_rules_group.'_'.$id_address] += $price * (int)$product['cart_quantity'];
                    break;

                case Order::ROUND_LINE:
                    $product_price = $price * $product['cart_quantity'];
                    $products_total[$id_tax_rules_group] += Tools::ps_round($product_price, $compute_precision);
                    break;

                case Order::ROUND_ITEM:
                default:
                    $product_price = $price;
                    $products_total[$id_tax_rules_group] += Tools::ps_round($product_price, compute_precision) * (int)$product['cart_quantity'];
                    break;
            }

Also make sure that you have  return Tools::ps_round((float)$order_total, $compute_precision); at the of the getOrderTotal function.

Now let's check getProducts function from Cart.php and make sure that here You also have changed the switch function to this:

 switch (Configuration::get('PS_ROUND_TYPE')) {
                case Order::ROUND_TOTAL:
                    $row['total'] = $row['price_with_reduction_without_tax'] * (int)$row['cart_quantity'];
                    $row['total_wt'] = $row['price_with_reduction'] * (int)$row['cart_quantity'];
                    break;
                case Order::ROUND_LINE:
                    $row['total'] = Tools::ps_round($row['price_with_reduction_without_tax'] * (int)$row['cart_quantity'], 6);
                    $row['total_wt'] = Tools::ps_round($row['price_with_reduction'] * (int)$row['cart_quantity'], _PS_PRICE_COMPUTE_PRECISION_);
                    break;

                case Order::ROUND_ITEM:
                default:
                    $row['total'] = Tools::ps_round($row['price_with_reduction_without_tax'], 6) * (int)$row['cart_quantity'];
                    $row['total_wt'] = Tools::ps_round($row['price_with_reduction'], _PS_PRICE_COMPUTE_PRECISION_) * (int)$row['cart_quantity'];
                    break;
            }


To fix total_discounts_tax_excl in ps_orders you need to change in the same getOrderTotal in foreach ($cart_rules as $cart_rule) the very ending 

  // If the cart rule offers a reduction, the amount is prorated (with the products in the package)
                if ($cart_rule['obj']->reduction_percent > 0 || $cart_rule['obj']->reduction_amount > 0) {
                    $order_total_discount += Tools::ps_round($cart_rule['obj']->getContextualValue($with_taxes, $virtual_context, CartRule::FILTER_ACTION_REDUCTION, $package, $use_cache), 6);
                }
            }
            $order_total_discount = min(Tools::ps_round($order_total_discount, 6), (float)$order_total_products) + (float)$order_shipping_discount;


If You want to fix total_shipping_cost_tax_excl in ps_orders then go public function getPackageShippingCost in Cart.php and change at the very end this
 

$shipping_cost = (float)Tools::ps_round((float)$shipping_cost, (Currency::getCurrencyInstance((int)$this->id_currency)->decimals * _PS_PRICE_DISPLAY_PRECISION_));

to this
 

$shipping_cost = (float)Tools::ps_round((float)$shipping_cost, (Currency::getCurrencyInstance((int)$this->id_currency)->decimals * 6));

 

Edited by hakeryk2 (see edit history)
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...