diff --git a/currency.py b/currency.py index cad03d68f3..db35f63d8f 100644 --- a/currency.py +++ b/currency.py @@ -158,6 +158,8 @@ class Currency(SymbolMixin, DeactivableMixin, ModelSQL, ModelView): @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 @@ class Currency(SymbolMixin, DeactivableMixin, ModelSQL, ModelView): 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 --git a/tests/test_currency.py b/tests/test_currency.py index 3952ad3b81..bec4c1dba4 100644 --- a/tests/test_currency.py +++ b/tests/test_currency.py @@ -119,6 +119,85 @@ class CurrencyTestCase(ModuleTestCase): 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'