ruisonika Posted November 9, 2020 Share Posted November 9, 2020 Hello i am stuck with a problem on round method in prestashop 1.6. In shopping cart after choose shipping method, in last step (5) of checkout i have: the sum of products without tax - ok the shipping without tax - ok the subtotal (products + shipp) without tax - ok the total tax - wrong the total cart - wrong Example: product price 32,90 euros x 1 total products - 32,90 euros total shipp - 4,50 euros sub total - 37,40 euros total tax - 8,61 euros (it should be 8,60) total of order - 46,01 (and it should be 46,00 euros) How can i fix it? Link to comment Share on other sites More sharing options...
Guest Posted November 9, 2020 Share Posted November 9, 2020 This view is correct. Change the display administration to 3 decimal places. Then you will see the difference. If you have rounding to two tenths and the sum is eg 8.616235 then the rounding result is correct. Link to comment Share on other sites More sharing options...
EvaF Posted November 9, 2020 Share Posted November 9, 2020 (edited) Wrong proposal - correct bellow imho all values are rounded to 2 decimals. (the first three values come from product price or shipping price and therefore are seemingly rounded to 1 decimal. Change the configuration value "PS_PRICE_DISPLAY_PRECISION" from the value 2 to value 1 Edited November 9, 2020 by EvaF (see edit history) Link to comment Share on other sites More sharing options...
Guest Posted November 9, 2020 Share Posted November 9, 2020 (edited) And the result will be 8,6 without a zero at the end or am I wrong? Edited November 9, 2020 by Guest (see edit history) Link to comment Share on other sites More sharing options...
Guest Posted November 9, 2020 Share Posted November 9, 2020 I wasn't wrong, that's right Link to comment Share on other sites More sharing options...
EvaF Posted November 9, 2020 Share Posted November 9, 2020 Yes, you are right I didn't read displayPrice to the end and expected that they distinguish in format $currency->decimals and $c_decimals = (int)$currency->decimals * _PS_PRICE_DISPLAY_PRECISION_; so only one option that comes on my mind is override Tools::displayPrice Link to comment Share on other sites More sharing options...
Guest Posted November 9, 2020 Share Posted November 9, 2020 For Prestashop 1.6 I programmed a module that can round prices by currency, language, e-shop .... 😉 Link to comment Share on other sites More sharing options...
Guest Posted November 9, 2020 Share Posted November 9, 2020 Just now, EvaF said: Yes, you are right I didn't read displayPrice to the end and expected that they distinguish in format $currency->decimals and $c_decimals = (int)$currency->decimals * _PS_PRICE_DISPLAY_PRECISION_; so only one option that comes on my mind is override Tools::displayPrice In Prestashop 1.6 the display is a bit more complicated than in 1.7. Link to comment Share on other sites More sharing options...
Guest Posted November 9, 2020 Share Posted November 9, 2020 (edited) 😁 I solved it in the Czech forum: 😎 https://www.prestashop.com/forums/topic/1034842-zaokrouhlovani-cen/ switch ($c_format) { case 1: $ret = $c_char.$blank.number_format($price, $c_decimals, '.', ','); break; case 2: $ret = number_format($price, $c_decimals, ',', ' ').$blank.$c_char; break; case 3: $ret = $c_char.$blank.number_format($price, $c_decimals, ',', '.'); break; case 4: $ret = number_format($price, $c_decimals, '.', ',').$blank.$c_char; break; case 5: $ret = $c_char.$blank.number_format($price, $c_decimals, '.', "'"); break; } Edited November 9, 2020 by Guest (see edit history) Link to comment Share on other sites More sharing options...
EvaF Posted November 9, 2020 Share Posted November 9, 2020 (edited) public static function displayPrice($price, $currency = null, $no_utf8 = false, Context $context = null) { if (!is_numeric($price)) { return $price; } if (!$context) { $context = Context::getContext(); } if ($currency === null) { $currency = $context->currency; } elseif (is_int($currency)) { $currency = Currency::getCurrencyInstance((int)$currency); } if (is_array($currency)) { $c_char = $currency['sign']; $c_format = $currency['format']; // change $c_decimals = (int)$currency['decimals']; $c_blank = $currency['blank']; } elseif (is_object($currency)) { $c_char = $currency->sign; $c_format = $currency->format; // change $c_decimals = (int)$currency->decimals ; $c_blank = $currency->blank; } else { return false; } // change $c_decimalsrounded = (int)$c_decimals ; // =currency decimals (=1) $c_decimals = (int)$c_decimals * _PS_PRICE_DISPLAY_PRECISION_; // display precison (= 1 * 2) $blank = ($c_blank ? ' ' : ''); $ret = 0; if (($is_negative = ($price < 0))) { $price *= -1; } // changed $price = Tools::ps_round($price, $c_decimalsrounded); /* * If the language is RTL and the selected currency format contains spaces as thousands separator * then the number will be printed in reverse since the space is interpreted as separating words. * To avoid this we replace the currency format containing a space with the one containing a comma (,) as thousand * separator when the language is RTL. * * TODO: This is not ideal, a currency format should probably be tied to a language, not to a currency. */ if (($c_format == 2) && ($context->language->is_rtl == 1)) { $c_format = 4; } switch ($c_format) { /* X 0,000.00 */ case 1: $ret = $c_char.$blank.number_format($price, $c_decimals, '.', ','); break; /* 0 000,00 X*/ case 2: $ret = number_format($price, $c_decimals, ',', ' ').$blank.$c_char; break; /* X 0.000,00 */ case 3: $ret = $c_char.$blank.number_format($price, $c_decimals, ',', '.'); break; /* 0,000.00 X */ case 4: $ret = number_format($price, $c_decimals, '.', ',').$blank.$c_char; break; /* X 0'000.00 Added for the switzerland currency */ case 5: $ret = number_format($price, $c_decimals, '.', "'").$blank.$c_char; break; } if ($is_negative) { $ret = '-'.$ret; } if ($no_utf8) { return str_replace('€', chr(128), $ret); } return $ret; } something like that !!!!and keep the PS_PRICE_DISPLAY_PRECISION at value = 2 to be true I would change also Cart.php (line 3052) // from // $shipping_cost = (float)Tools::ps_round((float)$shipping_cost, (Currency::getCurrencyInstance((int)$this->id_currency)->decimals * _PS_PRICE_DISPLAY_PRECISION_)); // to $shipping_cost = (float)Tools::ps_round((float)$shipping_cost, (Currency::getCurrencyInstance((int)$this->id_currency)->decimals )); and OrderInvoice.php (line 560) // from // $row['ecotax_tax_incl'] = Tools::ps_round($row['ecotax_tax_excl'] + ($row['ecotax_tax_excl'] * $row['rate'] / 100), _PS_PRICE_DISPLAY_PRECISION_); // $row['ecotax_tax_excl'] = Tools::ps_round($row['ecotax_tax_excl'], _PS_PRICE_DISPLAY_PRECISION_); // to $row['ecotax_tax_incl'] = Tools::ps_round($row['ecotax_tax_excl'] + ($row['ecotax_tax_excl'] * $row['rate'] / 100), Currency::getCurrencyInstance((int)$this->id_currency)->decimals ); $row['ecotax_tax_excl'] = Tools::ps_round($row['ecotax_tax_excl'], Currency::getCurrencyInstance((int)$this->id_currency)->decimals ); Edited November 9, 2020 by EvaF (see edit history) Link to comment Share on other sites More sharing options...
EvaF Posted November 9, 2020 Share Posted November 9, 2020 3 minutes ago, Guest said: 😁 I solved it in the Czech forum: 😎 https://www.prestashop.com/forums/topic/1034842-zaokrouhlovani-cen/ I didn't deeply study this problem - but i think, that these three changes in Tools::displayPrice should be enough. Am I wrong? Link to comment Share on other sites More sharing options...
Guest Posted November 9, 2020 Share Posted November 9, 2020 (edited) or just two lines 😉 Just add to case $add_zero. 😊 $add_zero = ''; if ($c_decimals == '1') {$add_zero = '0';} switch ($c_format) { case 1: $ret = $c_char.$blank.number_format($price, $c_decimals, '.', ',').$add_zero; break; case 2: $ret = number_format($price, $c_decimals, ',', ' ').$add_zero.$blank.$c_char; break; case 3: $ret = $c_char.$blank.number_format($price, $c_decimals, ',', '.').$add_zero; break; case 4: $ret = number_format($price, $c_decimals, '.', ',').$add_zero.$blank.$c_char; break; case 5: $ret = $c_char.$blank.number_format($price, $c_decimals, '.', "'").$add_zero; break; } Edited November 9, 2020 by Guest (see edit history) Link to comment Share on other sites More sharing options...
EvaF Posted November 9, 2020 Share Posted November 9, 2020 My mistake - I have fixed it in response above Link to comment Share on other sites More sharing options...
ruisonika Posted November 9, 2020 Author Share Posted November 9, 2020 (edited) 33 minutes ago, EvaF said: My mistake - I have fixed it in response above Hello @EvaF and @Guest thanks for all your hell. But with your income the total is wrong anyway, so lets see my image from cart. All the math with total product with shippment (all without tax) is right but when the tax field comes it blows all I'm in Portugal and in this client all product and shippment is 23% tax. So the math is: Total Tax = [Total products + shippement (without tax)] * 0.23 (and the problem is in here with round prestashop*) Total Order = [Total products + shippement (without tax)] + Total Tax * in math, rounds are made like (let's say 2 decimal) 1,234 it becames 1,23 1,235 it becames 1,24 So 3 decimal if is 5 or more, 2 decimal is up...and 3 decimal goes away So 3 decimal if is 4 or less, 2 decimal stays the same...and 3 decimal goes away If you have any ideias please help i'm all messed up It also can be hardcoded, because i only will work with tax 23% I've implemented @EvaF code and this is the result.... In tax field where is 16,20 it should be 16,17 because 70,30*0.23= 16,169 (and round it will be 16,17) Edited November 9, 2020 by ruisonika (see edit history) Link to comment Share on other sites More sharing options...
EvaF Posted November 9, 2020 Share Posted November 9, 2020 in the case of tax try to check configuration 'PS_ROUND_TYPE' there are three options: const ROUND_ITEM = 1; const ROUND_LINE = 2; const ROUND_TOTAL = 3; and results are rounded to PS_PRICE_DISPLAY_PRECISION places Link to comment Share on other sites More sharing options...
ruisonika Posted November 9, 2020 Author Share Posted November 9, 2020 11 minutes ago, EvaF said: in the case of tax try to check configuration 'PS_ROUND_TYPE' there are three options: const ROUND_ITEM = 1; const ROUND_LINE = 2; const ROUND_TOTAL = 3; and results are rounded to PS_PRICE_DISPLAY_PRECISION places I've sellect all one by one and the result is always wrong i have no more ideias Link to comment Share on other sites More sharing options...
EvaF Posted November 9, 2020 Share Posted November 9, 2020 (edited) the number of decimals for round of tax is set at the line 1430 in the Cart.php $compute_precision = $configuration->get('_PS_PRICE_COMPUTE_PRECISION_'); strange thing is, that I don't have set it. if I am not wrong, it means that in my case is $compute_precision set to 0 (decimal places) therefore check, plz your value of '_PS_PRICE_COMPUTE_PRECISION_' and if it is not set in ps_configuration, set it BTW - I am sorry - I don't still understand to how many decimal places do you want to round Edited November 9, 2020 by EvaF (see edit history) Link to comment Share on other sites More sharing options...
Guest Posted November 9, 2020 Share Posted November 9, 2020 I don't understand it either. In the first post he writes that he wants to round it and then he writes that he does not want to round it. VAT should always be a decimal number and the total amount may be rounded. Then another item is added and this is called a penny call. So there will be an amount either positive or negative. Link to comment Share on other sites More sharing options...
ruisonika Posted November 9, 2020 Author Share Posted November 9, 2020 1 hour ago, Guest said: I don't understand it either. In the first post he writes that he wants to round it and then he writes that he does not want to round it. VAT should always be a decimal number and the total amount may be rounded. Then another item is added and this is called a penny call. So there will be an amount either positive or negative. In Portugal we work with prices with 2 decimal, and way to round it is the following, lets work with this numbers 32,90 + 4,50 _______ 37,40 *0,23=8,602 (round it will be 8,60 but prestashop says that is 8,61; it only be 8,61 if the result it was 8,605 or higher) May sense to you? Link to comment Share on other sites More sharing options...
ruisonika Posted November 9, 2020 Author Share Posted November 9, 2020 If the digit in the next smallest place value is less than five (0, 1, 2, 3, or 4), you leave the digit you want to round to as-is. Any digits after that number (including the next smallest place value you just looked at) become zeros, or drop-off if they're located after the decimal point. If the next smallest place value is greater than or equal to five (5, 6, 7, 8, or 9), you increase the value of the digit you're rounding to by one (+1). Just like before, any remaining digits before the decimal point become zeros, and any that are after the decimal point are dropped. Link to comment Share on other sites More sharing options...
EvaF Posted November 10, 2020 Share Posted November 10, 2020 ok, in your case should be Configuration PS_PRICE_COMPUTE_PRECISION = 2 Configuration PS_ROUND_TYPE = 3 Configuration PS_PRICE_DISPLAY_PRECISION = 2 and cart.php without my changes plz check your values Link to comment Share on other sites More sharing options...
Guest Posted November 10, 2020 Share Posted November 10, 2020 14 minutes ago, EvaF said: ok, in your case should be Configuration PS_PRICE_COMPUTE_PRECISION = 2 Configuration PS_ROUND_TYPE = 3 Configuration PS_PRICE_DISPLAY_PRECISION = 2 and cart.php without my changes plz check your values ?????? PS_PRICE_COMPUTE_PRECISION ?????? Why are you still nonsense here? Test yourself in Prestashop 1.6.1.x to see if there are configurations that you still write here. He is an ordinary user, he does not know the programming jargon and does not know where to change. It is better for such users to upload images. This way you will confuse the user so much that he will not even know what he has already done, what changes he should return, etc. SELECT * FROM `ps_configuration` WHERE `name` LIKE ('PS_PRICE_%') OR `name` LIKE ('PS_ROUND_%') Link to comment Share on other sites More sharing options...
EvaF Posted November 10, 2020 Share Posted November 10, 2020 yes I have written about it - I don't have "PS_PRICE_COMPUTE_PRECISION" in Configuration too... but P1.6 works with it and rounds tax to PS_PRICE_COMPUTE_PRECISION Cart.php line 1419 public function getOrderTotal($with_taxes = true, $type = Cart::BOTH, $products = null, $id_carrier = null, $use_cache = true) { ... $compute_precision = $configuration->get('_PS_PRICE_COMPUTE_PRECISION_'); 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 = /*$with_taxes ? $tax_calculator->addTaxes($price) : */$price; $products_total[$id_tax_rules_group] += Tools::ps_round($product_price, $compute_precision) * (int)$product['cart_quantity']; break; } } ... return Tools::ps_round((float)$order_total, $compute_precision); } Link to comment Share on other sites More sharing options...
Guest Posted November 10, 2020 Share Posted November 10, 2020 (edited) Yes, I understand that now. In phpMyAdmin -> SQL query: INSERT INTO `ps_configuration` (`id_configuration`, `id_shop_group`, `id_shop`, `name`, `value`, `date_add`, `date_upd`) VALUES (NULL, NULL, NULL, 'PS_PRICE_COMPUTE_PRECISION', '2', '2020-11-10 00:00:00', '2020-11-10 00:00:00'); UPDATE `ps_configuration` SET `value` = '3' WHERE `name` = 'PS_ROUND_TYPE'; UPDATE `ps_configuration` SET `value` = '2' WHERE `name` = 'PS_PRICE_DISPLAY_PRECISION'; Of course, it is necessary to change the prefix ps_ to the prefix of the tables that are in the database. Edited November 10, 2020 by Guest (see edit history) Link to comment Share on other sites More sharing options...
EvaF Posted November 10, 2020 Share Posted November 10, 2020 yes, I would a little bit modify your query - because I do not know anything about his configuration INSERT IGNORE INTO `ps_configuration` (`id_configuration`, `id_shop_group`, `id_shop`, `name`, `value`, `date_add`, `date_upd`) VALUES (NULL, NULL, NULL, 'PS_PRICE_COMPUTE_PRECISION', '2', '2020-11-10 00:00:00', '2020-11-10 00:00:00'); Link to comment Share on other sites More sharing options...
ruisonika Posted November 10, 2020 Author Share Posted November 10, 2020 Hello @EvaF and @Guest i think is working like i wanna In conclusion my Tool.php public static function displayPrice remains the same. Cart.php i made the changes said by @EvaF and in phpmyadmin i made the query from @Guest and i've tested and for seems that all is fine. Many Thanks to both. You have many beers to drink in portugal Link to comment Share on other sites More sharing options...
EvaF Posted November 10, 2020 Share Posted November 10, 2020 to be true, it seems to me that in P1.6 are mixing Configuraton::get('PS_PRICE_COMPUTE_PRECISION') // or Configuraton::get('_PS_PRICE_COMPUTE_PRECISION_') _PS_PRICE_COMPUTE_PRECISION_ Configuraton::get('PS_PRICE_DISPLAY_PRECISION') // resp. _PS_PRICE_DISPLAY_PRECISION_ therefore I shoud repair my previous post Cart.php (line 3052) and OrderInvoice.php (line 560) stays without changes there is a danger of wrong result of rounding if Configuraton::get('PS_PRICE_COMPUTE_PRECISION') <> Configuraton::get('PS_PRICE_DISPLAY_PRECISION') Link to comment Share on other sites More sharing options...
ruisonika Posted November 10, 2020 Author Share Posted November 10, 2020 6 minutes ago, EvaF said: to be true, it seems to me that in P1.6 are mixing Configuraton::get('PS_PRICE_COMPUTE_PRECISION') // or Configuraton::get('_PS_PRICE_COMPUTE_PRECISION_') _PS_PRICE_COMPUTE_PRECISION_ Configuraton::get('PS_PRICE_DISPLAY_PRECISION') // resp. _PS_PRICE_DISPLAY_PRECISION_ therefore I shoud repair my previous post Cart.php (line 3052) and OrderInvoice.php (line 560) stays without changes there is a danger of wrong result of rounding if Configuraton::get('PS_PRICE_COMPUTE_PRECISION') <> Configuraton::get('PS_PRICE_DISPLAY_PRECISION') Thanks @EvaF i had allready erase those changes. Thanks for your support, this to me was an enigma 1 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now