[ADD] refactoring the structure of completion in order to limit the number of browse.

We only tries to alter function that should not be inherited on strandard way of using the addons
This commit is contained in:
unknown
2013-04-12 08:38:48 +02:00
parent 9df2f02a33
commit a1335c3f61
3 changed files with 54 additions and 24 deletions

View File

@@ -62,7 +62,13 @@ class AccountStatementProfil(orm.Model):
rel='as_rul_st_prof_rel'), rel='as_rul_st_prof_rel'),
} }
def find_values_from_rules(self, cr, uid, id, line_id, context=None): def _get_callable(self, cr, uid, pid, context=None):
profile = self.browse(cr, uid, pid, context=context)
# We need to respect the sequence order
sorted_array = sorted(profile.rule_ids, key=attrgetter('sequence'))
return tuple([x.function_to_call for x in sorted_array])
def _find_values_from_rules(self, cr, uid, calls, line_id, context=None):
""" """
This method will execute all related rules, in their sequence order, This method will execute all related rules, in their sequence order,
to retrieve all the values returned by the first rules that will match. to retrieve all the values returned by the first rules that will match.
@@ -78,17 +84,16 @@ class AccountStatementProfil(orm.Model):
""" """
if context is None: if context is None:
context = {} context = {}
res = {} if not calls:
calls = self._get_callable(cr, uid, id, context=context)
rule_obj = self.pool.get('account.statement.completion.rule') rule_obj = self.pool.get('account.statement.completion.rule')
profile = self.browse(cr, uid, id, context=context)
# We need to respect the sequence order for call in calls:
sorted_array = sorted(profile.rule_ids, key=attrgetter('sequence')) method_to_call = getattr(rule_obj, call)
for rule in sorted_array:
method_to_call = getattr(rule_obj, rule.function_to_call)
result = method_to_call(cr, uid, line_id, context) result = method_to_call(cr, uid, line_id, context)
if result: if result:
return result return result
return res return {}
class AccountStatementCompletionRule(orm.Model): class AccountStatementCompletionRule(orm.Model):
@@ -381,7 +386,7 @@ class AccountStatementLine(orm.Model):
'already_completed': False, 'already_completed': False,
} }
def get_line_values_from_rules(self, cr, uid, ids, context=None): def get_line_values_from_rules(self, cr, uid, ids, rules, context=None):
""" """
We'll try to find out the values related to the line based on rules setted on We'll try to find out the values related to the line based on rules setted on
the profile.. We will ignore line for which already_completed is ticked. the profile.. We will ignore line for which already_completed is ticked.
@@ -396,20 +401,13 @@ class AccountStatementLine(orm.Model):
res = {} res = {}
errors_stack = [] errors_stack = []
for line in self.browse(cr, uid, ids, context=context): for line in self.browse(cr, uid, ids, context=context):
res[line.id] = {}
if line.already_completed: if line.already_completed:
continue continue
try: try:
# Take the default values
res[line.id] = st_obj.get_values_for_line(
cr,
uid,
profile_id=line.statement_id.profile_id.id,
line_type=line.type,
amount=line.amount,
context=context)
# Ask the rule # Ask the rule
vals = profile_obj.find_values_from_rules( vals = profile_obj._find_values_from_rules(
cr, uid, line.statement_id.profile_id.id, line.id, context) cr, uid, rules, line.id, context)
# Merge the result # Merge the result
res[line.id].update(vals) res[line.id].update(vals)
except ErrorTooManyPartner, exc: except ErrorTooManyPartner, exc:
@@ -476,16 +474,23 @@ class AccountBankSatement(orm.Model):
""" """
if context is None: if context is None:
context = {} context = {}
stat_line_obj = self.pool.get('account.bank.statement.line') stat_line_obj = self.pool['account.bank.statement.line']
profile_obj = self.pool.get('account.statement.profile')
compl_lines = 0 compl_lines = 0
stat_line_obj.check_access_rule(cr, uid, [], 'create')
stat_line_obj.check_access_rights(cr, uid, 'create', raise_exception=True)
import datetime
a = datetime.datetime.now()
for stat in self.browse(cr, uid, ids, context=context): for stat in self.browse(cr, uid, ids, context=context):
msg_lines = [] msg_lines = []
ctx = context.copy() ctx = context.copy()
ctx['line_ids'] = stat.line_ids ctx['line_ids'] = stat.line_ids
rules = profile_obj._get_callable(cr, uid, stat.profile_id.id, context=context)
for line in stat.line_ids: for line in stat.line_ids:
res = {} res = {}
try: try:
res = stat_line_obj.get_line_values_from_rules(cr, uid, [line.id], context=ctx) res = stat_line_obj.get_line_values_from_rules(cr, uid, [line.id],
rules, context=ctx)
if res: if res:
compl_lines += 1 compl_lines += 1
except ErrorTooManyPartner, exc: except ErrorTooManyPartner, exc:
@@ -496,8 +501,18 @@ class AccountBankSatement(orm.Model):
if res: if res:
vals = res[line.id] vals = res[line.id]
vals['already_completed'] = True vals['already_completed'] = True
stat_line_obj.write(cr, uid, [line.id], vals, context=ctx) vals['id'] = line.id
#stat_line_obj.write(cr, uid, [line.id], vals, context=ctx)
try:
stat_line_obj._update_line(cr, uid, vals, context=context)
except osv.except_osv as exc:
msg_lines.append(repr(exc))
# we can commit as it is not needed to be atomic
# commiting here adds a nice perfo boost
if not compl_lines % 500:
cr.commit()
msg = u'\n'.join(msg_lines) msg = u'\n'.join(msg_lines)
self.write_completion_log(cr, uid, stat.id, self.write_completion_log(cr, uid, stat.id,
msg, compl_lines, context=context) msg, compl_lines, context=context)
print datetime.datetime.now() - a
return True return True

View File

@@ -46,7 +46,7 @@ class AccountStatementProfil(Model):
help="Tic that box to automatically launch the completion " help="Tic that box to automatically launch the completion "
"on each imported file using this profile."), "on each imported file using this profile."),
'last_import_date': fields.datetime("Last Import Date"), 'last_import_date': fields.datetime("Last Import Date"),
'rec_log': fields.text('log', readonly=True, deprecated=True), #'rec_log': fields.text('log', readonly=True, deprecated=True),
'import_type': fields.selection( 'import_type': fields.selection(
get_import_type_selection, get_import_type_selection,
'Type of import', 'Type of import',
@@ -278,6 +278,21 @@ class AccountStatementLine(Model):
cr.rollback() cr.rollback()
raise osv.except_osv(_("ORM bypass error"), raise osv.except_osv(_("ORM bypass error"),
sql_err.pgerror) sql_err.pgerror)
def _update_line(self, cr, uid, vals, context=None):
""" Do raw update into database because ORM is awfully slow
when doing batch write. It is a shame that batch function
does not exist"""
cols = self._get_available_columns([vals])
tmp_vals = (', '.join(['%s = %%(%s)s' % (i, i) for i in cols]))
sql = "UPDATE account_bank_statement_line SET %s where id = %%(id)s;" % tmp_vals
try:
cr.execute(sql, vals)
except psycopg2.Error as sql_err:
cr.rollback()
raise osv.except_osv(_("ORM bypass error"),
sql_err.pgerror)
_columns = { _columns = {
'commission_amount': fields.sparse( 'commission_amount': fields.sparse(
type='float', type='float',

View File

@@ -326,7 +326,7 @@ class AccountBankSatement(Model):
if not st.journal_id.analytic_journal_id: if not st.journal_id.analytic_journal_id:
raise osv.except_osv(_('No Analytic Journal !'), raise osv.except_osv(_('No Analytic Journal !'),
_("You have to assign an analytic" _("You have to assign an analytic"
" journal on the '%s' journal!") % (st.journal_id.name,)) " journal on the '%s' journal!") % st.journal_id.name)
if not st_line.amount: if not st_line.amount:
continue continue
st_line_number = self.get_next_st_line_number(cr, uid, st_number, st_line, context) st_line_number = self.get_next_st_line_number(cr, uid, st_number, st_line, context)