mirror of
https://github.com/OCA/account-reconcile.git
synced 2025-01-20 12:27:39 +02:00
[MIGR] migration of bank-statement-reconcile to v7.0 done by Guewen Baconnier and myself.
The goal is to make the modules installable and to clean them to respect the quality standard expected by the community modules. Not to use the new shiny features of the new version 7. * Adapt view * Change the huge create_move_from_st_line method to take part of the v7.0 refactoring done by my previous merge ;) * Small fixes * Make installable = False on non-needed module * Formatting, pep8, pylint warnings Details in the nested log.
This commit is contained in:
@@ -117,4 +117,3 @@ class easy_reconcile_advanced_ref(TransientModel):
|
|||||||
yield ('partner_id', move_line['partner_id'])
|
yield ('partner_id', move_line['partner_id'])
|
||||||
yield ('ref', (move_line['ref'].lower().strip(),
|
yield ('ref', (move_line['ref'].lower().strip(),
|
||||||
move_line['name'].lower().strip()))
|
move_line['name'].lower().strip()))
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
from itertools import groupby, product
|
from itertools import groupby, product
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
from openerp.osv.orm import Model, AbstractModel, TransientModel
|
from openerp.osv.orm import Model, AbstractModel, TransientModel
|
||||||
from openerp.osv import fields
|
from openerp.osv import fields, osv
|
||||||
|
|
||||||
|
|
||||||
class easy_reconcile_advanced(AbstractModel):
|
class easy_reconcile_advanced(AbstractModel):
|
||||||
@@ -271,4 +271,3 @@ class easy_reconcile_advanced(AbstractModel):
|
|||||||
partial_reconciled_ids += reconcile_group_ids
|
partial_reconciled_ids += reconcile_group_ids
|
||||||
|
|
||||||
return reconciled_ids, partial_reconciled_ids
|
return reconciled_ids, partial_reconciled_ids
|
||||||
|
|
||||||
|
|||||||
@@ -34,4 +34,3 @@ class account_easy_reconcile_method(Model):
|
|||||||
'Advanced. Partner and Ref.'),
|
'Advanced. Partner and Ref.'),
|
||||||
]
|
]
|
||||||
return methods
|
return methods
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
from openerp.osv.orm import AbstractModel
|
from openerp.osv.orm import AbstractModel
|
||||||
from openerp.osv import fields
|
from openerp.osv import fields, osv
|
||||||
from operator import itemgetter, attrgetter
|
from operator import itemgetter, attrgetter
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
import time
|
import time
|
||||||
from openerp.osv.orm import Model, AbstractModel
|
from openerp.osv.orm import Model, AbstractModel
|
||||||
from openerp.osv import fields
|
from openerp.osv import fields, osv
|
||||||
from openerp.tools.translate import _
|
from openerp.tools.translate import _
|
||||||
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
'author': 'Camptocamp',
|
'author': 'Camptocamp',
|
||||||
'maintainer': 'Camptocamp',
|
'maintainer': 'Camptocamp',
|
||||||
'category': 'Finance',
|
'category': 'Finance',
|
||||||
'complexity': 'normal', #easy, normal, expert
|
'complexity': 'normal',
|
||||||
'depends': ['account_statement_ext'],
|
'depends': ['account_statement_ext'],
|
||||||
'description': """
|
'description': """
|
||||||
The goal of this module is to improve the basic bank statement, help dealing with huge volume of
|
The goal of this module is to improve the basic bank statement, help dealing with huge volume of
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# -*- encoding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#################################################################################
|
#################################################################################
|
||||||
# #
|
# #
|
||||||
# Copyright (C) 2011 Akretion & Camptocamp
|
# Copyright (C) 2011 Akretion & Camptocamp
|
||||||
@@ -19,9 +19,11 @@
|
|||||||
# #
|
# #
|
||||||
#################################################################################
|
#################################################################################
|
||||||
|
|
||||||
from osv import fields, osv
|
from openerp.osv.orm import Model
|
||||||
|
from openerp.osv import fields, osv
|
||||||
|
|
||||||
class res_partner(osv.osv):
|
|
||||||
|
class res_partner(Model):
|
||||||
"""
|
"""
|
||||||
Add a bank label on the partner so that we can use it to match
|
Add a bank label on the partner so that we can use it to match
|
||||||
this partner when we found this in a statement line.
|
this partner when we found this in a statement line.
|
||||||
@@ -29,10 +31,8 @@ class res_partner(osv.osv):
|
|||||||
_inherit = 'res.partner'
|
_inherit = 'res.partner'
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'bank_statement_label':fields.char('Bank Statement Label', size=100,
|
'bank_statement_label': fields.char('Bank Statement Label', size=100,
|
||||||
help="Enter the various label found on your bank statement separated by a ; If \
|
help="Enter the various label found on your bank statement separated by a ; If \
|
||||||
one of this label is include in the bank statement line, the partner will be automatically \
|
one of this label is include in the bank statement line, the partner will be automatically \
|
||||||
filled (as long as you use this method/rules in your statement profile)."),
|
filled (as long as you use this method/rules in your statement profile)."),
|
||||||
}
|
}
|
||||||
|
|
||||||
res_partner()
|
|
||||||
|
|||||||
@@ -19,13 +19,12 @@
|
|||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
from tools.translate import _
|
from tools.translate import _
|
||||||
import netsvc
|
|
||||||
logger = netsvc.Logger()
|
|
||||||
from openerp.osv.orm import Model, fields
|
from openerp.osv.orm import Model, fields
|
||||||
from openerp.osv import fields, osv
|
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
||||||
from operator import itemgetter, attrgetter
|
from operator import attrgetter
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
class ErrorTooManyPartner(Exception):
|
class ErrorTooManyPartner(Exception):
|
||||||
"""
|
"""
|
||||||
New Exception definition that is raised when more than one partner is matched by
|
New Exception definition that is raised when more than one partner is matched by
|
||||||
@@ -33,6 +32,7 @@ class ErrorTooManyPartner(Exception):
|
|||||||
"""
|
"""
|
||||||
def __init__(self, value):
|
def __init__(self, value):
|
||||||
self.value = value
|
self.value = value
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return repr(self.value)
|
return repr(self.value)
|
||||||
|
|
||||||
@@ -45,17 +45,17 @@ class AccountStatementProfil(Model):
|
|||||||
|
|
||||||
_inherit = "account.statement.profile"
|
_inherit = "account.statement.profile"
|
||||||
|
|
||||||
_columns={
|
_columns = {
|
||||||
# @Akretion : For now, we don't implement this features, but this would probably be there:
|
# @Akretion : For now, we don't implement this features, but this would probably be there:
|
||||||
# 'auto_completion': fields.text('Auto Completion'),
|
# 'auto_completion': fields.text('Auto Completion'),
|
||||||
# 'transferts_account_id':fields.many2one('account.account', 'Transferts Account'),
|
# 'transferts_account_id':fields.many2one('account.account', 'Transferts Account'),
|
||||||
# => You can implement it in a module easily, we design it with your needs in mind
|
# => You can implement it in a module easily, we design it with your needs in mind
|
||||||
# as well !
|
# as well !
|
||||||
|
|
||||||
'rule_ids':fields.many2many('account.statement.completion.rule',
|
'rule_ids': fields.many2many(
|
||||||
|
'account.statement.completion.rule',
|
||||||
string='Related statement profiles',
|
string='Related statement profiles',
|
||||||
rel='as_rul_st_prof_rel',
|
rel='as_rul_st_prof_rel'),
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def find_values_from_rules(self, cr, uid, id, line_id, context=None):
|
def find_values_from_rules(self, cr, uid, id, line_id, context=None):
|
||||||
@@ -72,8 +72,8 @@ class AccountStatementProfil(Model):
|
|||||||
|
|
||||||
...}
|
...}
|
||||||
"""
|
"""
|
||||||
if not context:
|
if context is None:
|
||||||
context={}
|
context = {}
|
||||||
res = {}
|
res = {}
|
||||||
rule_obj = self.pool.get('account.statement.completion.rule')
|
rule_obj = self.pool.get('account.statement.completion.rule')
|
||||||
profile = self.browse(cr, uid, id, context=context)
|
profile = self.browse(cr, uid, id, context=context)
|
||||||
@@ -81,7 +81,7 @@ class AccountStatementProfil(Model):
|
|||||||
sorted_array = sorted(profile.rule_ids, key=attrgetter('sequence'))
|
sorted_array = sorted(profile.rule_ids, key=attrgetter('sequence'))
|
||||||
for rule in sorted_array:
|
for rule in sorted_array:
|
||||||
method_to_call = getattr(rule_obj, rule.function_to_call)
|
method_to_call = getattr(rule_obj, rule.function_to_call)
|
||||||
result = method_to_call(cr,uid,line_id,context)
|
result = method_to_call(cr, uid, line_id, context)
|
||||||
if result:
|
if result:
|
||||||
return result
|
return result
|
||||||
return res
|
return res
|
||||||
@@ -112,16 +112,17 @@ class AccountStatementCompletionRule(Model):
|
|||||||
('get_from_label_and_partner_name', 'From line label (based on partner name)'),
|
('get_from_label_and_partner_name', 'From line label (based on partner name)'),
|
||||||
]
|
]
|
||||||
|
|
||||||
_columns={
|
_columns = {
|
||||||
'sequence': fields.integer('Sequence', help="Lower means parsed first."),
|
'sequence': fields.integer('Sequence', help="Lower means parsed first."),
|
||||||
'name': fields.char('Name', size=128),
|
'name': fields.char('Name', size=128),
|
||||||
'profile_ids': fields.many2many('account.statement.profile',
|
'profile_ids': fields.many2many(
|
||||||
|
'account.statement.profile',
|
||||||
rel='as_rul_st_prof_rel',
|
rel='as_rul_st_prof_rel',
|
||||||
string='Related statement profiles'),
|
string='Related statement profiles'),
|
||||||
'function_to_call': fields.selection(_get_functions, 'Method'),
|
'function_to_call': fields.selection(_get_functions, 'Method'),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_from_ref_and_invoice(self, cursor, uid, line_id, context=None):
|
def get_from_ref_and_invoice(self, cr, uid, line_id, context=None):
|
||||||
"""
|
"""
|
||||||
Match the partner based on the invoice number and the reference of the statement
|
Match the partner based on the invoice number and the reference of the statement
|
||||||
line. Then, call the generic get_values_for_line method to complete other values.
|
line. Then, call the generic get_values_for_line method to complete other values.
|
||||||
@@ -137,23 +138,35 @@ class AccountStatementCompletionRule(Model):
|
|||||||
...}
|
...}
|
||||||
"""
|
"""
|
||||||
st_obj = self.pool.get('account.bank.statement.line')
|
st_obj = self.pool.get('account.bank.statement.line')
|
||||||
st_line = st_obj.browse(cursor,uid,line_id)
|
st_line = st_obj.browse(cr, uid, line_id, context=context)
|
||||||
res = {}
|
res = {}
|
||||||
if st_line:
|
if st_line:
|
||||||
inv_obj = self.pool.get('account.invoice')
|
inv_obj = self.pool.get('account.invoice')
|
||||||
inv_id = inv_obj.search(cursor, uid, [('number', '=', st_line.ref)])
|
inv_id = inv_obj.search(
|
||||||
|
cr,
|
||||||
|
uid,
|
||||||
|
[('number', '=', st_line.ref)],
|
||||||
|
context=context)
|
||||||
if inv_id:
|
if inv_id:
|
||||||
if inv_id and len(inv_id) == 1:
|
if inv_id and len(inv_id) == 1:
|
||||||
inv = inv_obj.browse(cursor, uid, inv_id[0])
|
inv = inv_obj.browse(cr, uid, inv_id[0], context=context)
|
||||||
res['partner_id'] = inv.partner_id.id
|
res['partner_id'] = inv.partner_id.id
|
||||||
elif inv_id and len(inv_id) > 1:
|
elif inv_id and len(inv_id) > 1:
|
||||||
raise ErrorTooManyPartner(_('Line named "%s" (Ref:%s) was matched by more than one partner.')%(st_line.name,st_line.ref))
|
raise ErrorTooManyPartner(
|
||||||
st_vals = st_obj.get_values_for_line(cursor, uid, profile_id = st_line.statement_id.profile_id.id,
|
_('Line named "%s" (Ref:%s) was matched by more '
|
||||||
partner_id = res.get('partner_id',False), line_type = st_line.type, amount = st_line.amount, context = context)
|
'than one partner.') % (st_line.name, st_line.ref))
|
||||||
|
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,
|
||||||
|
amount=st_line.amount,
|
||||||
|
context=context)
|
||||||
res.update(st_vals)
|
res.update(st_vals)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def get_from_ref_and_so(self, cursor, uid, line_id, context=None):
|
def get_from_ref_and_so(self, cr, uid, line_id, context=None):
|
||||||
"""
|
"""
|
||||||
Match the partner based on the SO number and the reference of the statement
|
Match the partner based on the SO number and the reference of the statement
|
||||||
line. Then, call the generic get_values_for_line method to complete other values.
|
line. Then, call the generic get_values_for_line method to complete other values.
|
||||||
@@ -169,24 +182,36 @@ class AccountStatementCompletionRule(Model):
|
|||||||
...}
|
...}
|
||||||
"""
|
"""
|
||||||
st_obj = self.pool.get('account.bank.statement.line')
|
st_obj = self.pool.get('account.bank.statement.line')
|
||||||
st_line = st_obj.browse(cursor,uid,line_id)
|
st_line = st_obj.browse(cr, uid, line_id, context=context)
|
||||||
res = {}
|
res = {}
|
||||||
if st_line:
|
if st_line:
|
||||||
so_obj = self.pool.get('sale.order')
|
so_obj = self.pool.get('sale.order')
|
||||||
so_id = so_obj.search(cursor, uid, [('name', '=', st_line.ref)])
|
so_id = so_obj.search(
|
||||||
|
cr,
|
||||||
|
uid,
|
||||||
|
[('name', '=', st_line.ref)],
|
||||||
|
context=context)
|
||||||
if so_id:
|
if so_id:
|
||||||
if so_id and len(so_id) == 1:
|
if so_id and len(so_id) == 1:
|
||||||
so = so_obj.browse(cursor, uid, so_id[0])
|
so = so_obj.browse(cr, uid, so_id[0], context=context)
|
||||||
res['partner_id'] = so.partner_id.id
|
res['partner_id'] = so.partner_id.id
|
||||||
elif so_id and len(so_id) > 1:
|
elif so_id and len(so_id) > 1:
|
||||||
raise ErrorTooManyPartner(_('Line named "%s" (Ref:%s) was matched by more than one partner.')%(st_line.name,st_line.ref))
|
raise ErrorTooManyPartner(
|
||||||
st_vals = st_obj.get_values_for_line(cursor, uid, profile_id = st_line.statement_id.profile_id.id,
|
_('Line named "%s" (Ref:%s) was matched by more '
|
||||||
partner_id = res.get('partner_id',False), line_type = st_line.type, amount = st_line.amount, context = context)
|
'than one partner.') %
|
||||||
|
(st_line.name, st_line.ref))
|
||||||
|
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,
|
||||||
|
amount=st_line.amount,
|
||||||
|
context=context)
|
||||||
res.update(st_vals)
|
res.update(st_vals)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def get_from_label_and_partner_field(self, cr, uid, line_id, context=None):
|
||||||
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
|
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.
|
and the text defined in the 'bank_statement_label' field of the partner.
|
||||||
@@ -205,25 +230,38 @@ class AccountStatementCompletionRule(Model):
|
|||||||
"""
|
"""
|
||||||
partner_obj = self.pool.get('res.partner')
|
partner_obj = self.pool.get('res.partner')
|
||||||
st_obj = self.pool.get('account.bank.statement.line')
|
st_obj = self.pool.get('account.bank.statement.line')
|
||||||
st_line = st_obj.browse(cursor,uid,line_id)
|
st_line = st_obj.browse(cr, uid, line_id, context=context)
|
||||||
res = {}
|
res = {}
|
||||||
compt = 0
|
compt = 0
|
||||||
if st_line:
|
if st_line:
|
||||||
ids = partner_obj.search(cursor, uid, [['bank_statement_label', '!=', False]], context=context)
|
ids = partner_obj.search(
|
||||||
for partner in partner_obj.browse(cursor, uid, ids, context=context):
|
cr,
|
||||||
|
uid,
|
||||||
|
[('bank_statement_label', '!=', False)],
|
||||||
|
context=context)
|
||||||
|
for partner in partner_obj.browse(cr, uid, ids, context=context):
|
||||||
for partner_label in partner.bank_statement_label.split(';'):
|
for partner_label in partner.bank_statement_label.split(';'):
|
||||||
if partner_label in st_line.label:
|
if partner_label in st_line.label:
|
||||||
compt += 1
|
compt += 1
|
||||||
res['partner_id'] = partner.id
|
res['partner_id'] = partner.id
|
||||||
if compt > 1:
|
if compt > 1:
|
||||||
raise ErrorTooManyPartner(_('Line named "%s" (Ref:%s) was matched by more than one partner.')%(st_line.name,st_line.ref))
|
raise ErrorTooManyPartner(
|
||||||
|
_('Line named "%s" (Ref:%s) was matched by '
|
||||||
|
'more than one partner.') %
|
||||||
|
(st_line.name, st_line.ref))
|
||||||
if res:
|
if res:
|
||||||
st_vals = st_obj.get_values_for_line(cursor, uid, profile_id = st_line.statement_id.profile_id.id,
|
st_vals = st_obj.get_values_for_line(
|
||||||
partner_id = res.get('partner_id',False), line_type = st_line.type, amount = st_line.amount, context = context)
|
cr,
|
||||||
|
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)
|
res.update(st_vals)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def get_from_label_and_partner_name(self, cursor, uid, line_id, context=None):
|
def get_from_label_and_partner_name(self, cr, uid, line_id, context=None):
|
||||||
"""
|
"""
|
||||||
Match the partner based on the label field of the statement line
|
Match the partner based on the label field of the statement line
|
||||||
and the name of the partner.
|
and the name of the partner.
|
||||||
@@ -242,19 +280,28 @@ class AccountStatementCompletionRule(Model):
|
|||||||
# This Method has not been tested yet !
|
# This Method has not been tested yet !
|
||||||
res = {}
|
res = {}
|
||||||
st_obj = self.pool.get('account.bank.statement.line')
|
st_obj = self.pool.get('account.bank.statement.line')
|
||||||
st_line = st_obj.browse(cursor,uid,line_id)
|
st_line = st_obj.browse(cr, uid, line_id, context=context)
|
||||||
if st_line:
|
if st_line:
|
||||||
sql = "SELECT id FROM res_partner WHERE name ~* %s"
|
sql = "SELECT id FROM res_partner WHERE name ~* %s"
|
||||||
pattern = ".*%s.*" % st_line.label
|
pattern = ".*%s.*" % st_line.label
|
||||||
cursor.execute(sql, (pattern,))
|
cr.execute(sql, (pattern,))
|
||||||
result = cursor.fetchall()
|
result = cr.fetchall()
|
||||||
if len(result) > 1:
|
if len(result) > 1:
|
||||||
raise ErrorTooManyPartner(_('Line named "%s" (Ref:%s) was matched by more than one partner.')%(st_line.name,st_line.ref))
|
raise ErrorTooManyPartner(
|
||||||
|
_('Line named "%s" (Ref:%s) was matched by more '
|
||||||
|
'than one partner.') %
|
||||||
|
(st_line.name, st_line.ref))
|
||||||
for id in result[0]:
|
for id in result[0]:
|
||||||
res['partner_id'] = id
|
res['partner_id'] = id
|
||||||
if res:
|
if res:
|
||||||
st_vals = st_obj.get_values_for_line(cursor, uid, profile_id = st_line.statement_id.profile_id.id,
|
st_vals = st_obj.get_values_for_line(
|
||||||
partner_id = res.get('partner_id',False), line_type = st_line.type, amount = st_line.amount, context = context)
|
cr,
|
||||||
|
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)
|
res.update(st_vals)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@@ -270,22 +317,28 @@ class AccountStatementLine(Model):
|
|||||||
"""
|
"""
|
||||||
_inherit = "account.bank.statement.line"
|
_inherit = "account.bank.statement.line"
|
||||||
|
|
||||||
_columns={
|
_columns = {
|
||||||
'additionnal_bank_fields' : fields.serialized('Additionnal infos from bank',
|
'additionnal_bank_fields': fields.serialized(
|
||||||
help="Used by completion and import system. Adds every field that is present in your bank/office \
|
'Additionnal infos from bank',
|
||||||
statement file"),
|
help="Used by completion and import system. Adds every field that "
|
||||||
'label': fields.sparse(type='char', string='Label',
|
"is present in your bank/office statement file"),
|
||||||
|
'label': fields.sparse(
|
||||||
|
type='char',
|
||||||
|
string='Label',
|
||||||
serialization_field='additionnal_bank_fields',
|
serialization_field='additionnal_bank_fields',
|
||||||
help="Generiy field to store a label given from the bank/office on which we can \
|
help="Generic field to store a label given from the "
|
||||||
base the default/standard providen rule."),
|
"bank/office on which we can base the default/standard "
|
||||||
'already_completed': fields.boolean("Auto-Completed",
|
"providen rule."),
|
||||||
help="When this checkbox is ticked, the auto-completion process/button will ignore this line."),
|
'already_completed': fields.boolean(
|
||||||
|
"Auto-Completed",
|
||||||
|
help="When this checkbox is ticked, the auto-completion "
|
||||||
|
"process/button will ignore this line."),
|
||||||
}
|
}
|
||||||
|
|
||||||
_defaults = {
|
_defaults = {
|
||||||
'already_completed': False,
|
'already_completed': False,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def get_line_values_from_rules(self, cr, uid, ids, context=None):
|
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 rules setted on
|
We'll try to find out the values related to the line based on rules setted on
|
||||||
@@ -298,26 +351,34 @@ class AccountStatementLine(Model):
|
|||||||
"""
|
"""
|
||||||
profile_obj = self.pool.get('account.statement.profile')
|
profile_obj = self.pool.get('account.statement.profile')
|
||||||
st_obj = self.pool.get('account.bank.statement.line')
|
st_obj = self.pool.get('account.bank.statement.line')
|
||||||
res={}
|
res = {}
|
||||||
errors_stack = []
|
errors_stack = []
|
||||||
for line in self.browse(cr,uid, ids, context):
|
for line in self.browse(cr, uid, ids, context=context):
|
||||||
if not line.already_completed:
|
if line.already_completed:
|
||||||
try:
|
continue
|
||||||
# Take the default values
|
try:
|
||||||
res[line.id] = st_obj.get_values_for_line(cr, uid, profile_id = line.statement_id.profile_id.id,
|
# Take the default values
|
||||||
line_type = line.type, amount = line.amount, context = context)
|
res[line.id] = st_obj.get_values_for_line(
|
||||||
# Ask the rule
|
cr,
|
||||||
vals = profile_obj.find_values_from_rules(cr, uid, line.statement_id.profile_id.id, line.id, context)
|
uid,
|
||||||
# Merge the result
|
profile_id=line.statement_id.profile_id.id,
|
||||||
res[line.id].update(vals)
|
line_type=line.type,
|
||||||
except ErrorTooManyPartner, exc:
|
amount=line.amount,
|
||||||
msg = "Line ID %s had following error: %s" % (line.id, exc.value)
|
context=context)
|
||||||
errors_stack.append(msg)
|
# Ask the rule
|
||||||
|
vals = profile_obj.find_values_from_rules(
|
||||||
|
cr, uid, line.statement_id.profile_id.id, line.id, context)
|
||||||
|
# Merge the result
|
||||||
|
res[line.id].update(vals)
|
||||||
|
except ErrorTooManyPartner, exc:
|
||||||
|
msg = "Line ID %s had following error: %s" % (line.id, exc.value)
|
||||||
|
errors_stack.append(msg)
|
||||||
if errors_stack:
|
if errors_stack:
|
||||||
msg = u"\n".join(errors_stack)
|
msg = u"\n".join(errors_stack)
|
||||||
raise ErrorTooManyPartner(msg)
|
raise ErrorTooManyPartner(msg)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
class AccountBankSatement(Model):
|
class AccountBankSatement(Model):
|
||||||
"""
|
"""
|
||||||
We add a basic button and stuff to support the auto-completion
|
We add a basic button and stuff to support the auto-completion
|
||||||
@@ -339,22 +400,26 @@ class AccountBankSatement(Model):
|
|||||||
:param char error_msg: Message to add
|
:param char error_msg: Message to add
|
||||||
:number_imported int/long: Number of lines that have been completed
|
:number_imported int/long: Number of lines that have been completed
|
||||||
:return : True
|
:return : True
|
||||||
|
|
||||||
"""
|
"""
|
||||||
error_log = ""
|
error_log = ""
|
||||||
user_name = self.pool.get('res.users').read(cr, uid, uid, ['name'])['name']
|
user_name = self.pool.get('res.users').read(
|
||||||
log = self.read(cr, uid, stat_id, ['completion_logs'], context=context)['completion_logs']
|
cr, uid, uid, ['name'], context=context)['name']
|
||||||
|
log = self.read(
|
||||||
|
cr, uid, stat_id, ['completion_logs'], context=context)['completion_logs']
|
||||||
log_line = log and log.split("\n") or []
|
log_line = log and log.split("\n") or []
|
||||||
completion_date = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
completion_date = datetime.datetime.now().strftime(DEFAULT_SERVER_DATETIME_FORMAT)
|
||||||
if error_msg:
|
if error_msg:
|
||||||
error_log = error_msg
|
error_log = error_msg
|
||||||
log_line[0:0] = [completion_date + ' : '
|
log_line[0:0] = [completion_date + ' : '
|
||||||
+ _("Bank Statement ID %s has %s lines completed by %s") %(stat_id, number_imported, user_name)
|
+ _("Bank Statement ID %s has %s lines completed by %s") % (stat_id, number_imported, user_name)
|
||||||
+ "\n" + error_log + "-------------" + "\n"]
|
+ "\n" + error_log + "-------------" + "\n"]
|
||||||
log = "\n".join(log_line)
|
log = "\n".join(log_line)
|
||||||
self.write(cr, uid, [stat_id], {'completion_logs' : log}, context=context)
|
self.write(cr, uid, [stat_id], {'completion_logs': log}, context=context)
|
||||||
logger.notifyChannel('Bank Statement Completion', netsvc.LOG_INFO,
|
self.message_post(
|
||||||
"Bank Statement ID %s has %s lines completed"%(stat_id, number_imported))
|
cr, uid,
|
||||||
|
[stat_id],
|
||||||
|
body=_('Statement ID %s auto-completed for %s lines completed') % (stat_id, number_imported),
|
||||||
|
context=context)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def button_auto_completion(self, cr, uid, ids, context=None):
|
def button_auto_completion(self, cr, uid, ids, context=None):
|
||||||
@@ -362,8 +427,8 @@ class AccountBankSatement(Model):
|
|||||||
Complete line with values given by rules and tic the already_completed
|
Complete line with values given by rules and tic the already_completed
|
||||||
checkbox so we won't compute them again unless the user untick them !
|
checkbox so we won't compute them again unless the user untick them !
|
||||||
"""
|
"""
|
||||||
if not context:
|
if context is None:
|
||||||
context={}
|
context = {}
|
||||||
stat_line_obj = self.pool.get('account.bank.statement.line')
|
stat_line_obj = self.pool.get('account.bank.statement.line')
|
||||||
msg = ""
|
msg = ""
|
||||||
compl_lines = 0
|
compl_lines = 0
|
||||||
@@ -372,7 +437,8 @@ class AccountBankSatement(Model):
|
|||||||
for line in stat.line_ids:
|
for line in stat.line_ids:
|
||||||
res = {}
|
res = {}
|
||||||
try:
|
try:
|
||||||
res = stat_line_obj.get_line_values_from_rules(cr, uid, [line.id], context=ctx)
|
res = stat_line_obj.get_line_values_from_rules(
|
||||||
|
cr, uid, [line.id], context=ctx)
|
||||||
if res:
|
if res:
|
||||||
compl_lines += 1
|
compl_lines += 1
|
||||||
except ErrorTooManyPartner, exc:
|
except ErrorTooManyPartner, exc:
|
||||||
@@ -383,6 +449,7 @@ class AccountBankSatement(Model):
|
|||||||
if res:
|
if res:
|
||||||
vals = res[line.id]
|
vals = res[line.id]
|
||||||
vals['already_completed'] = True
|
vals['already_completed'] = True
|
||||||
stat_line_obj.write(cr, uid, line.id, vals, context=ctx)
|
stat_line_obj.write(cr, uid, [line.id], vals, context=ctx)
|
||||||
self.write_completion_log(cr, uid, stat.id, msg, compl_lines, context=context)
|
self.write_completion_log(
|
||||||
|
cr, uid, stat.id, msg, compl_lines, context=context)
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -10,21 +10,21 @@
|
|||||||
<field name="type">form</field>
|
<field name="type">form</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<data>
|
<data>
|
||||||
<xpath expr="/form/notebook/page/field[@name='line_ids']/form/field[@name='sequence']" position="after">
|
<xpath expr="/form/sheet/notebook/page/field[@name='line_ids']/form/group/field[@name='sequence']" position="after">
|
||||||
<separator colspan="4" string="Importation related infos"/>
|
<separator colspan="4" string="Importation related infos"/>
|
||||||
<field name="label" />
|
<field name="label" />
|
||||||
<field name="already_completed" />
|
<field name="already_completed" />
|
||||||
</xpath>
|
</xpath>
|
||||||
|
|
||||||
<xpath expr="/form/group[2]" position="attributes">
|
<!-- <xpath expr="/form/group[2]" position="attributes">
|
||||||
<attribute name="col">10</attribute>
|
<attribute name="col">10</attribute>
|
||||||
</xpath>
|
</xpath> -->
|
||||||
|
|
||||||
<xpath expr="/form/group/field[@name='balance_end']" position="after">
|
<xpath expr="/form/sheet/div[@name='import_buttons']" position="after">
|
||||||
<button name="button_auto_completion" string="Auto Completion" states='draft,open' type="object" colspan="1"/>
|
<button name="button_auto_completion" string="Auto Completion" states='draft,open' type="object" colspan="1"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
|
||||||
<xpath expr="/form/notebook/page[@string='Journal Entries']" position="after">
|
<xpath expr="/form/sheet/notebook/page[@string='Transactions']" position="after">
|
||||||
<page string="Completion Logs" attrs="{'invisible':[('completion_logs','=',False)]}">
|
<page string="Completion Logs" attrs="{'invisible':[('completion_logs','=',False)]}">
|
||||||
<field name="completion_logs" colspan="4" nolabel="1" attrs="{'invisible':[('completion_logs','=',False)]}"/>
|
<field name="completion_logs" colspan="4" nolabel="1" attrs="{'invisible':[('completion_logs','=',False)]}"/>
|
||||||
</page>
|
</page>
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
<field name="type">form</field>
|
<field name="type">form</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<data>
|
<data>
|
||||||
<xpath expr="/form/notebook/page/field[@name='line_ids']/tree/field[@name='amount']" position="after">
|
<xpath expr="/form/sheet/notebook/page/field[@name='line_ids']/tree/field[@name='amount']" position="after">
|
||||||
<field name="already_completed" />
|
<field name="already_completed" />
|
||||||
</xpath>
|
</xpath>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -24,8 +24,11 @@
|
|||||||
'author': 'Camptocamp',
|
'author': 'Camptocamp',
|
||||||
'maintainer': 'Camptocamp',
|
'maintainer': 'Camptocamp',
|
||||||
'category': 'Finance',
|
'category': 'Finance',
|
||||||
'complexity': 'normal', #easy, normal, expert
|
'complexity': 'normal',
|
||||||
'depends': ['account_statement_ext','account_statement_base_completion'],
|
'depends': [
|
||||||
|
'account_statement_ext',
|
||||||
|
'account_statement_base_completion'
|
||||||
|
],
|
||||||
'description': """
|
'description': """
|
||||||
This module brings basic methods and fields on bank statement to deal with
|
This module brings basic methods and fields on bank statement to deal with
|
||||||
the importation of different bank and offices. A generic abstract method is defined and an
|
the importation of different bank and offices. A generic abstract method is defined and an
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ try:
|
|||||||
except:
|
except:
|
||||||
raise Exception(_('Please install python lib xlrd'))
|
raise Exception(_('Please install python lib xlrd'))
|
||||||
|
|
||||||
|
|
||||||
class FileParser(BankStatementImportParser):
|
class FileParser(BankStatementImportParser):
|
||||||
"""
|
"""
|
||||||
Generic abstract class for defining parser for .csv or .xls file format.
|
Generic abstract class for defining parser for .csv or .xls file format.
|
||||||
@@ -57,9 +58,9 @@ class FileParser(BankStatementImportParser):
|
|||||||
self.keys_to_validate = keys_to_validate
|
self.keys_to_validate = keys_to_validate
|
||||||
self.convertion_dict = convertion_dict
|
self.convertion_dict = convertion_dict
|
||||||
self.fieldnames = header
|
self.fieldnames = header
|
||||||
self._datemode = 0 # used only for xls documents,
|
self._datemode = 0 # used only for xls documents,
|
||||||
# 0 means Windows mode (1900 based dates).
|
# 0 means Windows mode (1900 based dates).
|
||||||
# Set in _parse_xls, from the contents of the file
|
# Set in _parse_xls, from the contents of the file
|
||||||
|
|
||||||
def _custom_format(self, *args, **kwargs):
|
def _custom_format(self, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
@@ -108,7 +109,6 @@ class FileParser(BankStatementImportParser):
|
|||||||
self.result_row_list = self._cast_rows(*args, **kwargs)
|
self.result_row_list = self._cast_rows(*args, **kwargs)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def _parse_csv(self):
|
def _parse_csv(self):
|
||||||
"""
|
"""
|
||||||
:return: list of dict from csv file (line/rows)
|
:return: list of dict from csv file (line/rows)
|
||||||
@@ -138,7 +138,7 @@ class FileParser(BankStatementImportParser):
|
|||||||
try:
|
try:
|
||||||
wb_file.close()
|
wb_file.close()
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
pass #file is allready closed
|
pass # file is already closed
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _from_csv(self, result_set, conversion_rules):
|
def _from_csv(self, result_set, conversion_rules):
|
||||||
@@ -175,6 +175,6 @@ class FileParser(BankStatementImportParser):
|
|||||||
Convert the self.result_row_list using the self.convertion_dict providen.
|
Convert the self.result_row_list using the self.convertion_dict providen.
|
||||||
We call here _from_xls or _from_csv depending on the self.ftype variable.
|
We call here _from_xls or _from_csv depending on the self.ftype variable.
|
||||||
"""
|
"""
|
||||||
func = getattr(self, '_from_%s'%(self.ftype))
|
func = getattr(self, '_from_%s' % self.ftype)
|
||||||
res = func(self.result_row_list, self.convertion_dict)
|
res = func(self.result_row_list, self.convertion_dict)
|
||||||
return res
|
return res
|
||||||
|
|||||||
@@ -23,13 +23,13 @@ import base64
|
|||||||
import csv
|
import csv
|
||||||
import tempfile
|
import tempfile
|
||||||
import datetime
|
import datetime
|
||||||
# from . import file_parser
|
|
||||||
from file_parser import FileParser
|
from file_parser import FileParser
|
||||||
try:
|
try:
|
||||||
import xlrd
|
import xlrd
|
||||||
except:
|
except:
|
||||||
raise Exception(_('Please install python lib xlrd'))
|
raise Exception(_('Please install python lib xlrd'))
|
||||||
|
|
||||||
|
|
||||||
class GenericFileParser(FileParser):
|
class GenericFileParser(FileParser):
|
||||||
"""
|
"""
|
||||||
Standard parser that use a define format in csv or xls to import into a
|
Standard parser that use a define format in csv or xls to import into a
|
||||||
@@ -47,7 +47,7 @@ class GenericFileParser(FileParser):
|
|||||||
}
|
}
|
||||||
# Order of cols does not matter but first row of the file has to be header
|
# Order of cols does not matter but first row of the file has to be header
|
||||||
keys_to_validate = ['ref', 'label', 'date', 'amount', 'commission_amount']
|
keys_to_validate = ['ref', 'label', 'date', 'amount', 'commission_amount']
|
||||||
super(GenericFileParser,self).__init__(parse_name, keys_to_validate=keys_to_validate, ftype=ftype, convertion_dict=convertion_dict)
|
super(GenericFileParser, self).__init__(parse_name, keys_to_validate=keys_to_validate, ftype=ftype, convertion_dict=convertion_dict)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def parser_for(cls, parser_name):
|
def parser_for(cls, parser_name):
|
||||||
@@ -78,11 +78,11 @@ class GenericFileParser(FileParser):
|
|||||||
for each one.
|
for each one.
|
||||||
"""
|
"""
|
||||||
return {
|
return {
|
||||||
'name': line.get('label', line.get('ref','/')),
|
'name': line.get('label', line.get('ref', '/')),
|
||||||
'date': line.get('date', datetime.datetime.now().date()),
|
'date': line.get('date', datetime.datetime.now().date()),
|
||||||
'amount': line.get('amount', 0.0),
|
'amount': line.get('amount', 0.0),
|
||||||
'ref': line.get('ref','/'),
|
'ref': line.get('ref', '/'),
|
||||||
'label': line.get('label',''),
|
'label': line.get('label', ''),
|
||||||
'commission_amount': line.get('commission_amount', 0.0),
|
'commission_amount': line.get('commission_amount', 0.0),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,10 +93,6 @@ class GenericFileParser(FileParser):
|
|||||||
res = super(GenericFileParser, self)._post(*args, **kwargs)
|
res = super(GenericFileParser, self)._post(*args, **kwargs)
|
||||||
val = 0.0
|
val = 0.0
|
||||||
for row in self.result_row_list:
|
for row in self.result_row_list:
|
||||||
val += row.get('commission_amount',0.0)
|
val += row.get('commission_amount', 0.0)
|
||||||
self.commission_global_amount = val
|
self.commission_global_amount = val
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
import base64
|
import base64
|
||||||
import csv
|
import csv
|
||||||
|
|
||||||
|
|
||||||
def UnicodeDictReader(utf8_data, **kwargs):
|
def UnicodeDictReader(utf8_data, **kwargs):
|
||||||
sniffer = csv.Sniffer()
|
sniffer = csv.Sniffer()
|
||||||
pos = utf8_data.tell()
|
pos = utf8_data.tell()
|
||||||
@@ -31,6 +32,7 @@ def UnicodeDictReader(utf8_data, **kwargs):
|
|||||||
for row in csv_reader:
|
for row in csv_reader:
|
||||||
yield dict([(key, unicode(value, 'utf-8')) for key, value in row.iteritems()])
|
yield dict([(key, unicode(value, 'utf-8')) for key, value in row.iteritems()])
|
||||||
|
|
||||||
|
|
||||||
class BankStatementImportParser(object):
|
class BankStatementImportParser(object):
|
||||||
"""
|
"""
|
||||||
Generic abstract class for defining parser for different files and
|
Generic abstract class for defining parser for different files and
|
||||||
@@ -83,7 +85,6 @@ class BankStatementImportParser(object):
|
|||||||
"""
|
"""
|
||||||
return NotImplementedError
|
return NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
def _pre(self, *args, **kwargs):
|
def _pre(self, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Implement a method in your parser to make a pre-treatment on datas before parsing
|
Implement a method in your parser to make a pre-treatment on datas before parsing
|
||||||
@@ -114,8 +115,6 @@ class BankStatementImportParser(object):
|
|||||||
"""
|
"""
|
||||||
return NotImplementedError
|
return NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_st_line_vals(self, line, *args, **kwargs):
|
def get_st_line_vals(self, line, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Implement a method in your parser that must return a dict of vals that can be
|
Implement a method in your parser that must return a dict of vals that can be
|
||||||
@@ -166,6 +165,7 @@ class BankStatementImportParser(object):
|
|||||||
self._post(*args, **kwargs)
|
self._post(*args, **kwargs)
|
||||||
return self.result_row_list
|
return self.result_row_list
|
||||||
|
|
||||||
|
|
||||||
def itersubclasses(cls, _seen=None):
|
def itersubclasses(cls, _seen=None):
|
||||||
"""
|
"""
|
||||||
itersubclasses(cls)
|
itersubclasses(cls)
|
||||||
@@ -193,10 +193,11 @@ def itersubclasses(cls, _seen=None):
|
|||||||
if not isinstance(cls, type):
|
if not isinstance(cls, type):
|
||||||
raise TypeError('itersubclasses must be called with '
|
raise TypeError('itersubclasses must be called with '
|
||||||
'new-style classes, not %.100r' % cls)
|
'new-style classes, not %.100r' % cls)
|
||||||
if _seen is None: _seen = set()
|
if _seen is None:
|
||||||
|
_seen = set()
|
||||||
try:
|
try:
|
||||||
subs = cls.__subclasses__()
|
subs = cls.__subclasses__()
|
||||||
except TypeError: # fails only when cls is type
|
except TypeError: # fails only when cls is type
|
||||||
subs = cls.__subclasses__(cls)
|
subs = cls.__subclasses__(cls)
|
||||||
for sub in subs:
|
for sub in subs:
|
||||||
if sub not in _seen:
|
if sub not in _seen:
|
||||||
@@ -205,6 +206,7 @@ def itersubclasses(cls, _seen=None):
|
|||||||
for sub in itersubclasses(sub, _seen):
|
for sub in itersubclasses(sub, _seen):
|
||||||
yield sub
|
yield sub
|
||||||
|
|
||||||
|
|
||||||
def new_bank_statement_parser(parser_name, *args, **kwargs):
|
def new_bank_statement_parser(parser_name, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Return an instance of the good parser class base on the providen name
|
Return an instance of the good parser class base on the providen name
|
||||||
@@ -215,4 +217,3 @@ def new_bank_statement_parser(parser_name, *args, **kwargs):
|
|||||||
if cls.parser_for(parser_name):
|
if cls.parser_for(parser_name):
|
||||||
return cls(parser_name, *args, **kwargs)
|
return cls(parser_name, *args, **kwargs)
|
||||||
raise ValueError
|
raise ValueError
|
||||||
|
|
||||||
|
|||||||
@@ -19,36 +19,37 @@
|
|||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
from tools.translate import _
|
from openerp.tools.translate import _
|
||||||
import datetime
|
import datetime
|
||||||
import netsvc
|
from openerp.osv.orm import Model
|
||||||
logger = netsvc.Logger()
|
|
||||||
from openerp.osv.orm import Model, fields
|
|
||||||
from openerp.osv import fields, osv
|
from openerp.osv import fields, osv
|
||||||
# from account_statement_base_import.parser.file_parser import FileParser
|
|
||||||
from parser import new_bank_statement_parser
|
from parser import new_bank_statement_parser
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
|
|
||||||
class AccountStatementProfil(Model):
|
class AccountStatementProfil(Model):
|
||||||
_inherit = "account.statement.profile"
|
_inherit = "account.statement.profile"
|
||||||
|
|
||||||
|
|
||||||
def get_import_type_selection(self, cr, uid, context=None):
|
def get_import_type_selection(self, cr, uid, context=None):
|
||||||
"""
|
"""
|
||||||
Has to be inherited to add parser
|
Has to be inherited to add parser
|
||||||
"""
|
"""
|
||||||
return [('generic_csvxls_so', 'Generic .csv/.xls based on SO Name')]
|
return [('generic_csvxls_so', 'Generic .csv/.xls based on SO Name')]
|
||||||
|
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'launch_import_completion': fields.boolean("Launch completion after import",
|
'launch_import_completion': fields.boolean(
|
||||||
help="Tic that box to automatically launch the completion on each imported\
|
"Launch completion after import",
|
||||||
file using this profile."),
|
help="Tic that box to automatically launch the completion "
|
||||||
|
"on each imported file using this profile."),
|
||||||
'last_import_date': fields.datetime("Last Import Date"),
|
'last_import_date': fields.datetime("Last Import Date"),
|
||||||
'rec_log': fields.text('log', readonly=True),
|
'rec_log': fields.text('log', readonly=True),
|
||||||
'import_type': fields.selection(get_import_type_selection, 'Type of import', required=True,
|
'import_type': fields.selection(
|
||||||
help = "Choose here the method by which you want to import bank statement for this profile."),
|
get_import_type_selection,
|
||||||
|
'Type of import',
|
||||||
|
required=True,
|
||||||
|
help="Choose here the method by which you want to import bank"
|
||||||
|
"statement for this profile."),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,22 +62,26 @@ class AccountStatementProfil(Model):
|
|||||||
:param int/long num_lines: Number of line that have been parsed
|
:param int/long num_lines: Number of line that have been parsed
|
||||||
:return: True
|
:return: True
|
||||||
"""
|
"""
|
||||||
if type(ids) is int:
|
if isinstance(ids, (int, long)):
|
||||||
ids = [ids]
|
ids = [ids]
|
||||||
for id in ids:
|
for id in ids:
|
||||||
log = self.read(cr, uid, id, ['rec_log'], context=context)['rec_log']
|
log = self.read(cr, uid, id, ['rec_log'], context=context)['rec_log']
|
||||||
log_line = log and log.split("\n") or []
|
log_line = log and log.split("\n") or []
|
||||||
import_date = datetime.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 + ' : '
|
log_line[0:0] = [import_date + ' : '
|
||||||
+ _("Bank Statement ID %s have been imported with %s lines ") %(statement_id, num_lines)]
|
+ _("Bank Statement ID %s have been imported with %s lines ") % (statement_id, num_lines)]
|
||||||
log = "\n".join(log_line)
|
log = "\n".join(log_line)
|
||||||
self.write(cr, uid, id, {'rec_log' : log, 'last_import_date':import_date}, context=context)
|
self.write(cr, uid, id, {'rec_log': log, 'last_import_date': import_date}, context=context)
|
||||||
logger.notifyChannel('Bank Statement Import', netsvc.LOG_INFO,
|
self.message_post(
|
||||||
"Bank Statement ID %s have been imported with %s lines "%(statement_id, num_lines))
|
cr,
|
||||||
|
uid,
|
||||||
|
[statement_id],
|
||||||
|
body=_('Statement ID %s have been imported with %s lines.') % (statement_id, num_lines),
|
||||||
|
context=context)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def prepare_global_commission_line_vals(self, cr, uid, parser,
|
def prepare_global_commission_line_vals(
|
||||||
result_row_list, profile, statement_id, context):
|
self, cr, uid, parser, result_row_list, profile, statement_id, context):
|
||||||
"""
|
"""
|
||||||
Prepare the global commission line if there is one. The global
|
Prepare the global commission line if there is one. The global
|
||||||
commission is computed by by calling the get_st_line_commision
|
commission is computed by by calling the get_st_line_commision
|
||||||
@@ -95,9 +100,8 @@ class AccountStatementProfil(Model):
|
|||||||
partner_id = profile.partner_id and profile.partner_id.id or False
|
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_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
|
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 = {
|
comm_values = {
|
||||||
'name': 'IN '+ _('Commission line'),
|
'name': 'IN ' + _('Commission line'),
|
||||||
'date': datetime.datetime.now().date(),
|
'date': datetime.datetime.now().date(),
|
||||||
'amount': parser.get_st_line_commision(),
|
'amount': parser.get_st_line_commision(),
|
||||||
'partner_id': partner_id,
|
'partner_id': partner_id,
|
||||||
@@ -111,8 +115,9 @@ class AccountStatementProfil(Model):
|
|||||||
}
|
}
|
||||||
return comm_values
|
return comm_values
|
||||||
|
|
||||||
def prepare_statetement_lines_vals(self, cursor, uid, parser_vals,
|
def prepare_statetement_lines_vals(
|
||||||
account_payable, account_receivable, statement_id, context):
|
self, cr, uid, parser_vals, account_payable, account_receivable,
|
||||||
|
statement_id, context):
|
||||||
"""
|
"""
|
||||||
Hook to build the values of a line from the parser returned values. At
|
Hook to build the values of a line from the parser returned values. At
|
||||||
least it fullfill the statement_id and account_id. Overide it to add your
|
least it fullfill the statement_id and account_id. Overide it to add your
|
||||||
@@ -127,9 +132,9 @@ class AccountStatementProfil(Model):
|
|||||||
"""
|
"""
|
||||||
statement_obj = self.pool.get('account.bank.statement')
|
statement_obj = self.pool.get('account.bank.statement')
|
||||||
values = parser_vals
|
values = parser_vals
|
||||||
values['statement_id']= statement_id
|
values['statement_id'] = statement_id
|
||||||
values['account_id'] = statement_obj.get_account_for_counterpart(
|
values['account_id'] = statement_obj.get_account_for_counterpart(
|
||||||
cursor,
|
cr,
|
||||||
uid,
|
uid,
|
||||||
parser_vals['amount'],
|
parser_vals['amount'],
|
||||||
account_receivable,
|
account_receivable,
|
||||||
@@ -137,7 +142,7 @@ class AccountStatementProfil(Model):
|
|||||||
)
|
)
|
||||||
return values
|
return values
|
||||||
|
|
||||||
def statement_import(self, cursor, uid, ids, profile_id, file_stream, ftype="csv", context=None):
|
def statement_import(self, cr, 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
|
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
|
with the values of the file providen, but will not complete data (like finding the partner, or
|
||||||
@@ -150,7 +155,6 @@ class AccountStatementProfil(Model):
|
|||||||
:param char: ftype represent the file exstension (csv by default)
|
:param char: ftype represent the file exstension (csv by default)
|
||||||
:return: ID of the created account.bank.statemênt
|
:return: ID of the created account.bank.statemênt
|
||||||
"""
|
"""
|
||||||
context = context or {}
|
|
||||||
statement_obj = self.pool.get('account.bank.statement')
|
statement_obj = self.pool.get('account.bank.statement')
|
||||||
statement_line_obj = self.pool.get('account.bank.statement.line')
|
statement_line_obj = self.pool.get('account.bank.statement.line')
|
||||||
attachment_obj = self.pool.get('ir.attachment')
|
attachment_obj = self.pool.get('ir.attachment')
|
||||||
@@ -159,7 +163,7 @@ class AccountStatementProfil(Model):
|
|||||||
raise osv.except_osv(
|
raise osv.except_osv(
|
||||||
_("No Profile !"),
|
_("No Profile !"),
|
||||||
_("You must provide a valid profile to import a bank statement !"))
|
_("You must provide a valid profile to import a bank statement !"))
|
||||||
prof = prof_obj.browse(cursor,uid,profile_id,context)
|
prof = prof_obj.browse(cr, uid, profile_id, context=context)
|
||||||
|
|
||||||
parser = new_bank_statement_parser(prof.import_type, ftype=ftype)
|
parser = new_bank_statement_parser(prof.import_type, ftype=ftype)
|
||||||
result_row_list = parser.parse(file_stream)
|
result_row_list = parser.parse(file_stream)
|
||||||
@@ -169,32 +173,38 @@ class AccountStatementProfil(Model):
|
|||||||
if col not in statement_line_obj._columns:
|
if col not in statement_line_obj._columns:
|
||||||
raise osv.except_osv(
|
raise osv.except_osv(
|
||||||
_("Missing column !"),
|
_("Missing column !"),
|
||||||
_("Column %s you try to import is not present in the bank statement line !") %(col))
|
_("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)
|
statement_id = statement_obj.create(
|
||||||
account_receivable, account_payable = statement_obj.get_default_pay_receiv_accounts(cursor, uid, context)
|
cr, uid, {'profile_id': prof.id}, context=context)
|
||||||
|
account_receivable, account_payable = statement_obj.get_default_pay_receiv_accounts(
|
||||||
|
cr, uid, context)
|
||||||
try:
|
try:
|
||||||
# Record every line in the bank statement and compute the global commission
|
# Record every line in the bank statement and compute the global commission
|
||||||
# based on the commission_amount column
|
# based on the commission_amount column
|
||||||
for line in result_row_list:
|
for line in result_row_list:
|
||||||
parser_vals = parser.get_st_line_vals(line)
|
parser_vals = parser.get_st_line_vals(line)
|
||||||
values = self.prepare_statetement_lines_vals(cursor, uid, parser_vals, account_payable,
|
values = self.prepare_statetement_lines_vals(
|
||||||
account_receivable, statement_id, context)
|
cr, uid, parser_vals, account_payable,
|
||||||
|
account_receivable, statement_id, context)
|
||||||
# we finally create the line in system
|
# we finally create the line in system
|
||||||
statement_line_obj.create(cursor, uid, values, context=context)
|
statement_line_obj.create(cr, uid, values, context=context)
|
||||||
# Build and create the global commission line for the whole statement
|
# Build and create the global commission line for the whole statement
|
||||||
comm_vals = self.prepare_global_commission_line_vals(cursor, uid, parser, result_row_list, prof, statement_id, context)
|
comm_vals = self.prepare_global_commission_line_vals(
|
||||||
|
cr, uid, parser, result_row_list, prof, statement_id, context)
|
||||||
if comm_vals:
|
if comm_vals:
|
||||||
res = statement_line_obj.create(cursor, uid, comm_vals,context=context)
|
statement_line_obj.create(cr, uid, comm_vals, context=context)
|
||||||
|
|
||||||
attachment_obj.create(
|
attachment_obj.create(
|
||||||
cursor,
|
cr,
|
||||||
uid,
|
uid,
|
||||||
{
|
{
|
||||||
'name': 'statement file',
|
'name': 'statement file',
|
||||||
'datas': file_stream,
|
'datas': file_stream,
|
||||||
'datas_fname': "%s.%s"%(datetime.datetime.now().date(),
|
'datas_fname': "%s.%s" % (
|
||||||
ftype),
|
datetime.datetime.now().date(),
|
||||||
|
ftype),
|
||||||
'res_model': 'account.bank.statement',
|
'res_model': 'account.bank.statement',
|
||||||
'res_id': statement_id,
|
'res_id': statement_id,
|
||||||
},
|
},
|
||||||
@@ -202,24 +212,23 @@ class AccountStatementProfil(Model):
|
|||||||
)
|
)
|
||||||
# If user ask to launch completion at end of import, do it !
|
# If user ask to launch completion at end of import, do it !
|
||||||
if prof.launch_import_completion:
|
if prof.launch_import_completion:
|
||||||
statement_obj.button_auto_completion(cursor, uid, [statement_id], context)
|
statement_obj.button_auto_completion(cr, uid, [statement_id], context)
|
||||||
|
|
||||||
# Write the needed log infos on profile
|
# Write the needed log infos on profile
|
||||||
self.write_logs_after_import(cursor, uid, prof.id, statement_id,
|
self.write_logs_after_import(
|
||||||
len(result_row_list), context)
|
cr, uid, prof.id, statement_id, len(result_row_list), context)
|
||||||
|
|
||||||
except Exception, exc:
|
except Exception:
|
||||||
statement_obj.unlink(cursor, uid, [statement_id])
|
statement_obj.unlink(cr, uid, [statement_id], context=context)
|
||||||
error_type, error_value, trbk = sys.exc_info()
|
error_type, error_value, trbk = sys.exc_info()
|
||||||
st = "Error: %s\nDescription: %s\nTraceback:" % (error_type.__name__, error_value)
|
st = "Error: %s\nDescription: %s\nTraceback:" % (error_type.__name__, error_value)
|
||||||
st += ''.join(traceback.format_tb(trbk, 30))
|
st += ''.join(traceback.format_tb(trbk, 30))
|
||||||
raise osv.except_osv(
|
raise osv.except_osv(
|
||||||
_("Statement import error"),
|
_("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):
|
class AccountStatementLine(Model):
|
||||||
"""
|
"""
|
||||||
Add sparse field on the statement line to allow to store all the
|
Add sparse field on the statement line to allow to store all the
|
||||||
@@ -228,8 +237,9 @@ class AccountStatementLine(Model):
|
|||||||
"""
|
"""
|
||||||
_inherit = "account.bank.statement.line"
|
_inherit = "account.bank.statement.line"
|
||||||
|
|
||||||
_columns={
|
_columns = {
|
||||||
'commission_amount': fields.sparse(type='float', string='Line Commission Amount',
|
'commission_amount': fields.sparse(
|
||||||
|
type='float',
|
||||||
|
string='Line Commission Amount',
|
||||||
serialization_field='additionnal_bank_fields'),
|
serialization_field='additionnal_bank_fields'),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
<field eval="20" name="priority"/>
|
<field eval="20" name="priority"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<data>
|
<data>
|
||||||
<xpath expr="/form/notebook/page/field[@name='line_ids']/form/field[@name='label']" position="after">
|
<xpath expr="/form/sheet/notebook/page/field[@name='line_ids']/form/group/field[@name='label']" position="after">
|
||||||
<field name="commission_amount" />
|
<field name="commission_amount" />
|
||||||
</xpath>
|
</xpath>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -23,15 +23,18 @@
|
|||||||
Wizard to import financial institute date in bank statement
|
Wizard to import financial institute date in bank statement
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from osv import fields, osv
|
from openerp.osv import orm, fields
|
||||||
from tools.translate import _
|
|
||||||
|
from openerp.tools.translate import _
|
||||||
import os
|
import os
|
||||||
|
|
||||||
class CreditPartnerStatementImporter(osv.osv_memory):
|
|
||||||
|
class CreditPartnerStatementImporter(orm.TransientModel):
|
||||||
_name = "credit.statement.import"
|
_name = "credit.statement.import"
|
||||||
|
|
||||||
def default_get(self, cr, uid, fields, context=None):
|
def default_get(self, cr, uid, fields, context=None):
|
||||||
if context is None: context = {}
|
if context is None:
|
||||||
|
context = {}
|
||||||
res = {}
|
res = {}
|
||||||
if (context.get('active_model', False) == 'account.statement.profile' and
|
if (context.get('active_model', False) == 'account.statement.profile' and
|
||||||
context.get('active_ids', False)):
|
context.get('active_ids', False)):
|
||||||
@@ -39,7 +42,7 @@ class CreditPartnerStatementImporter(osv.osv_memory):
|
|||||||
assert len(ids) == 1, 'You cannot use this on more than one profile !'
|
assert len(ids) == 1, 'You cannot use this on more than one profile !'
|
||||||
res['profile_id'] = ids[0]
|
res['profile_id'] = ids[0]
|
||||||
other_vals = self.onchange_profile_id(cr, uid, [], res['profile_id'], context=context)
|
other_vals = self.onchange_profile_id(cr, uid, [], res['profile_id'], context=context)
|
||||||
res.update(other_vals.get('value',{}))
|
res.update(other_vals.get('value', {}))
|
||||||
return res
|
return res
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
@@ -48,71 +51,72 @@ class CreditPartnerStatementImporter(osv.osv_memory):
|
|||||||
required=True),
|
required=True),
|
||||||
'input_statement': fields.binary('Statement file', required=True),
|
'input_statement': fields.binary('Statement file', required=True),
|
||||||
'partner_id': fields.many2one('res.partner',
|
'partner_id': fields.many2one('res.partner',
|
||||||
'Credit insitute partner',
|
'Credit insitute partner'),
|
||||||
),
|
|
||||||
'journal_id': fields.many2one('account.journal',
|
'journal_id': fields.many2one('account.journal',
|
||||||
'Financial journal to use transaction',
|
'Financial journal to use transaction'),
|
||||||
),
|
|
||||||
'input_statement': fields.binary('Statement file', required=True),
|
|
||||||
'file_name': fields.char('File Name', size=128),
|
'file_name': fields.char('File Name', size=128),
|
||||||
'commission_account_id': fields.many2one('account.account',
|
'commission_account_id': fields.many2one('account.account',
|
||||||
'Commission account',
|
'Commission account'),
|
||||||
),
|
|
||||||
'commission_analytic_id': fields.many2one('account.analytic.account',
|
'commission_analytic_id': fields.many2one('account.analytic.account',
|
||||||
'Commission analytic account',
|
'Commission analytic account'),
|
||||||
),
|
|
||||||
'receivable_account_id': fields.many2one('account.account',
|
'receivable_account_id': fields.many2one('account.account',
|
||||||
'Force Receivable/Payable Account'),
|
'Force Receivable/Payable Account'),
|
||||||
'force_partner_on_bank': fields.boolean('Force partner on bank move',
|
'force_partner_on_bank': fields.boolean(
|
||||||
help="Tic that box if you want to use the credit insitute partner\
|
'Force partner on bank move',
|
||||||
in the counterpart of the treasury/banking move."
|
help="Tic that box if you want to use the credit insitute partner "
|
||||||
),
|
"in the counterpart of the treasury/banking move."),
|
||||||
'balance_check': fields.boolean('Balance check',
|
'balance_check': fields.boolean(
|
||||||
help="Tic that box if you want OpenERP to control the start/end balance\
|
'Balance check',
|
||||||
before confirming a bank statement. If don't ticked, no balance control will be done."
|
help="Tic that box if you want OpenERP to control the "
|
||||||
),
|
"start/end balance before confirming a bank statement. "
|
||||||
|
"If don't ticked, no balance control will be done."),
|
||||||
}
|
}
|
||||||
|
|
||||||
def onchange_profile_id(self, cr, uid, ids, profile_id, context=None):
|
def onchange_profile_id(self, cr, uid, ids, profile_id, context=None):
|
||||||
res={}
|
res = {}
|
||||||
if profile_id:
|
if profile_id:
|
||||||
c = self.pool.get("account.statement.profile").browse(cr,uid,profile_id)
|
c = self.pool.get("account.statement.profile").browse(
|
||||||
res = {'value': {'partner_id': c.partner_id and c.partner_id.id or False,
|
cr, uid, profile_id, context=context)
|
||||||
'journal_id': c.journal_id and c.journal_id.id or False, 'commission_account_id': \
|
res = {'value':
|
||||||
c.commission_account_id and c.commission_account_id.id or False,
|
{'partner_id': c.partner_id and c.partner_id.id or False,
|
||||||
'receivable_account_id': c.receivable_account_id and c.receivable_account_id.id or False,
|
'journal_id': c.journal_id and c.journal_id.id or False,
|
||||||
'commission_a':c.commission_analytic_id and c.commission_analytic_id.id or False,
|
'commission_account_id':
|
||||||
'force_partner_on_bank':c.force_partner_on_bank,
|
c.commission_account_id and c.commission_account_id.id or False,
|
||||||
'balance_check':c.balance_check,}}
|
'receivable_account_id': c.receivable_account_id and c.receivable_account_id.id or False,
|
||||||
|
'commission_a': c.commission_analytic_id and c.commission_analytic_id.id or False,
|
||||||
|
'force_partner_on_bank': c.force_partner_on_bank,
|
||||||
|
'balance_check': c.balance_check,
|
||||||
|
}
|
||||||
|
}
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _check_extension(self, filename):
|
def _check_extension(self, filename):
|
||||||
(shortname, ftype) = os.path.splitext(filename)
|
(__, ftype) = os.path.splitext(filename)
|
||||||
if not ftype:
|
if not ftype:
|
||||||
#We do not use osv exception we do not want to have it logged
|
#We do not use osv exception we do not want to have it logged
|
||||||
raise Exception(_('Please use a file with an extention'))
|
raise Exception(_('Please use a file with an extention'))
|
||||||
return ftype
|
return ftype
|
||||||
|
|
||||||
def import_statement(self, cursor, uid, req_id, context=None):
|
def import_statement(self, cr, uid, req_id, context=None):
|
||||||
"""This Function import credit card agency statement"""
|
"""This Function import credit card agency statement"""
|
||||||
context = context or {}
|
context = context or {}
|
||||||
if isinstance(req_id, list):
|
if isinstance(req_id, list):
|
||||||
req_id = req_id[0]
|
req_id = req_id[0]
|
||||||
importer = self.browse(cursor, uid, req_id, context)
|
importer = self.browse(cr, uid, req_id, context)
|
||||||
ftype = self._check_extension(importer.file_name)
|
ftype = self._check_extension(importer.file_name)
|
||||||
sid = self.pool.get(
|
sid = self.pool.get(
|
||||||
'account.statement.profile').statement_import(
|
'account.statement.profile').statement_import(
|
||||||
cursor,
|
cr,
|
||||||
uid,
|
uid,
|
||||||
False,
|
False,
|
||||||
importer.profile_id.id,
|
importer.profile_id.id,
|
||||||
importer.input_statement,
|
importer.input_statement,
|
||||||
ftype.replace('.',''),
|
ftype.replace('.', ''),
|
||||||
context=context
|
context=context
|
||||||
)
|
)
|
||||||
model_obj = self.pool.get('ir.model.data')
|
model_obj = self.pool.get('ir.model.data')
|
||||||
action_obj = self.pool.get('ir.actions.act_window')
|
action_obj = self.pool.get('ir.actions.act_window')
|
||||||
action_id = model_obj.get_object_reference(cursor, uid, 'account', 'action_bank_statement_tree')[1]
|
action_id = model_obj.get_object_reference(cr, uid, 'account', 'action_bank_statement_tree')[1]
|
||||||
res = action_obj.read(cursor, uid, action_id)
|
res = action_obj.read(cr, uid, action_id)
|
||||||
res['domain'] = res['domain'][:-1] + ",('id', '=', %d)]" % sid
|
res['domain'] = res['domain'][:-1] + ",('id', '=', %d)]" % sid
|
||||||
return res
|
return res
|
||||||
|
|||||||
@@ -18,4 +18,3 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
|||||||
@@ -24,8 +24,11 @@
|
|||||||
'author': 'Camptocamp',
|
'author': 'Camptocamp',
|
||||||
'maintainer': 'Camptocamp',
|
'maintainer': 'Camptocamp',
|
||||||
'category': 'Finance',
|
'category': 'Finance',
|
||||||
'complexity': 'normal', #easy, normal, expert
|
'complexity': 'normal',
|
||||||
'depends': ['account_statement_base_completion','account_voucher'],
|
'depends': [
|
||||||
|
'account_statement_base_completion',
|
||||||
|
'account_voucher'
|
||||||
|
],
|
||||||
'description': """
|
'description': """
|
||||||
This module is only needed when using account_statement_base_completion with voucher in order adapt the view correctly.
|
This module is only needed when using account_statement_base_completion with voucher in order adapt the view correctly.
|
||||||
""",
|
""",
|
||||||
@@ -36,9 +39,9 @@
|
|||||||
],
|
],
|
||||||
'demo_xml': [],
|
'demo_xml': [],
|
||||||
'test': [],
|
'test': [],
|
||||||
'installable': True,
|
'installable': False,
|
||||||
'images': [],
|
'images': [],
|
||||||
'auto_install': True,
|
'auto_install': False,
|
||||||
'license': 'AGPL-3',
|
'license': 'AGPL-3',
|
||||||
'active': False,
|
'active': False,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,19 +3,19 @@
|
|||||||
<data>
|
<data>
|
||||||
|
|
||||||
<!-- Override what we have in account_statement_base_completion to replace the one in the voucher -->
|
<!-- Override what we have in account_statement_base_completion to replace the one in the voucher -->
|
||||||
<record id="account_statement_base_completion.bank_statement_view_form2" model="ir.ui.view">
|
<!-- <record id="account_statement_base_completion.bank_statement_view_form2" model="ir.ui.view">
|
||||||
<field name="name">account_bank_statement_import_base.bank_statement.auto_cmpl</field>
|
<field name="name">account_bank_statement_import_base.bank_statement.auto_cmpl</field>
|
||||||
<field name="model">account.bank.statement</field>
|
<field name="model">account.bank.statement</field>
|
||||||
<field name="inherit_id" ref="account_voucher.view_bank_statement_tree_voucher" />
|
<field name="inherit_id" ref="account_voucher.view_bank_statement_tree_voucher" />
|
||||||
<field name="type">form</field>
|
<field name="type">form</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<data>
|
<data>
|
||||||
<xpath expr="/form/notebook/page/field[@name='line_ids']/tree/field[@name='voucher_id']" position="after">
|
<xpath expr="/form/sheet/notebook/page/field[@name='line_ids']/tree/field[@name='voucher_id']" position="after">
|
||||||
<field name="already_completed" />
|
<field name="already_completed" />
|
||||||
</xpath>
|
</xpath>
|
||||||
</data>
|
</data>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record> -->
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
</openerp>
|
</openerp>
|
||||||
|
|||||||
@@ -24,8 +24,11 @@
|
|||||||
'author': 'Camptocamp',
|
'author': 'Camptocamp',
|
||||||
'maintainer': 'Camptocamp',
|
'maintainer': 'Camptocamp',
|
||||||
'category': 'Finance',
|
'category': 'Finance',
|
||||||
'complexity': 'normal', #easy, normal, expert
|
'complexity': 'normal',
|
||||||
'depends': ['account'],
|
'depends': [
|
||||||
|
'account',
|
||||||
|
'report_webkit'
|
||||||
|
],
|
||||||
'description': """
|
'description': """
|
||||||
Improve the basic bank statement, by adding various new features,
|
Improve the basic bank statement, by adding various new features,
|
||||||
and help dealing with huge volume of reconciliation through payment offices such as Paypal, Lazer,
|
and help dealing with huge volume of reconciliation through payment offices such as Paypal, Lazer,
|
||||||
|
|||||||
@@ -18,12 +18,13 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
import netsvc
|
|
||||||
logger = netsvc.Logger()
|
from openerp.osv.orm import Model
|
||||||
from openerp.osv.orm import Model, fields
|
from openerp.osv import fields
|
||||||
|
|
||||||
|
|
||||||
class account_move(Model):
|
class account_move(Model):
|
||||||
_inherit='account.move'
|
_inherit = 'account.move'
|
||||||
|
|
||||||
def unlink(self, cr, uid, ids, context=None):
|
def unlink(self, cr, uid, ids, context=None):
|
||||||
"""
|
"""
|
||||||
@@ -35,6 +36,3 @@ class account_move(Model):
|
|||||||
if move_line.reconcile_id:
|
if move_line.reconcile_id:
|
||||||
move_line.reconcile_id.unlink(context=context)
|
move_line.reconcile_id.unlink(context=context)
|
||||||
return super(account_move, self).unlink(cr, uid, ids, context=context)
|
return super(account_move, self).unlink(cr, uid, ids, context=context)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
# -*- encoding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
|
||||||
# __init__.py
|
|
||||||
#
|
|
||||||
# Copyright (c) 2009 CamptoCamp. All rights reserved.
|
|
||||||
##############################################################################
|
|
||||||
#
|
#
|
||||||
# WARNING: This program as such is intended to be used by professional
|
# WARNING: This program as such is intended to be used by professional
|
||||||
# programmers who take the whole responsability of assessing all potential
|
# programmers who take the whole responsability of assessing all potential
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# -*- encoding: utf-8 -*-
|
# -*- coding utf-8 -*-
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
# Author: Nicolas Bessi. Copyright Camptocamp SA
|
# Author: Nicolas Bessi. Copyright Camptocamp SA
|
||||||
@@ -18,33 +18,29 @@
|
|||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
import time
|
from openerp.report import report_sxw
|
||||||
|
from openerp.tools.translate import _
|
||||||
from report import report_sxw
|
from openerp import pooler
|
||||||
from osv import osv
|
|
||||||
from tools.translate import _
|
|
||||||
import pooler
|
|
||||||
from operator import add, itemgetter
|
|
||||||
from itertools import groupby
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from report_webkit import webkit_report
|
from report_webkit import webkit_report
|
||||||
|
|
||||||
|
|
||||||
class BankStatementWebkit(report_sxw.rml_parse):
|
class BankStatementWebkit(report_sxw.rml_parse):
|
||||||
|
|
||||||
def __init__(self, cursor, uid, name, context):
|
def __init__(self, cr, uid, name, context):
|
||||||
super(BankStatementWebkit, self).__init__(cursor, uid, name, context=context)
|
super(BankStatementWebkit, self).__init__(cr, uid, name, context=context)
|
||||||
self.pool = pooler.get_pool(self.cr.dbname)
|
self.pool = pooler.get_pool(self.cr.dbname)
|
||||||
self.cursor = self.cr
|
self.cursor = self.cr
|
||||||
|
|
||||||
company = self.pool.get('res.users').browse(self.cr, uid, uid, context=context).company_id
|
company = self.pool.get('res.users').browse(
|
||||||
|
self.cr, uid, uid, context=context).company_id
|
||||||
header_report_name = ' - '.join((_('BORDEREAU DE REMISE DE CHEQUES'),
|
header_report_name = ' - '.join((_('BORDEREAU DE REMISE DE CHEQUES'),
|
||||||
company.name, company.currency_id.name))
|
company.name, company.currency_id.name))
|
||||||
statement = self.pool.get('account.bank.statement').browse(cursor,uid,context['active_id']);
|
|
||||||
footer_date_time = self.formatLang(str(datetime.today())[:19], date_time=True)
|
footer_date_time = self.formatLang(str(datetime.today())[:19], date_time=True)
|
||||||
self.localcontext.update({
|
self.localcontext.update({
|
||||||
'cr': cursor,
|
'cr': cr,
|
||||||
'uid': uid,
|
'uid': uid,
|
||||||
'get_bank_statement' : self._get_bank_statement_data,
|
'get_bank_statement': self._get_bank_statement_data,
|
||||||
'report_name': _('BORDEREAU DE REMISE DE CHEQUES'),
|
'report_name': _('BORDEREAU DE REMISE DE CHEQUES'),
|
||||||
'additional_args': [
|
'additional_args': [
|
||||||
('--header-font-name', 'Helvetica'),
|
('--header-font-name', 'Helvetica'),
|
||||||
@@ -58,10 +54,15 @@ class BankStatementWebkit(report_sxw.rml_parse):
|
|||||||
('--footer-line',),
|
('--footer-line',),
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
def _get_bank_statement_data(self,statement):
|
|
||||||
|
def _get_bank_statement_data(self, statement):
|
||||||
statement_obj = self.pool.get('account.bank.statement.line')
|
statement_obj = self.pool.get('account.bank.statement.line')
|
||||||
statement_line_ids = statement_obj.search(self.cr,self.uid,[['statement_id','=',statement.id]])
|
statement_line_ids = statement_obj.search(
|
||||||
statement_lines = statement_obj.browse(self.cr,self.uid,statement_line_ids)
|
self.cr,
|
||||||
|
self.uid,
|
||||||
|
[('statement_id', '=', statement.id)])
|
||||||
|
statement_lines = statement_obj.browse(
|
||||||
|
self.cr, self.uid, statement_line_ids)
|
||||||
return statement_lines
|
return statement_lines
|
||||||
|
|
||||||
webkit_report.WebKitParser('report.bank_statement_webkit',
|
webkit_report.WebKitParser('report.bank_statement_webkit',
|
||||||
|
|||||||
@@ -19,12 +19,10 @@
|
|||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
from tools.translate import _
|
from openerp.osv.orm import Model
|
||||||
import datetime
|
|
||||||
import netsvc
|
|
||||||
logger = netsvc.Logger()
|
|
||||||
from openerp.osv.orm import Model, fields
|
|
||||||
from openerp.osv import fields, osv
|
from openerp.osv import fields, osv
|
||||||
|
from openerp.tools.translate import _
|
||||||
|
|
||||||
|
|
||||||
class AccountStatementProfil(Model):
|
class AccountStatementProfil(Model):
|
||||||
"""
|
"""
|
||||||
@@ -36,43 +34,51 @@ class AccountStatementProfil(Model):
|
|||||||
_description = "Statement Profil"
|
_description = "Statement Profil"
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'name': fields.char('Name', size=128, required=True),
|
'name': fields.char('Name', required=True),
|
||||||
'partner_id': fields.many2one('res.partner',
|
'partner_id': fields.many2one(
|
||||||
'Bank/Payment Office partner',
|
'res.partner',
|
||||||
help="Put a partner if you want to have it on the commission move \
|
'Bank/Payment Office partner',
|
||||||
(and optionaly on the counterpart of the intermediate/banking move \
|
help="Put a partner if you want to have it on the "
|
||||||
if you tic the corresponding checkbox)."),
|
"commission move (and optionaly on the counterpart "
|
||||||
'journal_id': fields.many2one('account.journal',
|
"of the intermediate/banking move if you tick the "
|
||||||
'Financial journal to use for transaction',
|
"corresponding checkbox)."),
|
||||||
required=True),
|
'journal_id': fields.many2one(
|
||||||
'commission_account_id': fields.many2one('account.account',
|
'account.journal',
|
||||||
'Commission account',
|
'Financial journal to use for transaction',
|
||||||
required=True),
|
required=True),
|
||||||
'commission_analytic_id': fields.many2one('account.analytic.account',
|
'commission_account_id': fields.many2one(
|
||||||
'Commission analytic account'),
|
'account.account',
|
||||||
'receivable_account_id': fields.many2one('account.account',
|
'Commission account',
|
||||||
'Force Receivable/Payable Account',
|
required=True),
|
||||||
help="Choose a receivable account to force the default\
|
'commission_analytic_id': fields.many2one(
|
||||||
debit/credit account (eg. an intermediat bank account instead of\
|
'account.analytic.account',
|
||||||
default debitors)."),
|
'Commission analytic account'),
|
||||||
'force_partner_on_bank': fields.boolean('Force partner on bank move',
|
'receivable_account_id': fields.many2one(
|
||||||
help="Tic that box if you want to use the credit insitute partner\
|
'account.account',
|
||||||
in the counterpart of the intermediat/banking move."
|
'Force Receivable/Payable Account',
|
||||||
),
|
help="Choose a receivable account to force the default "
|
||||||
'balance_check': fields.boolean('Balance check',
|
"debit/credit account (eg. an intermediat bank account "
|
||||||
help="Tic that box if you want OpenERP to control the start/end \
|
"instead of default debitors)."),
|
||||||
balance before confirming a bank statement. If don't ticked, no \
|
'force_partner_on_bank': fields.boolean(
|
||||||
balance control will be done."
|
'Force partner on bank move',
|
||||||
),
|
help="Tick that box if you want to use the credit "
|
||||||
'bank_statement_prefix': fields.char('Bank Statement Prefix', size=32),
|
"institute partner in the counterpart of the "
|
||||||
'bank_statement_ids': fields.one2many('account.bank.statement', 'profile_id', 'Bank Statement Imported'),
|
"intermediate/banking move."),
|
||||||
|
'balance_check': fields.boolean(
|
||||||
|
'Balance check',
|
||||||
|
help="Tick that box if you want OpenERP to control "
|
||||||
|
"the start/end balance before confirming a bank statement. "
|
||||||
|
"If don't ticked, no balance control will be done."
|
||||||
|
),
|
||||||
|
'bank_statement_prefix': fields.char(
|
||||||
|
'Bank Statement Prefix', size=32),
|
||||||
|
'bank_statement_ids': fields.one2many(
|
||||||
|
'account.bank.statement', 'profile_id', 'Bank Statement Imported'),
|
||||||
}
|
}
|
||||||
|
|
||||||
def _check_partner(self, cr, uid, ids, context=None):
|
def _check_partner(self, cr, uid, ids, context=None):
|
||||||
obj = self.browse(cr, uid, ids[0], context=context)
|
obj = self.browse(cr, uid, ids[0], context=context)
|
||||||
if obj.partner_id == False and obj.force_partner_on_bank:
|
if obj.partner_id is False and obj.force_partner_on_bank:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -96,33 +102,41 @@ class AccountBankSatement(Model):
|
|||||||
_inherit = "account.bank.statement"
|
_inherit = "account.bank.statement"
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'profile_id': fields.many2one('account.statement.profile',
|
'profile_id': fields.many2one(
|
||||||
'Profil', required=True, readonly=True, states={'draft': [('readonly', False)]}),
|
'account.statement.profile',
|
||||||
|
'Profil',
|
||||||
|
required=True,
|
||||||
|
readonly=True,
|
||||||
|
states={'draft': [('readonly', False)]}),
|
||||||
'credit_partner_id': fields.related(
|
'credit_partner_id': fields.related(
|
||||||
'profile_id',
|
'profile_id',
|
||||||
'partner_id',
|
'partner_id',
|
||||||
type='many2one',
|
type='many2one',
|
||||||
relation='res.partner',
|
relation='res.partner',
|
||||||
string='Financial Partner',
|
string='Financial Partner',
|
||||||
store=True, readonly=True),
|
store=True,
|
||||||
|
readonly=True),
|
||||||
'balance_check': fields.related(
|
'balance_check': fields.related(
|
||||||
'profile_id',
|
'profile_id',
|
||||||
'balance_check',
|
'balance_check',
|
||||||
type='boolean',
|
type='boolean',
|
||||||
string='Balance check',
|
string='Balance check',
|
||||||
store=True, readonly=True),
|
store=True,
|
||||||
'journal_id': fields.related(
|
readonly=True),
|
||||||
|
'journal_id': fields.related(
|
||||||
'profile_id',
|
'profile_id',
|
||||||
'journal_id',
|
'journal_id',
|
||||||
type='many2one',
|
type='many2one',
|
||||||
relation='account.journal',
|
relation='account.journal',
|
||||||
string='Journal',
|
string='Journal',
|
||||||
store=True, readonly=True),
|
store=True,
|
||||||
'period_id': fields.many2one('account.period', 'Period', required=False, readonly=True),
|
readonly=True),
|
||||||
|
'period_id': fields.many2one(
|
||||||
|
'account.period', 'Period', required=False, readonly=True),
|
||||||
}
|
}
|
||||||
|
|
||||||
_defaults = {
|
_defaults = {
|
||||||
'period_id': lambda *a: False,
|
'period_id': False,
|
||||||
}
|
}
|
||||||
|
|
||||||
def create(self, cr, uid, vals, context=None):
|
def create(self, cr, uid, vals, context=None):
|
||||||
@@ -130,16 +144,16 @@ class AccountBankSatement(Model):
|
|||||||
need it."""
|
need it."""
|
||||||
if 'profile_id' in vals:
|
if 'profile_id' in vals:
|
||||||
profile_obj = self.pool.get('account.statement.profile')
|
profile_obj = self.pool.get('account.statement.profile')
|
||||||
profile = profile_obj.browse(cr,uid,vals['profile_id'],context)
|
profile = profile_obj.browse(cr, uid, vals['profile_id'], context=context)
|
||||||
vals['journal_id'] = profile.journal_id.id
|
vals['journal_id'] = profile.journal_id.id
|
||||||
return super(AccountBankSatement, self).create(cr, uid, vals, context=context)
|
return super(AccountBankSatement, self).create(cr, uid, vals, context=context)
|
||||||
|
|
||||||
def _get_period(self, cursor, uid, date, context=None):
|
def _get_period(self, cr, uid, date, context=None):
|
||||||
"""
|
"""
|
||||||
Find matching period for date, used in the statement line creation.
|
Find matching period for date, used in the statement line creation.
|
||||||
"""
|
"""
|
||||||
period_obj = self.pool.get('account.period')
|
period_obj = self.pool.get('account.period')
|
||||||
periods = period_obj.find(cursor, uid, dt=date, context=context)
|
periods = period_obj.find(cr, uid, dt=date, context=context)
|
||||||
return periods and periods[0] or False
|
return periods and periods[0] or False
|
||||||
|
|
||||||
def _check_company_id(self, cr, uid, ids, context=None):
|
def _check_company_id(self, cr, uid, ids, context=None):
|
||||||
@@ -158,158 +172,98 @@ class AccountBankSatement(Model):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
_constraints = [
|
_constraints = [
|
||||||
(_check_company_id, 'The journal and period chosen have to belong to the same company.', ['journal_id','period_id']),
|
(_check_company_id,
|
||||||
|
'The journal and period chosen have to belong to the same company.',
|
||||||
|
['journal_id', 'period_id']),
|
||||||
]
|
]
|
||||||
|
|
||||||
def button_cancel(self, cr, uid, ids, context={}):
|
def button_cancel(self, cr, uid, ids, context=None):
|
||||||
"""
|
"""
|
||||||
We cancel the related move, delete them and finally put the
|
We cancel the related move, delete them and finally put the
|
||||||
statement in draft state. So no need to unreconcile all entries,
|
statement in draft state. So no need to unreconcile all entries,
|
||||||
then unpost them, then finaly cancel the bank statement.
|
then unpost them, then finaly cancel the bank statement.
|
||||||
"""
|
"""
|
||||||
done = []
|
|
||||||
for st in self.browse(cr, uid, ids, context=context):
|
for st in self.browse(cr, uid, ids, context=context):
|
||||||
if st.state=='draft':
|
if st.state == 'draft':
|
||||||
continue
|
continue
|
||||||
ids = []
|
ids = []
|
||||||
for line in st.line_ids:
|
for line in st.line_ids:
|
||||||
for move in line.move_ids:
|
for move in line.move_ids:
|
||||||
if move.state <> 'draft':
|
if move.state != 'draft':
|
||||||
move.button_cancel(context=context)
|
move.button_cancel(context=context)
|
||||||
move.unlink(context=context)
|
return super(AccountBankSatement, self).button_cancel(
|
||||||
done.append(st.id)
|
cr, uid, ids, context=context)
|
||||||
self.write(cr, uid, done, {'state':'draft'}, context=context)
|
|
||||||
return True
|
|
||||||
|
|
||||||
def create_move_from_st_line(self, cr, uid, st_line_id, company_currency_id, st_line_number, context=None):
|
def _prepare_move(self, cr, uid, st_line, st_line_number, context=None):
|
||||||
|
"""Add the period_id from the statement line date to the move preparation.
|
||||||
|
Originaly, it was taken from the statement period_id
|
||||||
|
:param browse_record st_line: account.bank.statement.line record to
|
||||||
|
create the move from.
|
||||||
|
:param char st_line_number: will be used as the name of the generated account move
|
||||||
|
:return: dict of value to create() the account.move
|
||||||
|
"""
|
||||||
|
if context is None:
|
||||||
|
context = {}
|
||||||
|
res = super(AccountBankSatement, self)._prepare_move(
|
||||||
|
cr, uid, st_line, st_line_number, context=context)
|
||||||
|
ctx = context.copy()
|
||||||
|
ctx['company_id'] = st_line.company_id.id
|
||||||
|
period_id = self._get_period(cr, uid, st_line.date, context=ctx)
|
||||||
|
res.update({'period_id': period_id})
|
||||||
|
return res
|
||||||
|
|
||||||
|
def _prepare_move_line_vals(
|
||||||
|
self, cr, uid, st_line, move_id, debit, credit, currency_id=False,
|
||||||
|
amount_currency=False, account_id=False, analytic_id=False,
|
||||||
|
partner_id=False, context=None):
|
||||||
|
"""Add the period_id from the statement line date to the move preparation.
|
||||||
|
Originaly, it was taken from the statement period_id
|
||||||
|
|
||||||
|
:param browse_record st_line: account.bank.statement.line record to
|
||||||
|
create the move from.
|
||||||
|
:param int/long move_id: ID of the account.move to link the move line
|
||||||
|
:param float debit: debit amount of the move line
|
||||||
|
:param float credit: credit amount of the move line
|
||||||
|
:param int/long currency_id: ID of currency of the move line to create
|
||||||
|
:param float amount_currency: amount of the debit/credit expressed in the currency_id
|
||||||
|
:param int/long account_id: ID of the account to use in the move line if different
|
||||||
|
from the statement line account ID
|
||||||
|
:param int/long analytic_id: ID of analytic account to put on the move line
|
||||||
|
:param int/long partner_id: ID of the partner to put on the move line
|
||||||
|
:return: dict of value to create() the account.move.line
|
||||||
|
"""
|
||||||
|
if context is None:
|
||||||
|
context = {}
|
||||||
|
res = super(AccountBankSatement, self)._prepare_move_line_vals(
|
||||||
|
cr, uid, st_line, move_id, debit, credit,
|
||||||
|
currency_id=currency_id,
|
||||||
|
amount_currency=amount_currency,
|
||||||
|
account_id=account_id,
|
||||||
|
analytic_id=analytic_id,
|
||||||
|
partner_id=partner_id, context=context)
|
||||||
|
ctx = context.copy()
|
||||||
|
ctx['company_id'] = st_line.company_id.id
|
||||||
|
period_id = self._get_period(cr, uid, st_line.date, context=ctx)
|
||||||
|
res.update({'period_id': period_id})
|
||||||
|
return res
|
||||||
|
|
||||||
|
def _get_counter_part_partner(self, cr, uid, st_line, context=None):
|
||||||
"""
|
"""
|
||||||
Override a large portion of the code to compute the periode for each line instead of
|
|
||||||
taking the period of the whole statement.
|
|
||||||
Remove the entry posting on generated account moves.
|
|
||||||
We change the move line generated from the lines depending on the profile:
|
We change the move line generated from the lines depending on the profile:
|
||||||
- If receivable_account_id is set, we'll use it instead of the "partner" one
|
|
||||||
- If partner_id is set, we'll us it for the commission (when imported throufh the wizard)
|
|
||||||
- If partner_id is set and force_partner_on_bank is ticked, we'll let the partner of each line
|
- If partner_id is set and force_partner_on_bank is ticked, we'll let the partner of each line
|
||||||
for the debit line, but we'll change it on the credit move line for the choosen partner_id
|
for the debit line, but we'll change it on the credit move line for the choosen partner_id
|
||||||
=> This will ease the reconciliation process with the bank as the partner will match the bank
|
=> This will ease the reconciliation process with the bank as the partner will match the bank
|
||||||
statement line
|
statement line
|
||||||
|
:param browse_record st_line: account.bank.statement.line record to
|
||||||
:param int/long: st_line_id: account.bank.statement.line ID
|
create the move from.
|
||||||
:param int/long: company_currency_id: res.currency ID
|
:return: int/long of the res.partner to use as counterpart
|
||||||
:param char: st_line_number: that will be used as the name of the generated account move
|
|
||||||
:return: int/long: ID of the created account.move
|
|
||||||
"""
|
"""
|
||||||
if context is None:
|
bank_partner_id = super(AccountBankSatement, self).\
|
||||||
context = {}
|
_get_counter_part_partner(cr, uid, st_line, context=context)
|
||||||
res_currency_obj = self.pool.get('res.currency')
|
# get the right partner according to the chosen profil
|
||||||
account_move_obj = self.pool.get('account.move')
|
if st_line.statement_id.profile_id.force_partner_on_bank:
|
||||||
account_move_line_obj = self.pool.get('account.move.line')
|
bank_partner_id = st_line.statement_id.profile_id.partner_id.id
|
||||||
account_bank_statement_line_obj = self.pool.get('account.bank.statement.line') # Chg
|
return bank_partner_id
|
||||||
st_line = account_bank_statement_line_obj.browse(cr, uid, st_line_id, context=context) # Chg
|
|
||||||
st = st_line.statement_id
|
|
||||||
|
|
||||||
context.update({'date': st_line.date})
|
|
||||||
ctx = context.copy() # Chg
|
|
||||||
ctx['company_id'] = st_line.company_id.id # Chg
|
|
||||||
period_id = self._get_period( # Chg
|
|
||||||
cr, uid, st_line.date, context=ctx)
|
|
||||||
|
|
||||||
move_id = account_move_obj.create(cr, uid, {
|
|
||||||
'journal_id': st.journal_id.id,
|
|
||||||
'period_id': period_id, # Chg
|
|
||||||
'date': st_line.date,
|
|
||||||
'name': st_line_number,
|
|
||||||
'ref': st_line.ref,
|
|
||||||
}, context=context)
|
|
||||||
account_bank_statement_line_obj.write(cr, uid, [st_line.id], { # Chg
|
|
||||||
'move_ids': [(4, move_id, False)]
|
|
||||||
})
|
|
||||||
|
|
||||||
torec = []
|
|
||||||
if st_line.amount >= 0:
|
|
||||||
account_id = st.journal_id.default_credit_account_id.id
|
|
||||||
else:
|
|
||||||
account_id = st.journal_id.default_debit_account_id.id
|
|
||||||
|
|
||||||
acc_cur = ((st_line.amount<=0) and st.journal_id.default_debit_account_id) or st_line.account_id
|
|
||||||
context.update({
|
|
||||||
'res.currency.compute.account': acc_cur,
|
|
||||||
})
|
|
||||||
amount = res_currency_obj.compute(cr, uid, st.currency.id,
|
|
||||||
company_currency_id, st_line.amount, context=context)
|
|
||||||
|
|
||||||
val = {
|
|
||||||
'name': st_line.name,
|
|
||||||
'date': st_line.date,
|
|
||||||
'ref': st_line.ref,
|
|
||||||
'move_id': move_id,
|
|
||||||
'partner_id': ((st_line.partner_id) and st_line.partner_id.id) or False,
|
|
||||||
'account_id': (st_line.account_id) and st_line.account_id.id,
|
|
||||||
'credit': ((amount>0) and amount) or 0.0,
|
|
||||||
'debit': ((amount<0) and -amount) or 0.0,
|
|
||||||
# Replace with the treasury one instead of bank #Chg
|
|
||||||
'statement_id': st.id,
|
|
||||||
'journal_id': st.journal_id.id,
|
|
||||||
'period_id': period_id, #Chg
|
|
||||||
'currency_id': st.currency.id,
|
|
||||||
'analytic_account_id': st_line.analytic_account_id and st_line.analytic_account_id.id or False
|
|
||||||
}
|
|
||||||
|
|
||||||
if st.currency.id <> company_currency_id:
|
|
||||||
amount_cur = res_currency_obj.compute(cr, uid, company_currency_id,
|
|
||||||
st.currency.id, amount, context=context)
|
|
||||||
val['amount_currency'] = -amount_cur
|
|
||||||
|
|
||||||
if st_line.account_id and st_line.account_id.currency_id and st_line.account_id.currency_id.id <> company_currency_id:
|
|
||||||
val['currency_id'] = st_line.account_id.currency_id.id
|
|
||||||
amount_cur = res_currency_obj.compute(cr, uid, company_currency_id,
|
|
||||||
st_line.account_id.currency_id.id, amount, context=context)
|
|
||||||
val['amount_currency'] = -amount_cur
|
|
||||||
|
|
||||||
move_line_id = account_move_line_obj.create(cr, uid, val, context=context)
|
|
||||||
torec.append(move_line_id)
|
|
||||||
|
|
||||||
# Fill the secondary amount/currency
|
|
||||||
# if currency is not the same than the company
|
|
||||||
amount_currency = False
|
|
||||||
currency_id = False
|
|
||||||
if st.currency.id <> company_currency_id:
|
|
||||||
amount_currency = st_line.amount
|
|
||||||
currency_id = st.currency.id
|
|
||||||
# GET THE RIGHT PARTNER ACCORDING TO THE CHOSEN PROFIL # Chg
|
|
||||||
if st.profile_id.force_partner_on_bank: # Chg
|
|
||||||
bank_parrtner_id = st.profile_id.partner_id.id # Chg
|
|
||||||
else: # Chg
|
|
||||||
bank_parrtner_id = ((st_line.partner_id) and st_line.partner_id.id) or False # Chg
|
|
||||||
|
|
||||||
account_move_line_obj.create(cr, uid, {
|
|
||||||
'name': st_line.name,
|
|
||||||
'date': st_line.date,
|
|
||||||
'ref': st_line.ref,
|
|
||||||
'move_id': move_id,
|
|
||||||
'partner_id': bank_parrtner_id, # Chg
|
|
||||||
'account_id': account_id,
|
|
||||||
'credit': ((amount < 0) and -amount) or 0.0,
|
|
||||||
'debit': ((amount > 0) and amount) or 0.0,
|
|
||||||
# Replace with the treasury one instead of bank #Chg
|
|
||||||
'statement_id': st.id,
|
|
||||||
'journal_id': st.journal_id.id,
|
|
||||||
'period_id': period_id, #Chg
|
|
||||||
'amount_currency': amount_currency,
|
|
||||||
'currency_id': currency_id,
|
|
||||||
}, context=context)
|
|
||||||
|
|
||||||
for line in account_move_line_obj.browse(cr, uid, [x.id for x in
|
|
||||||
account_move_obj.browse(cr, uid, move_id,
|
|
||||||
context=context).line_id],
|
|
||||||
context=context):
|
|
||||||
if line.state <> 'valid':
|
|
||||||
raise osv.except_osv(_('Error !'),
|
|
||||||
_('Journal item "%s" is not valid.') % line.name)
|
|
||||||
|
|
||||||
# Bank statements will not consider boolean on journal entry_posted
|
|
||||||
account_move_obj.post(cr, uid, [move_id], context=context)
|
|
||||||
return move_id
|
|
||||||
|
|
||||||
def _get_st_number_period_profile(self, cr, uid, date, profile_id):
|
def _get_st_number_period_profile(self, cr, uid, date, profile_id):
|
||||||
"""
|
"""
|
||||||
@@ -322,11 +276,13 @@ class AccountBankSatement(Model):
|
|||||||
:return: char: name of the bank statement (st_number)
|
:return: char: name of the bank statement (st_number)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
year = self.pool.get('account.period').browse(cr, uid, self._get_period(cr, uid, date)).fiscalyear_id.id
|
year = self.pool.get('account.period').browse(
|
||||||
profile = self.pool.get('account.statement.profile').browse(cr,uid, profile_id)
|
cr, uid, self._get_period(cr, uid, date)).fiscalyear_id.id
|
||||||
|
profile = self.pool.get('account.statement.profile').browse(cr, uid, profile_id)
|
||||||
c = {'fiscalyear_id': year}
|
c = {'fiscalyear_id': year}
|
||||||
obj_seq = self.pool.get('ir.sequence')
|
obj_seq = self.pool.get('ir.sequence')
|
||||||
journal_sequence_id = profile.journal_id.sequence_id and profile.journal_id.sequence_id.id or False
|
journal_sequence_id = (profile.journal_id.sequence_id and
|
||||||
|
profile.journal_id.sequence_id.id or False)
|
||||||
if journal_sequence_id:
|
if journal_sequence_id:
|
||||||
st_number = obj_seq.next_by_id(cr, uid, journal_sequence_id, context=c)
|
st_number = obj_seq.next_by_id(cr, uid, journal_sequence_id, context=c)
|
||||||
else:
|
else:
|
||||||
@@ -345,9 +301,6 @@ class AccountBankSatement(Model):
|
|||||||
|
|
||||||
TODO: Log the error in a bank statement field instead of using a popup !
|
TODO: Log the error in a bank statement field instead of using a popup !
|
||||||
"""
|
"""
|
||||||
# obj_seq = self.pool.get('irerrors_stack.sequence')
|
|
||||||
if context is None:
|
|
||||||
context = {}
|
|
||||||
for st in self.browse(cr, uid, ids, context=context):
|
for st in self.browse(cr, uid, ids, context=context):
|
||||||
|
|
||||||
j_type = st.journal_id.type
|
j_type = st.journal_id.type
|
||||||
@@ -368,7 +321,7 @@ class AccountBankSatement(Model):
|
|||||||
st_number = self._get_st_number_period_profile(cr, uid, st.date, st.profile_id.id)
|
st_number = self._get_st_number_period_profile(cr, uid, st.date, st.profile_id.id)
|
||||||
# End Changes
|
# End Changes
|
||||||
for line in st.move_line_ids:
|
for line in st.move_line_ids:
|
||||||
if line.state <> 'valid':
|
if line.state != 'valid':
|
||||||
raise osv.except_osv(_('Error !'),
|
raise osv.except_osv(_('Error !'),
|
||||||
_('The account entries lines are not in valid state.'))
|
_('The account entries lines are not in valid state.'))
|
||||||
# begin changes
|
# begin changes
|
||||||
@@ -397,11 +350,11 @@ class AccountBankSatement(Model):
|
|||||||
'name': st_number,
|
'name': st_number,
|
||||||
'balance_end_real': st.balance_end
|
'balance_end_real': st.balance_end
|
||||||
}, context=context)
|
}, context=context)
|
||||||
self.log(cr, uid, st.id, _('Statement %s is confirmed, journal items are created.') % (st_number,))
|
self.message_post(cr, uid, [st.id], body=_('Statement %s confirmed, journal items were created.') % (st_number,), context=context)
|
||||||
return self.write(cr, uid, ids, {'state':'confirm'}, context=context)
|
return self.write(cr, uid, ids, {'state': 'confirm'}, context=context)
|
||||||
|
|
||||||
def get_account_for_counterpart(self, cursor, uid,
|
def get_account_for_counterpart(
|
||||||
amount, account_receivable, account_payable):
|
self, cr, uid, amount, account_receivable, account_payable):
|
||||||
"""
|
"""
|
||||||
Give the amount, payable and receivable account (that can be found using
|
Give the amount, payable and receivable account (that can be found using
|
||||||
get_default_pay_receiv_accounts method) and receive the one to use. This method
|
get_default_pay_receiv_accounts method) and receive the one to use. This method
|
||||||
@@ -425,7 +378,7 @@ class AccountBankSatement(Model):
|
|||||||
)
|
)
|
||||||
return account_id
|
return account_id
|
||||||
|
|
||||||
def get_default_pay_receiv_accounts(self, cursor, uid, context=None):
|
def get_default_pay_receiv_accounts(self, cr, uid, context=None):
|
||||||
"""
|
"""
|
||||||
We try to determine default payable/receivable accounts to be used as counterpart
|
We try to determine default payable/receivable accounts to be used as counterpart
|
||||||
from the company default propoerty. This is to be used if there is no otherway to
|
from the company default propoerty. This is to be used if there is no otherway to
|
||||||
@@ -437,28 +390,27 @@ class AccountBankSatement(Model):
|
|||||||
"""
|
"""
|
||||||
account_receivable = False
|
account_receivable = False
|
||||||
account_payable = False
|
account_payable = False
|
||||||
context = context or {}
|
|
||||||
property_obj = self.pool.get('ir.property')
|
property_obj = self.pool.get('ir.property')
|
||||||
model_fields_obj = self.pool.get('ir.model.fields')
|
model_fields_obj = self.pool.get('ir.model.fields')
|
||||||
model_fields_ids = model_fields_obj.search(
|
model_fields_ids = model_fields_obj.search(
|
||||||
cursor,
|
cr,
|
||||||
uid,
|
uid,
|
||||||
[('name', 'in', ['property_account_receivable',
|
[('name', 'in', ['property_account_receivable',
|
||||||
'property_account_payable']),
|
'property_account_payable']),
|
||||||
('model', '=', 'res.partner'),],
|
('model', '=', 'res.partner')],
|
||||||
context=context
|
context=context
|
||||||
)
|
)
|
||||||
property_ids = property_obj.search(
|
property_ids = property_obj.search(
|
||||||
cursor,
|
cr,
|
||||||
uid, [
|
uid,
|
||||||
('fields_id', 'in', model_fields_ids),
|
[('fields_id', 'in', model_fields_ids),
|
||||||
('res_id', '=', False),
|
('res_id', '=', False),
|
||||||
],
|
],
|
||||||
context=context
|
context=context
|
||||||
)
|
)
|
||||||
|
|
||||||
for erp_property in property_obj.browse(cursor, uid,
|
for erp_property in property_obj.browse(
|
||||||
property_ids, context=context):
|
cr, uid, property_ids, context=context):
|
||||||
if erp_property.fields_id.name == 'property_account_receivable':
|
if erp_property.fields_id.name == 'property_account_receivable':
|
||||||
account_receivable = erp_property.value_reference.id
|
account_receivable = erp_property.value_reference.id
|
||||||
elif erp_property.fields_id.name == 'property_account_payable':
|
elif erp_property.fields_id.name == 'property_account_payable':
|
||||||
@@ -476,7 +428,8 @@ class AccountBankSatement(Model):
|
|||||||
"""
|
"""
|
||||||
st = self.browse(cr, uid, st_id, context=context)
|
st = self.browse(cr, uid, st_id, context=context)
|
||||||
if st.balance_check:
|
if st.balance_check:
|
||||||
return super(AccountBankSatement,self).balance_check(cr, uid, st_id, journal_type, context)
|
return super(AccountBankSatement, self).balance_check(
|
||||||
|
cr, uid, st_id, journal_type, context=context)
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -489,14 +442,18 @@ class AccountBankSatement(Model):
|
|||||||
"""
|
"""
|
||||||
if not profile_id:
|
if not profile_id:
|
||||||
return {}
|
return {}
|
||||||
import_config = self.pool.get("account.statement.profile").browse(cr,uid,profile_id)
|
import_config = self.pool.get("account.statement.profile").browse(
|
||||||
|
cr, uid, profile_id, context=context)
|
||||||
journal_id = import_config.journal_id.id
|
journal_id = import_config.journal_id.id
|
||||||
account_id = import_config.journal_id.default_debit_account_id.id
|
account_id = import_config.journal_id.default_debit_account_id.id
|
||||||
credit_partner_id = import_config.partner_id and import_config.partner_id.id or False
|
credit_partner_id = import_config.partner_id and import_config.partner_id.id or False
|
||||||
return {'value': {'journal_id':journal_id, 'account_id': account_id,
|
return {'value':
|
||||||
'balance_check':import_config.balance_check,
|
{'journal_id': journal_id,
|
||||||
'credit_partner_id':credit_partner_id,
|
'account_id': account_id,
|
||||||
}}
|
'balance_check': import_config.balance_check,
|
||||||
|
'credit_partner_id': credit_partner_id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class AccountBankSatementLine(Model):
|
class AccountBankSatementLine(Model):
|
||||||
@@ -508,16 +465,16 @@ class AccountBankSatementLine(Model):
|
|||||||
"""
|
"""
|
||||||
_inherit = "account.bank.statement.line"
|
_inherit = "account.bank.statement.line"
|
||||||
|
|
||||||
def _get_period(self, cursor, user, context=None):
|
def _get_period(self, cr, uid, context=None):
|
||||||
"""
|
"""
|
||||||
Return a period from a given date in the context.
|
Return a period from a given date in the context.
|
||||||
"""
|
"""
|
||||||
date = context.get('date', None)
|
date = context.get('date', None)
|
||||||
periods = self.pool.get('account.period').find(cursor, user, dt=date)
|
periods = self.pool.get('account.period').find(cr, uid, dt=date)
|
||||||
return periods and periods[0] or False
|
return periods and periods[0] or False
|
||||||
|
|
||||||
def _get_default_account(self, cursor, user, context=None):
|
def _get_default_account(self, cr, uid, context=None):
|
||||||
return self.get_values_for_line(cursor, user, context = context)['account_id']
|
return self.get_values_for_line(cr, uid, context=context)['account_id']
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
# Set them as required + 64 char instead of 32
|
# Set them as required + 64 char instead of 32
|
||||||
@@ -529,7 +486,7 @@ class AccountBankSatementLine(Model):
|
|||||||
'account_id': _get_default_account,
|
'account_id': _get_default_account,
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_values_for_line(self, cr, uid, profile_id = False, partner_id = False, line_type = False, amount = False, context = None):
|
def get_values_for_line(self, cr, uid, profile_id=False, partner_id=False, line_type=False, amount=False, context=None):
|
||||||
"""
|
"""
|
||||||
Return the account_id to be used in the line of a bank statement. It'll base the result as follow:
|
Return the account_id to be used in the line of a bank statement. It'll base the result as follow:
|
||||||
- If a receivable_account_id is set in the profile, return this value and type = general
|
- If a receivable_account_id is set in the profile, return this value and type = general
|
||||||
@@ -553,15 +510,14 @@ class AccountBankSatementLine(Model):
|
|||||||
...
|
...
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
if context is None:
|
|
||||||
context = {}
|
|
||||||
res = {}
|
res = {}
|
||||||
obj_partner = self.pool.get('res.partner')
|
obj_partner = self.pool.get('res.partner')
|
||||||
obj_stat = self.pool.get('account.bank.statement')
|
obj_stat = self.pool.get('account.bank.statement')
|
||||||
receiv_account = pay_account = account_id = False
|
receiv_account = pay_account = account_id = False
|
||||||
# If profile has a receivable_account_id, we return it in any case
|
# If profile has a receivable_account_id, we return it in any case
|
||||||
if profile_id:
|
if profile_id:
|
||||||
profile = self.pool.get("account.statement.profile").browse(cr,uid,profile_id)
|
profile = self.pool.get("account.statement.profile").browse(
|
||||||
|
cr, uid, profile_id, context=context)
|
||||||
if profile.receivable_account_id:
|
if profile.receivable_account_id:
|
||||||
res['account_id'] = profile.receivable_account_id.id
|
res['account_id'] = profile.receivable_account_id.id
|
||||||
res['type'] = 'general'
|
res['type'] = 'general'
|
||||||
@@ -573,7 +529,8 @@ class AccountBankSatementLine(Model):
|
|||||||
receiv_account = part.property_account_receivable.id
|
receiv_account = part.property_account_receivable.id
|
||||||
# If no value, look on the default company property
|
# If no value, look on the default company property
|
||||||
if not pay_account or not receiv_account:
|
if not pay_account or not receiv_account:
|
||||||
receiv_account, pay_account = obj_stat.get_default_pay_receiv_accounts(cr, uid, context=None)
|
receiv_account, pay_account = obj_stat.get_default_pay_receiv_accounts(
|
||||||
|
cr, uid, context=None)
|
||||||
# Now we have both pay and receive account, choose the one to use
|
# Now we have both pay and receive account, choose the one to use
|
||||||
# based on line_type first, then amount, otherwise take receivable one.
|
# based on line_type first, then amount, otherwise take receivable one.
|
||||||
if line_type is not False:
|
if line_type is not False:
|
||||||
@@ -589,18 +546,15 @@ class AccountBankSatementLine(Model):
|
|||||||
res['account_id'] = pay_account
|
res['account_id'] = pay_account
|
||||||
res['type'] = 'supplier'
|
res['type'] = 'supplier'
|
||||||
if not account_id:
|
if not account_id:
|
||||||
res['account_id'] = receiv_account
|
res['account_id'] = receiv_account
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def onchange_partner_id(self, cr, uid, ids, partner_id, profile_id, context=None):
|
def onchange_partner_id(self, cr, uid, ids, partner_id, profile_id, context=None):
|
||||||
"""
|
"""
|
||||||
Override of the basic method as we need to pass the profile_id in the on_change_type
|
Override of the basic method as we need to pass the profile_id in the on_change_type
|
||||||
call.
|
call.
|
||||||
"""
|
"""
|
||||||
obj_partner = self.pool.get('res.partner')
|
obj_partner = self.pool.get('res.partner')
|
||||||
if context is None:
|
|
||||||
context = {}
|
|
||||||
if not partner_id:
|
if not partner_id:
|
||||||
return {}
|
return {}
|
||||||
part = obj_partner.browse(cr, uid, partner_id, context=context)
|
part = obj_partner.browse(cr, uid, partner_id, context=context)
|
||||||
@@ -613,7 +567,7 @@ class AccountBankSatementLine(Model):
|
|||||||
type = 'supplier'
|
type = 'supplier'
|
||||||
if part.customer == True:
|
if part.customer == True:
|
||||||
type = 'customer'
|
type = 'customer'
|
||||||
res_type = self.onchange_type(cr, uid, ids, partner_id, type, profile_id, context=context) # Chg
|
res_type = self.onchange_type(cr, uid, ids, partner_id, type, profile_id, context=context) # Chg
|
||||||
if res_type['value'] and res_type['value'].get('account_id', False):
|
if res_type['value'] and res_type['value'].get('account_id', False):
|
||||||
return {'value': {'type': type, 'account_id': res_type['value']['account_id']}}
|
return {'value': {'type': type, 'account_id': res_type['value']['account_id']}}
|
||||||
return {'value': {'type': type}}
|
return {'value': {'type': type}}
|
||||||
@@ -623,13 +577,15 @@ class AccountBankSatementLine(Model):
|
|||||||
Keep the same features as in standard and call super. If an account is returned,
|
Keep the same features as in standard and call super. If an account is returned,
|
||||||
call the method to compute line values.
|
call the method to compute line values.
|
||||||
"""
|
"""
|
||||||
if context is None:
|
res = super(AccountBankSatementLine, self).onchange_type(
|
||||||
context = {}
|
cr, uid, line_id, partner_id, type, context=context)
|
||||||
res = super(AccountBankSatementLine,self).onchange_type(cr, uid, line_id, partner_id, type, context)
|
|
||||||
if 'account_id' in res['value']:
|
if 'account_id' in res['value']:
|
||||||
result = self.get_values_for_line(cr, uid, profile_id = profile_id,
|
result = self.get_values_for_line(
|
||||||
partner_id = partner_id, line_type = type, context = context)
|
cr, uid,
|
||||||
|
profile_id=profile_id,
|
||||||
|
partner_id=partner_id,
|
||||||
|
line_type=type,
|
||||||
|
context=context)
|
||||||
if result:
|
if result:
|
||||||
res['value'].update({'account_id':result['account_id']})
|
res['value'].update({'account_id': result['account_id']})
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|||||||
@@ -73,32 +73,20 @@
|
|||||||
|
|
||||||
<menuitem string="Bank Statements Profile" action="action_treasury_statement_profile_tree" id="menu_treasury_statement_profile_tree" parent="account.menu_configuration_misc" sequence="30"/>
|
<menuitem string="Bank Statements Profile" action="action_treasury_statement_profile_tree" id="menu_treasury_statement_profile_tree" parent="account.menu_configuration_misc" sequence="30"/>
|
||||||
|
|
||||||
<record model="ir.ui.view" id="id_in_statement_line">
|
|
||||||
<field name="name">account.bank.statement.line.inherit</field>
|
|
||||||
<field name="model">account.bank.statement</field>
|
|
||||||
<field name="inherit_id" ref="account.view_bank_statement_periodic_form"/>
|
|
||||||
<field name="priority" eval="30"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<xpath expr="/form/notebook/page[@string='Journal Entries']/field/tree/field[@name='ref']" position="before">
|
|
||||||
<field name="id" />
|
|
||||||
</xpath>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
|
|
||||||
<record id="view_treasury_statement_search" model="ir.ui.view">
|
<record id="view_treasury_statement_search" model="ir.ui.view">
|
||||||
<field name="name">account.bank.statement.search</field>
|
<field name="name">account.bank.statement.search</field>
|
||||||
<field name="model">account.bank.statement</field>
|
<field name="model">account.bank.statement</field>
|
||||||
<field name="inherit_id" ref="account.view_bank_statement_search"/>
|
<field name="inherit_id" ref="account.view_bank_statement_search"/>
|
||||||
<field name="type">search</field>
|
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<xpath expr="/search/group/field[@name='name']" position="before">
|
<xpath expr="/search/field[@name='name']" position="before">
|
||||||
<field name="id"/>
|
<field name="id"/>
|
||||||
<field name="profile_id"/>
|
<field name="profile_id"/>
|
||||||
<field name="credit_partner_id"/>
|
<field name="credit_partner_id"/>
|
||||||
<separator orientation="vertical"/>
|
<separator orientation="vertical"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="/search/group/field[@name='period_id']" position="replace">
|
<xpath expr="/search/field[@name='period_id']" position="replace">
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="/search/group/filter[@string='Period']" position="replace">
|
<xpath expr="/search/group/filter[@string='Period']" position="replace">
|
||||||
<filter string="Financial Partner" context="{'group_by': 'credit_partner_id'}" icon="terp-partner"/>
|
<filter string="Financial Partner" context="{'group_by': 'credit_partner_id'}" icon="terp-partner"/>
|
||||||
@@ -125,75 +113,63 @@
|
|||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|
||||||
<record id="view_treasury_statement_form" model="ir.ui.view">
|
<record id="view_treasury_statement_form" model="ir.ui.view">
|
||||||
<field name="name">account.bank.statement.form</field>
|
<field name="name">account.bank.statement.form</field>
|
||||||
<field name="model">account.bank.statement</field>
|
<field name="model">account.bank.statement</field>
|
||||||
<field name="inherit_id" ref="account.view_bank_statement_form"/>
|
<field name="inherit_id" ref="account.view_bank_statement_form"/>
|
||||||
<field name="type">form</field>
|
<field name="type">form</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<!-- Remove name and date from group tag -->
|
|
||||||
<xpath expr="/form/group/field[@name='name']" position="replace">
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="/form/group/field[@name='date']" position="replace">
|
|
||||||
</xpath>
|
|
||||||
<!-- Add a new group before the first one with name, profile and date -->
|
|
||||||
<xpath expr="/form/group[@col='7']" position="before">
|
|
||||||
<group col="8" colspan="4">
|
|
||||||
<field name="profile_id" select="1" required="1" on_change="onchange_imp_config_id(profile_id)" widget="selection"/>
|
|
||||||
<field name="date" select="1" on_change="onchange_date(date, company_id)"/>
|
|
||||||
<field name="name" select="1"/>
|
|
||||||
</group>
|
|
||||||
<separator string="Profile Details" colspan="4"/>
|
|
||||||
</xpath>
|
|
||||||
<!-- Make balance visible or not depending on profile -->
|
|
||||||
<xpath expr="/form/group/field[@name='balance_start']" position="replace">
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="/form/group/field[@name='balance_end_real']" position="replace">
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="/form/group[@col='7']" position="after">
|
|
||||||
<separator string="Balance Check" colspan="4" attrs="{'invisible':[('balance_check','=',False)]}"/>
|
|
||||||
<group col="6" colspan="4" attrs="{'invisible':[('balance_check','=',False)]}">
|
|
||||||
<field name="balance_start" />
|
|
||||||
<field name="balance_end_real" />
|
|
||||||
</group>
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="/form/group/field[@name='balance_end']" position="replace">
|
|
||||||
<field name="balance_end"/>
|
|
||||||
</xpath>
|
|
||||||
|
|
||||||
<xpath expr="/form/group/field[@name='journal_id']" position="attributes">
|
<!-- Add before the group : profile and related infos -->
|
||||||
<attribute name="widget"></attribute>
|
<xpath expr="/form/sheet/group/group/field[@name='journal_id']" position="replace">
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="/form/group/field[@name='period_id']" position="replace">
|
|
||||||
<field name="credit_partner_id"/>
|
|
||||||
<field name="account_id" invisible="1"/>
|
|
||||||
<field name="balance_check" invisible="1"/>
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="/form/notebook/page/field/tree/field[@name='sequence']" position="after">
|
|
||||||
<field name="id"/>
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="/form/notebook/page/field/tree/field[@name='partner_id']" position="replace">
|
|
||||||
<field name="partner_id" on_change="onchange_partner_id(partner_id,parent.profile_id)"/>
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="/form/notebook/page/field/form/field[@name='date']" position="before">
|
|
||||||
<field name="id"/>
|
|
||||||
</xpath>
|
|
||||||
<!-- Adapt onchange signature -->
|
|
||||||
<xpath expr="/form/notebook/page/field/tree/field[@name='partner_id']" position="replace">
|
|
||||||
<field name="partner_id" on_change="onchange_partner_id(partner_id,parent.profile_id)"/>
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="/form/notebook/page/field/form/field[@name='partner_id']" position="replace">
|
|
||||||
<field name="partner_id" on_change="onchange_partner_id(partner_id,parent.profile_id)"/>
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="/form/notebook/page/field/form/field[@name='type']" position="replace">
|
|
||||||
<field name="type" on_change="onchange_type(partner_id, type, parent.profile_id)"/>
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="/form/notebook/page/field/tree/field[@name='type']" position="replace">
|
|
||||||
<field name="type" on_change="onchange_type(partner_id, type, parent.profile_id)"/>
|
|
||||||
</xpath>
|
|
||||||
|
|
||||||
</field>
|
<xpath expr="/form/sheet/group" position="after">
|
||||||
</record>
|
<group>
|
||||||
|
<field name="profile_id" select="1" required="1" on_change="onchange_imp_config_id(profile_id)" widget="selection"/>
|
||||||
|
<separator string="Profile Details" colspan="4"/>
|
||||||
|
<field name="journal_id" domain="[('type', '=', 'bank')]" on_change="onchange_journal_id(journal_id)" widget="selection"/>
|
||||||
|
<field name="credit_partner_id"/>
|
||||||
|
<field name="account_id" invisible="1"/>
|
||||||
|
<field name="balance_check" invisible="1"/>
|
||||||
|
</group>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
# Make balance visible or not depending on profile
|
||||||
|
<xpath expr="/form/sheet/group/group/field[@name='balance_start']" position="attributes">
|
||||||
|
<attribute name="attrs">{'invisible':[('balance_check','=',False)]}</attribute>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="/form/sheet/group/group/field[@name='balance_end_real']" position="attributes">
|
||||||
|
<attribute name="attrs">{'invisible':[('balance_check','=',False)]}</attribute>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="/form/sheet/group/group/field[@name='balance_end_real']" position="after">
|
||||||
|
<field name="balance_end" widget="monetary" options='{"currency_field" : "currency"}'/>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
<xpath expr="/form/sheet/notebook/page/field/tree/field[@name='sequence']" position="after">
|
||||||
|
<field name="id" readonly="1" />
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
<xpath expr="/form/sheet/notebook/page/field/form/group/field[@name='date']" position="before">
|
||||||
|
<field name="id" readonly="1" />
|
||||||
|
</xpath>
|
||||||
|
# Adapt onchange signature
|
||||||
|
<xpath expr="/form/sheet/notebook/page/field/tree/field[@name='partner_id']" position="replace">
|
||||||
|
<field name="partner_id" on_change="onchange_partner_id(partner_id,parent.profile_id)" domain="['|',('parent_id','=',False),('is_company','=',True)]"/>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
<xpath expr="/form/sheet/notebook/page/field/form/group/field[@name='partner_id']" position="replace">
|
||||||
|
<field name="partner_id" on_change="onchange_partner_id(partner_id,parent.profile_id)" domain="['|',('parent_id','=',False),('is_company','=',True)]"/>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="/form/sheet/notebook/page/field/form/group/field[@name='type']" position="replace">
|
||||||
|
<field name="type" on_change="onchange_type(partner_id, type, parent.profile_id)"/>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="/form/sheet/notebook/page/field/tree/field[@name='type']" position="replace">
|
||||||
|
<field name="type" on_change="onchange_type(partner_id, type, parent.profile_id)"/>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
<act_window id="act_bank_statement_from_profile"
|
<act_window id="act_bank_statement_from_profile"
|
||||||
|
|||||||
@@ -24,8 +24,11 @@
|
|||||||
'author': 'Camptocamp',
|
'author': 'Camptocamp',
|
||||||
'maintainer': 'Camptocamp',
|
'maintainer': 'Camptocamp',
|
||||||
'category': 'Finance',
|
'category': 'Finance',
|
||||||
'complexity': 'normal', #easy, normal, expert
|
'complexity': 'normal',
|
||||||
'depends': ['account_statement_ext','account_voucher'],
|
'depends': [
|
||||||
|
'account_statement_ext',
|
||||||
|
'account_voucher'
|
||||||
|
],
|
||||||
'description': """
|
'description': """
|
||||||
This module is only needed when using account_bank_statement_ext with voucher in order to compute the period
|
This module is only needed when using account_bank_statement_ext with voucher in order to compute the period
|
||||||
correctly. This is mainly because with account_bank_statement_ext, the period is computed for each line.
|
correctly. This is mainly because with account_bank_statement_ext, the period is computed for each line.
|
||||||
|
|||||||
@@ -18,7 +18,8 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
from openerp.osv.orm import Model, fields
|
|
||||||
|
from openerp.osv.orm import Model
|
||||||
|
|
||||||
|
|
||||||
class AccountVoucher(Model):
|
class AccountVoucher(Model):
|
||||||
@@ -30,7 +31,8 @@ class AccountVoucher(Model):
|
|||||||
if context is None:
|
if context is None:
|
||||||
context = {}
|
context = {}
|
||||||
if not context.get('period_id') and context.get('move_line_ids'):
|
if not context.get('period_id') and context.get('move_line_ids'):
|
||||||
res = self.pool.get('account.move.line').browse(cr, uid , context.get('move_line_ids'))[0].period_id.id
|
res = self.pool.get('account.move.line').browse(
|
||||||
|
cr, uid, context.get('move_line_ids'), context=context)[0].period_id.id
|
||||||
context['period_id'] = res
|
context['period_id'] = res
|
||||||
elif context.get('date'):
|
elif context.get('date'):
|
||||||
periods = self.pool.get('account.period').find(
|
periods = self.pool.get('account.period').find(
|
||||||
@@ -47,4 +49,3 @@ class AccountVoucher(Model):
|
|||||||
ctx = dict(context, date=values.get('date'))
|
ctx = dict(context, date=values.get('date'))
|
||||||
values['period_id'] = self._get_period(cr, uid, ctx)
|
values['period_id'] = self._get_period(cr, uid, ctx)
|
||||||
return super(AccountVoucher, self).create(cr, uid, values, context)
|
return super(AccountVoucher, self).create(cr, uid, values, context)
|
||||||
|
|
||||||
|
|||||||
@@ -24,8 +24,11 @@
|
|||||||
'author': 'Camptocamp',
|
'author': 'Camptocamp',
|
||||||
'maintainer': 'Camptocamp',
|
'maintainer': 'Camptocamp',
|
||||||
'category': 'Finance',
|
'category': 'Finance',
|
||||||
'complexity': 'normal', #easy, normal, expert
|
'complexity': 'normal',
|
||||||
'depends': ['account_statement_base_completion', 'base_transaction_id'],
|
'depends': [
|
||||||
|
'account_statement_base_completion',
|
||||||
|
'base_transaction_id'
|
||||||
|
],
|
||||||
'description': """
|
'description': """
|
||||||
Add a completion method based on transaction ID providen by the bank/office.
|
Add a completion method based on transaction ID providen by the bank/office.
|
||||||
|
|
||||||
|
|||||||
@@ -19,25 +19,25 @@
|
|||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
from tools.translate import _
|
from openerp.tools.translate import _
|
||||||
import datetime
|
from openerp.osv.orm import Model
|
||||||
import netsvc
|
from openerp.osv import fields
|
||||||
logger = netsvc.Logger()
|
|
||||||
from openerp.osv.orm import Model, fields
|
|
||||||
from openerp.addons.account_statement_base_completion.statement import ErrorTooManyPartner
|
from openerp.addons.account_statement_base_completion.statement import ErrorTooManyPartner
|
||||||
|
|
||||||
|
|
||||||
class AccountStatementCompletionRule(Model):
|
class AccountStatementCompletionRule(Model):
|
||||||
"""Add a rule based on transaction ID"""
|
"""Add a rule based on transaction ID"""
|
||||||
|
|
||||||
_inherit = "account.statement.completion.rule"
|
_inherit = "account.statement.completion.rule"
|
||||||
|
|
||||||
def _get_functions(self, cr, uid, context=None):
|
def _get_functions(self, cr, uid, context=None):
|
||||||
res = super (AccountStatementCompletionRule, self)._get_functions(
|
res = super(AccountStatementCompletionRule, self)._get_functions(
|
||||||
cr, uid, context=context)
|
cr, uid, context=context)
|
||||||
res.append(('get_from_transaction_id_and_so', 'From line reference (based on SO transaction ID)'))
|
res.append(('get_from_transaction_id_and_so',
|
||||||
|
'From line reference (based on SO transaction ID)'))
|
||||||
return res
|
return res
|
||||||
|
|
||||||
_columns={
|
_columns = {
|
||||||
'function_to_call': fields.selection(_get_functions, 'Method'),
|
'function_to_call': fields.selection(_get_functions, 'Method'),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,20 +55,32 @@ class AccountStatementCompletionRule(Model):
|
|||||||
...}
|
...}
|
||||||
"""
|
"""
|
||||||
st_obj = self.pool.get('account.bank.statement.line')
|
st_obj = self.pool.get('account.bank.statement.line')
|
||||||
st_line = st_obj.browse(cr,uid,line_id)
|
st_line = st_obj.browse(cr, uid, line_id, context=context)
|
||||||
res = {}
|
res = {}
|
||||||
if st_line:
|
if st_line:
|
||||||
so_obj = self.pool.get('sale.order')
|
so_obj = self.pool.get('sale.order')
|
||||||
so_id = so_obj.search(cr, uid, [('transaction_id', '=', st_line.transaction_id)])
|
so_id = so_obj.search(
|
||||||
|
cr,
|
||||||
|
uid,
|
||||||
|
[('transaction_id', '=', st_line.transaction_id)],
|
||||||
|
context=context)
|
||||||
if so_id and len(so_id) == 1:
|
if so_id and len(so_id) == 1:
|
||||||
so = so_obj.browse(cr, uid, so_id[0])
|
so = so_obj.browse(cr, uid, so_id[0], context=context)
|
||||||
res['partner_id'] = so.partner_id.id
|
res['partner_id'] = so.partner_id.id
|
||||||
res['ref'] = so.name
|
res['ref'] = so.name
|
||||||
elif so_id and len(so_id) > 1:
|
elif so_id and len(so_id) > 1:
|
||||||
raise ErrorTooManyPartner(_('Line named "%s" (Ref:%s) was matched by more than one partner.')%(st_line.name,st_line.ref))
|
raise ErrorTooManyPartner(
|
||||||
|
_('Line named "%s" (Ref:%s) was matched by more than '
|
||||||
|
'one partner.') % (st_line.name, st_line.ref))
|
||||||
if so_id:
|
if so_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(
|
||||||
partner_id = res.get('partner_id',False), line_type = st_line.type, amount = st_line.amount, context=context)
|
cr,
|
||||||
|
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)
|
res.update(st_vals)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@@ -76,15 +88,12 @@ class AccountStatementCompletionRule(Model):
|
|||||||
class AccountStatementLine(Model):
|
class AccountStatementLine(Model):
|
||||||
_inherit = "account.bank.statement.line"
|
_inherit = "account.bank.statement.line"
|
||||||
|
|
||||||
_columns={
|
_columns = {
|
||||||
# '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."),
|
||||||
'transaction_id': fields.sparse(type='char', string='Transaction ID',
|
'transaction_id': fields.sparse(
|
||||||
|
type='char',
|
||||||
|
string='Transaction ID',
|
||||||
size=128,
|
size=128,
|
||||||
serialization_field='additionnal_bank_fields',
|
serialization_field='additionnal_bank_fields',
|
||||||
help="Transction id from the financial institute"),
|
help="Transction id from the financial institute"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<field name="type">form</field>
|
<field name="type">form</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<data>
|
<data>
|
||||||
<xpath expr="/form/notebook/page/field[@name='line_ids']/form/field[@name='label']" position="after">
|
<xpath expr="/form/sheet/notebook/page/field[@name='line_ids']/form/group/field[@name='label']" position="after">
|
||||||
<field name="transaction_id" />
|
<field name="transaction_id" />
|
||||||
</xpath>
|
</xpath>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -24,8 +24,11 @@
|
|||||||
'author': 'Camptocamp',
|
'author': 'Camptocamp',
|
||||||
'maintainer': 'Camptocamp',
|
'maintainer': 'Camptocamp',
|
||||||
'category': 'Finance',
|
'category': 'Finance',
|
||||||
'complexity': 'normal', #easy, normal, expert
|
'complexity': 'normal',
|
||||||
'depends': ['account_statement_base_import','account_statement_transactionid_completion'],
|
'depends': [
|
||||||
|
'account_statement_base_import',
|
||||||
|
'account_statement_transactionid_completion'
|
||||||
|
],
|
||||||
'description': """
|
'description': """
|
||||||
This module brings generic methods and fields on bank statement to deal with
|
This module brings generic methods and fields on bank statement to deal with
|
||||||
the importation of different bank and offices that uses transactionID.
|
the importation of different bank and offices that uses transactionID.
|
||||||
@@ -36,12 +39,12 @@
|
|||||||
|
|
||||||
This module can handle a commission taken by the payment office and has the following format:
|
This module can handle a commission taken by the payment office and has the following format:
|
||||||
|
|
||||||
* transaction_id : the transaction ID given by the bank/office. It is used as reference
|
* transaction_id: the transaction ID given by the bank/office. It is used as reference
|
||||||
in the generated entries and is useful for reconciliation process
|
in the generated entries and is useful for reconciliation process
|
||||||
* date : date of the payment
|
* date: date of the payment
|
||||||
* amount : amount paid in the currency of the journal used in the importation profile
|
* amount: amount paid in the currency of the journal used in the importation profile
|
||||||
* commission_amount : amount of the comission for each line
|
* commission_amount: amount of the comission for each line
|
||||||
* label : the comunication given by the payment office, used as communication in the
|
* label: the comunication given by the payment office, used as communication in the
|
||||||
generated entries.
|
generated entries.
|
||||||
""",
|
""",
|
||||||
'website': 'http://www.camptocamp.com',
|
'website': 'http://www.camptocamp.com',
|
||||||
|
|||||||
@@ -19,6 +19,4 @@
|
|||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
# from parser import new_bank_statement_parser
|
|
||||||
# from parser import BankStatementImportParser
|
|
||||||
import transactionid_file_parser
|
import transactionid_file_parser
|
||||||
@@ -19,16 +19,9 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
from openerp.tools.translate import _
|
from openerp.tools.translate import _
|
||||||
import base64
|
|
||||||
import csv
|
|
||||||
import tempfile
|
|
||||||
import datetime
|
import datetime
|
||||||
from account_statement_base_import.parser.file_parser import FileParser
|
from account_statement_base_import.parser.file_parser import FileParser
|
||||||
|
|
||||||
try:
|
|
||||||
import xlrd
|
|
||||||
except:
|
|
||||||
raise Exception(_('Please install python lib xlrd'))
|
|
||||||
|
|
||||||
class TransactionIDFileParser(FileParser):
|
class TransactionIDFileParser(FileParser):
|
||||||
"""
|
"""
|
||||||
@@ -46,7 +39,7 @@ class TransactionIDFileParser(FileParser):
|
|||||||
}
|
}
|
||||||
# Order of cols does not matter but first row of the file has to be header
|
# Order of cols does not matter but first row of the file has to be header
|
||||||
keys_to_validate = ['transaction_id', 'label', 'date', 'amount', 'commission_amount']
|
keys_to_validate = ['transaction_id', 'label', 'date', 'amount', 'commission_amount']
|
||||||
super(TransactionIDFileParser,self).__init__(parse_name, keys_to_validate=keys_to_validate, ftype=ftype, convertion_dict=convertion_dict)
|
super(TransactionIDFileParser, self).__init__(parse_name, keys_to_validate=keys_to_validate, ftype=ftype, convertion_dict=convertion_dict)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def parser_for(cls, parser_name):
|
def parser_for(cls, parser_name):
|
||||||
@@ -77,12 +70,12 @@ class TransactionIDFileParser(FileParser):
|
|||||||
for each one.
|
for each one.
|
||||||
"""
|
"""
|
||||||
return {
|
return {
|
||||||
'name': line.get('label', line.get('ref','/')),
|
'name': line.get('label', line.get('ref', '/')),
|
||||||
'date': line.get('date', datetime.datetime.now().date()),
|
'date': line.get('date', datetime.datetime.now().date()),
|
||||||
'amount': line.get('amount', 0.0),
|
'amount': line.get('amount', 0.0),
|
||||||
'ref': line.get('transaction_id','/'),
|
'ref': line.get('transaction_id', '/'),
|
||||||
'label': line.get('label',''),
|
'label': line.get('label', ''),
|
||||||
'transaction_id': line.get('transaction_id','/'),
|
'transaction_id': line.get('transaction_id', '/'),
|
||||||
'commission_amount': line.get('commission_amount', 0.0),
|
'commission_amount': line.get('commission_amount', 0.0),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +86,6 @@ class TransactionIDFileParser(FileParser):
|
|||||||
res = super(TransactionIDFileParser, self)._post(*args, **kwargs)
|
res = super(TransactionIDFileParser, self)._post(*args, **kwargs)
|
||||||
val = 0.0
|
val = 0.0
|
||||||
for row in self.result_row_list:
|
for row in self.result_row_list:
|
||||||
val += row.get('commission_amount',0.0)
|
val += row.get('commission_amount', 0.0)
|
||||||
self.commission_global_amount = val
|
self.commission_global_amount = val
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|||||||
@@ -19,25 +19,29 @@
|
|||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
from openerp.osv.orm import Model, fields
|
from openerp.osv.orm import Model
|
||||||
from openerp.osv import fields, osv
|
from openerp.osv import fields
|
||||||
|
|
||||||
|
|
||||||
class AccountStatementProfil(Model):
|
class AccountStatementProfil(Model):
|
||||||
_inherit = "account.statement.profile"
|
_inherit = "account.statement.profile"
|
||||||
|
|
||||||
|
|
||||||
def get_import_type_selection(self, cr, uid, context=None):
|
def get_import_type_selection(self, cr, uid, context=None):
|
||||||
"""
|
"""
|
||||||
Has to be inherited to add parser
|
Has to be inherited to add parser
|
||||||
"""
|
"""
|
||||||
res = super(AccountStatementProfil, self).get_import_type_selection(cr, uid, context=context)
|
res = super(AccountStatementProfil, self).get_import_type_selection(
|
||||||
res.append(('generic_csvxls_transaction','Generic .csv/.xls based on SO transaction ID'))
|
cr, uid, context=context)
|
||||||
|
res.append(('generic_csvxls_transaction',
|
||||||
|
'Generic .csv/.xls based on SO transaction ID'))
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'import_type': fields.selection(get_import_type_selection, 'Type of import', required=True,
|
'import_type': fields.selection(
|
||||||
help = "Choose here the method by which you want to import bank statement for this profile."),
|
get_import_type_selection,
|
||||||
|
'Type of import',
|
||||||
|
required=True,
|
||||||
|
help="Choose here the method by which you want to import "
|
||||||
|
"bank statement for this profile."),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,18 +24,30 @@
|
|||||||
'author': 'Camptocamp',
|
'author': 'Camptocamp',
|
||||||
'maintainer': 'Camptocamp',
|
'maintainer': 'Camptocamp',
|
||||||
'category': 'Hidden/Dependency',
|
'category': 'Hidden/Dependency',
|
||||||
'complexity': 'easy', #easy, normal, expert
|
'complexity': 'easy',
|
||||||
'depends': ['account', 'sale','stock'],
|
'depends': [
|
||||||
|
'account',
|
||||||
|
'sale',
|
||||||
|
'stock'
|
||||||
|
],
|
||||||
'description': """
|
'description': """
|
||||||
Adds transaction id to invoice and sale models and views. On Sales order, you can specify the transaction ID
|
Adds transaction id to invoice and sale models and views.
|
||||||
used for the payment and it will be propagated to the invoice (even if made from packing).
|
On Sales order, you can specify the transaction ID used
|
||||||
This is mostly used for e-commerce handling. You can then add a mapping on that SO field to save the e-commerce
|
for the payment and it will be propagated to the invoice
|
||||||
financial Transaction ID into the OpenERP SO field. The main purpose is to ease the reconciliation process and
|
(even if made from packing).
|
||||||
|
This is mostly used for e-commerce handling.
|
||||||
|
You can then add a mapping on that SO field to save
|
||||||
|
the e-commerce financial Transaction ID into the
|
||||||
|
OpenERP sale order field.
|
||||||
|
The main purpose is to ease the reconciliation process and
|
||||||
be able to find the partner when importing the bank statement.
|
be able to find the partner when importing the bank statement.
|
||||||
""",
|
""",
|
||||||
'website': 'http://www.openerp.com',
|
'website': 'http://www.openerp.com',
|
||||||
'init_xml': [],
|
'init_xml': [],
|
||||||
'update_xml': ['invoice_view.xml', 'sale_view.xml'],
|
'update_xml': [
|
||||||
|
'invoice_view.xml',
|
||||||
|
'sale_view.xml'
|
||||||
|
],
|
||||||
'demo_xml': [],
|
'demo_xml': [],
|
||||||
'test': [],
|
'test': [],
|
||||||
'installable': True,
|
'installable': True,
|
||||||
|
|||||||
@@ -19,17 +19,18 @@
|
|||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
from osv import fields, osv
|
from openerp.osv.orm import Model
|
||||||
from tools.translate import _
|
from openerp.osv import fields
|
||||||
|
|
||||||
class AccountInvoice(osv.osv):
|
|
||||||
|
class AccountInvoice(Model):
|
||||||
_inherit = 'account.invoice'
|
_inherit = 'account.invoice'
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'transaction_id':fields.char(
|
'transaction_id': fields.char(
|
||||||
'Transaction id',
|
'Transaction id',
|
||||||
size=128,
|
size=128,
|
||||||
required=False,
|
required=False,
|
||||||
select=1,
|
select=1,
|
||||||
help="Transction id from the financial institute"
|
help="Transction id from the financial institute"),
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,21 +19,25 @@
|
|||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
from osv import fields, osv
|
from openerp.osv.orm import Model
|
||||||
|
from openerp.osv import fields
|
||||||
|
|
||||||
class SaleOrder(osv.osv):
|
|
||||||
|
class SaleOrder(Model):
|
||||||
_inherit = 'sale.order'
|
_inherit = 'sale.order'
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'transaction_id':fields.char('Transaction id', size=128,required=False,
|
'transaction_id': fields.char(
|
||||||
help="Transction id from the financial institute"),
|
'Transaction id',
|
||||||
|
size=128,
|
||||||
|
required=False,
|
||||||
|
help="Transaction id from the financial institute"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def _prepare_invoice(self, cr, uid, order, lines, context=None):
|
||||||
def _prepare_invoice(self, cursor, uid, order, lines, context=None):
|
|
||||||
#we put the transaction id in the generated invoices
|
#we put the transaction id in the generated invoices
|
||||||
if context is None:
|
invoice_vals = super(SaleOrder, self)._prepare_invoice(
|
||||||
context = {}
|
cr, uid, order, lines, context=context)
|
||||||
invoice_vals = super(SaleOrder, self)._prepare_invoice(cursor, uid, order, lines, context)
|
|
||||||
invoice_vals.update({
|
invoice_vals.update({
|
||||||
'transaction_id': order.transaction_id})
|
'transaction_id': order.transaction_id})
|
||||||
return invoice_vals
|
return invoice_vals
|
||||||
|
|||||||
@@ -19,20 +19,24 @@
|
|||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
from osv import osv
|
from openerp.osv.orm import Model
|
||||||
|
|
||||||
class StockPicking(osv.osv):
|
|
||||||
|
class StockPicking(Model):
|
||||||
_inherit = "stock.picking"
|
_inherit = "stock.picking"
|
||||||
|
|
||||||
def action_invoice_create(self, cursor, uid, ids, journal_id=False,
|
def action_invoice_create(
|
||||||
group=False, type='out_invoice', context=None):
|
self, cr, uid, ids, journal_id=False, group=False,
|
||||||
res = super(StockPicking, self).action_invoice_create(cursor, uid, ids,
|
type='out_invoice', context=None):
|
||||||
journal_id,group, type, context)
|
res = super(StockPicking, self).action_invoice_create(
|
||||||
|
cr, uid, ids, journal_id, group, type, context)
|
||||||
for pick_id in res:
|
for pick_id in res:
|
||||||
pick = self.browse(cursor, uid, pick_id)
|
pick = self.browse(cr, uid, pick_id, context=context)
|
||||||
if pick.sale_id and pick.sale_id.transaction_id:
|
if pick.sale_id and pick.sale_id.transaction_id:
|
||||||
self.pool.get('account.invoice').write(cursor,
|
self.pool.get('account.invoice').write(
|
||||||
uid,
|
cr,
|
||||||
res[pick_id],
|
uid,
|
||||||
{'transaction_id': pick.sale_id.transaction_id})
|
res[pick_id],
|
||||||
|
{'transaction_id': pick.sale_id.transaction_id},
|
||||||
|
context=context)
|
||||||
return res
|
return res
|
||||||
|
|||||||
Reference in New Issue
Block a user