mirror of
https://github.com/OCA/account-reconcile.git
synced 2025-01-20 12:27:39 +02:00
[FIX] Bug fixing and first running version
(lp:c2c-financial-addons/6.1 rev 24.1.19)
This commit is contained in:
@@ -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...
|
||||
|
||||
Reference in New Issue
Block a user