changeset 5037451db47e in modules/currency:default
details: https://hg.tryton.org/modules/currency?cmd=changeset&node=5037451db47e
description:
Manage negative and zero rounding
issue10180
review342071007
diffstat:
currency.py | 6 +++-
tests/test_currency.py | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 84 insertions(+), 1 deletions(-)
diffs (112 lines):
diff -r c2d846d99cc9 -r 5037451db47e currency.py
--- a/currency.py Tue Apr 13 10:57:33 2021 +0200
+++ b/currency.py Fri Apr 16 18:59:08 2021 +0200
@@ -158,6 +158,8 @@
@classmethod
def _round(cls, amount, factor, rounding):
+ if not factor:
+ return amount
with localcontext() as ctx:
ctx.prec = max(ctx.prec, (amount / factor).adjusted() + 1)
# Divide and multiple by factor for case factor is not 10En
@@ -167,7 +169,9 @@
def is_zero(self, amount):
'Return True if the amount can be considered as zero for the currency'
- return abs(self.round(amount)) < self.rounding
+ if not self.rounding:
+ return not amount
+ return abs(self.round(amount)) < abs(self.rounding)
@classmethod
def compute(cls, from_currency, amount, to_currency, round=True):
diff -r c2d846d99cc9 -r 5037451db47e tests/test_currency.py
--- a/tests/test_currency.py Tue Apr 13 10:57:33 2021 +0200
+++ b/tests/test_currency.py Fri Apr 16 18:59:08 2021 +0200
@@ -120,6 +120,85 @@
self.assertEqual(rounded, Decimal('1E50'))
@with_transaction()
+ def test_round_negative(self):
+ "Test rounding with negative rounding"
+ cu = create_currency('cu')
+ cu.rounding = -Decimal('0.1')
+ cu.digits = 1
+ cu.save()
+
+ rounded = cu.round(Decimal('1.23'))
+
+ self.assertEqual(rounded, Decimal('1.2'))
+
+ @with_transaction()
+ def test_round_zero(self):
+ "Test rounding with 0 as rounding"
+ cu = create_currency('cu')
+ cu.rounding = Decimal('0')
+ cu.save()
+
+ rounded = cu.round(Decimal('1.2345'))
+
+ self.assertEqual(rounded, Decimal('1.2345'))
+
+ @with_transaction()
+ def test_is_zero(self):
+ "Test is zero"
+ cu = create_currency('cu')
+ cu.rounding = Decimal('0.001')
+ cu.digits = 3
+ cu.save()
+
+ for value, result in [
+ (Decimal('0'), True),
+ (Decimal('0.0002'), True),
+ (Decimal('0.0009'), False),
+ (Decimal('0.002'), False),
+ ]:
+ with self.subTest(value=value):
+ self.assertEqual(cu.is_zero(value), result)
+ with self.subTest(value=-value):
+ self.assertEqual(cu.is_zero(-value), result)
+
+ @with_transaction()
+ def test_is_zero_negative(self):
+ "Test is zero with negative rounding"
+ cu = create_currency('cu')
+ cu.rounding = Decimal('-0.001')
+ cu.digits = 3
+ cu.save()
+
+ for value, result in [
+ (Decimal('0'), True),
+ (Decimal('0.0002'), True),
+ (Decimal('0.0009'), False),
+ (Decimal('0.002'), False),
+ ]:
+ with self.subTest(value=value):
+ self.assertEqual(cu.is_zero(value), result)
+ with self.subTest(value=-value):
+ self.assertEqual(cu.is_zero(-value), result)
+
+ @with_transaction()
+ def test_is_zero_zero(self):
+ "Test is zero with 0 as rounding"
+ cu = create_currency('cu')
+ cu.rounding = Decimal('0')
+ cu.save()
+
+ for value, result in [
+ (Decimal('0'), True),
+ (Decimal('0.0002'), False),
+ (Decimal('0.0009'), False),
+ (Decimal('0.002'), False),
+ ]:
+ with self.subTest(value=value):
+ self.assertEqual(cu.is_zero(value), result)
+ with self.subTest(value=-value):
+ self.assertEqual(cu.is_zero(-value), result)
+
+ @with_transaction()
def test_compute_simple(self):
'Simple conversion'
pool = Pool()