relocate methods defined for AccountStatementLine in account_statement_base_import to account_statement_base_completion

This commit is contained in:
Laurent Mignon (Acsone)
2013-09-12 11:05:01 +02:00
parent 3cb4e69d22
commit 423820aa18
4 changed files with 77 additions and 91 deletions

View File

@@ -27,11 +27,6 @@
'complexity': 'normal', 'complexity': 'normal',
'depends': [ 'depends': [
'account_statement_base_completion', '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': """ 'description': """
Add a completion method based on the partner bank account number provided by the bank/office. Add a completion method based on the partner bank account number provided by the bank/office.

View File

@@ -42,7 +42,6 @@ class bankaccount_completion(common.TransactionCase):
"name": "TEST", "name": "TEST",
"commission_account_id": self.account_id, "commission_account_id": self.account_id,
"journal_id": self.journal_id, "journal_id": self.journal_id,
"import_type": 'generic_csvxls_so',
"rule_ids": [(6, 0, [self.completion_rule_id])]}) "rule_ids": [(6, 0, [self.completion_rule_id])]})
# Create the completion rule # Create the completion rule

View File

@@ -22,6 +22,9 @@
import traceback import traceback
import sys import sys
import logging import logging
import simplejson
import psycopg2
from collections import defaultdict from collections import defaultdict
import re import re
@@ -425,6 +428,80 @@ class AccountStatementLine(orm.Model):
return vals return vals
return {} 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): class AccountBankSatement(orm.Model):
""" """

View File

@@ -21,14 +21,11 @@
import sys import sys
import traceback import traceback
import psycopg2
from openerp.tools.translate import _ from openerp.tools.translate import _
import datetime import datetime
from openerp.osv.orm import Model from openerp.osv.orm import Model
from openerp.osv import fields, osv from openerp.osv import fields, osv
from parser import new_bank_statement_parser from parser import new_bank_statement_parser
import simplejson
class AccountStatementProfil(Model): class AccountStatementProfil(Model):
@@ -217,85 +214,3 @@ class AccountStatementProfil(Model):
raise osv.except_osv(_("Statement import error"), raise osv.except_osv(_("Statement import error"),
_("The statement cannot be created: %s") % st) _("The statement cannot be created: %s") % st)
return statement_id 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)