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()

Reply via email to