Quantize to number of digits instead of rounding computed amount

Rounding may change the result if currency rounding is not unitary.

issue7284
review37251002
This commit is contained in:
Cédric Krier
2018-04-18 10:18:37 +02:00
parent e798828de9
commit e2d8d0a808
5 changed files with 16 additions and 23 deletions
+10 -10
View File
@@ -263,7 +263,8 @@ class Type(sequence_ordered(), ModelSQL, ModelView):
])
for child in childs:
res[type_.id] += type_sum[child.id]
res[type_.id] = type_.company.currency.round(res[type_.id])
exp = Decimal(str(10.0 ** -type_.currency_digits))
res[type_.id] = res[type_.id].quantize(exp)
if type_.display_balance == 'credit-debit':
res[type_.id] = - res[type_.id]
return res
@@ -809,7 +810,7 @@ class Account(DeactivableMixin, ModelSQL, ModelView):
table_c = cls.__table__()
line = MoveLine.__table__()
ids = [a.id for a in accounts]
balances = dict((i, 0) for i in ids)
balances = dict((i, Decimal(0)) for i in ids)
line_query, fiscalyear_ids = MoveLine.query_get(line)
for sub_ids in grouped_slice(ids):
red_sql = reduce_ids(table_a.id, sub_ids)
@@ -832,8 +833,8 @@ class Account(DeactivableMixin, ModelSQL, ModelView):
balances[account_id] = Decimal(str(balance))
for account in accounts:
balances[account.id] = account.company.currency.round(
balances[account.id])
exp = Decimal(str(10.0 ** -account.currency_digits))
balances[account.id] = balances[account.id].quantize(exp)
fiscalyears = FiscalYear.browse(fiscalyear_ids)
@@ -859,7 +860,7 @@ class Account(DeactivableMixin, ModelSQL, ModelView):
for name in names:
if name not in {'credit', 'debit', 'amount_second_currency'}:
raise ValueError('Unknown name: %s' % name)
result[name] = dict((i, 0) for i in ids)
result[name] = dict((i, Decimal(0)) for i in ids)
table = cls.__table__()
line = MoveLine.__table__()
@@ -885,12 +886,11 @@ class Account(DeactivableMixin, ModelSQL, ModelView):
for account in accounts:
for name in names:
if name == 'amount_second_currency':
currency = account.second_currency
exp = Decimal(str(10.0 ** -account.second_currency_digits))
else:
currency = account.company.currency
if currency:
result[name][account.id] = currency.round(
result[name][account.id])
exp = Decimal(str(10.0 ** -account.currency_digits))
result[name][account.id] = (
result[name][account.id].quantize(exp))
cumulate_names = []
if Transaction().context.get('cumulate'):
-1
View File
@@ -1203,7 +1203,6 @@ class Line(ModelSQL, ModelView):
reconcile_account = line.account
if not reconcile_party:
reconcile_party = line.party
amount = reconcile_account.currency.round(amount)
if amount:
move = cls._get_writeoff_move(
reconcile_account, reconcile_party, amount, **writeoff)
+2 -9
View File
@@ -136,7 +136,7 @@ class Party(CompanyMultiValueMixin):
if not user.company:
return result
company_id = user.company.id
to_round = False
exp = Decimal(str(10.0 ** -user.company.currency.digits))
amount = Sum(Coalesce(line.debit, 0) - Coalesce(line.credit, 0))
for name in names:
@@ -163,14 +163,7 @@ class Party(CompanyMultiValueMixin):
# SQLite uses float for SUM
if not isinstance(value, Decimal):
value = Decimal(str(value))
to_round = True
result[name][party] = value
# Float amount must be rounded to get the right precision
if to_round:
currency = user.company.currency
for name, values in result.iteritems():
for id, value in values.iteritems():
values[id] = currency.round(value)
result[name][party] = value.quantize(exp)
return result
@classmethod
+3 -2
View File
@@ -201,8 +201,9 @@ class TaxCode(DeactivableMixin, ModelSQL, ModelView):
('parent', 'child_of', [c.id for c in codes]),
])
for code in childs:
result[code.id] = code.company.currency.round(
sum((l.value for l in code.lines), Decimal(0)))
exp = Decimal(str(10.0 ** -code.currency_digits))
result[code.id] = sum(
(l.value for l in code.lines), Decimal(0)).quantize(exp)
parents[code.id] = code.parent.id if code.parent else None
ids = set(map(int, childs))
+1 -1
View File
@@ -151,4 +151,4 @@ Reconcile Lines with writeoff::
>>> writeoff_line2.account == expense
True
>>> writeoff_line2.debit
Decimal('3.00')
Decimal('3.0')