From a1335c3f611a72516f23a38394bf02b8fa6bbc2d Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 12 Apr 2013 08:38:48 +0200 Subject: [PATCH] [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 --- .../statement.py | 59 ++++++++++++------- account_statement_base_import/statement.py | 17 +++++- account_statement_ext/statement.py | 2 +- 3 files changed, 54 insertions(+), 24 deletions(-) diff --git a/account_statement_base_completion/statement.py b/account_statement_base_completion/statement.py index d81f0679..68bc99f0 100644 --- a/account_statement_base_completion/statement.py +++ b/account_statement_base_completion/statement.py @@ -62,7 +62,13 @@ class AccountStatementProfil(orm.Model): 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, 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: context = {} - res = {} + if not calls: + calls = self._get_callable(cr, uid, id, context=context) rule_obj = self.pool.get('account.statement.completion.rule') - profile = self.browse(cr, uid, id, context=context) - # We need to respect the sequence order - sorted_array = sorted(profile.rule_ids, key=attrgetter('sequence')) - for rule in sorted_array: - method_to_call = getattr(rule_obj, rule.function_to_call) + + for call in calls: + method_to_call = getattr(rule_obj, call) result = method_to_call(cr, uid, line_id, context) if result: return result - return res + return {} class AccountStatementCompletionRule(orm.Model): @@ -381,7 +386,7 @@ class AccountStatementLine(orm.Model): '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 the profile.. We will ignore line for which already_completed is ticked. @@ -396,20 +401,13 @@ class AccountStatementLine(orm.Model): res = {} errors_stack = [] for line in self.browse(cr, uid, ids, context=context): + res[line.id] = {} if line.already_completed: continue 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 - vals = profile_obj.find_values_from_rules( - cr, uid, line.statement_id.profile_id.id, line.id, context) + vals = profile_obj._find_values_from_rules( + cr, uid, rules, line.id, context) # Merge the result res[line.id].update(vals) except ErrorTooManyPartner, exc: @@ -476,16 +474,23 @@ class AccountBankSatement(orm.Model): """ if context is None: 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 + 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): msg_lines = [] ctx = context.copy() 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: res = {} 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: compl_lines += 1 except ErrorTooManyPartner, exc: @@ -496,8 +501,18 @@ class AccountBankSatement(orm.Model): if res: vals = res[line.id] 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) self.write_completion_log(cr, uid, stat.id, msg, compl_lines, context=context) + print datetime.datetime.now() - a return True diff --git a/account_statement_base_import/statement.py b/account_statement_base_import/statement.py index 4c7d0133..d0735faf 100644 --- a/account_statement_base_import/statement.py +++ b/account_statement_base_import/statement.py @@ -46,7 +46,7 @@ class AccountStatementProfil(Model): help="Tic that box to automatically launch the completion " "on each imported file using this profile."), '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( get_import_type_selection, 'Type of import', @@ -278,6 +278,21 @@ class AccountStatementLine(Model): cr.rollback() raise osv.except_osv(_("ORM bypass error"), 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 = { 'commission_amount': fields.sparse( type='float', diff --git a/account_statement_ext/statement.py b/account_statement_ext/statement.py index 2d27f32d..a6867216 100644 --- a/account_statement_ext/statement.py +++ b/account_statement_ext/statement.py @@ -326,7 +326,7 @@ class AccountBankSatement(Model): if not st.journal_id.analytic_journal_id: raise osv.except_osv(_('No Analytic Journal !'), _("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: continue st_line_number = self.get_next_st_line_number(cr, uid, st_number, st_line, context)