summaryrefslogtreecommitdiff
path: root/odoo/tools/float_utils.py
diff options
context:
space:
mode:
authorLaurent Smet <las@openerp.com>2017-09-01 18:23:45 +0200
committerqdp-odoo <qdp@odoo.com>2017-09-01 18:23:45 +0200
commitaee43c0d145aa55ae87029ab1457fd8b74b97b94 (patch)
tree981278b520519346916e1144089c4281675092bc /odoo/tools/float_utils.py
parentc030213fa3b822b1ea373c77b552bfda716a3900 (diff)
[ADD] account: add cash rounding managment
In some countries, we need to be able to make appear on an invoice a rounding line, appearing there only because the smallest coinage has been removed from the circulation. For example, in Switerzland invoices have to be rounded to 0.05 CHF because coins of 0.01 CHF and 0.02 CHF aren't used anymore. Was PR #15231 Was task 30904
Diffstat (limited to 'odoo/tools/float_utils.py')
-rw-r--r--odoo/tools/float_utils.py20
1 files changed, 11 insertions, 9 deletions
diff --git a/odoo/tools/float_utils.py b/odoo/tools/float_utils.py
index 9dc751604c2..bf3f0463c0a 100644
--- a/odoo/tools/float_utils.py
+++ b/odoo/tools/float_utils.py
@@ -47,9 +47,10 @@ def float_round(value, precision_digits=None, precision_rounding=None, rounding_
:param float precision_rounding: decimal number representing the minimum
non-zero value at the desired precision (for example, 0.01 for a
2-digit precision).
- :param rounding_method: the rounding method used: 'HALF-UP' or 'UP', the first
- one rounding up to the closest number with the rule that number>=0.5 is
- rounded up to 1, and the latest one always rounding up.
+ :param rounding_method: the rounding method used: 'HALF-UP', 'UP' or 'DOWN',
+ the first one rounding up to the closest number with the rule that
+ number>=0.5 is rounded up to 1, the second always rounding up and the
+ latest one always rounding down.
:return: rounded float
"""
rounding_factor = _float_check_precision(precision_digits=precision_digits,
@@ -79,18 +80,19 @@ def float_round(value, precision_digits=None, precision_rounding=None, rounding_
normalized_value += math.copysign(epsilon, normalized_value)
rounded_value = round(normalized_value) # round to integer
- # TIE-BREAKING: UP (for ceiling operations)
- # When rounding the value up, we instead subtract the epsilon value
+ # TIE-BREAKING: UP (for ceiling[resp. flooring] operations)
+ # When rounding the value up[resp. down], we instead subtract the epsilon value
# as the the approximation of the real value may be slightly *above* the
- # tie limit, this would result in incorrectly rounding up to the next number
- # The math.ceil operation is applied on the absolute value in order to
+ # tie limit, this would result in incorrectly rounding up[resp. down] to the next number
+ # The math.ceil[resp. math.floor] operation is applied on the absolute value in order to
# round "away from zero" and not "towards infinity", then the sign is
# restored.
- elif rounding_method == 'UP':
+ else:
+ func = math.floor if rounding_method == 'DOWN' else math.ceil
sign = math.copysign(1.0, normalized_value)
normalized_value -= sign*epsilon
- rounded_value = math.ceil(abs(normalized_value))*sign # ceil to integer
+ rounded_value = func(abs(normalized_value)) * sign
result = rounded_value * rounding_factor # de-normalize
return result