Manage negative and zero rounding
issue10180 review342071007
This commit is contained in:
+5
-1
@@ -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):
|
||||
|
||||
@@ -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'
|
||||
|
||||
Reference in New Issue
Block a user