[FIX] pep8, pylint, eyeballing

This commit is contained in:
Guewen Baconnier @ Camptocamp
2012-12-20 14:37:01 +01:00
parent a5979a9f45
commit 412d86809d
36 changed files with 673 additions and 540 deletions

View File

@@ -117,4 +117,3 @@ class easy_reconcile_advanced_ref(TransientModel):
yield ('partner_id', move_line['partner_id'])
yield ('ref', (move_line['ref'].lower().strip(),
move_line['name'].lower().strip()))

View File

@@ -271,4 +271,3 @@ class easy_reconcile_advanced(AbstractModel):
partial_reconciled_ids += reconcile_group_ids
return reconciled_ids, partial_reconciled_ids

View File

@@ -34,4 +34,3 @@ class account_easy_reconcile_method(Model):
'Advanced. Partner and Ref.'),
]
return methods

View File

@@ -24,7 +24,7 @@
'author': 'Camptocamp',
'maintainer': 'Camptocamp',
'category': 'Finance',
'complexity': 'normal', #easy, normal, expert
'complexity': 'normal',
'depends': ['account_statement_ext'],
'description': """
The goal of this module is to improve the basic bank statement, help dealing with huge volume of

View File

@@ -1,4 +1,4 @@
# -*- encoding: utf-8 -*-
# -*- coding: utf-8 -*-
#################################################################################
# #
# Copyright (C) 2011 Akretion & Camptocamp
@@ -36,5 +36,3 @@ class res_partner(Model):
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)."),
}
res_partner()

View File

@@ -20,10 +20,11 @@
##############################################################################
from tools.translate import _
from openerp.osv.orm import Model, fields
from openerp.osv import fields, osv, osv
from operator import itemgetter, attrgetter
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
from operator import attrgetter
import datetime
class ErrorTooManyPartner(Exception):
"""
New Exception definition that is raised when more than one partner is matched by
@@ -31,6 +32,7 @@ class ErrorTooManyPartner(Exception):
"""
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
@@ -50,10 +52,10 @@ class AccountStatementProfil(Model):
# => You can implement it in a module easily, we design it with your needs in mind
# as well !
'rule_ids':fields.many2many('account.statement.completion.rule',
'rule_ids': fields.many2many(
'account.statement.completion.rule',
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):
@@ -70,7 +72,7 @@ class AccountStatementProfil(Model):
...}
"""
if not context:
if context is None:
context = {}
res = {}
rule_obj = self.pool.get('account.statement.completion.rule')
@@ -113,7 +115,8 @@ class AccountStatementCompletionRule(Model):
_columns = {
'sequence': fields.integer('Sequence', help="Lower means parsed first."),
'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',
string='Related statement profiles'),
'function_to_call': fields.selection(_get_functions, 'Method'),
@@ -135,19 +138,31 @@ class AccountStatementCompletionRule(Model):
...}
"""
st_obj = self.pool.get('account.bank.statement.line')
st_line = st_obj.browse(cursor,uid,line_id)
st_line = st_obj.browse(cursor, uid, line_id, context=context)
res = {}
if st_line:
inv_obj = self.pool.get('account.invoice')
inv_id = inv_obj.search(cursor, uid, [('number', '=', st_line.ref)])
inv_id = inv_obj.search(
cursor,
uid,
[('number', '=', st_line.ref)],
context=context)
if inv_id:
if inv_id and len(inv_id) == 1:
inv = inv_obj.browse(cursor, uid, inv_id[0])
inv = inv_obj.browse(cursor, uid, inv_id[0], context=context)
res['partner_id'] = inv.partner_id.id
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))
st_vals = st_obj.get_values_for_line(cursor, uid, profile_id = st_line.statement_id.profile_id.id,
partner_id = res.get('partner_id',False), line_type = st_line.type, amount = st_line.amount, context = context)
raise ErrorTooManyPartner(
_('Line named "%s" (Ref:%s) was matched by more '
'than one partner.') % (st_line.name, st_line.ref))
st_vals = st_obj.get_values_for_line(
cursor,
uid,
profile_id=st_line.statement_id.profile_id.id,
partner_id=res.get('partner_id', False),
line_type=st_line.type,
amount=st_line.amount,
context=context)
res.update(st_vals)
return res
@@ -167,23 +182,35 @@ class AccountStatementCompletionRule(Model):
...}
"""
st_obj = self.pool.get('account.bank.statement.line')
st_line = st_obj.browse(cursor,uid,line_id)
st_line = st_obj.browse(cursor, uid, line_id, context=context)
res = {}
if st_line:
so_obj = self.pool.get('sale.order')
so_id = so_obj.search(cursor, uid, [('name', '=', st_line.ref)])
so_id = so_obj.search(
cursor,
uid,
[('name', '=', st_line.ref)],
context=context)
if so_id:
if so_id and len(so_id) == 1:
so = so_obj.browse(cursor, uid, so_id[0])
so = so_obj.browse(cursor, uid, so_id[0], context=context)
res['partner_id'] = so.partner_id.id
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))
st_vals = st_obj.get_values_for_line(cursor, uid, profile_id = st_line.statement_id.profile_id.id,
partner_id = res.get('partner_id',False), line_type = st_line.type, amount = st_line.amount, context = context)
raise ErrorTooManyPartner(
_('Line named "%s" (Ref:%s) was matched by more '
'than one partner.') %
(st_line.name, st_line.ref))
st_vals = st_obj.get_values_for_line(
cursor,
uid,
profile_id=st_line.statement_id.profile_id.id,
partner_id=res.get('partner_id', False),
line_type=st_line.type,
amount=st_line.amount,
context=context)
res.update(st_vals)
return res
def get_from_label_and_partner_field(self, cursor, uid, line_id, context=None):
"""
Match the partner based on the label field of the statement line
@@ -203,21 +230,34 @@ class AccountStatementCompletionRule(Model):
"""
partner_obj = self.pool.get('res.partner')
st_obj = self.pool.get('account.bank.statement.line')
st_line = st_obj.browse(cursor,uid,line_id)
st_line = st_obj.browse(cursor, uid, line_id, context=context)
res = {}
compt = 0
if st_line:
ids = partner_obj.search(cursor, uid, [['bank_statement_label', '!=', False]], context=context)
ids = partner_obj.search(
cursor,
uid,
[('bank_statement_label', '!=', False)],
context=context)
for partner in partner_obj.browse(cursor, uid, ids, context=context):
for partner_label in partner.bank_statement_label.split(';'):
if partner_label in st_line.label:
compt += 1
res['partner_id'] = partner.id
if compt > 1:
raise ErrorTooManyPartner(_('Line named "%s" (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:
st_vals = st_obj.get_values_for_line(cursor, uid, profile_id = st_line.statement_id.profile_id.id,
partner_id = res.get('partner_id',False), line_type = st_line.type, amount = st_line.amount, context = context)
st_vals = st_obj.get_values_for_line(
cursor,
uid,
profile_id=st_line.statement_id.profile_id.id,
partner_id=res.get('partner_id', False),
line_type=st_line.type,
amount=st_line.amount,
context=context)
res.update(st_vals)
return res
@@ -240,19 +280,28 @@ class AccountStatementCompletionRule(Model):
# This Method has not been tested yet !
res = {}
st_obj = self.pool.get('account.bank.statement.line')
st_line = st_obj.browse(cursor,uid,line_id)
st_line = st_obj.browse(cursor, uid, line_id, context=context)
if st_line:
sql = "SELECT id FROM res_partner WHERE name ~* %s"
pattern = ".*%s.*" % st_line.label
cursor.execute(sql, (pattern,))
result = cursor.fetchall()
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]:
res['partner_id'] = id
if res:
st_vals = st_obj.get_values_for_line(cursor, uid, profile_id = st_line.statement_id.profile_id.id,
partner_id = res.get('partner_id',False), line_type = st_line.type, amount = st_line.amount, context = context)
st_vals = st_obj.get_values_for_line(
cursor,
uid,
profile_id=st_line.statement_id.profile_id.id,
partner_id=res.get('partner_id', False),
line_type=st_line.type,
amount=st_line.amount,
context=context)
res.update(st_vals)
return res
@@ -269,21 +318,27 @@ class AccountStatementLine(Model):
_inherit = "account.bank.statement.line"
_columns = {
'additionnal_bank_fields' : fields.serialized('Additionnal infos from bank',
help="Used by completion and import system. Adds every field that is present in your bank/office \
statement file"),
'label': fields.sparse(type='char', string='Label',
'additionnal_bank_fields': fields.serialized(
'Additionnal infos from bank',
help="Used by completion and import system. Adds every field that "
"is present in your bank/office statement file"),
'label': fields.sparse(
type='char',
string='Label',
serialization_field='additionnal_bank_fields',
help="Generiy field to store a label given from the bank/office on which we can \
base the default/standard providen rule."),
'already_completed': fields.boolean("Auto-Completed",
help="When this checkbox is ticked, the auto-completion process/button will ignore this line."),
help="Generic field to store a label given from the "
"bank/office on which we can base the default/standard "
"providen rule."),
'already_completed': fields.boolean(
"Auto-Completed",
help="When this checkbox is ticked, the auto-completion "
"process/button will ignore this line."),
}
_defaults = {
'already_completed': False,
}
def get_line_values_from_rules(self, cr, uid, ids, context=None):
"""
We'll try to find out the values related to the line based on rules setted on
@@ -298,14 +353,21 @@ class AccountStatementLine(Model):
st_obj = self.pool.get('account.bank.statement.line')
res = {}
errors_stack = []
for line in self.browse(cr,uid, ids, context):
if not line.already_completed:
for line in self.browse(cr, uid, ids, context=context):
if line.already_completed:
continue
try:
# Take the default values
res[line.id] = st_obj.get_values_for_line(cr, uid, profile_id = line.statement_id.profile_id.id,
line_type = line.type, amount = line.amount, context = context)
res[line.id] = st_obj.get_values_for_line(
cr,
uid,
profile_id=line.statement_id.profile_id.id,
line_type=line.type,
amount=line.amount,
context=context)
# Ask the rule
vals = profile_obj.find_values_from_rules(cr, uid, line.statement_id.profile_id.id, line.id, context)
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:
@@ -316,6 +378,7 @@ class AccountStatementLine(Model):
raise ErrorTooManyPartner(msg)
return res
class AccountBankSatement(Model):
"""
We add a basic button and stuff to support the auto-completion
@@ -337,13 +400,14 @@ class AccountBankSatement(Model):
:param char error_msg: Message to add
:number_imported int/long: Number of lines that have been completed
:return : True
"""
error_log = ""
user_name = self.pool.get('res.users').read(cr, uid, uid, ['name'])['name']
log = self.read(cr, uid, stat_id, ['completion_logs'], context=context)['completion_logs']
user_name = self.pool.get('res.users').read(
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 []
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:
error_log = error_msg
log_line[0:0] = [completion_date + ' : '
@@ -351,7 +415,11 @@ class AccountBankSatement(Model):
+ "\n" + error_log + "-------------" + "\n"]
log = "\n".join(log_line)
self.write(cr, uid, [stat_id], {'completion_logs': log}, context=context)
self.message_post(cr, uid, [stat_id], body=_('Statement ID %s auto-completed for %s lines completed') % (stat_id,number_imported), context=context)
self.message_post(
cr, uid,
[stat_id],
body=_('Statement ID %s auto-completed for %s lines completed') % (stat_id, number_imported),
context=context)
return True
def button_auto_completion(self, cr, uid, ids, context=None):
@@ -359,7 +427,7 @@ class AccountBankSatement(Model):
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 !
"""
if not context:
if context is None:
context = {}
stat_line_obj = self.pool.get('account.bank.statement.line')
msg = ""
@@ -369,7 +437,8 @@ class AccountBankSatement(Model):
for line in stat.line_ids:
res = {}
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:
compl_lines += 1
except ErrorTooManyPartner, exc:
@@ -381,5 +450,6 @@ class AccountBankSatement(Model):
vals = res[line.id]
vals['already_completed'] = True
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

View File

@@ -24,8 +24,11 @@
'author': 'Camptocamp',
'maintainer': 'Camptocamp',
'category': 'Finance',
'complexity': 'normal', #easy, normal, expert
'depends': ['account_statement_ext','account_statement_base_completion'],
'complexity': 'normal',
'depends': [
'account_statement_ext',
'account_statement_base_completion'
],
'description': """
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

View File

@@ -28,6 +28,7 @@ try:
except:
raise Exception(_('Please install python lib xlrd'))
class FileParser(BankStatementImportParser):
"""
Generic abstract class for defining parser for .csv or .xls file format.
@@ -108,7 +109,6 @@ class FileParser(BankStatementImportParser):
self.result_row_list = self._cast_rows(*args, **kwargs)
return True
def _parse_csv(self):
"""
:return: list of dict from csv file (line/rows)
@@ -138,7 +138,7 @@ class FileParser(BankStatementImportParser):
try:
wb_file.close()
except Exception, e:
pass #file is allready closed
pass # file is already closed
return res
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.
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)
return res

View File

@@ -23,13 +23,13 @@ import base64
import csv
import tempfile
import datetime
# from . import file_parser
from file_parser import FileParser
try:
import xlrd
except:
raise Exception(_('Please install python lib xlrd'))
class GenericFileParser(FileParser):
"""
Standard parser that use a define format in csv or xls to import into a
@@ -96,7 +96,3 @@ class GenericFileParser(FileParser):
val += row.get('commission_amount', 0.0)
self.commission_global_amount = val
return res

View File

@@ -21,6 +21,7 @@
import base64
import csv
def UnicodeDictReader(utf8_data, **kwargs):
sniffer = csv.Sniffer()
pos = utf8_data.tell()
@@ -31,6 +32,7 @@ def UnicodeDictReader(utf8_data, **kwargs):
for row in csv_reader:
yield dict([(key, unicode(value, 'utf-8')) for key, value in row.iteritems()])
class BankStatementImportParser(object):
"""
Generic abstract class for defining parser for different files and
@@ -83,7 +85,6 @@ class BankStatementImportParser(object):
"""
return NotImplementedError
def _pre(self, *args, **kwargs):
"""
Implement a method in your parser to make a pre-treatment on datas before parsing
@@ -114,8 +115,6 @@ class BankStatementImportParser(object):
"""
return NotImplementedError
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
@@ -166,6 +165,7 @@ class BankStatementImportParser(object):
self._post(*args, **kwargs)
return self.result_row_list
def itersubclasses(cls, _seen=None):
"""
itersubclasses(cls)
@@ -193,7 +193,8 @@ def itersubclasses(cls, _seen=None):
if not isinstance(cls, type):
raise TypeError('itersubclasses must be called with '
'new-style classes, not %.100r' % cls)
if _seen is None: _seen = set()
if _seen is None:
_seen = set()
try:
subs = cls.__subclasses__()
except TypeError: # fails only when cls is type
@@ -205,6 +206,7 @@ def itersubclasses(cls, _seen=None):
for sub in itersubclasses(sub, _seen):
yield sub
def new_bank_statement_parser(parser_name, *args, **kwargs):
"""
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):
return cls(parser_name, *args, **kwargs)
raise ValueError

View File

@@ -21,33 +21,35 @@
from openerp.tools.translate import _
import datetime
import netsvc
logger = netsvc.Logger()
from openerp.osv.orm import Model
from openerp.osv import fields, osv
from parser import new_bank_statement_parser
import sys
import traceback
class AccountStatementProfil(Model):
_inherit = "account.statement.profile"
def get_import_type_selection(self, cr, uid, context=None):
"""
Has to be inherited to add parser
"""
return [('generic_csvxls_so', 'Generic .csv/.xls based on SO Name')]
_columns = {
'launch_import_completion': fields.boolean("Launch completion after import",
help="Tic that box to automatically launch the completion on each imported\
file using this profile."),
'launch_import_completion': fields.boolean(
"Launch completion after import",
help="Tic that box to automatically launch the completion "
"on each imported file using this profile."),
'last_import_date': fields.datetime("Last Import Date"),
'rec_log': fields.text('log', readonly=True),
'import_type': fields.selection(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."),
'import_type': fields.selection(
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."),
}
@@ -60,7 +62,7 @@ class AccountStatementProfil(Model):
:param int/long num_lines: Number of line that have been parsed
:return: True
"""
if type(ids) is int:
if isinstance(ids, (int, long)):
ids = [ids]
for id in ids:
log = self.read(cr, uid, id, ['rec_log'], context=context)['rec_log']
@@ -70,12 +72,16 @@ class AccountStatementProfil(Model):
+ _("Bank Statement ID %s have been imported with %s lines ") % (statement_id, num_lines)]
log = "\n".join(log_line)
self.write(cr, uid, id, {'rec_log': log, 'last_import_date': import_date}, context=context)
self.message_post(cr, uid, [statement_id], body=_('Statement ID %s have been imported with %s lines.')
% (statement_id,num_lines), context=context)
self.message_post(
cr,
uid,
[statement_id],
body=_('Statement ID %s have been imported with %s lines.') % (statement_id, num_lines),
context=context)
return True
def prepare_global_commission_line_vals(self, cr, uid, parser,
result_row_list, profile, statement_id, context):
def prepare_global_commission_line_vals(
self, cr, uid, parser, result_row_list, profile, statement_id, context):
"""
Prepare the global commission line if there is one. The global
commission is computed by by calling the get_st_line_commision
@@ -94,7 +100,6 @@ class AccountStatementProfil(Model):
partner_id = profile.partner_id and profile.partner_id.id or False
commission_account_id = profile.commission_account_id and profile.commission_account_id.id or False
commission_analytic_id = profile.commission_analytic_id and profile.commission_analytic_id.id or False
statement_line_obj = self.pool.get('account.bank.statement.line')
comm_values = {
'name': 'IN ' + _('Commission line'),
'date': datetime.datetime.now().date(),
@@ -110,8 +115,9 @@ class AccountStatementProfil(Model):
}
return comm_values
def prepare_statetement_lines_vals(self, cursor, uid, parser_vals,
account_payable, account_receivable, statement_id, context):
def prepare_statetement_lines_vals(
self, cursor, uid, parser_vals, account_payable, account_receivable,
statement_id, context):
"""
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
@@ -149,7 +155,6 @@ class AccountStatementProfil(Model):
:param char: ftype represent the file exstension (csv by default)
:return: ID of the created account.bank.statemênt
"""
context = context or {}
statement_obj = self.pool.get('account.bank.statement')
statement_line_obj = self.pool.get('account.bank.statement.line')
attachment_obj = self.pool.get('ir.attachment')
@@ -158,7 +163,7 @@ class AccountStatementProfil(Model):
raise osv.except_osv(
_("No Profile !"),
_("You must provide a valid profile to import a bank statement !"))
prof = prof_obj.browse(cursor,uid,profile_id,context)
prof = prof_obj.browse(cursor, uid, profile_id, context=context)
parser = new_bank_statement_parser(prof.import_type, ftype=ftype)
result_row_list = parser.parse(file_stream)
@@ -168,23 +173,28 @@ class AccountStatementProfil(Model):
if col not in statement_line_obj._columns:
raise osv.except_osv(
_("Missing column !"),
_("Column %s you try to import is not present in the bank statement line !") %(col))
_("Column %s you try to import is not "
"present in the bank statement line !") % col)
statement_id = statement_obj.create(cursor,uid,{'profile_id':prof.id,},context)
account_receivable, account_payable = statement_obj.get_default_pay_receiv_accounts(cursor, uid, context)
statement_id = statement_obj.create(
cursor, uid, {'profile_id': prof.id}, context=context)
account_receivable, account_payable = statement_obj.get_default_pay_receiv_accounts(
cursor, uid, context)
try:
# Record every line in the bank statement and compute the global commission
# based on the commission_amount column
for line in result_row_list:
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(
cursor, uid, parser_vals, account_payable,
account_receivable, statement_id, context)
# we finally create the line in system
statement_line_obj.create(cursor, uid, values, context=context)
# 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(
cursor, uid, parser, result_row_list, prof, statement_id, context)
if comm_vals:
res = statement_line_obj.create(cursor, uid, comm_vals,context=context)
statement_line_obj.create(cursor, uid, comm_vals, context=context)
attachment_obj.create(
cursor,
@@ -192,7 +202,8 @@ class AccountStatementProfil(Model):
{
'name': 'statement file',
'datas': file_stream,
'datas_fname': "%s.%s"%(datetime.datetime.now().date(),
'datas_fname': "%s.%s" % (
datetime.datetime.now().date(),
ftype),
'res_model': 'account.bank.statement',
'res_id': statement_id,
@@ -204,21 +215,20 @@ class AccountStatementProfil(Model):
statement_obj.button_auto_completion(cursor, uid, [statement_id], context)
# Write the needed log infos on profile
self.write_logs_after_import(cursor, uid, prof.id, statement_id,
len(result_row_list), context)
self.write_logs_after_import(
cursor, uid, prof.id, statement_id, len(result_row_list), context)
except Exception, exc:
statement_obj.unlink(cursor, uid, [statement_id])
except Exception:
statement_obj.unlink(cursor, uid, [statement_id], context=context)
error_type, error_value, trbk = sys.exc_info()
st = "Error: %s\nDescription: %s\nTraceback:" % (error_type.__name__, error_value)
st += ''.join(traceback.format_tb(trbk, 30))
raise osv.except_osv(
_("Statement import error"),
_("The statement cannot be created : %s") %(st))
_("The statement cannot be created : %s") % st)
return statement_id
class AccountStatementLine(Model):
"""
Add sparse field on the statement line to allow to store all the
@@ -228,7 +238,8 @@ class AccountStatementLine(Model):
_inherit = "account.bank.statement.line"
_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'),
}

View File

@@ -23,17 +23,18 @@
Wizard to import financial institute date in bank statement
"""
from openerp.osv import osv, orm
from openerp.osv import fields, osv
from openerp.osv import orm, fields
from openerp.tools.translate import _
import os
class CreditPartnerStatementImporter(orm.TransientModel):
_name = "credit.statement.import"
def default_get(self, cr, uid, fields, context=None):
if context is None: context = {}
if context is None:
context = {}
res = {}
if (context.get('active_model', False) == 'account.statement.profile' and
context.get('active_ids', False)):
@@ -50,46 +51,47 @@ class CreditPartnerStatementImporter(orm.TransientModel):
required=True),
'input_statement': fields.binary('Statement file', required=True),
'partner_id': fields.many2one('res.partner',
'Credit insitute partner',
),
'Credit insitute partner'),
'journal_id': fields.many2one('account.journal',
'Financial journal to use transaction',
),
'input_statement': fields.binary('Statement file', required=True),
'Financial journal to use transaction'),
'file_name': fields.char('File Name', size=128),
'commission_account_id': fields.many2one('account.account',
'Commission account',
),
'Commission account'),
'commission_analytic_id': fields.many2one('account.analytic.account',
'Commission analytic account',
),
'Commission analytic account'),
'receivable_account_id': fields.many2one('account.account',
'Force Receivable/Payable Account'),
'force_partner_on_bank': fields.boolean('Force partner on bank 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',
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."
),
'force_partner_on_bank': fields.boolean(
'Force partner on bank 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',
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):
res = {}
if profile_id:
c = self.pool.get("account.statement.profile").browse(cr,uid,profile_id)
res = {'value': {'partner_id': c.partner_id and c.partner_id.id or False,
'journal_id': c.journal_id and c.journal_id.id or False, 'commission_account_id': \
c = self.pool.get("account.statement.profile").browse(
cr, uid, profile_id, context=context)
res = {'value':
{'partner_id': c.partner_id and c.partner_id.id or False,
'journal_id': c.journal_id and c.journal_id.id or False,
'commission_account_id':
c.commission_account_id and c.commission_account_id.id or False,
'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,}}
'balance_check': c.balance_check,
}
}
return res
def _check_extension(self, filename):
(shortname, ftype) = os.path.splitext(filename)
(__, ftype) = os.path.splitext(filename)
if not ftype:
#We do not use osv exception we do not want to have it logged
raise Exception(_('Please use a file with an extention'))

View File

@@ -18,4 +18,3 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

View File

@@ -24,8 +24,11 @@
'author': 'Camptocamp',
'maintainer': 'Camptocamp',
'category': 'Finance',
'complexity': 'normal', #easy, normal, expert
'depends': ['account_statement_base_completion','account_voucher'],
'complexity': 'normal',
'depends': [
'account_statement_base_completion',
'account_voucher'
],
'description': """
This module is only needed when using account_statement_base_completion with voucher in order adapt the view correctly.
""",

View File

@@ -24,8 +24,11 @@
'author': 'Camptocamp',
'maintainer': 'Camptocamp',
'category': 'Finance',
'complexity': 'normal', #easy, normal, expert
'depends': ['account','report_webkit'],
'complexity': 'normal',
'depends': [
'account',
'report_webkit'
],
'description': """
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,

View File

@@ -20,7 +20,7 @@
##############################################################################
from openerp.osv.orm import Model
from openerp.osv import fields, osv
from openerp.osv import fields
class account_move(Model):
@@ -36,6 +36,3 @@ class account_move(Model):
if move_line.reconcile_id:
move_line.reconcile_id.unlink(context=context)
return super(account_move, self).unlink(cr, uid, ids, context=context)

View File

@@ -1,9 +1,4 @@
# -*- encoding: utf-8 -*-
#
# __init__.py
#
# Copyright (c) 2009 CamptoCamp. All rights reserved.
##############################################################################
# -*- coding: utf-8 -*-
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential

View File

@@ -1,4 +1,4 @@
# -*- encoding: utf-8 -*-
# -*- coding utf-8 -*-
##############################################################################
#
# Author: Nicolas Bessi. Copyright Camptocamp SA
@@ -18,16 +18,13 @@
#
##############################################################################
import time
from report import report_sxw
from openerp.report import report_sxw
from openerp.tools.translate import _
import pooler
from operator import add, itemgetter
from itertools import groupby
from openerp import pooler
from datetime import datetime
from report_webkit import webkit_report
class BankStatementWebkit(report_sxw.rml_parse):
def __init__(self, cursor, uid, name, context):
@@ -35,10 +32,10 @@ class BankStatementWebkit(report_sxw.rml_parse):
self.pool = pooler.get_pool(self.cr.dbname)
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'),
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)
self.localcontext.update({
'cr': cursor,
@@ -57,10 +54,15 @@ class BankStatementWebkit(report_sxw.rml_parse):
('--footer-line',),
],
})
def _get_bank_statement_data(self, statement):
statement_obj = self.pool.get('account.bank.statement.line')
statement_line_ids = statement_obj.search(self.cr,self.uid,[['statement_id','=',statement.id]])
statement_lines = statement_obj.browse(self.cr,self.uid,statement_line_ids)
statement_line_ids = statement_obj.search(
self.cr,
self.uid,
[('statement_id', '=', statement.id)])
statement_lines = statement_obj.browse(
self.cr, self.uid, statement_line_ids)
return statement_lines
webkit_report.WebKitParser('report.bank_statement_webkit',

View File

@@ -19,11 +19,10 @@
#
##############################################################################
import time
from openerp.osv.orm import Model
from openerp.osv import fields, osv, osv
from openerp.osv import fields, osv
from openerp.tools.translate import _
import openerp.addons.decimal_precision as dp
class AccountStatementProfil(Model):
"""
@@ -35,43 +34,51 @@ class AccountStatementProfil(Model):
_description = "Statement Profil"
_columns = {
'name': fields.char('Name', size=128, required=True),
'partner_id': fields.many2one('res.partner',
'name': fields.char('Name', required=True),
'partner_id': fields.many2one(
'res.partner',
'Bank/Payment Office partner',
help="Put a partner if you want to have it on the commission move \
(and optionaly on the counterpart of the intermediate/banking move \
if you tic the corresponding checkbox)."),
'journal_id': fields.many2one('account.journal',
help="Put a partner if you want to have it on the "
"commission move (and optionaly on the counterpart "
"of the intermediate/banking move if you tick the "
"corresponding checkbox)."),
'journal_id': fields.many2one(
'account.journal',
'Financial journal to use for transaction',
required=True),
'commission_account_id': fields.many2one('account.account',
'commission_account_id': fields.many2one(
'account.account',
'Commission account',
required=True),
'commission_analytic_id': fields.many2one('account.analytic.account',
'commission_analytic_id': fields.many2one(
'account.analytic.account',
'Commission analytic account'),
'receivable_account_id': fields.many2one('account.account',
'receivable_account_id': fields.many2one(
'account.account',
'Force Receivable/Payable Account',
help="Choose a receivable account to force the default\
debit/credit account (eg. an intermediat bank account instead of\
default debitors)."),
'force_partner_on_bank': fields.boolean('Force partner on bank move',
help="Tic that box if you want to use the credit insitute partner\
in the counterpart of the intermediat/banking move."
help="Choose a receivable account to force the default "
"debit/credit account (eg. an intermediat bank account "
"instead of default debitors)."),
'force_partner_on_bank': fields.boolean(
'Force partner on bank move',
help="Tick that box if you want to use the credit "
"institute partner in the counterpart of the "
"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."
),
'balance_check': fields.boolean('Balance check',
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."
),
'bank_statement_prefix': fields.char('Bank Statement Prefix', size=32),
'bank_statement_ids': fields.one2many('account.bank.statement', 'profile_id', 'Bank Statement Imported'),
'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):
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 True
@@ -95,33 +102,41 @@ class AccountBankSatement(Model):
_inherit = "account.bank.statement"
_columns = {
'profile_id': fields.many2one('account.statement.profile',
'Profil', required=True, readonly=True, states={'draft': [('readonly', False)]}),
'profile_id': fields.many2one(
'account.statement.profile',
'Profil',
required=True,
readonly=True,
states={'draft': [('readonly', False)]}),
'credit_partner_id': fields.related(
'profile_id',
'partner_id',
type='many2one',
relation='res.partner',
string='Financial Partner',
store=True, readonly=True),
store=True,
readonly=True),
'balance_check': fields.related(
'profile_id',
'balance_check',
type='boolean',
string='Balance check',
store=True, readonly=True),
store=True,
readonly=True),
'journal_id': fields.related(
'profile_id',
'journal_id',
type='many2one',
relation='account.journal',
string='Journal',
store=True, readonly=True),
'period_id': fields.many2one('account.period', 'Period', required=False, readonly=True),
store=True,
readonly=True),
'period_id': fields.many2one(
'account.period', 'Period', required=False, readonly=True),
}
_defaults = {
'period_id': lambda *a: False,
'period_id': False,
}
def create(self, cr, uid, vals, context=None):
@@ -129,7 +144,7 @@ class AccountBankSatement(Model):
need it."""
if 'profile_id' in vals:
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
return super(AccountBankSatement, self).create(cr, uid, vals, context=context)
@@ -157,25 +172,27 @@ class AccountBankSatement(Model):
return True
_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
statement in draft state. So no need to unreconcile all entries,
then unpost them, then finaly cancel the bank statement.
"""
done = []
for st in self.browse(cr, uid, ids, context=context):
if st.state == 'draft':
continue
ids = []
for line in st.line_ids:
for move in line.move_ids:
if move.state <> 'draft':
if move.state != 'draft':
move.button_cancel(context=context)
return super(AccountBankSatement, self).button_cancel(cr, uid, vals, context=context)
return super(AccountBankSatement, self).button_cancel(
cr, uid, ids, context=context)
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.
@@ -187,14 +204,16 @@ class AccountBankSatement(Model):
"""
if context is None:
context = {}
res = super(AccountBankSatement, self)._prepare_move(cr, uid, st_line, st_line_number, context=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,
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.
@@ -215,9 +234,13 @@ class AccountBankSatement(Model):
"""
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)
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)
@@ -235,8 +258,9 @@ class AccountBankSatement(Model):
create the move from.
:return: int/long of the res.partner to use as counterpart
"""
bank_partner_id = super(AccountBankSatement, self)._get_counter_part_partner(cr, uid, st_line, context=context)
# GET THE RIGHT PARTNER ACCORDING TO THE CHOSEN PROFIL
bank_partner_id = super(AccountBankSatement, self).\
_get_counter_part_partner(cr, uid, st_line, context=context)
# get the right partner according to the chosen profil
if st_line.statement_id.profile_id.force_partner_on_bank:
bank_partner_id = st_line.statement_id.profile_id.partner_id.id
return bank_partner_id
@@ -252,11 +276,13 @@ class AccountBankSatement(Model):
: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(
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}
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:
st_number = obj_seq.next_by_id(cr, uid, journal_sequence_id, context=c)
else:
@@ -275,9 +301,6 @@ class AccountBankSatement(Model):
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):
j_type = st.journal_id.type
@@ -298,7 +321,7 @@ class AccountBankSatement(Model):
st_number = self._get_st_number_period_profile(cr, uid, st.date, st.profile_id.id)
# End Changes
for line in st.move_line_ids:
if line.state <> 'valid':
if line.state != 'valid':
raise osv.except_osv(_('Error !'),
_('The account entries lines are not in valid state.'))
# begin changes
@@ -330,8 +353,8 @@ class AccountBankSatement(Model):
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)
def get_account_for_counterpart(self, cursor, uid,
amount, account_receivable, account_payable):
def get_account_for_counterpart(
self, cursor, uid, amount, account_receivable, account_payable):
"""
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
@@ -367,7 +390,6 @@ class AccountBankSatement(Model):
"""
account_receivable = False
account_payable = False
context = context or {}
property_obj = self.pool.get('ir.property')
model_fields_obj = self.pool.get('ir.model.fields')
model_fields_ids = model_fields_obj.search(
@@ -375,20 +397,20 @@ class AccountBankSatement(Model):
uid,
[('name', 'in', ['property_account_receivable',
'property_account_payable']),
('model', '=', 'res.partner'),],
('model', '=', 'res.partner')],
context=context
)
property_ids = property_obj.search(
cursor,
uid, [
('fields_id', 'in', model_fields_ids),
uid,
[('fields_id', 'in', model_fields_ids),
('res_id', '=', False),
],
context=context
)
for erp_property in property_obj.browse(cursor, uid,
property_ids, context=context):
for erp_property in property_obj.browse(
cursor, uid, property_ids, context=context):
if erp_property.fields_id.name == 'property_account_receivable':
account_receivable = erp_property.value_reference.id
elif erp_property.fields_id.name == 'property_account_payable':
@@ -406,7 +428,8 @@ class AccountBankSatement(Model):
"""
st = self.browse(cr, uid, st_id, context=context)
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:
return True
@@ -419,14 +442,18 @@ class AccountBankSatement(Model):
"""
if not profile_id:
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
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
return {'value': {'journal_id':journal_id, 'account_id': account_id,
return {'value':
{'journal_id': journal_id,
'account_id': account_id,
'balance_check': import_config.balance_check,
'credit_partner_id': credit_partner_id,
}}
}
}
class AccountBankSatementLine(Model):
@@ -483,15 +510,14 @@ class AccountBankSatementLine(Model):
...
}
"""
if context is None:
context = {}
res = {}
obj_partner = self.pool.get('res.partner')
obj_stat = self.pool.get('account.bank.statement')
receiv_account = pay_account = account_id = False
# If profile has a receivable_account_id, we return it in any case
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:
res['account_id'] = profile.receivable_account_id.id
res['type'] = 'general'
@@ -503,7 +529,8 @@ class AccountBankSatementLine(Model):
receiv_account = part.property_account_receivable.id
# If no value, look on the default company property
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
# based on line_type first, then amount, otherwise take receivable one.
if line_type is not False:
@@ -522,15 +549,12 @@ class AccountBankSatementLine(Model):
res['account_id'] = receiv_account
return res
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
call.
"""
obj_partner = self.pool.get('res.partner')
if context is None:
context = {}
if not partner_id:
return {}
part = obj_partner.browse(cr, uid, partner_id, context=context)
@@ -553,13 +577,15 @@ class AccountBankSatementLine(Model):
Keep the same features as in standard and call super. If an account is returned,
call the method to compute line values.
"""
if context is None:
context = {}
res = super(AccountBankSatementLine,self).onchange_type(cr, uid, line_id, partner_id, type, context)
res = super(AccountBankSatementLine, self).onchange_type(
cr, uid, line_id, partner_id, type, context=context)
if 'account_id' in res['value']:
result = self.get_values_for_line(cr, uid, profile_id = profile_id,
partner_id = partner_id, line_type = type, context = context)
result = self.get_values_for_line(
cr, uid,
profile_id=profile_id,
partner_id=partner_id,
line_type=type,
context=context)
if result:
res['value'].update({'account_id': result['account_id']})
return res

View File

@@ -24,8 +24,11 @@
'author': 'Camptocamp',
'maintainer': 'Camptocamp',
'category': 'Finance',
'complexity': 'normal', #easy, normal, expert
'depends': ['account_statement_ext','account_voucher'],
'complexity': 'normal',
'depends': [
'account_statement_ext',
'account_voucher'
],
'description': """
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.

View File

@@ -20,7 +20,7 @@
##############################################################################
from openerp.osv.orm import Model
from openerp.osv import fields, osv
class AccountVoucher(Model):
@@ -31,7 +31,8 @@ class AccountVoucher(Model):
if context is None:
context = {}
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
elif context.get('date'):
periods = self.pool.get('account.period').find(
@@ -48,4 +49,3 @@ class AccountVoucher(Model):
ctx = dict(context, date=values.get('date'))
values['period_id'] = self._get_period(cr, uid, ctx)
return super(AccountVoucher, self).create(cr, uid, values, context)

View File

@@ -24,8 +24,11 @@
'author': 'Camptocamp',
'maintainer': 'Camptocamp',
'category': 'Finance',
'complexity': 'normal', #easy, normal, expert
'depends': ['account_statement_base_completion', 'base_transaction_id'],
'complexity': 'normal',
'depends': [
'account_statement_base_completion',
'base_transaction_id'
],
'description': """
Add a completion method based on transaction ID providen by the bank/office.

View File

@@ -20,12 +20,11 @@
##############################################################################
from openerp.tools.translate import _
import datetime
import netsvc
from openerp.osv.orm import Model
from openerp.osv import fields, osv
from openerp.osv import fields
from openerp.addons.account_statement_base_completion.statement import ErrorTooManyPartner
class AccountStatementCompletionRule(Model):
"""Add a rule based on transaction ID"""
@@ -34,7 +33,8 @@ class AccountStatementCompletionRule(Model):
def _get_functions(self, cr, uid, context=None):
res = super(AccountStatementCompletionRule, self)._get_functions(
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
_columns = {
@@ -55,20 +55,32 @@ class AccountStatementCompletionRule(Model):
...}
"""
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 = {}
if st_line:
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:
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['ref'] = so.name
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:
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)
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)
return res
@@ -78,13 +90,10 @@ class AccountStatementLine(Model):
_columns = {
# '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,
serialization_field='additionnal_bank_fields',
help="Transction id from the financial institute"),
}

View File

@@ -24,8 +24,11 @@
'author': 'Camptocamp',
'maintainer': 'Camptocamp',
'category': 'Finance',
'complexity': 'normal', #easy, normal, expert
'depends': ['account_statement_base_import','account_statement_transactionid_completion'],
'complexity': 'normal',
'depends': [
'account_statement_base_import',
'account_statement_transactionid_completion'
],
'description': """
This module brings generic methods and fields on bank statement to deal with
the importation of different bank and offices that uses transactionID.

View File

@@ -19,6 +19,4 @@
#
##############################################################################
# from parser import new_bank_statement_parser
# from parser import BankStatementImportParser
import transactionid_file_parser

View File

@@ -19,16 +19,9 @@
##############################################################################
from openerp.tools.translate import _
import base64
import csv
import tempfile
import datetime
from account_statement_base_import.parser.file_parser import FileParser
try:
import xlrd
except:
raise Exception(_('Please install python lib xlrd'))
class TransactionIDFileParser(FileParser):
"""
@@ -96,4 +89,3 @@ class TransactionIDFileParser(FileParser):
val += row.get('commission_amount', 0.0)
self.commission_global_amount = val
return res

View File

@@ -20,24 +20,28 @@
##############################################################################
from openerp.osv.orm import Model
from openerp.osv import fields, osv
from openerp.osv import fields
class AccountStatementProfil(Model):
_inherit = "account.statement.profile"
def get_import_type_selection(self, cr, uid, context=None):
"""
Has to be inherited to add parser
"""
res = super(AccountStatementProfil, self).get_import_type_selection(cr, uid, context=context)
res.append(('generic_csvxls_transaction','Generic .csv/.xls based on SO transaction ID'))
res = super(AccountStatementProfil, self).get_import_type_selection(
cr, uid, context=context)
res.append(('generic_csvxls_transaction',
'Generic .csv/.xls based on SO transaction ID'))
return res
_columns = {
'import_type': fields.selection(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."),
'import_type': fields.selection(
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."),
}

View File

@@ -24,18 +24,30 @@
'author': 'Camptocamp',
'maintainer': 'Camptocamp',
'category': 'Hidden/Dependency',
'complexity': 'easy', #easy, normal, expert
'depends': ['account', 'sale','stock'],
'complexity': 'easy',
'depends': [
'account',
'sale',
'stock'
],
'description': """
Adds transaction id to invoice and sale models and views. On Sales order, you can specify the transaction ID
used for the payment and it will be propagated to the invoice (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 SO field. The main purpose is to ease the reconciliation process and
Adds transaction id to invoice and sale models and views.
On Sales order, you can specify the transaction ID used
for the payment and it will be propagated to the invoice
(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.
""",
'website': 'http://www.openerp.com',
'init_xml': [],
'update_xml': ['invoice_view.xml', 'sale_view.xml'],
'update_xml': [
'invoice_view.xml',
'sale_view.xml'
],
'demo_xml': [],
'test': [],
'installable': True,

View File

@@ -20,17 +20,17 @@
##############################################################################
from openerp.osv.orm import Model
from openerp.osv import fields, osv
from openerp.tools.translate import _
from openerp.osv import fields
class AccountInvoice(Model):
_inherit = 'account.invoice'
_columns = {
'transaction_id': fields.char(
'Transaction id',
size=128,
required=False,
select=1,
help="Transction id from the financial institute"
),
help="Transction id from the financial institute"),
}

View File

@@ -20,21 +20,24 @@
##############################################################################
from openerp.osv.orm import Model
from openerp.osv import fields, osv
from openerp.osv import fields
class SaleOrder(Model):
_inherit = 'sale.order'
_columns = {
'transaction_id':fields.char('Transaction id', size=128,required=False,
help="Transction id from the financial institute"),
}
_columns = {
'transaction_id': fields.char(
'Transaction id',
size=128,
required=False,
help="Transaction id from the financial institute"),
}
def _prepare_invoice(self, cursor, uid, order, lines, context=None):
#we put the transaction id in the generated invoices
if context is None:
context = {}
invoice_vals = super(SaleOrder, self)._prepare_invoice(cursor, uid, order, lines, context)
invoice_vals = super(SaleOrder, self)._prepare_invoice(
cursor, uid, order, lines, context=context)
invoice_vals.update({
'transaction_id': order.transaction_id})
return invoice_vals

View File

@@ -20,20 +20,23 @@
##############################################################################
from openerp.osv.orm import Model
from openerp.osv import fields, osv
class StockPicking(Model):
_inherit = "stock.picking"
def action_invoice_create(self, cursor, uid, ids, journal_id=False,
group=False, type='out_invoice', context=None):
res = super(StockPicking, self).action_invoice_create(cursor, uid, ids,
journal_id,group, type, context)
def action_invoice_create(
self, cursor, uid, ids, journal_id=False, group=False,
type='out_invoice', context=None):
res = super(StockPicking, self).action_invoice_create(
cursor, uid, ids, journal_id, group, type, context)
for pick_id in res:
pick = self.browse(cursor, uid, pick_id)
pick = self.browse(cursor, uid, pick_id, context=context)
if pick.sale_id and pick.sale_id.transaction_id:
self.pool.get('account.invoice').write(cursor,
self.pool.get('account.invoice').write(
cursor,
uid,
res[pick_id],
{'transaction_id': pick.sale_id.transaction_id})
{'transaction_id': pick.sale_id.transaction_id},
context=context)
return res