diff options
| author | oco-odoo <oco@odoo.com> | 2021-03-11 11:12:02 +0000 |
|---|---|---|
| committer | oco-odoo <oco@odoo.com> | 2021-03-16 13:21:42 +0000 |
| commit | e1df7aea0f1209398ca318678ba6742d7d986cb0 (patch) | |
| tree | 36e2810241d24c21bcbb4646eecf24e0d7a41f6c /odoo | |
| parent | 71b6fc7341dfec5e8fc2352c3143b1e324a880f8 (diff) | |
[FIX] base: tools: float_split_str: avoid traceback when rounding to 0 places and add some test cases
closes odoo/odoo#67949
X-original-commit: 42d409f180381316c97abd0c0ef5a062656e6122
Signed-off-by: Olivier Dony (odo) <odo@openerp.com>
Signed-off-by: oco-odoo <oco-odoo@users.noreply.github.com>
Diffstat (limited to 'odoo')
| -rw-r--r-- | odoo/addons/base/tests/test_float.py | 31 | ||||
| -rw-r--r-- | odoo/tools/float_utils.py | 25 |
2 files changed, 41 insertions, 15 deletions
diff --git a/odoo/addons/base/tests/test_float.py b/odoo/addons/base/tests/test_float.py index 8196c2433ab..5e1db6c074f 100644 --- a/odoo/addons/base/tests/test_float.py +++ b/odoo/addons/base/tests/test_float.py @@ -4,7 +4,7 @@ from math import log10 from odoo.tests.common import TransactionCase -from odoo.tools import float_compare, float_is_zero, float_repr, float_round, float_split_str +from odoo.tools import float_compare, float_is_zero, float_repr, float_round, float_split, float_split_str class TestFloatPrecision(TransactionCase): @@ -186,16 +186,29 @@ class TestFloatPrecision(TransactionCase): """ Test split method with 2 digits. """ currency = self.env.ref('base.EUR') - def try_split(value, expected): - digits = max(0, -int(log10(currency.rounding))) - result = float_split_str(value, precision_digits=digits) + def try_split(value, expected, split_fun, rounding=None): + digits = max(0, -int(log10(currency.rounding))) if rounding is None else rounding + result = split_fun(value, precision_digits=digits) self.assertEqual(result, expected, 'Split error: got %s, expected %s' % (result, expected)) - try_split(2.674, ('2', '67')) - try_split(2.675, ('2', '68')) # in Python 2.7.2, round(2.675,2) gives 2.67 - try_split(-2.675, ('-2', '68')) # in Python 2.7.2, round(2.675,2) gives 2.67 - try_split(0.001, ('0', '00')) - try_split(-0.001, ('-0', '00')) + try_split(2.674, ('2', '67'), float_split_str) + try_split(2.675, ('2', '68'), float_split_str) # in Python 2.7.2, round(2.675,2) gives 2.67 + try_split(-2.675, ('-2', '68'), float_split_str) # in Python 2.7.2, round(2.675,2) gives 2.67 + try_split(0.001, ('0', '00'), float_split_str) + try_split(-0.001, ('-0', '00'), float_split_str) + try_split(42, ('42', '00'), float_split_str) + try_split(0.1, ('0', '10'), float_split_str) + try_split(13.0, ('13', ''), float_split_str, rounding=0) + + try_split(2.674, (2, 67), float_split) + try_split(2.675, (2, 68), float_split) # in Python 2.7.2, round(2.675,2) gives 2.67 + try_split(-2.675, (-2, 68), float_split) # in Python 2.7.2, round(2.675,2) gives 2.67 + try_split(0.001, (0, 0), float_split) + try_split(-0.001, (0, 0), float_split) + try_split(42, (42, 0), float_split) + try_split(0.1, (0, 10), float_split) + try_split(13.0, (13, 0), float_split, rounding=0) + def test_rounding_invalid(self): """ verify that invalid parameters are forbidden """ diff --git a/odoo/tools/float_utils.py b/odoo/tools/float_utils.py index afbdeb6846c..ff7246ee7d9 100644 --- a/odoo/tools/float_utils.py +++ b/odoo/tools/float_utils.py @@ -178,10 +178,21 @@ def float_repr(value, precision_digits): _float_repr = float_repr def float_split_str(value, precision_digits): - """ Splits the given float 'value' in its unitary and decimal parts. The value - is first rounded thanks to the ``precision_digits`` argument given. + """Splits the given float 'value' in its unitary and decimal parts, + returning each of them as a string, rounding the value using + the provided ``precision_digits`` argument. - Example: 1.432 would return (1, 43) for a digits precision of 2. + The length of the string returned for decimal places will always + be equal to ``precision_digits``, adding zeros at the end if needed. + + In case ``precision_digits`` is zero, an empty string is returned for + the decimal places. + + Examples: + 1.432 with precision 2 => ('1', '43') + 1.49 with precision 1 => ('1', '5') + 1.1 with precision 3 => ('1', '100') + 1.12 with precision 0 => ('1', '') :param float value: value to split. :param int precision_digits: number of fractional digits to round to. @@ -190,16 +201,18 @@ def float_split_str(value, precision_digits): """ value = float_round(value, precision_digits=precision_digits) value_repr = float_repr(value, precision_digits) - units, cents = value_repr.split('.') - return units, cents + return tuple(value_repr.split('.')) if precision_digits else (value_repr, '') def float_split(value, precision_digits): """ same as float_split_str() except that it returns the unitary and decimal - parts as integers instead of strings. + parts as integers instead of strings. In case ``precision_digits`` is zero, + 0 is always returned as decimal part. :rtype: tuple(int, int) """ units, cents = float_split_str(value, precision_digits) + if not cents: + return int(units), 0 return int(units), int(cents) |
