Improve speed of Move.validate

review623002
This commit is contained in:
Cédric Krier committed 2013-02-23 14:09:33 +01:00
1 parent f943da6141
commit c2e5b3b50a
1 file changed
+54 -21
+54 -21
View File
@@ -3,6 +3,8 @@
from decimal import Decimal
import datetime
import time
from itertools import groupby
from operator import itemgetter
from trytond.model import ModelView, ModelSQL, fields
from trytond.wizard import Wizard, StateTransition, StateView, StateAction, \
@@ -13,6 +15,7 @@ from trytond.pyson import Eval, PYSONEncoder
from trytond.transaction import Transaction
from trytond.pool import Pool, PoolMeta
from trytond.rpc import RPC
from trytond.tools import reduce_ids
__all__ = ['Move', 'Reconciliation', 'Line', 'Move2', 'OpenJournalAsk',
'OpenJournal', 'OpenAccount', 'ReconcileLinesWriteOff', 'ReconcileLines',
@@ -283,24 +286,47 @@ class Move(ModelSQL, ModelView):
'''
pool = Pool()
MoveLine = pool.get('account.move.line')
User = pool.get('res.user')
cursor = Transaction().cursor
if (Transaction().user == 0
and Transaction().context.get('user')):
user = Transaction().context.get('user')
else:
user = Transaction().user
company = User(user).company
amounts = {}
move2draft_lines = {}
for i in range(0, len(moves), cursor.IN_MAX):
sub_moves = moves[i:i + cursor.IN_MAX]
sub_move_ids = [m.id for m in sub_moves]
red_sql, red_ids = reduce_ids('move', sub_move_ids)
cursor.execute('SELECT move, SUM(debit - credit) '
'FROM "' + MoveLine._table + '" '
'WHERE ' + red_sql + ' '
'GROUP BY move', red_ids)
amounts.update(dict(cursor.fetchall()))
cursor.execute('SELECT move, id '
'FROM "' + MoveLine._table + '" '
'WHERE ' + red_sql + ' AND state = %s '
'ORDER BY move', red_ids + ['draft'])
move2draft_lines.update(dict((k, (j[1] for j in g))
for k, g in groupby(cursor.fetchall(), itemgetter(0))))
valid_moves = []
draft_moves = []
for move in moves:
if not move.lines:
if move.id not in amounts:
continue
amount = Decimal('0.0')
company = None
draft_lines = []
for line in move.lines:
amount += line.debit - line.credit
if not company:
company = line.account.company
if line.state == 'draft':
draft_lines.append(line)
amount = amounts[move.id]
draft_lines = MoveLine.browse(
list(move2draft_lines.get(move.id, [])))
if not company.currency.is_zero(amount):
if not move.journal.centralised:
MoveLine.write(
[x for x in move.lines if x.state != 'draft'], {
'state': 'draft',
})
draft_moves.append(move.id)
else:
if not move.centralised_line:
centralised_amount = - amount
@@ -335,9 +361,19 @@ class Move(ModelSQL, ModelView):
continue
if not draft_lines:
continue
MoveLine.write(draft_lines, {
'state': 'valid',
})
valid_moves.append(move.id)
for move_ids, state in (
(valid_moves, 'valid'),
(draft_moves, 'draft'),
):
if move_ids:
for i in range(0, len(move_ids), cursor.IN_MAX):
sub_ids = move_ids[i:i + cursor.IN_MAX]
red_sql, red_ids = reduce_ids('move', sub_ids)
# Use SQL to prevent double validate loop
cursor.execute('UPDATE "' + MoveLine._table + '" '
'SET state = %s '
'WHERE ' + red_sql, [state] + red_ids)
@classmethod
@ModelView.button
@@ -1162,10 +1198,7 @@ class Line(ModelSQL, ModelView):
Transaction().timestamp = {}
for line in lines:
if line.move not in moves:
moves.append(line.move)
Move.validate(moves)
Move.validate(list(set(l.move for l in lines) | set(moves)))
@classmethod
def create(cls, vlist):