diff options
| author | qdp-odoo <qdp@odoo.com> | 2017-03-03 15:58:05 +0100 |
|---|---|---|
| committer | qdp-odoo <qdp@odoo.com> | 2017-03-03 15:58:05 +0100 |
| commit | 0031f98f1d469a0fcece776ec1d510db374bffa5 (patch) | |
| tree | 0b28f6073ccdeac2083a7da4d37c5bed2cc9a7dc | |
| parent | eb56b9bebc56dbcde8d7d1fad09aeae331de7c8f (diff) | |
[ADD] tools/float_utils: add float_split() and float_split_str() methods.
Add utility methods allowing to split floating points numbers and return their unitary and decimal parts.
| -rw-r--r-- | odoo/addons/base/tests/test_float.py | 17 | ||||
| -rw-r--r-- | odoo/tools/float_utils.py | 26 |
2 files changed, 42 insertions, 1 deletions
diff --git a/odoo/addons/base/tests/test_float.py b/odoo/addons/base/tests/test_float.py index 6737cbc63df..393cf1ea18e 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 +from odoo.tools import float_compare, float_is_zero, float_repr, float_round, float_split_str class TestFloatPrecision(TransactionCase): @@ -165,6 +165,21 @@ class TestFloatPrecision(TransactionCase): try_roundtrip(10000.999999, 10000.999999) try_roundtrip(-10000.999999, -10000.999999) + def test_float_split_05(self): + """ 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) + 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')) + def test_rounding_invalid(self): """ verify that invalid parameters are forbidden """ with self.assertRaises(AssertionError): diff --git a/odoo/tools/float_utils.py b/odoo/tools/float_utils.py index 67777145dba..127c546125f 100644 --- a/odoo/tools/float_utils.py +++ b/odoo/tools/float_utils.py @@ -150,6 +150,32 @@ 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. + + Example: 1.432 would return (1, 43) for a digits precision of 2. + + :param float value: value to split. + :param int precision_digits: number of fractional digits to round to. + :return: returns the tuple(<unitary part>, <decimal part>) of the given value + :rtype: tuple(str, str) + """ + value = float_round(value, precision_digits=precision_digits) + value_repr = float_repr(value, precision_digits) + units, cents = value_repr.split('.') + return units, cents + +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. + + :rtype: tuple(int, int) + """ + units, cents = float_split_str(value, precision_digits) + return int(units), int(cents) + + class float_precision(float): """ A class for float values that carry precision digits. This is a thin layer on top of ``float``, and the precision digits are not propagated |
