summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorqdp-odoo <qdp@odoo.com>2017-03-03 15:58:05 +0100
committerqdp-odoo <qdp@odoo.com>2017-03-03 15:58:05 +0100
commit0031f98f1d469a0fcece776ec1d510db374bffa5 (patch)
tree0b28f6073ccdeac2083a7da4d37c5bed2cc9a7dc
parenteb56b9bebc56dbcde8d7d1fad09aeae331de7c8f (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.py17
-rw-r--r--odoo/tools/float_utils.py26
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