[FIX] Bug fixing and first running version

(lp:c2c-financial-addons/6.1 rev 24.1.19)
This commit is contained in:
Joël Grand-Guillaume
2012-06-15 16:04:08 +02:00
parent 57215e0aa1
commit 5ddd981875
13 changed files with 312 additions and 168 deletions

View File

@@ -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...