[FIX] account: consistency on the allowed precision

This fixes 2 issues.
First, it keeps consistent the precision required for posted entries and the
precision for the balance assertion. This could be an issue if the account
precision is larger than 4.
Then, it makes sure to round the amount with the appropriate precision to avoid
numerical errors. For example 1.2344 - 1.2345 = -9.999999999998899e-05, which
is indeed smaller than the required precision 10 ** -4.

A minimum precision of 10 ** -5 is kept for historical reason.

Fixes #7276
opw-643305
This commit is contained in:
Nicolas Martinelli 2015-06-26 17:48:33 +02:00
parent f498583a98
commit 95f49eadc1
1 changed files with 7 additions and 3 deletions

View File

@ -1162,13 +1162,15 @@ class account_move(osv.osv):
_order = 'id desc' _order = 'id desc'
def account_assert_balanced(self, cr, uid, context=None): def account_assert_balanced(self, cr, uid, context=None):
obj_precision = self.pool.get('decimal.precision')
prec = obj_precision.precision_get(cr, uid, 'Account')
cr.execute("""\ cr.execute("""\
SELECT move_id SELECT move_id
FROM account_move_line FROM account_move_line
WHERE state = 'valid' WHERE state = 'valid'
GROUP BY move_id GROUP BY move_id
HAVING abs(sum(debit) - sum(credit)) > 0.00001 HAVING abs(sum(debit) - sum(credit)) >= %s
""") """ % (10 ** (-max(5, prec))))
assert len(cr.fetchall()) == 0, \ assert len(cr.fetchall()) == 0, \
"For all Journal Items, the state is valid implies that the sum " \ "For all Journal Items, the state is valid implies that the sum " \
"of credits equals the sum of debits" "of credits equals the sum of debits"
@ -1537,6 +1539,8 @@ class account_move(osv.osv):
valid_moves = [] #Maintains a list of moves which can be responsible to create analytic entries valid_moves = [] #Maintains a list of moves which can be responsible to create analytic entries
obj_analytic_line = self.pool.get('account.analytic.line') obj_analytic_line = self.pool.get('account.analytic.line')
obj_move_line = self.pool.get('account.move.line') obj_move_line = self.pool.get('account.move.line')
obj_precision = self.pool.get('decimal.precision')
prec = obj_precision.precision_get(cr, uid, 'Account')
for move in self.browse(cr, uid, ids, context): for move in self.browse(cr, uid, ids, context):
journal = move.journal_id journal = move.journal_id
amount = 0 amount = 0
@ -1560,7 +1564,7 @@ class account_move(osv.osv):
if line.account_id.currency_id.id != line.currency_id.id and (line.account_id.currency_id.id != line.account_id.company_id.currency_id.id): if line.account_id.currency_id.id != line.currency_id.id and (line.account_id.currency_id.id != line.account_id.company_id.currency_id.id):
raise osv.except_osv(_('Error!'), _("""Cannot create move with currency different from ..""") % (line.account_id.code, line.account_id.name)) raise osv.except_osv(_('Error!'), _("""Cannot create move with currency different from ..""") % (line.account_id.code, line.account_id.name))
if abs(amount) < 10 ** -4: if round(abs(amount), prec) < 10 ** (-max(5, prec)):
# If the move is balanced # If the move is balanced
# Add to the list of valid moves # Add to the list of valid moves
# (analytic lines will be created later for valid moves) # (analytic lines will be created later for valid moves)