From 423820aa18c58b381774870b3df26b04e6699290 Mon Sep 17 00:00:00 2001 From: "Laurent Mignon (Acsone)" Date: Thu, 12 Sep 2013 11:05:01 +0200 Subject: [PATCH] relocate methods defined for AccountStatementLine in account_statement_base_import to account_statement_base_completion --- .../__openerp__.py | 5 -- .../tests/test_bankaccount_completion.py | 1 - .../statement.py | 77 +++++++++++++++++ account_statement_base_import/statement.py | 85 ------------------- 4 files changed, 77 insertions(+), 91 deletions(-) diff --git a/account_statement_bankaccount_completion/__openerp__.py b/account_statement_bankaccount_completion/__openerp__.py index 4ee46643..0986b97d 100644 --- a/account_statement_bankaccount_completion/__openerp__.py +++ b/account_statement_bankaccount_completion/__openerp__.py @@ -27,11 +27,6 @@ 'complexity': 'normal', 'depends': [ 'account_statement_base_completion', - # HACK! the account_statement_base_completion need - # to depend from account_statement_base_import since it use specific method on the - # statement line during completion. (methods are defined in the - # account_statement_base_impor module - 'account_statement_base_import' ], 'description': """ Add a completion method based on the partner bank account number provided by the bank/office. diff --git a/account_statement_bankaccount_completion/tests/test_bankaccount_completion.py b/account_statement_bankaccount_completion/tests/test_bankaccount_completion.py index cbd97262..5f1f9142 100644 --- a/account_statement_bankaccount_completion/tests/test_bankaccount_completion.py +++ b/account_statement_bankaccount_completion/tests/test_bankaccount_completion.py @@ -42,7 +42,6 @@ class bankaccount_completion(common.TransactionCase): "name": "TEST", "commission_account_id": self.account_id, "journal_id": self.journal_id, - "import_type": 'generic_csvxls_so', "rule_ids": [(6, 0, [self.completion_rule_id])]}) # Create the completion rule diff --git a/account_statement_base_completion/statement.py b/account_statement_base_completion/statement.py index dd67e095..49361447 100644 --- a/account_statement_base_completion/statement.py +++ b/account_statement_base_completion/statement.py @@ -22,6 +22,9 @@ import traceback import sys import logging +import simplejson + +import psycopg2 from collections import defaultdict import re @@ -425,6 +428,80 @@ class AccountStatementLine(orm.Model): return vals return {} + def _get_available_columns(self, statement_store, include_serializable=False): + """Return writeable by SQL columns""" + statement_line_obj = self.pool['account.bank.statement.line'] + model_cols = statement_line_obj._columns + avail = [k for k, col in model_cols.iteritems() if not hasattr(col, '_fnct')] + keys = [k for k in statement_store[0].keys() if k in avail] + # add sparse fields.. + if include_serializable: + for k, col in model_cols.iteritems(): + if k in statement_store[0].keys() and \ + isinstance(col, fields.sparse) and \ + col.serialization_field not in keys and \ + col._type == 'char': + keys.append(col.serialization_field) + keys.sort() + return keys + + def _serialize_sparse_fields(self, cols, statement_store): + """ Serialize sparse fields values in the target serialized field + Return a copy of statement_store + """ + statement_line_obj = self.pool['account.bank.statement.line'] + model_cols = statement_line_obj._columns + sparse_fields = dict([(k , col) for k, col in model_cols.iteritems() if isinstance(col, fields.sparse) and col._type == 'char']) + values = [] + for statement in statement_store: + to_json_k = set() + st_copy = statement.copy() + for k, col in sparse_fields.iteritems(): + if k in st_copy: + to_json_k.add(col.serialization_field) + serialized = st_copy.setdefault(col.serialization_field, {}) + serialized[k] = st_copy[k] + for k in to_json_k: + st_copy[k] = simplejson.dumps(st_copy[k]) + values.append(st_copy) + return values + + + def _insert_lines(self, cr, uid, statement_store, context=None): + """ Do raw insert into database because ORM is awfully slow + when doing batch write. It is a shame that batch function + does not exist""" + statement_line_obj = self.pool['account.bank.statement.line'] + statement_line_obj.check_access_rule(cr, uid, [], 'create') + statement_line_obj.check_access_rights(cr, uid, 'create', raise_exception=True) + cols = self._get_available_columns(statement_store, include_serializable=True) + tmp_vals = (', '.join(cols), ', '.join(['%%(%s)s' % i for i in cols])) + sql = "INSERT INTO account_bank_statement_line (%s) VALUES (%s);" % tmp_vals + try: + cr.executemany(sql, tuple(self._serialize_sparse_fields(cols, statement_store))) + except psycopg2.Error as sql_err: + 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 cheking security. + TODO / WARM: sparse fields are skipped by the method. IOW, if your + completion rule update an sparse field, the updated value will never + be stored in the database. It would be safer to call the update method + from the ORM for records updating this kind of fields. + """ + 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) + class AccountBankSatement(orm.Model): """ diff --git a/account_statement_base_import/statement.py b/account_statement_base_import/statement.py index f6730abe..97e8e8ab 100644 --- a/account_statement_base_import/statement.py +++ b/account_statement_base_import/statement.py @@ -21,14 +21,11 @@ import sys import traceback -import psycopg2 - from openerp.tools.translate import _ import datetime from openerp.osv.orm import Model from openerp.osv import fields, osv from parser import new_bank_statement_parser -import simplejson class AccountStatementProfil(Model): @@ -217,85 +214,3 @@ class AccountStatementProfil(Model): raise osv.except_osv(_("Statement import error"), _("The statement cannot be created: %s") % st) return statement_id - - -class AccountStatementLine(Model): - """ - Add sparse field on the statement line to allow to store all the - bank infos that are given by an office. - """ - _inherit = "account.bank.statement.line" - - def _get_available_columns(self, statement_store, include_serializable=False): - """Return writeable by SQL columns""" - statement_line_obj = self.pool['account.bank.statement.line'] - model_cols = statement_line_obj._columns - avail = [k for k, col in model_cols.iteritems() if not hasattr(col, '_fnct')] - keys = [k for k in statement_store[0].keys() if k in avail] - # add sparse fields.. - if include_serializable: - for k, col in model_cols.iteritems(): - if k in statement_store[0].keys() and \ - isinstance(col, fields.sparse) and \ - col.serialization_field not in keys and \ - col._type == 'char': - keys.append(col.serialization_field) - keys.sort() - return keys - - def _serialize_sparse_fields(self, cols, statement_store): - """ Serialize sparse fields values in the target serialized field - Return a copy of statement_store - """ - statement_line_obj = self.pool['account.bank.statement.line'] - model_cols = statement_line_obj._columns - sparse_fields = dict([(k , col) for k, col in model_cols.iteritems() if isinstance(col, fields.sparse) and col._type == 'char']) - values = [] - for statement in statement_store: - to_json_k = set() - st_copy = statement.copy() - for k, col in sparse_fields.iteritems(): - if k in st_copy: - to_json_k.add(col.serialization_field) - serialized = st_copy.setdefault(col.serialization_field, {}) - serialized[k] = st_copy[k] - for k in to_json_k: - st_copy[k] = simplejson.dumps(st_copy[k]) - values.append(st_copy) - return values - - - def _insert_lines(self, cr, uid, statement_store, context=None): - """ Do raw insert into database because ORM is awfully slow - when doing batch write. It is a shame that batch function - does not exist""" - statement_line_obj = self.pool['account.bank.statement.line'] - statement_line_obj.check_access_rule(cr, uid, [], 'create') - statement_line_obj.check_access_rights(cr, uid, 'create', raise_exception=True) - cols = self._get_available_columns(statement_store, include_serializable=True) - tmp_vals = (', '.join(cols), ', '.join(['%%(%s)s' % i for i in cols])) - sql = "INSERT INTO account_bank_statement_line (%s) VALUES (%s);" % tmp_vals - try: - cr.executemany(sql, tuple(self._serialize_sparse_fields(cols, statement_store))) - except psycopg2.Error as sql_err: - 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 cheking security. - TODO / WARM: sparse fields are skipped by the method. IOW, if your - completion rule update an sparse field, the updated value will never - be stored in the database. It would be safer to call the update method - from the ORM for records updating this kind of fields. - """ - 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)