diff --git a/account_statement_base_completion/__openerp__.py b/account_statement_base_completion/__openerp__.py
index f32f29ff..46b371a7 100644
--- a/account_statement_base_completion/__openerp__.py
+++ b/account_statement_base_completion/__openerp__.py
@@ -29,9 +29,18 @@
'description': """
The goal of this module is to improve the basic bank statement, help dealing with huge volume of
reconciliation by providing basic rules to identify the partner of a bank statement line.
- It will also take care of the chosen profile to make his work.
+ Each bank statement profile can have his own rules to apply respecting a sequence order.
+
+ Some basic rules are provided in this module:
+
+ 1) Match from statement line label (based on partner field 'Bank Statement Label')
+ 2) Match from statement line label (based on partner name)
+ 3) Match from statement line reference (based on SO number)
+
+ It add as well a label on the bank statement line (on which the pre-define rules can match) and
+ a char field on the partner called 'Bank Statement Label'. Using the pre-define rules, you'll be
+ able to match various label for a partner.
- His goal is to provide an easy way to fullfill the info of a bank statement line based on rules.
The reference of the line is always used by the reconciliation process. We're supposed to copy
there (or write manually) the matching string. That can be : the order Number or an invoice number,
or anything that will be found in the invoice entry part to make the match.
@@ -41,6 +50,7 @@
'init_xml': [],
'update_xml': [
'statement_view.xml',
+ 'partner_view.xml',
'data.xml',
],
'demo_xml': [],
diff --git a/account_statement_base_completion/data.xml b/account_statement_base_completion/data.xml
index 6a4a29cf..3757e4fd 100644
--- a/account_statement_base_completion/data.xml
+++ b/account_statement_base_completion/data.xml
@@ -6,16 +6,25 @@
Match from line label (based on partner field 'Bank Statement Label')60get_from_label_and_partner_field
-
Match from line label (based on partner name)70get_from_label_and_partner_name
-
+
+ Match from line reference (based on SO number)
+ 50
+ get_from_ref_and_so
+
+
+
+ Match from line reference (based on Invoice number)
+ 40
+ get_from_ref_and_invoice
+
diff --git a/account_statement_base_completion/statement.py b/account_statement_base_completion/statement.py
index a502205e..6b55a207 100644
--- a/account_statement_base_completion/statement.py
+++ b/account_statement_base_completion/statement.py
@@ -22,7 +22,8 @@ from tools.translate import _
import netsvc
logger = netsvc.Logger()
from openerp.osv.orm import Model, fields
-
+from openerp.osv import fields, osv
+from operator import itemgetter, attrgetter
class ErrorTooManyPartner(Exception):
def __init__(self, value):
@@ -41,12 +42,11 @@ class AccountStatementProfil(Model):
'rule_ids':fields.many2many('account.statement.completion.rule',
string='Related statement profiles',
- rel='account_statement_rule_statement_profile_to_rel',
- ids1='profile_id',ids2='rule_id',
+ rel='as_rul_st_prof_rel',
),
}
- def find_values_from_rules(self, cr, uid, ids, line_id, context=None):
+ def find_values_from_rules(self, cr, uid, id, line_id, context=None):
"""This method will execute all rules, in their sequence order,
to match a partner for the given statement.line and return his id.
@@ -58,15 +58,19 @@ class AccountStatementProfil(Model):
...
}
"""
+
if not context:
context={}
res = {}
- for profile in self.browse(cr, uid, ids, context=context):
- for rule in profile.rule_ids:
- method_to_call = getattr(rule, rule.function_to_call)
- result = method_to_call(cr,uid,line_id,context)
- if result:
- return res
+ 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)
+ result = method_to_call(cr,uid,line_id,context)
+ if result:
+ return result
return res
@@ -74,32 +78,89 @@ class AccountStatementCompletionRule(Model):
"""This will represent all the completion method that we can have to
fullfill the bank statement. You'll be able to extend them in you own module
and choose those to apply for every statement profile.
- The goal of a rules is to fullfill at least the partner of the line, but
+ The goal of a rule is to fullfill at least the partner of the line, but
if possible also the reference because we'll use it in the reconciliation
process. The reference should contain the invoice number or the SO number
+ or any reference that will be matched by the invoice genertaed move.
"""
_name = "account.statement.completion.rule"
_order = "sequence asc"
- def _get_functions(self):
+ def _get_functions(self, cr, uid, context=None):
"""List of available methods for rules. Override this to add you own."""
return [
+ ('get_from_ref_and_invoice', 'From line reference (based on invoice number)'),
+ ('get_from_ref_and_so', 'From line reference (based on SO number)'),
('get_from_label_and_partner_field', 'From line label (based on partner field)'),
('get_from_label_and_partner_name', 'From line label (based on partner name)'),
]
_columns={
'sequence': fields.integer('Sequence', help="Lower means paresed first."),
- 'name': fields.char('Name'),
+ 'name': fields.char('Name', size=128),
'profile_ids': fields.many2many('account.statement.profil',
- rel='account_statement_rule_statement_profile_to_rel',
- ids1='rule_id', ids2='profile_id',
+ rel='as_rul_st_prof_rel',
string='Related statement profiles'),
'function_to_call': fields.selection(_get_functions, 'Method'),
}
+
+ def get_from_ref_and_invoice(self, cursor, uid, line_id, context=None):
+ """Match the partner based on the invoice number and the reference of the statement
+ line. Then, call the generic st_line method to complete other values.
+ If more than one partner matched, raise an error.
+ Return:
+ A dict of value that can be passed directly to the write method of
+ the statement line.
+ {'partner_id': value,
+ 'account_id' : value,
+ ...}
+ """
+ st_obj = self.pool.get('account.bank.statement.line')
+ st_line = st_obj.browse(cursor,uid,line_id)
+ res = {}
+ if st_line:
+ inv_obj = self.pool.get('account.invoice')
+ inv_id = inv_obj.search(cursor, uid, [('number', '=', st_line.ref)])
+ if inv_id and len(inv_id) == 1:
+ inv = inv_obj.browse(cursor, uid, inv_id[0])
+ res['partner_id'] = inv.partner_id.id
+ elif inv_id and len(inv_id) > 1:
+ raise ErrorTooManyPartner(_('Line named "%s" was matched by more than one partner.')%(st_line.name,st_line.id))
+ st_vals = st_obj.get_values_for_line(cursor, uid, profile_id = st_line.statement_id.profile_id.id,
+ partner_id = res.get('partner_id',False), line_type = st_line.type, amount = st_line.amount, context = context)
+ res.update(st_vals)
+ return res
- def get_from_label_and_partner_field(self, cr, uid, line_id, context=None):
+ def get_from_ref_and_so(self, cursor, uid, line_id, context=None):
+ """Match the partner based on the SO number and the reference of the statement
+ line. Then, call the generic st_line method to complete other values.
+ If more than one partner matched, raise an error.
+ Return:
+ A dict of value that can be passed directly to the write method of
+ the statement line.
+ {'partner_id': value,
+ 'account_id' : value,
+ ...}
+ """
+ st_obj = self.pool.get('account.bank.statement.line')
+ st_line = st_obj.browse(cursor,uid,line_id)
+ res = {}
+ if st_line:
+ so_obj = self.pool.get('sale.order')
+ so_id = so_obj.search(cursor, uid, [('name', '=', st_line.ref)])
+ if so_id and len(so_id) == 1:
+ so = so_obj.browse(cursor, uid, so_id[0])
+ res['partner_id'] = so.partner_id.id
+ elif so_id and len(so_id) > 1:
+ raise ErrorTooManyPartner(_('Line named "%s" was matched by more than one partner.')%(st_line.name,st_line.id))
+ st_vals = st_obj.get_values_for_line(cursor, uid, profile_id = st_line.statement_id.profile_id.id,
+ partner_id = res.get('partner_id',False), line_type = st_line.type, amount = st_line.amount, context = context)
+ res.update(st_vals)
+ return res
+
+
+ def get_from_label_and_partner_field(self, cursor, uid, line_id, context=None):
"""Match the partner based on the label field of the statement line
and the text defined in the 'bank_statement_label' field of the partner.
Remember that we can have values separated with ; Then, call the generic
@@ -114,24 +175,24 @@ class AccountStatementCompletionRule(Model):
"""
partner_obj = self.pool.get('res.partner')
st_obj = self.pool.get('account.bank.statement.line')
- st_line = st_obj.browse(cr,uid,line_id)
+ st_line = st_obj.browse(cursor,uid,line_id)
res = {}
compt = 0
if st_line:
- ids = partner_obj.search(cr, uid, [['bank_statement_label', '!=', False]], context=context)
- for partner in self.browse(cr, uid, ids, context=context):
+ ids = partner_obj.search(cursor, uid, [['bank_statement_label', '!=', False]], context=context)
+ for partner in self.browse(cursor, uid, ids, context=context):
for partner_label in partner.bank_statement_label.split(';'):
if partner_label in st_line.label:
compt += 1
res['partner_id'] = partner.id
if compt > 1:
raise ErrorTooManyPartner(_('Line named "%s" was matched by more than one partner.')%(st_line.name,st_line.id))
- st_vals = st_obj.get_values_for_line(cr, uid, profile_id = st_line.statement_id.profile_id.id,
+ st_vals = st_obj.get_values_for_line(cursor, uid, profile_id = st_line.statement_id.profile_id.id,
partner_id = res.get('partner_id',False), line_type = st_line.type, amount = st_line.amount, context = context)
res.update(st_vals)
return res
- def get_from_label_and_partner_name(self, cr, uid, line_id, context=None):
+ def get_from_label_and_partner_name(self, cursor, uid, line_id, context=None):
"""Match the partner based on the label field of the statement line
and the name of the partner.
Then, call the generic st_line method to complete other values.
@@ -145,17 +206,17 @@ class AccountStatementCompletionRule(Model):
"""
res = {}
st_obj = self.pool.get('account.bank.statement.line')
- st_line = st_obj.browse(cr,uid,line_id)
+ st_line = st_obj.browse(cursor,uid,line_id)
if st_line:
sql = "SELECT id FROM res_partner WHERE name ~* '.*%s.*'"
- cr.execute(sql, (st_line.label,))
- result = cr.fetchall()
+ cursor.execute(sql, (st_line.label,))
+ result = cursor.fetchall()
if len(result) > 1:
raise ErrorTooManyPartner(_('Line named "%s" was matched by more than one partner.')%(st_line.name,st_line.id))
for id in result:
res['partner_id'] = id
- st_vals = st_obj.get_values_for_line(cr, uid, profile_id = st_line.statement_id.profile_id.id,
- partner_id = res.get('partner_id',False), line_type = st_line.type, st_line.amount, context)
+ st_vals = st_obj.get_values_for_line(cursor, uid, profile_id = st_line.statement_id.profile_id.id,
+ partner_id = res.get('partner_id',False), line_type = st_line.type, amount = st_line.amount, context = context)
res.update(st_vals)
return res
@@ -167,79 +228,45 @@ class AccountStatementLine(Model):
_inherit = "account.bank.statement.line"
_columns={
- # 'email_address': fields.char('Email', size=64),
- # 'order_ref': fields.char('Order Ref', size=64),
- # 'partner_name': fields.char('Partner Name', size=64),
- #
# Only label for a start, but other module can add their own
- 'additionnal_bank_fields' : fields.serialized('Additionnal infos from bank', help="Used by completion and import system."),
+ 'additionnal_bank_fields' : fields.serialized('Additionnal infos from bank',
+ help="Used by completion and import system. Adds every field that is present in your bank/office \
+ statement file"),
'label': fields.sparse(type='char', string='Label',
serialization_field='additionnal_bank_fields'),
+ 'already_completed': fields.boolean("Auto-Completed",
+ help="When this checkbox is ticked, the auto-completion process/button will ignore it."),
+
}
+ _defaults = {
+ 'already_completed': False,
+ }
+
def get_line_values_from_rules(self, cr, uid, ids, context=None):
"""
We'll try to find out the values related to the line based on what we
have and rules setted on the profile..
+
+ We ignore line for which already_completed is ticked!
"""
profile_obj = self.pool.get('account.statement.profil')
res={}
errors_stack = []
for line in self.browse(cr,uid, ids, context):
- try:
- vals = profile_obj.find_values_from_rules(cr, uid, ids, line.id, context)
- res[line.id]=vals
- except ErrorTooManyPartner, exc:
- msg = "Line ID %s had following error: %s" % (line.id, str(exc))
- errors_stack.append(msg)
- # if not auto_complete_line
- # if not line.partner_id or line.account_id.id ==1:
- # partner_obj = self.pool.get('res.partner')
- # partner_id=False
- # if line.order_ref:
- # partner_id = partner_obj.get_partner_from_order_ref(cr, uid, line.order_ref, context=context)
- # if not partner_id and line.email_address:
- # partner_id = partner_obj.get_partner_from_email(cr, uid, line.email_address, context=context)
- # if not partner_id and line.partner_name:
- # partner_id = partner_obj.get_partner_from_name(cr, uid, line.partner_name, context=context)
- # if not partner_id and line.label:
- # partner_id = partner_obj.get_partner_from_label_based_on_bank_statement_label(cr, uid, line.label, context=context)
- # if partner_id:
- # res = {'partner_id': partner_id}
- # if context['auto_completion']:
- # #Build the space for expr
- # space = {
- # 'self':self,
- # 'cr':cr,
- # 'uid':uid,
- # 'line': line,
- # 'res': res,
- # 'context':context,
- # }
- # exec context['auto_completion'] in space
- # if space.get('result', False):
- # res.update(space['result'])
+ if not line.already_completed:
+ try:
+ vals = profile_obj.find_values_from_rules(cr, uid, line.statement_id.profile_id.id, line.id, context)
+ res[line.id]=vals
+ except ErrorTooManyPartner, exc:
+ msg = "Line ID %s had following error: %s" % (line.id, str(exc))
+ errors_stack.append(msg)
if errors_stack:
msg = u"\n".join(errors_stack)
raise ErrorTooManyPartner(msg)
return res
-#
-# class A(object):
-# def xx_toto():
-# print 'toto'
-#
-#
-# a = A()
-# funcs = ['yy_toto', 'xx_toto']
-# for i in funcs:
-# if hasattr(a, i):
-# to_call = getattr(a, i)
-# to_call()
-# else:
-# raise NameError('blblblb')
-
class AccountBankSatement(Model):
"""
We add a basic button and stuff to support the auto-completion
@@ -248,6 +275,8 @@ class AccountBankSatement(Model):
_inherit = "account.bank.statement"
def button_auto_completion(self, cr, uid, ids, context=None):
+ """Complete line with values given by rules and tic the already_completed
+ checkbox so we won't compute them again until the user untick it !"""
if not context:
context={}
stat_line_obj = self.pool.get('account.bank.statement.line')
@@ -260,8 +289,9 @@ class AccountBankSatement(Model):
except ErrorTooManyPartner, exc:
errors_msg = str(exc)
for id in line_ids:
- vals = res[line.id]
+ vals = res.get(id, False)
if vals:
+ vals['already_completed'] = True
stat_line_obj.write(cr, uid, id, vals, context=ctx)
# cr.commit()
# TOTEST: I don't know if this is working...
diff --git a/account_statement_base_completion/statement_view.xml b/account_statement_base_completion/statement_view.xml
index 0494d505..82a31897 100644
--- a/account_statement_base_completion/statement_view.xml
+++ b/account_statement_base_completion/statement_view.xml
@@ -10,11 +10,12 @@
form
+
+
+
-
-
+
+
@@ -29,6 +30,57 @@
+
+ account.statement.profil.view
+ account.statement.profil
+
+ form
+
+
+
+
+
+
+
+
+
+
+ account.statement.completion.rule.view
+ account.statement.completion.rule
+ form
+
+
+
+
+
+
+ account.statement.completion.rule.view
+ account.statement.completion.rule
+ tree
+
+
+
+
+
+
+
+
+
+
+ Statement Completion Rule
+ account.statement.completion.rule
+ form
+ tree,form
+
+
+
+
diff --git a/account_statement_base_import/__openerp__.py b/account_statement_base_import/__openerp__.py
index e99e8268..4ca05299 100644
--- a/account_statement_base_import/__openerp__.py
+++ b/account_statement_base_import/__openerp__.py
@@ -56,6 +56,8 @@
'website': 'http://www.camptocamp.com',
'init_xml': [],
'update_xml': [
+ "wizard/import_statement_view.xml",
+ "statement_view.xml",
],
'demo_xml': [],
'test': [],
diff --git a/account_statement_base_import/parser/file_parser.py b/account_statement_base_import/parser/file_parser.py
index 69c4f0e2..7c14c4f9 100644
--- a/account_statement_base_import/parser/file_parser.py
+++ b/account_statement_base_import/parser/file_parser.py
@@ -23,7 +23,9 @@ import base64
import csv
import tempfile
import datetime
-from . import parser
+# from . import parser
+from parser import BankStatementImportParser
+from parser import UnicodeDictReader
try:
import xlrd
except:
@@ -33,7 +35,7 @@ class FileParser(BankStatementImportParser):
"""Abstract clall for that help to build a specific parser for all
.csv and .xls files"""
- def __init__(self, parse_name=None, keys_to_validate={}, ftype='csv', convertion_dict=None, *args, **kwargs):
+ def __init__(self, parse_name, keys_to_validate={}, ftype='csv', convertion_dict=None, *args, **kwargs):
"""
:param: convertion_dict : keys and type to convert of every column in the file like
{
@@ -46,7 +48,7 @@ class FileParser(BankStatementImportParser):
"""
- super(self,FileParser).__init__(parse_name, *args, **kwargs)
+ super(FileParser, self).__init__(parse_name, *args, **kwargs)
if ftype in ('csv', 'xls'):
self.ftype = ftype
else:
@@ -69,7 +71,7 @@ class FileParser(BankStatementImportParser):
def _post(self, *args, **kwargs):
"""Cast row type depending on the file format .csv or .xls"""
- self.result_row_list = self._cast_rows(kwargs)
+ self.result_row_list = self._cast_rows(*args, **kwargs)
return True
def _parse(self, *args, **kwargs):
@@ -135,7 +137,7 @@ class FileParser(BankStatementImportParser):
line[rule] = conversion_rules[rule](line[rule])
return result_set
- def _cast_rows(self):
+ def _cast_rows(self, *args, **kwargs):
func = getattr(self, '_from_%s'%(self.ftype))
res = func(self.result_row_list, self.convertion_dict)
return res
diff --git a/account_statement_base_import/parser/generic_file_parser.py b/account_statement_base_import/parser/generic_file_parser.py
index 92cf0559..1c32f0d4 100644
--- a/account_statement_base_import/parser/generic_file_parser.py
+++ b/account_statement_base_import/parser/generic_file_parser.py
@@ -23,7 +23,8 @@ import base64
import csv
import tempfile
import datetime
-from . import file_parser
+# from . import file_parser
+from file_parser import FileParser
try:
import xlrd
except:
@@ -36,7 +37,7 @@ class GenericFileParser(FileParser):
- def __init__(self, parse_name = None, ftype='csv'):
+ def __init__(self, parse_name, ftype='csv'):
convertion_dict = {
'ref': unicode,
'label': unicode,
@@ -48,7 +49,7 @@ class GenericFileParser(FileParser):
keys_to_validate = ['ref', 'label', 'date', 'amount', 'commission_amount']
- super(self,GenericFileParser).__init__(parser_for = parse_name, keys_to_validate={}, ftype='csv', convertion_dict=None ):
+ super(GenericFileParser,self).__init__(parse_name, keys_to_validate=keys_to_validate, ftype=ftype, convertion_dict=convertion_dict)
@classmethod
def parser_for(cls, parser_name):
diff --git a/account_statement_base_import/parser/parser.py b/account_statement_base_import/parser/parser.py
index dcc98876..72e60a72 100644
--- a/account_statement_base_import/parser/parser.py
+++ b/account_statement_base_import/parser/parser.py
@@ -19,6 +19,7 @@
#
##############################################################################
import base64
+import csv
def UnicodeDictReader(utf8_data, **kwargs):
@@ -31,7 +32,7 @@ class BankStatementImportParser(object):
format to import in a bank statement"""
- def __init__(self, parser_name = None, *args, **kwargs):
+ def __init__(self, parser_name, *args, **kwargs):
# The name of the parser as it will be called
self.parser_name = parser_name
# The result as a list of row
@@ -97,12 +98,12 @@ class BankStatementImportParser(object):
self.filebuffer = filebuffer
else:
raise Exception(_('No buffer file given.'))
- self._format(args, kwargs)
- self._pre(args, kwargs)
- self._parse(args, kwargs)
- self._validate(args, kwargs)
- self._post(args, kwargs)
- return self.result_row_list,
+ self._format(*args, **kwargs)
+ self._pre(*args, **kwargs)
+ self._parse(*args, **kwargs)
+ self._validate(*args, **kwargs)
+ self._post(*args, **kwargs)
+ return self.result_row_list
def itersubclasses(cls, _seen=None):
"""
diff --git a/account_statement_base_import/statement.py b/account_statement_base_import/statement.py
index 50dd1a9a..fa5acfcf 100644
--- a/account_statement_base_import/statement.py
+++ b/account_statement_base_import/statement.py
@@ -24,14 +24,17 @@ import datetime
import netsvc
logger = netsvc.Logger()
from openerp.osv.orm import Model, fields
+from openerp.osv import fields, osv
# from account_statement_base_import.parser.file_parser import FileParser
from parser import new_bank_statement_parser
+import sys
+import traceback
class AccountStatementProfil(Model):
_inherit = "account.statement.profil"
- def get_type_selection(self, cr, uid, context=None):
+ def get_import_type_selection(self, cr, uid, context=None):
"""
Has to be inherited to add parser
"""
@@ -50,10 +53,12 @@ class AccountStatementProfil(Model):
}
def write_logs_after_import(self, cr, uid, ids, statement_id, num_lines, context):
+ if type(ids) is int:
+ ids = [ids]
for id in ids:
log = self.read(cr, uid, id, ['rec_log'], context=context)['rec_log']
log_line = log and log.split("\n") or []
- import_date = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
+ import_date = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
log_line[0:0] = [import_date + ' : '
+ _("Bank Statement ID %s have been imported with %s lines ") %(statement_id, num_lines)]
log = "\n".join(log_line)
@@ -62,6 +67,69 @@ class AccountStatementProfil(Model):
"Bank Statement ID %s have been imported with %s lines "%(statement_id, num_lines))
return True
+ def create_global_commission_line(self, cr, uid, commission_global_amount,
+ result_row_list, profile, statement_id, context):
+ """Create the global commission line if there is one. The global commission is computed by
+ summing the commission column of each row. Feel free to override the methode to compute
+ your own commission line from the result_row_list.
+ :params: cr: The DB Cursor
+ :params: uid: int/long ID of the current user in the system
+ :params: commission_global_amount: float
+ :params: result_row_list: [{'key':value}]
+ :params: profile: browserecord of account.statement.profile
+ :params: statement_id : int/long of the current importing statement ID
+ :params: context: global context
+ return: an ID of the statement line that represent the global commission
+ for the statement.
+ """
+ res = False
+ if commission_global_amount:
+ partner_id = profile.partner_id and profile.partner_id.id or False
+ commission_account_id = profile.commission_account_id and profile.commission_account_id.id or False
+ commission_analytic_id = profile.commission_analytic_id and profile.commission_analytic_id.id or False
+ statement_line_obj = self.pool.get('account.bank.statement.line')
+ comm_values = {
+ 'name': 'IN '+ _('Commission line'),
+ 'date': datetime.datetime.now().date(),
+ 'amount': commission_global_amount,
+ 'partner_id': partner_id,
+ 'type': 'general',
+ 'statement_id': statement_id,
+ 'account_id': commission_account_id,
+ 'ref': 'commission',
+ 'analytic_account_id': commission_analytic_id,
+ # !! We set the already_completed so auto-completion will not update those values !
+ 'already_completed': True,
+ }
+ res = statement_line_obj.create(cr, uid,
+ comm_values,
+ context=context)
+ return res
+
+ def prepare_statetement_lines_vals(self, cursor, uid, parser_line,
+ account_payable, account_receivable, statement_id, context):
+ """Hook to change the values of a line. Overide it to compute or change
+ the account or any other values (e.g. if a line is the global commission)"""
+ values = {
+ 'name': parser_line.get('label', parser_line.get('ref','/')),
+ 'date': parser_line.get('date', datetime.datetime.now().date()),
+ 'amount': parser_line['amount'],
+ 'ref': parser_line['ref'],
+ 'type': 'customer',
+ 'statement_id': statement_id,
+ 'label': parser_line.get('label',''),
+ 'commission_amount': parser_line.get('commission_amount', 0.0),
+ #'account_id': journal.default_debit_account_id
+ }
+ values['account_id'] = statement_obj.get_account_for_counterpart(
+ cursor,
+ uid,
+ parser_line['amount'],
+ account_receivable,
+ account_payable
+ )
+ return values
+
def statement_import(self, cursor, uid, ids, profile_id, file_stream, ftype="csv", context=None):
"""Create a bank statement with the given profile and parser. It will fullfill the bank statement
with the values of the file providen, but will not complete data (like finding the partner, or
@@ -76,69 +144,34 @@ class AccountStatementProfil(Model):
raise osv.except_osv(
_("No Profile !"),
_("You must provide a valid profile to import a bank statement !"))
- else:
prof = prof_obj.browse(cursor,uid,profile_id,context)
- partner_id = prof.partner_id and prof.partner_id.id or False
- commission_account_id = prof.commission_account_id and prof.commission_account_id.id or False
- commission_analytic_id = prof.commission_analytic_id and prof.commission_analytic_id.id or False
- parser = new_bank_statement_parser(parse_name=prof.import_type, ftype=ftype)
+ parser = new_bank_statement_parser(prof.import_type, ftype=ftype)
result_row_list = parser.parse(file_stream)
-
# Check all key are present in account.bank.statement.line !!
- parsed_cols = self.result_row_list[0].keys()
+ parsed_cols = result_row_list[0].keys()
for col in parsed_cols:
- if col not in statement_line_obj.__columns__:
+ if col not in statement_line_obj._columns:
raise osv.except_osv(
_("Missing column !"),
_("Column %s you try to import is not present in the bank statement line !") %(col))
statement_id = statement_obj.create(cursor,uid,{'profile_id':prof.id,},context)
- account_receivable, account_payable = self.get_default_pay_receiv_accounts(cursor, uid, context)
+ account_receivable, account_payable = statement_obj.get_default_pay_receiv_accounts(cursor, uid, context)
commission_global_amount = 0.0
try:
# Record every line in the bank statement and compute the global commission
# based on the commission_amount column
for line in result_row_list:
- line_partner_id = False
- line_to_reconcile = False
-
commission_global_amount += line.get('commission_amount', 0.0)
- values = {
- 'name': line.get('label', line.get('ref','/')),
- 'date': line.get('date', datetime.datetime.now().date()),
- 'amount': line['amount'],
- 'ref': line['ref'],
- 'type': 'customer',
- 'statement_id': statement_id,
- #'account_id': journal.default_debit_account_id
- }
- values['account_id'] = self.get_account_for_counterpart(
- cursor,
- uid,
- line['amount'],
- account_receivable,
- account_payable
- )
+ values = self.prepare_statetement_lines_vals(cursor, uid, line, account_payable,
+ account_receivable, statement_id, context)
# we finally create the line in system
statement_line_obj.create(cursor, uid, values, context=context)
# we create commission line
- if commission_global_amount:
- comm_values = {
- 'name': 'IN '+ _('Commission line'),
- 'date': datetime.datetime.now().date(),
- 'amount': commission_global_amount,
- 'partner_id': partner_id,
- 'type': 'general',
- 'statement_id': statement_id,
- 'account_id': commission_account_id,
- 'ref': 'commission',
- 'analytic_account_id': commission_analytic_id
- }
- statement_line_obj.create(cursor, uid,
- comm_values,
- context=context)
+ self.create_global_commission_line(cursor, uid, commission_global_amount,
+ result_row_list, prof, statement_id, context)
attachment_obj.create(
cursor,
@@ -158,16 +191,17 @@ class AccountStatementProfil(Model):
self.button_auto_completion(cursor, uid, statement_id, context)
# Write the needed log infos on profile
- self.write_logs_after_import(self, cr, uid, prof.id, statement_id,
+ self.write_logs_after_import(cursor, uid, prof.id, statement_id,
len(result_row_list), context)
except Exception, exc:
- logger.notifyChannel("Statement import",
- netsvc.LOG_ERROR,
- _("Statement can not be created %s") %(exc,))
-
statement_obj.unlink(cursor, uid, [statement_id])
- raise exc
+ error_type, error_value, trbk = sys.exc_info()
+ st = "Error: %s\nDescription: %s\nTraceback:" % (error_type.__name__, error_value)
+ st += ''.join(traceback.format_tb(trbk, 30))
+ raise osv.except_osv(
+ _("Statement import error"),
+ _("The statement cannot be created : %s") %(st))
return statement_id
diff --git a/account_statement_base_import/statement_view.xml b/account_statement_base_import/statement_view.xml
index 159e53b8..5f4ef287 100644
--- a/account_statement_base_import/statement_view.xml
+++ b/account_statement_base_import/statement_view.xml
@@ -10,22 +10,22 @@
form
-
+
+
-
-
+ string="Import Bank Statement"
+ type="action" icon="gtk-ok"
+ colspan = "2"/>
+
- account_bank_statement_import_base.bank_statement.view_form
+ account_bank_statement.bank_statement.view_formaccount.bank.statementform
diff --git a/account_statement_base_import/wizard/import_statement.py b/account_statement_base_import/wizard/import_statement.py
index 20f58b89..d8c54b4d 100644
--- a/account_statement_base_import/wizard/import_statement.py
+++ b/account_statement_base_import/wizard/import_statement.py
@@ -40,7 +40,8 @@ class CreditPartnerStatementImporter(osv.osv_memory):
res = context['active_ids']
if len(res) > 1:
raise Exception (_('You cannot use this on more than one profile !'))
- return res[0]
+ return res[0]
+ return res
_columns = {
@@ -93,7 +94,7 @@ class CreditPartnerStatementImporter(osv.osv_memory):
return res
def _check_extension(self, filename):
- (shortname, ftype) = os.path.splitext(file_name)
+ (shortname, ftype) = os.path.splitext(filename)
if not ftype:
#We do not use osv exception we do not want to have it logged
raise Exception(_('Please use a file with an extention'))
@@ -107,7 +108,7 @@ class CreditPartnerStatementImporter(osv.osv_memory):
importer = self.browse(cursor, uid, req_id, context)
ftype = self._check_extension(importer.file_name)
sid = self.pool.get(
- 'account.bank.statement').statement_import(
+ 'account.statement.profil').statement_import(
cursor,
uid,
False,
@@ -115,7 +116,7 @@ class CreditPartnerStatementImporter(osv.osv_memory):
importer.input_statement,
ftype.replace('.',''),
context=context
- )
+ )
# obj_data = self.pool.get('ir.model.data')
# act_obj = self.pool.get('ir.actions.act_window')
# result = obj_data.get_object_reference(cursor, uid, 'account_statement_import', 'action_treasury_statement_tree')
diff --git a/account_statement_ext/statement.py b/account_statement_ext/statement.py
index a72319db..97b498b8 100644
--- a/account_statement_ext/statement.py
+++ b/account_statement_ext/statement.py
@@ -24,6 +24,7 @@ import datetime
import netsvc
logger = netsvc.Logger()
from openerp.osv.orm import Model, fields
+from openerp.osv import fields, osv
class AccountStatementProfil(Model):
"""A Profile will contain all infos related to the type of
@@ -493,7 +494,7 @@ class AccountBankSatementLine(Model):
res = {}
obj_partner = self.pool.get('res.partner')
obj_stat = self.pool.get('account.bank.statement')
- receiv_account, pay_account, account_id = False
+ receiv_account = pay_account = account_id = False
# If profil has a receivable_account_id, we return it in any case
if profile_id:
profile = self.pool.get("account.statement.profil").browse(cr,uid,profile_id)
diff --git a/account_statement_ext/statement_view.xml b/account_statement_ext/statement_view.xml
index c5b4f7c1..6f8761a9 100644
--- a/account_statement_ext/statement_view.xml
+++ b/account_statement_ext/statement_view.xml
@@ -188,13 +188,14 @@
+
+ domain="[('profile_id','=',active_id),]"
+ view_type="form"/>