Manage negative and zero rounding

issue10180
review342071007
This commit is contained in:
Cédric Krier
2021-04-16 18:59:08 +02:00
parent 93be030285
commit c290f7ee5b
2 changed files with 84 additions and 1 deletions
+5 -1
View File
@@ -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):
+79
View File
@@ -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'