mirror of
https://github.com/OCA/bank-payment.git
synced 2025-02-02 10:37:31 +02:00
PEP8 on account_banking
This commit is contained in:
@@ -11,8 +11,8 @@
|
|||||||
# garantees and support are strongly adviced to contract EduSense BV
|
# garantees and support are strongly adviced to contract EduSense BV
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU Affero General Public License as published by
|
# it under the terms of the GNU Affero General Public License as published
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# by the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
# 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 sepa
|
import sepa
|
||||||
import record
|
import record
|
||||||
import banking_import_transaction
|
import banking_import_transaction
|
||||||
@@ -33,5 +34,3 @@ import wizard
|
|||||||
import res_partner
|
import res_partner
|
||||||
import res_bank
|
import res_bank
|
||||||
import res_partner_bank
|
import res_partner_bank
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
||||||
|
|||||||
@@ -70,7 +70,8 @@
|
|||||||
+ IBAN accounts are the standard in the SEPA countries
|
+ IBAN accounts are the standard in the SEPA countries
|
||||||
+ local accounts are derived from SEPA (excluding Turkey) but are
|
+ local accounts are derived from SEPA (excluding Turkey) but are
|
||||||
considered to be identical to the corresponding SEPA account.
|
considered to be identical to the corresponding SEPA account.
|
||||||
+ Banks are identified with either Country + Bank code + Branch code or BIC
|
+ Banks are identified with either Country + Bank code + Branch code or
|
||||||
|
BIC
|
||||||
+ Each bank can have its own pace in introducing SEPA into their
|
+ Each bank can have its own pace in introducing SEPA into their
|
||||||
communication with their customers.
|
communication with their customers.
|
||||||
+ National online databases can be used to convert BBAN's to IBAN's.
|
+ National online databases can be used to convert BBAN's to IBAN's.
|
||||||
|
|||||||
@@ -98,8 +98,8 @@ class account_banking_account_settings(orm.Model):
|
|||||||
select=True, required=True,
|
select=True, required=True,
|
||||||
help=('The account to use when an unexpected payment is received. '
|
help=('The account to use when an unexpected payment is received. '
|
||||||
'This can be needed when a customer pays in advance or when '
|
'This can be needed when a customer pays in advance or when '
|
||||||
'no matching invoice can be found. Mind that you can correct '
|
'no matching invoice can be found. Mind that you can '
|
||||||
'movements before confirming them.'
|
'correct movements before confirming them.'
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
'costs_account_id': fields.many2one(
|
'costs_account_id': fields.many2one(
|
||||||
@@ -229,35 +229,57 @@ class account_banking_imported_file(orm.Model):
|
|||||||
_description = __doc__
|
_description = __doc__
|
||||||
_rec_name = 'date'
|
_rec_name = 'date'
|
||||||
_columns = {
|
_columns = {
|
||||||
'company_id': fields.many2one('res.company', 'Company',
|
'company_id': fields.many2one(
|
||||||
select=True, readonly=True
|
'res.company',
|
||||||
|
'Company',
|
||||||
|
select=True,
|
||||||
|
readonly=True,
|
||||||
),
|
),
|
||||||
'date': fields.datetime('Import Date', readonly=True, select=True,
|
'date': fields.datetime(
|
||||||
states={'draft': [('readonly', False)]}
|
'Import Date',
|
||||||
|
readonly=True,
|
||||||
|
select=True,
|
||||||
|
states={'draft': [('readonly', False)]},
|
||||||
),
|
),
|
||||||
'format': fields.char('File Format', size=20, readonly=True,
|
'format': fields.char(
|
||||||
states={'draft': [('readonly', False)]}
|
'File Format',
|
||||||
|
size=20,
|
||||||
|
readonly=True,
|
||||||
|
states={'draft': [('readonly', False)]},
|
||||||
),
|
),
|
||||||
'file': fields.binary('Raw Data', readonly=True,
|
'file': fields.binary(
|
||||||
states={'draft': [('readonly', False)]}
|
'Raw Data',
|
||||||
|
readonly=True,
|
||||||
|
states={'draft': [('readonly', False)]},
|
||||||
),
|
),
|
||||||
'file_name': fields.char('File name', size=256),
|
'file_name': fields.char('File name', size=256),
|
||||||
'log': fields.text('Import Log', readonly=True,
|
'log': fields.text(
|
||||||
states={'draft': [('readonly', False)]}
|
'Import Log',
|
||||||
|
readonly=True,
|
||||||
|
states={'draft': [('readonly', False)]},
|
||||||
),
|
),
|
||||||
'user_id': fields.many2one('res.users', 'Responsible User',
|
'user_id': fields.many2one(
|
||||||
readonly=True, select=True,
|
'res.users',
|
||||||
states={'draft': [('readonly', False)]}
|
'Responsible User',
|
||||||
|
readonly=True,
|
||||||
|
select=True,
|
||||||
|
states={'draft': [('readonly', False)]},
|
||||||
),
|
),
|
||||||
'state': fields.selection(
|
'state': fields.selection(
|
||||||
[('unfinished', 'Unfinished'),
|
[
|
||||||
|
('unfinished', 'Unfinished'),
|
||||||
('error', 'Error'),
|
('error', 'Error'),
|
||||||
('review', 'Review'),
|
('review', 'Review'),
|
||||||
('ready', 'Finished'),
|
('ready', 'Finished'),
|
||||||
], 'State', select=True, readonly=True
|
],
|
||||||
|
'State',
|
||||||
|
select=True,
|
||||||
|
readonly=True,
|
||||||
),
|
),
|
||||||
'statement_ids': fields.one2many('account.bank.statement',
|
'statement_ids': fields.one2many(
|
||||||
'banking_id', 'Statements',
|
'account.bank.statement',
|
||||||
|
'banking_id',
|
||||||
|
'Statements',
|
||||||
readonly=False,
|
readonly=False,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
@@ -284,10 +306,16 @@ class account_bank_statement(orm.Model):
|
|||||||
_inherit = 'account.bank.statement'
|
_inherit = 'account.bank.statement'
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'period_id': fields.many2one('account.period', 'Period',
|
'period_id': fields.many2one(
|
||||||
required=False, readonly=True),
|
'account.period',
|
||||||
'banking_id': fields.many2one('account.banking.imported.file',
|
'Period',
|
||||||
'Imported File', readonly=True,
|
required=False,
|
||||||
|
readonly=True,
|
||||||
|
),
|
||||||
|
'banking_id': fields.many2one(
|
||||||
|
'account.banking.imported.file',
|
||||||
|
'Imported File',
|
||||||
|
readonly=True,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -419,9 +447,10 @@ class account_bank_statement(orm.Model):
|
|||||||
('account_id', '=', st_line.account_id.id)],
|
('account_id', '=', st_line.account_id.id)],
|
||||||
context=context)
|
context=context)
|
||||||
account_move_line_obj.write(cr, uid, torec, {
|
account_move_line_obj.write(cr, uid, torec, {
|
||||||
(st_line.reconcile_id.line_partial_ids and
|
(st_line.reconcile_id.line_partial_ids
|
||||||
'reconcile_partial_id' or 'reconcile_id'):
|
and 'reconcile_partial_id'
|
||||||
st_line.reconcile_id.id }, context=context)
|
or 'reconcile_id'): st_line.reconcile_id.id
|
||||||
|
}, context=context)
|
||||||
for move_line in (st_line.reconcile_id.line_id or []) + (
|
for move_line in (st_line.reconcile_id.line_id or []) + (
|
||||||
st_line.reconcile_id.line_partial_ids or []):
|
st_line.reconcile_id.line_partial_ids or []):
|
||||||
netsvc.LocalService("workflow").trg_trigger(
|
netsvc.LocalService("workflow").trg_trigger(
|
||||||
@@ -498,8 +527,8 @@ class account_bank_statement_line(orm.Model):
|
|||||||
which is inaccessible from within this method.
|
which is inaccessible from within this method.
|
||||||
'''
|
'''
|
||||||
res_users_obj = self.pool.get('res.users')
|
res_users_obj = self.pool.get('res.users')
|
||||||
return res_users_obj.browse(cr, uid, uid,
|
return res_users_obj.browse(
|
||||||
context=context).company_id.currency_id.id
|
cr, uid, uid, context=context).company_id.currency_id.id
|
||||||
|
|
||||||
def _get_invoice_id(self, cr, uid, ids, name, args, context=None):
|
def _get_invoice_id(self, cr, uid, ids, name, args, context=None):
|
||||||
res = {}
|
res = {}
|
||||||
@@ -519,35 +548,69 @@ class account_bank_statement_line(orm.Model):
|
|||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
# Redefines. Todo: refactor away to view attrs
|
# Redefines. Todo: refactor away to view attrs
|
||||||
'amount': fields.float('Amount', readonly=True,
|
'amount': fields.float(
|
||||||
|
'Amount',
|
||||||
|
readonly=True,
|
||||||
digits_compute=dp.get_precision('Account'),
|
digits_compute=dp.get_precision('Account'),
|
||||||
states={'draft': [('readonly', False)]}),
|
states={'draft': [('readonly', False)]},
|
||||||
'ref': fields.char('Ref.', size=32, readonly=True,
|
),
|
||||||
states={'draft': [('readonly', False)]}),
|
'ref': fields.char(
|
||||||
'name': fields.char('Name', size=64, required=False, readonly=True,
|
'Ref.',
|
||||||
states={'draft': [('readonly', False)]}),
|
size=32,
|
||||||
'date': fields.date('Date', required=True, readonly=True,
|
|
||||||
states={'draft': [('readonly', False)]}),
|
|
||||||
|
|
||||||
# New columns
|
|
||||||
'trans': fields.char('Bank Transaction ID', size=15, required=False,
|
|
||||||
readonly=True,
|
readonly=True,
|
||||||
states={'draft': [('readonly', False)]},
|
states={'draft': [('readonly', False)]},
|
||||||
),
|
),
|
||||||
'partner_bank_id': fields.many2one('res.partner.bank', 'Bank Account',
|
'name': fields.char(
|
||||||
required=False, readonly=True,
|
'Name',
|
||||||
|
size=64,
|
||||||
|
required=False,
|
||||||
|
readonly=True,
|
||||||
states={'draft': [('readonly', False)]},
|
states={'draft': [('readonly', False)]},
|
||||||
),
|
),
|
||||||
'period_id': fields.many2one('account.period', 'Period', required=True,
|
'date': fields.date(
|
||||||
states={'confirmed': [('readonly', True)]}),
|
'Date',
|
||||||
'currency': fields.many2one('res.currency', 'Currency', required=True,
|
required=True,
|
||||||
states={'confirmed': [('readonly', True)]}),
|
readonly=True,
|
||||||
|
states={'draft': [('readonly', False)]},
|
||||||
|
),
|
||||||
|
# New columns
|
||||||
|
'trans': fields.char(
|
||||||
|
'Bank Transaction ID',
|
||||||
|
size=15,
|
||||||
|
required=False,
|
||||||
|
readonly=True,
|
||||||
|
states={'draft': [('readonly', False)]},
|
||||||
|
),
|
||||||
|
'partner_bank_id': fields.many2one(
|
||||||
|
'res.partner.bank',
|
||||||
|
'Bank Account',
|
||||||
|
required=False,
|
||||||
|
readonly=True,
|
||||||
|
states={'draft': [('readonly', False)]},
|
||||||
|
),
|
||||||
|
'period_id': fields.many2one(
|
||||||
|
'account.period',
|
||||||
|
'Period',
|
||||||
|
required=True,
|
||||||
|
states={'confirmed': [('readonly', True)]},
|
||||||
|
),
|
||||||
|
'currency': fields.many2one(
|
||||||
|
'res.currency',
|
||||||
|
'Currency',
|
||||||
|
required=True,
|
||||||
|
states={'confirmed': [('readonly', True)]},
|
||||||
|
),
|
||||||
'reconcile_id': fields.many2one(
|
'reconcile_id': fields.many2one(
|
||||||
'account.move.reconcile', 'Reconciliation', readonly=True
|
'account.move.reconcile',
|
||||||
|
'Reconciliation',
|
||||||
|
readonly=True,
|
||||||
),
|
),
|
||||||
'invoice_id': fields.function(
|
'invoice_id': fields.function(
|
||||||
_get_invoice_id, method=True, string='Linked Invoice',
|
_get_invoice_id,
|
||||||
type='many2one', relation='account.invoice'
|
method=True,
|
||||||
|
string='Linked Invoice',
|
||||||
|
type='many2one',
|
||||||
|
relation='account.invoice',
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -600,8 +663,6 @@ class invoice(orm.Model):
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
invoice()
|
|
||||||
|
|
||||||
|
|
||||||
class account_move_line(orm.Model):
|
class account_move_line(orm.Model):
|
||||||
_inherit = "account.move.line"
|
_inherit = "account.move.line"
|
||||||
@@ -620,6 +681,3 @@ class account_move_line(orm.Model):
|
|||||||
cr, uid, ids, ['debit', 'credit'], context=context):
|
cr, uid, ids, ['debit', 'credit'], context=context):
|
||||||
total += (line['debit'] or 0.0) - (line['credit'] or 0.0)
|
total += (line['debit'] or 0.0) - (line['credit'] or 0.0)
|
||||||
return total
|
return total
|
||||||
account_move_line()
|
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ from openerp.tools.translate import _
|
|||||||
from openerp.addons.decimal_precision import decimal_precision as dp
|
from openerp.addons.decimal_precision import decimal_precision as dp
|
||||||
from openerp.addons.account_banking.parsers import models
|
from openerp.addons.account_banking.parsers import models
|
||||||
from openerp.addons.account_banking.parsers import convert
|
from openerp.addons.account_banking.parsers import convert
|
||||||
from openerp.addons.account_banking import sepa
|
|
||||||
from openerp.addons.account_banking.wizard import banktools
|
from openerp.addons.account_banking.wizard import banktools
|
||||||
|
|
||||||
bt = models.mem_bank_transaction
|
bt = models.mem_bank_transaction
|
||||||
@@ -48,8 +47,9 @@ class banking_import_transaction(orm.Model):
|
|||||||
_description = 'Bank import transaction'
|
_description = 'Bank import transaction'
|
||||||
_rec_name = 'transaction'
|
_rec_name = 'transaction'
|
||||||
|
|
||||||
# This variable is used to match supplier invoices with an invoice date after
|
# This variable is used to match supplier invoices with an invoice date
|
||||||
# the real payment date. This can occur with online transactions (web shops).
|
# after the real payment date. This can occur with online transactions
|
||||||
|
# (web shops).
|
||||||
# TODO: Convert this to a proper configuration variable
|
# TODO: Convert this to a proper configuration variable
|
||||||
payment_window = datetime.timedelta(days=10)
|
payment_window = datetime.timedelta(days=10)
|
||||||
|
|
||||||
@@ -65,7 +65,9 @@ class banking_import_transaction(orm.Model):
|
|||||||
amount = round(abs(trans.statement_line_id.amount), digits)
|
amount = round(abs(trans.statement_line_id.amount), digits)
|
||||||
# Make sure to be able to pinpoint our costs invoice for later
|
# Make sure to be able to pinpoint our costs invoice for later
|
||||||
# matching
|
# matching
|
||||||
reference = '%s.%s: %s' % (trans.statement, trans.transaction, trans.reference)
|
reference = '%s.%s: %s' % (trans.statement,
|
||||||
|
trans.transaction,
|
||||||
|
trans.reference)
|
||||||
|
|
||||||
# search supplier invoice
|
# search supplier invoice
|
||||||
invoice_obj = self.pool.get('account.invoice')
|
invoice_obj = self.pool.get('account.invoice')
|
||||||
@@ -100,7 +102,8 @@ class banking_import_transaction(orm.Model):
|
|||||||
address_invoice_id=invoice_address_id['invoice'],
|
address_invoice_id=invoice_address_id['invoice'],
|
||||||
period_id=period_id,
|
period_id=period_id,
|
||||||
journal_id=account_info.invoice_journal_id.id,
|
journal_id=account_info.invoice_journal_id.id,
|
||||||
account_id = account_info.bank_partner_id.property_account_payable.id,
|
account_id=(
|
||||||
|
account_info.bank_partner_id.property_account_payable.id),
|
||||||
date_invoice=trans.execution_date,
|
date_invoice=trans.execution_date,
|
||||||
reference_type='none',
|
reference_type='none',
|
||||||
reference=reference,
|
reference=reference,
|
||||||
@@ -129,8 +132,8 @@ class banking_import_transaction(orm.Model):
|
|||||||
Use the sales journal to check.
|
Use the sales journal to check.
|
||||||
|
|
||||||
Challenges we're facing:
|
Challenges we're facing:
|
||||||
1. The sending or receiving party is not necessarily the same as the
|
1. The sending or receiving party is not necessarily the same as
|
||||||
partner the payment relates to.
|
the partner the payment relates to.
|
||||||
2. References can be messed up during manual encoding and inexact
|
2. References can be messed up during manual encoding and inexact
|
||||||
matching can link the wrong invoices.
|
matching can link the wrong invoices.
|
||||||
3. Amounts can or can not match the expected amount.
|
3. Amounts can or can not match the expected amount.
|
||||||
@@ -138,8 +141,8 @@ class banking_import_transaction(orm.Model):
|
|||||||
.. There are countless more, but these we'll try to address.
|
.. There are countless more, but these we'll try to address.
|
||||||
|
|
||||||
Assumptions for matching:
|
Assumptions for matching:
|
||||||
1. There are no payments for invoices not sent. These are dealt with
|
1. There are no payments for invoices not sent. These are dealt
|
||||||
later on.
|
with later on.
|
||||||
2. Debit amounts are either customer invoices or credited supplier
|
2. Debit amounts are either customer invoices or credited supplier
|
||||||
invoices.
|
invoices.
|
||||||
3. Credit amounts are either supplier invoices or credited customer
|
3. Credit amounts are either supplier invoices or credited customer
|
||||||
@@ -152,8 +155,8 @@ class banking_import_transaction(orm.Model):
|
|||||||
1. No match was made.
|
1. No match was made.
|
||||||
No harm done. Proceed with manual matching as usual.
|
No harm done. Proceed with manual matching as usual.
|
||||||
2. The wrong match was made.
|
2. The wrong match was made.
|
||||||
Statements are encoded in draft. You will have the opportunity to
|
Statements are encoded in draft. You will have the opportunity
|
||||||
manually correct the wrong assumptions.
|
to manually correct the wrong assumptions.
|
||||||
|
|
||||||
TODO: REVISE THIS DOC
|
TODO: REVISE THIS DOC
|
||||||
#Return values:
|
#Return values:
|
||||||
@@ -170,8 +173,10 @@ class banking_import_transaction(orm.Model):
|
|||||||
'''
|
'''
|
||||||
Return the eyecatcher for an invoice
|
Return the eyecatcher for an invoice
|
||||||
'''
|
'''
|
||||||
return invoice.type.startswith('in_') and invoice.name or \
|
if invoice.type.startswith('in_'):
|
||||||
invoice.number
|
return invoice.name or invoice.number
|
||||||
|
else:
|
||||||
|
return invoice.number
|
||||||
|
|
||||||
def has_id_match(invoice, ref, msg):
|
def has_id_match(invoice, ref, msg):
|
||||||
'''
|
'''
|
||||||
@@ -197,7 +202,8 @@ class banking_import_transaction(orm.Model):
|
|||||||
iname = invoice.name.upper()
|
iname = invoice.name.upper()
|
||||||
if iname in ref or iname in msg:
|
if iname in ref or iname in msg:
|
||||||
return True
|
return True
|
||||||
if invoice.supplier_invoice_number and len(invoice.supplier_invoice_number) > 2:
|
if (invoice.supplier_invoice_number
|
||||||
|
and len(invoice.supplier_invoice_number) > 2):
|
||||||
supp_ref = invoice.supplier_invoice_number.upper()
|
supp_ref = invoice.supplier_invoice_number.upper()
|
||||||
if supp_ref in ref or supp_ref in msg:
|
if supp_ref in ref or supp_ref in msg:
|
||||||
return True
|
return True
|
||||||
@@ -228,7 +234,8 @@ class banking_import_transaction(orm.Model):
|
|||||||
|
|
||||||
def _sign(invoice):
|
def _sign(invoice):
|
||||||
'''Return the direction of an invoice'''
|
'''Return the direction of an invoice'''
|
||||||
return {'in_invoice': -1,
|
return {
|
||||||
|
'in_invoice': -1,
|
||||||
'in_refund': 1,
|
'in_refund': 1,
|
||||||
'out_invoice': 1,
|
'out_invoice': 1,
|
||||||
'out_refund': -1
|
'out_refund': -1
|
||||||
@@ -256,9 +263,9 @@ class banking_import_transaction(orm.Model):
|
|||||||
|
|
||||||
# Next on reference/invoice number. Mind that this uses the invoice
|
# Next on reference/invoice number. Mind that this uses the invoice
|
||||||
# itself, as the move_line references have been fiddled with on invoice
|
# itself, as the move_line references have been fiddled with on invoice
|
||||||
# creation. This also enables us to search for the invoice number in the
|
# creation. This also enables us to search for the invoice number in
|
||||||
# reference instead of the other way around, as most human interventions
|
# the reference instead of the other way around, as most human
|
||||||
# *add* text.
|
# interventions *add* text.
|
||||||
ref = trans.reference.upper()
|
ref = trans.reference.upper()
|
||||||
msg = trans.message.upper()
|
msg = trans.message.upper()
|
||||||
if len(candidates) > 1 or not candidates:
|
if len(candidates) > 1 or not candidates:
|
||||||
@@ -297,7 +304,8 @@ class banking_import_transaction(orm.Model):
|
|||||||
# amounts expected and received.
|
# amounts expected and received.
|
||||||
#
|
#
|
||||||
# TODO: currency coercing
|
# TODO: currency coercing
|
||||||
best = [x for x in candidates
|
best = [
|
||||||
|
x for x in candidates
|
||||||
if (is_zero(x.move_id, ((x.debit or 0.0) - (x.credit or 0.0)) -
|
if (is_zero(x.move_id, ((x.debit or 0.0) - (x.credit or 0.0)) -
|
||||||
trans.statement_line_id.amount)
|
trans.statement_line_id.amount)
|
||||||
and convert.str2date(x.date, '%Y-%m-%d') <=
|
and convert.str2date(x.date, '%Y-%m-%d') <=
|
||||||
@@ -317,7 +325,8 @@ class banking_import_transaction(orm.Model):
|
|||||||
elif len(candidates) > 1:
|
elif len(candidates) > 1:
|
||||||
# Before giving up, check cache for catching duplicate
|
# Before giving up, check cache for catching duplicate
|
||||||
# transfers first
|
# transfers first
|
||||||
paid = [x for x in move_lines
|
paid = [
|
||||||
|
x for x in move_lines
|
||||||
if x.invoice and has_id_match(x.invoice, ref, msg)
|
if x.invoice and has_id_match(x.invoice, ref, msg)
|
||||||
and convert.str2date(x.invoice.date_invoice, '%Y-%m-%d')
|
and convert.str2date(x.invoice.date_invoice, '%Y-%m-%d')
|
||||||
<= convert.str2date(trans.execution_date, '%Y-%m-%d')
|
<= convert.str2date(trans.execution_date, '%Y-%m-%d')
|
||||||
@@ -328,10 +337,10 @@ class banking_import_transaction(orm.Model):
|
|||||||
_('Unable to link transaction id %(trans)s '
|
_('Unable to link transaction id %(trans)s '
|
||||||
'(ref: %(ref)s) to invoice: '
|
'(ref: %(ref)s) to invoice: '
|
||||||
'invoice %(invoice)s was already paid') % {
|
'invoice %(invoice)s was already paid') % {
|
||||||
'trans': '%s.%s' % (trans.statement, trans.transaction),
|
'trans': '%s.%s' % (trans.statement,
|
||||||
|
trans.transaction),
|
||||||
'ref': trans.reference,
|
'ref': trans.reference,
|
||||||
'invoice': eyecatcher(paid[0].invoice)
|
'invoice': eyecatcher(paid[0].invoice)})
|
||||||
})
|
|
||||||
else:
|
else:
|
||||||
# Multiple matches
|
# Multiple matches
|
||||||
# TODO select best bank account in this case
|
# TODO select best bank account in this case
|
||||||
@@ -356,8 +365,8 @@ class banking_import_transaction(orm.Model):
|
|||||||
# Last partial payment will not flag invoice paid without
|
# Last partial payment will not flag invoice paid without
|
||||||
# manual assistence
|
# manual assistence
|
||||||
# Stefan: disabled this here for the interactive method
|
# Stefan: disabled this here for the interactive method
|
||||||
# Handled this with proper handling of partial reconciliation
|
# Handled this with proper handling of partial
|
||||||
# and the workflow service
|
# reconciliation and the workflow service
|
||||||
# invoice_obj = self.pool.get('account.invoice')
|
# invoice_obj = self.pool.get('account.invoice')
|
||||||
# invoice_obj.write(cr, uid, [invoice.id], {
|
# invoice_obj.write(cr, uid, [invoice.id], {
|
||||||
# 'state': 'paid'
|
# 'state': 'paid'
|
||||||
@@ -396,7 +405,8 @@ class banking_import_transaction(orm.Model):
|
|||||||
_("Cannot link transaction %s with invoice") %
|
_("Cannot link transaction %s with invoice") %
|
||||||
transaction.statement_line_id.name,
|
transaction.statement_line_id.name,
|
||||||
(transaction.invoice_ids and
|
(transaction.invoice_ids and
|
||||||
(_("Please select one of the matches in transaction %s.%s") or
|
(_("Please select one of the matches in transaction "
|
||||||
|
"%s.%s") or
|
||||||
_("No match found for transaction %s.%s")) % (
|
_("No match found for transaction %s.%s")) % (
|
||||||
transaction.statement_line_id.statement_id.name,
|
transaction.statement_line_id.statement_id.name,
|
||||||
transaction.statement_line_id.name
|
transaction.statement_line_id.name
|
||||||
@@ -406,7 +416,8 @@ class banking_import_transaction(orm.Model):
|
|||||||
_("Cannot link transaction %s with accounting entry") %
|
_("Cannot link transaction %s with accounting entry") %
|
||||||
transaction.statement_line_id.name,
|
transaction.statement_line_id.name,
|
||||||
(transaction.move_line_ids and
|
(transaction.move_line_ids and
|
||||||
(_("Please select one of the matches in transaction %s.%s") or
|
(_("Please select one of the matches in transaction "
|
||||||
|
"%s.%s") or
|
||||||
_("No match found for transaction %s.%s")) % (
|
_("No match found for transaction %s.%s")) % (
|
||||||
transaction.statement_line_id.statement_id.name,
|
transaction.statement_line_id.statement_id.name,
|
||||||
transaction.statement_line_id.name
|
transaction.statement_line_id.name
|
||||||
@@ -458,7 +469,8 @@ class banking_import_transaction(orm.Model):
|
|||||||
# Define the voucher
|
# Define the voucher
|
||||||
voucher = {
|
voucher = {
|
||||||
'journal_id': st_line.statement_id.journal_id.id,
|
'journal_id': st_line.statement_id.journal_id.id,
|
||||||
'partner_id': st_line.partner_id and st_line.partner_id.id or False,
|
'partner_id': (
|
||||||
|
st_line.partner_id and st_line.partner_id.id or False),
|
||||||
'company_id': st_line.company_id.id,
|
'company_id': st_line.company_id.id,
|
||||||
'type': voucher_type,
|
'type': voucher_type,
|
||||||
'account_id': account_id,
|
'account_id': account_id,
|
||||||
@@ -490,7 +502,8 @@ class banking_import_transaction(orm.Model):
|
|||||||
{'voucher_id': voucher_id}, context=context)
|
{'voucher_id': voucher_id}, context=context)
|
||||||
transaction.refresh()
|
transaction.refresh()
|
||||||
|
|
||||||
def _legacy_do_move_unreconcile(self, cr, uid, move_line_ids, currency, context=None):
|
def _legacy_do_move_unreconcile(self, cr, uid, move_line_ids, currency,
|
||||||
|
context=None):
|
||||||
"""
|
"""
|
||||||
Legacy method. Allow for canceling bank statement lines that
|
Legacy method. Allow for canceling bank statement lines that
|
||||||
were confirmed using earlier versions of the interactive wizard branch.
|
were confirmed using earlier versions of the interactive wizard branch.
|
||||||
@@ -508,9 +521,14 @@ class banking_import_transaction(orm.Model):
|
|||||||
reconcile_obj = self.pool.get('account.move.reconcile')
|
reconcile_obj = self.pool.get('account.move.reconcile')
|
||||||
is_zero = lambda amount: self.pool.get('res.currency').is_zero(
|
is_zero = lambda amount: self.pool.get('res.currency').is_zero(
|
||||||
cr, uid, currency, amount)
|
cr, uid, currency, amount)
|
||||||
move_lines = move_line_obj.browse(cr, uid, move_line_ids, context=context)
|
move_lines = move_line_obj.browse(cr, uid, move_line_ids,
|
||||||
reconcile = move_lines[0].reconcile_id or move_lines[0].reconcile_partial_id
|
context=context)
|
||||||
line_ids = [x.id for x in reconcile.line_id or reconcile.line_partial_ids]
|
reconcile = (move_lines[0].reconcile_id
|
||||||
|
or move_lines[0].reconcile_partial_id)
|
||||||
|
line_ids = [
|
||||||
|
x.id
|
||||||
|
for x in reconcile.line_id or reconcile.line_partial_ids
|
||||||
|
]
|
||||||
for move_line_id in move_line_ids:
|
for move_line_id in move_line_ids:
|
||||||
line_ids.remove(move_line_id)
|
line_ids.remove(move_line_id)
|
||||||
if len(line_ids) > 1:
|
if len(line_ids) > 1:
|
||||||
@@ -531,7 +549,9 @@ class banking_import_transaction(orm.Model):
|
|||||||
if move_line.invoice:
|
if move_line.invoice:
|
||||||
# reopening the invoice
|
# reopening the invoice
|
||||||
netsvc.LocalService('workflow').trg_validate(
|
netsvc.LocalService('workflow').trg_validate(
|
||||||
uid, 'account.invoice', move_line.invoice.id, 'undo_paid', cr)
|
uid, 'account.invoice', move_line.invoice.id, 'undo_paid',
|
||||||
|
cr
|
||||||
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _legacy_clear_up_writeoff(self, cr, uid, transaction, context=None):
|
def _legacy_clear_up_writeoff(self, cr, uid, transaction, context=None):
|
||||||
@@ -550,8 +570,7 @@ class banking_import_transaction(orm.Model):
|
|||||||
context=context)
|
context=context)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _legacy_cancel_move(
|
def _legacy_cancel_move(self, cr, uid, transaction, context=None):
|
||||||
self, cr, uid, transaction, context=None):
|
|
||||||
"""
|
"""
|
||||||
Legacy method to support upgrades from older installations
|
Legacy method to support upgrades from older installations
|
||||||
of the interactive wizard branch.
|
of the interactive wizard branch.
|
||||||
@@ -590,16 +609,15 @@ class banking_import_transaction(orm.Model):
|
|||||||
cr, uid, transaction.statement_line_id.id,
|
cr, uid, transaction.statement_line_id.id,
|
||||||
{'reconcile_id': False}, context=context)
|
{'reconcile_id': False}, context=context)
|
||||||
|
|
||||||
def _cancel_voucher(
|
def _cancel_voucher(self, cr, uid, transaction_id, context=None):
|
||||||
self, cr, uid, transaction_id, context=None):
|
|
||||||
voucher_pool = self.pool.get('account.voucher')
|
voucher_pool = self.pool.get('account.voucher')
|
||||||
transaction = self.browse(cr, uid, transaction_id, context=context)
|
transaction = self.browse(cr, uid, transaction_id, context=context)
|
||||||
st_line = transaction.statement_line_id
|
st_line = transaction.statement_line_id
|
||||||
if transaction.match_type:
|
if transaction.match_type:
|
||||||
if st_line.voucher_id:
|
if st_line.voucher_id:
|
||||||
# Although vouchers can be associated with statement lines
|
# Although vouchers can be associated with statement lines
|
||||||
# in standard OpenERP, we consider ourselves owner of the voucher
|
# in standard OpenERP, we consider ourselves owner of the
|
||||||
# if the line has an associated transaction
|
# voucher if the line has an associated transaction
|
||||||
# Upon canceling of the statement line/transaction,
|
# Upon canceling of the statement line/transaction,
|
||||||
# we cancel and delete the vouchers.
|
# we cancel and delete the vouchers.
|
||||||
# Otherwise, the statement line will leave the voucher
|
# Otherwise, the statement line will leave the voucher
|
||||||
@@ -610,7 +628,8 @@ class banking_import_transaction(orm.Model):
|
|||||||
cr, uid, [st_line.voucher_id.id], context=context)
|
cr, uid, [st_line.voucher_id.id], context=context)
|
||||||
voucher_pool.unlink(
|
voucher_pool.unlink(
|
||||||
cr, uid, [st_line.voucher_id.id], context=context)
|
cr, uid, [st_line.voucher_id.id], context=context)
|
||||||
if transaction.move_line_id and transaction.move_line_id.invoice:
|
if (transaction.move_line_id
|
||||||
|
and transaction.move_line_id.invoice):
|
||||||
# reopening the invoice
|
# reopening the invoice
|
||||||
netsvc.LocalService('workflow').trg_validate(
|
netsvc.LocalService('workflow').trg_validate(
|
||||||
uid, 'account.invoice',
|
uid, 'account.invoice',
|
||||||
@@ -639,7 +658,9 @@ class banking_import_transaction(orm.Model):
|
|||||||
_("No method found to cancel this type"))
|
_("No method found to cancel this type"))
|
||||||
self.cancel_map[transaction.match_type](
|
self.cancel_map[transaction.match_type](
|
||||||
self, cr, uid, transaction.id, context)
|
self, cr, uid, transaction.id, context)
|
||||||
self._legacy_clear_up_writeoff(cr, uid, transaction, context=context)
|
self._legacy_clear_up_writeoff(
|
||||||
|
cr, uid, transaction, context=context
|
||||||
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
confirm_map = {
|
confirm_map = {
|
||||||
@@ -665,7 +686,7 @@ class banking_import_transaction(orm.Model):
|
|||||||
if transaction.match_type not in ('invoice', 'move', 'manual'):
|
if transaction.match_type not in ('invoice', 'move', 'manual'):
|
||||||
raise orm.except_orm(
|
raise orm.except_orm(
|
||||||
_("Cannot reconcile"),
|
_("Cannot reconcile"),
|
||||||
_("Bank transaction %s: write off not implemented for " +
|
_("Bank transaction %s: write off not implemented for "
|
||||||
"this match type.") %
|
"this match type.") %
|
||||||
transaction.statement_line_id.name
|
transaction.statement_line_id.name
|
||||||
)
|
)
|
||||||
@@ -723,7 +744,7 @@ class banking_import_transaction(orm.Model):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def _get_move_info(self, cr, uid, move_line_ids, partner_bank_id=False,
|
def _get_move_info(self, cr, uid, move_line_ids, partner_bank_id=False,
|
||||||
partial=False, match_type = False):
|
partial=False, match_type=False, context=None):
|
||||||
type_map = {
|
type_map = {
|
||||||
'out_invoice': 'customer',
|
'out_invoice': 'customer',
|
||||||
'in_invoice': 'supplier',
|
'in_invoice': 'supplier',
|
||||||
@@ -738,7 +759,9 @@ class banking_import_transaction(orm.Model):
|
|||||||
'match_type': match_type,
|
'match_type': match_type,
|
||||||
'account_id': False,
|
'account_id': False,
|
||||||
}
|
}
|
||||||
move_lines = self.pool.get('account.move.line').browse(cr, uid, move_line_ids)
|
move_lines = self.pool.get('account.move.line').browse(
|
||||||
|
cr, uid, move_line_ids, context=context
|
||||||
|
)
|
||||||
for move_line in move_lines:
|
for move_line in move_lines:
|
||||||
if move_line.partner_id:
|
if move_line.partner_id:
|
||||||
if retval['partner_id']:
|
if retval['partner_id']:
|
||||||
@@ -780,7 +803,7 @@ class banking_import_transaction(orm.Model):
|
|||||||
if move_lines and len(move_lines) == 1:
|
if move_lines and len(move_lines) == 1:
|
||||||
retval['reference'] = move_lines[0].ref
|
retval['reference'] = move_lines[0].ref
|
||||||
if retval['match_type'] == 'invoice':
|
if retval['match_type'] == 'invoice':
|
||||||
retval['invoice_ids'] = list(set([x.invoice.id for x in move_lines]))
|
retval['invoice_ids'] = list(set(x.invoice.id for x in move_lines))
|
||||||
retval['type'] = type_map[move_lines[0].invoice.type]
|
retval['type'] = type_map[move_lines[0].invoice.type]
|
||||||
return retval
|
return retval
|
||||||
|
|
||||||
@@ -791,13 +814,11 @@ class banking_import_transaction(orm.Model):
|
|||||||
vals['invoice_ids'] = [(6, 0, move_info.get('invoice_ids') or [])]
|
vals['invoice_ids'] = [(6, 0, move_info.get('invoice_ids') or [])]
|
||||||
vals['move_line_id'] = (move_info.get('move_line_ids', False) and
|
vals['move_line_id'] = (move_info.get('move_line_ids', False) and
|
||||||
len(move_info['move_line_ids']) == 1 and
|
len(move_info['move_line_ids']) == 1 and
|
||||||
move_info['move_line_ids'][0]
|
move_info['move_line_ids'][0])
|
||||||
)
|
|
||||||
if move_info['match_type'] == 'invoice':
|
if move_info['match_type'] == 'invoice':
|
||||||
vals['invoice_id'] = (move_info.get('invoice_ids', False) and
|
vals['invoice_id'] = (move_info.get('invoice_ids', False) and
|
||||||
len(move_info['invoice_ids']) == 1 and
|
len(move_info['invoice_ids']) == 1 and
|
||||||
move_info['invoice_ids'][0]
|
move_info['invoice_ids'][0])
|
||||||
)
|
|
||||||
return vals
|
return vals
|
||||||
|
|
||||||
def hook_match_payment(self, cr, uid, transaction, log, context=None):
|
def hook_match_payment(self, cr, uid, transaction, log, context=None):
|
||||||
@@ -849,7 +870,8 @@ class banking_import_transaction(orm.Model):
|
|||||||
payment_line_ids = payment_line_obj.search(
|
payment_line_ids = payment_line_obj.search(
|
||||||
cr, uid, [
|
cr, uid, [
|
||||||
('order_id.state', '=', 'sent'),
|
('order_id.state', '=', 'sent'),
|
||||||
('date_done', '=', False)], context=context)
|
('date_done', '=', False)
|
||||||
|
], context=context)
|
||||||
payment_lines = payment_line_obj.browse(
|
payment_lines = payment_line_obj.browse(
|
||||||
cr, uid, payment_line_ids)
|
cr, uid, payment_line_ids)
|
||||||
|
|
||||||
@@ -885,25 +907,30 @@ class banking_import_transaction(orm.Model):
|
|||||||
|
|
||||||
# Get interesting journals once
|
# Get interesting journals once
|
||||||
# Added type 'general' to capture fund transfers
|
# Added type 'general' to capture fund transfers
|
||||||
journal_ids = journal_obj.search(cr, uid, [
|
journal_ids = journal_obj.search(
|
||||||
|
cr, uid, [
|
||||||
('type', 'in', ('general', 'sale', 'purchase',
|
('type', 'in', ('general', 'sale', 'purchase',
|
||||||
'purchase_refund', 'sale_refund')),
|
'purchase_refund', 'sale_refund')),
|
||||||
('company_id', '=', company.id),
|
('company_id', '=', company.id),
|
||||||
])
|
],
|
||||||
|
)
|
||||||
# Get all unreconciled moves
|
# Get all unreconciled moves
|
||||||
move_line_ids = move_line_obj.search(cr, uid, [
|
move_line_ids = move_line_obj.search(
|
||||||
|
cr, uid, [
|
||||||
('reconcile_id', '=', False),
|
('reconcile_id', '=', False),
|
||||||
('journal_id', 'in', journal_ids),
|
('journal_id', 'in', journal_ids),
|
||||||
('account_id.reconcile', '=', True),
|
('account_id.reconcile', '=', True),
|
||||||
('date', '<=', transaction.execution_date),
|
('date', '<=', transaction.execution_date),
|
||||||
])
|
],
|
||||||
|
)
|
||||||
if move_line_ids:
|
if move_line_ids:
|
||||||
move_lines = move_line_obj.browse(cr, uid, move_line_ids)
|
move_lines = move_line_obj.browse(cr, uid, move_line_ids)
|
||||||
else:
|
else:
|
||||||
move_lines = []
|
move_lines = []
|
||||||
|
|
||||||
# Create fallback currency code
|
# Create fallback currency code
|
||||||
currency_code = transaction.local_currency or company.currency_id.name
|
currency_code = (transaction.local_currency
|
||||||
|
or company.currency_id.name)
|
||||||
|
|
||||||
# Check cache for account info/currency
|
# Check cache for account info/currency
|
||||||
if transaction.local_account in info and \
|
if transaction.local_account in info and \
|
||||||
@@ -917,7 +944,8 @@ class banking_import_transaction(orm.Model):
|
|||||||
)
|
)
|
||||||
if not account_info:
|
if not account_info:
|
||||||
results['log'].append(
|
results['log'].append(
|
||||||
_('Transaction found for unknown account %(bank_account)s') %
|
_('Transaction found for unknown account '
|
||||||
|
'%(bank_account)s') %
|
||||||
{'bank_account': transaction.local_account}
|
{'bank_account': transaction.local_account}
|
||||||
)
|
)
|
||||||
error_accounts[transaction.local_account] = True
|
error_accounts[transaction.local_account] = True
|
||||||
@@ -941,12 +969,14 @@ class banking_import_transaction(orm.Model):
|
|||||||
currency_code = account_info.currency_id.name
|
currency_code = account_info.currency_id.name
|
||||||
|
|
||||||
# Cache results
|
# Cache results
|
||||||
if not transaction.local_account in info:
|
if transaction.local_account not in info:
|
||||||
info[transaction.local_account] = {
|
info[transaction.local_account] = {
|
||||||
currency_code: account_info
|
currency_code: account_info
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
info[transaction.local_account][currency_code] = account_info
|
info[transaction.local_account][currency_code] = (
|
||||||
|
account_info
|
||||||
|
)
|
||||||
|
|
||||||
# Link accounting period
|
# Link accounting period
|
||||||
period_id = banktools.get_period(
|
period_id = banktools.get_period(
|
||||||
@@ -965,7 +995,8 @@ class banking_import_transaction(orm.Model):
|
|||||||
_("Cannot perform match on a confirmed transction"))
|
_("Cannot perform match on a confirmed transction"))
|
||||||
else:
|
else:
|
||||||
values = {
|
values = {
|
||||||
'name': '%s.%s' % (transaction.statement, transaction.transaction),
|
'name': '%s.%s' % (transaction.statement,
|
||||||
|
transaction.transaction),
|
||||||
'date': transaction.execution_date,
|
'date': transaction.execution_date,
|
||||||
'amount': transaction.transferred_amount,
|
'amount': transaction.transferred_amount,
|
||||||
'statement_id': transaction.statement_id.id,
|
'statement_id': transaction.statement_id.id,
|
||||||
@@ -979,7 +1010,9 @@ class banking_import_transaction(orm.Model):
|
|||||||
account_info.default_credit_account_id.id or
|
account_info.default_credit_account_id.id or
|
||||||
account_info.default_debit_account_id.id),
|
account_info.default_debit_account_id.id),
|
||||||
}
|
}
|
||||||
statement_line_id = statement_line_obj.create(cr, uid, values, context)
|
statement_line_id = statement_line_obj.create(
|
||||||
|
cr, uid, values, context
|
||||||
|
)
|
||||||
results['trans_loaded_cnt'] += 1
|
results['trans_loaded_cnt'] += 1
|
||||||
transaction.write({'statement_line_id': statement_line_id})
|
transaction.write({'statement_line_id': statement_line_id})
|
||||||
transaction.refresh()
|
transaction.refresh()
|
||||||
@@ -991,8 +1024,9 @@ class banking_import_transaction(orm.Model):
|
|||||||
and account_info.currency_id.name != transaction.local_currency:
|
and account_info.currency_id.name != transaction.local_currency:
|
||||||
# TODO: convert currencies?
|
# TODO: convert currencies?
|
||||||
results['log'].append(
|
results['log'].append(
|
||||||
_('transaction %(statement_id)s.%(transaction_id)s for account %(bank_account)s'
|
_('transaction %(statement_id)s.%(transaction_id)s for '
|
||||||
' uses different currency than the defined bank journal.'
|
'account %(bank_account)s uses different currency than '
|
||||||
|
'the defined bank journal.'
|
||||||
) % {
|
) % {
|
||||||
'bank_account': transactions.local_account,
|
'bank_account': transactions.local_account,
|
||||||
'statement_id': transaction.statement,
|
'statement_id': transaction.statement,
|
||||||
@@ -1006,7 +1040,8 @@ class banking_import_transaction(orm.Model):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# When bank costs are part of transaction itself, split it.
|
# When bank costs are part of transaction itself, split it.
|
||||||
if transaction.type != bt.BANK_COSTS and transaction.provision_costs:
|
if (transaction.type != bt.BANK_COSTS
|
||||||
|
and transaction.provision_costs):
|
||||||
# Create new transaction for bank costs
|
# Create new transaction for bank costs
|
||||||
cost_id = self.copy(
|
cost_id = self.copy(
|
||||||
cr, uid, transaction.id,
|
cr, uid, transaction.id,
|
||||||
@@ -1028,14 +1063,17 @@ class banking_import_transaction(orm.Model):
|
|||||||
self.write(
|
self.write(
|
||||||
cr, uid, transaction.id,
|
cr, uid, transaction.id,
|
||||||
dict(
|
dict(
|
||||||
transferred_amount =
|
transferred_amount=(
|
||||||
transaction.transferred_amount - transaction.provision_costs,
|
transaction.transferred_amount -
|
||||||
|
transaction.provision_costs),
|
||||||
provision_costs=False,
|
provision_costs=False,
|
||||||
provision_costs_currency=False,
|
provision_costs_currency=False,
|
||||||
provision_costs_description=False,
|
provision_costs_description=False,
|
||||||
), context=context)
|
), context=context)
|
||||||
# rebrowse the current record after writing
|
# rebrowse the current record after writing
|
||||||
transaction = self.browse(cr, uid, transaction.id, context=context)
|
transaction = self.browse(
|
||||||
|
cr, uid, transaction.id, context=context
|
||||||
|
)
|
||||||
|
|
||||||
# Match payment and direct debit orders
|
# Match payment and direct debit orders
|
||||||
move_info_payment = self.hook_match_payment(
|
move_info_payment = self.hook_match_payment(
|
||||||
@@ -1088,7 +1126,8 @@ class banking_import_transaction(orm.Model):
|
|||||||
|
|
||||||
# Credit means payment... isn't it?
|
# Credit means payment... isn't it?
|
||||||
if (not move_info
|
if (not move_info
|
||||||
and transaction.statement_line_id.amount < 0 and payment_lines):
|
and transaction.statement_line_id.amount < 0
|
||||||
|
and payment_lines):
|
||||||
# Link open payment - if any
|
# Link open payment - if any
|
||||||
# Note that _match_payment is defined in the
|
# Note that _match_payment is defined in the
|
||||||
# account_banking_payment module which should be installed
|
# account_banking_payment module which should be installed
|
||||||
@@ -1146,10 +1185,13 @@ class banking_import_transaction(orm.Model):
|
|||||||
values['type'] = move_info['type']
|
values['type'] = move_info['type']
|
||||||
else:
|
else:
|
||||||
values['partner_id'] = values['partner_bank_id'] = False
|
values['partner_id'] = values['partner_bank_id'] = False
|
||||||
if not values['partner_id'] and partner_ids and len(partner_ids) == 1:
|
if (not values['partner_id']
|
||||||
|
and partner_ids
|
||||||
|
and len(partner_ids) == 1):
|
||||||
values['partner_id'] = partner_ids[0]
|
values['partner_id'] = partner_ids[0]
|
||||||
if (not values['partner_bank_id'] and partner_banks and
|
if (not values['partner_bank_id']
|
||||||
len(partner_banks) == 1):
|
and partner_banks
|
||||||
|
and len(partner_banks) == 1):
|
||||||
values['partner_bank_id'] = partner_banks[0].id
|
values['partner_bank_id'] = partner_banks[0].id
|
||||||
|
|
||||||
statement_line_obj.write(
|
statement_line_obj.write(
|
||||||
@@ -1214,22 +1256,32 @@ class banking_import_transaction(orm.Model):
|
|||||||
Write values in argument 'vals', but clear all match
|
Write values in argument 'vals', but clear all match
|
||||||
related values first
|
related values first
|
||||||
"""
|
"""
|
||||||
write_vals = (dict([(x, False) for x in [
|
write_vals = (
|
||||||
|
dict([
|
||||||
|
(x, False)
|
||||||
|
for x in [
|
||||||
'match_type',
|
'match_type',
|
||||||
'move_line_id',
|
'move_line_id',
|
||||||
'invoice_id',
|
'invoice_id',
|
||||||
]] +
|
]
|
||||||
[(x, [(6, 0, [])]) for x in [
|
] + [
|
||||||
|
(x, [(6, 0, [])])
|
||||||
|
for x in [
|
||||||
'move_line_ids',
|
'move_line_ids',
|
||||||
'invoice_ids',
|
'invoice_ids',
|
||||||
]]))
|
]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
write_vals.update(vals or {})
|
write_vals.update(vals or {})
|
||||||
return self.write(cr, uid, ids, write_vals, context=context)
|
return self.write(cr, uid, ids, write_vals, context=context)
|
||||||
|
|
||||||
def _get_move_amount(self, cr, uid, ids, name, args, context=None):
|
def _get_move_amount(self, cr, uid, ids, name, args, context=None):
|
||||||
"""
|
"""
|
||||||
Need to get the residual amount on the move (invoice) in the bank statement currency.
|
Need to get the residual amount on the move (invoice) in the bank
|
||||||
This will be used to calculate the write-off amount (in statement currency).
|
statement currency.
|
||||||
|
This will be used to calculate the write-off amount
|
||||||
|
(in statement currency).
|
||||||
"""
|
"""
|
||||||
if not ids:
|
if not ids:
|
||||||
return {}
|
return {}
|
||||||
@@ -1240,20 +1292,25 @@ class banking_import_transaction(orm.Model):
|
|||||||
for transaction in self.browse(cr, uid, ids, context):
|
for transaction in self.browse(cr, uid, ids, context):
|
||||||
|
|
||||||
if transaction.move_line_id:
|
if transaction.move_line_id:
|
||||||
move_line_amount = transaction.move_line_id.amount_residual_currency
|
move_line_amount = (
|
||||||
|
transaction.move_line_id.amount_residual_currency)
|
||||||
|
statement = transaction.statement_line_id.statement_id
|
||||||
to_curr_id = (
|
to_curr_id = (
|
||||||
transaction.statement_line_id.statement_id.journal_id.currency
|
statement.journal_id.currency
|
||||||
and transaction.statement_line_id.statement_id.journal_id.currency.id
|
and statement.journal_id.currency.id
|
||||||
or transaction.statement_line_id.statement_id.company_id.currency_id.id
|
or statement.company_id.currency_id.id
|
||||||
)
|
)
|
||||||
from_curr_id = (
|
from_curr_id = (
|
||||||
transaction.move_line_id.currency_id
|
transaction.move_line_id.currency_id
|
||||||
and transaction.move_line_id.currency_id.id
|
and transaction.move_line_id.currency_id.id
|
||||||
or transaction.statement_line_id.statement_id.company_id.currency_id.id
|
or statement.company_id.currency_id.id
|
||||||
)
|
)
|
||||||
if from_curr_id != to_curr_id:
|
if from_curr_id != to_curr_id:
|
||||||
amount_currency = stline_pool._convert_currency(cr, uid, from_curr_id, to_curr_id, move_line_amount, round=True,
|
amount_currency = stline_pool._convert_currency(
|
||||||
date=transaction.statement_line_id.date, context=context)
|
cr, uid, from_curr_id, to_curr_id, move_line_amount,
|
||||||
|
round=True, date=transaction.statement_line_id.date,
|
||||||
|
context=context
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
amount_currency = move_line_amount
|
amount_currency = move_line_amount
|
||||||
sign = 1
|
sign = 1
|
||||||
@@ -1261,7 +1318,8 @@ class banking_import_transaction(orm.Model):
|
|||||||
if transaction.move_line_id.amount_currency < 0:
|
if transaction.move_line_id.amount_currency < 0:
|
||||||
sign = -1
|
sign = -1
|
||||||
else:
|
else:
|
||||||
if (transaction.move_line_id.debit - transaction.move_line_id.credit) < 0:
|
if (transaction.move_line_id.debit
|
||||||
|
- transaction.move_line_id.credit) < 0:
|
||||||
sign = -1
|
sign = -1
|
||||||
res[transaction.id] = sign * amount_currency
|
res[transaction.id] = sign * amount_currency
|
||||||
|
|
||||||
@@ -1274,10 +1332,12 @@ class banking_import_transaction(orm.Model):
|
|||||||
for this in self.browse(cr, uid, ids, context):
|
for this in self.browse(cr, uid, ids, context):
|
||||||
if this.parent_id:
|
if this.parent_id:
|
||||||
this.parent_id.write(
|
this.parent_id.write(
|
||||||
{'transferred_amount':
|
{
|
||||||
this.parent_id.transferred_amount + \
|
'transferred_amount':
|
||||||
|
this.parent_id.transferred_amount +
|
||||||
this.transferred_amount,
|
this.transferred_amount,
|
||||||
})
|
}
|
||||||
|
)
|
||||||
this.parent_id.refresh()
|
this.parent_id.refresh()
|
||||||
return super(banking_import_transaction, self).unlink(
|
return super(banking_import_transaction, self).unlink(
|
||||||
cr, uid, ids, context=context)
|
cr, uid, ids, context=context)
|
||||||
@@ -1307,8 +1367,14 @@ class banking_import_transaction(orm.Model):
|
|||||||
'remote_owner': fields.char('remote_owner', size=128),
|
'remote_owner': fields.char('remote_owner', size=128),
|
||||||
'remote_owner_address': fields.char('remote_owner_address', size=256),
|
'remote_owner_address': fields.char('remote_owner_address', size=256),
|
||||||
'remote_owner_city': fields.char('remote_owner_city', size=128),
|
'remote_owner_city': fields.char('remote_owner_city', size=128),
|
||||||
'remote_owner_postalcode': fields.char('remote_owner_postalcode', size=24),
|
'remote_owner_postalcode': fields.char(
|
||||||
'remote_owner_country_code': fields.char('remote_owner_country_code', size=24),
|
'remote_owner_postalcode',
|
||||||
|
size=24,
|
||||||
|
),
|
||||||
|
'remote_owner_country_code': fields.char(
|
||||||
|
'remote_owner_country_code',
|
||||||
|
size=24,
|
||||||
|
),
|
||||||
'remote_owner_custno': fields.char('remote_owner_custno', size=24),
|
'remote_owner_custno': fields.char('remote_owner_custno', size=24),
|
||||||
'remote_bank_bic': fields.char('remote_bank_bic', size=24),
|
'remote_bank_bic': fields.char('remote_bank_bic', size=24),
|
||||||
'remote_bank_bei': fields.char('remote_bank_bei', size=24),
|
'remote_bank_bei': fields.char('remote_bank_bei', size=24),
|
||||||
@@ -1318,8 +1384,14 @@ class banking_import_transaction(orm.Model):
|
|||||||
'remote_bank_duns': fields.char('remote_bank_duns', size=24),
|
'remote_bank_duns': fields.char('remote_bank_duns', size=24),
|
||||||
'remote_bank_tax_id': fields.char('remote_bank_tax_id', size=24),
|
'remote_bank_tax_id': fields.char('remote_bank_tax_id', size=24),
|
||||||
'provision_costs': fields.float('provision_costs', size=24),
|
'provision_costs': fields.float('provision_costs', size=24),
|
||||||
'provision_costs_currency': fields.char('provision_costs_currency', size=64),
|
'provision_costs_currency': fields.char(
|
||||||
'provision_costs_description': fields.char('provision_costs_description', size=24),
|
'provision_costs_currency',
|
||||||
|
size=64,
|
||||||
|
),
|
||||||
|
'provision_costs_description': fields.char(
|
||||||
|
'provision_costs_description',
|
||||||
|
size=24,
|
||||||
|
),
|
||||||
'error_message': fields.char('error_message', size=1024),
|
'error_message': fields.char('error_message', size=1024),
|
||||||
'storno_retry': fields.boolean('storno_retry'),
|
'storno_retry': fields.boolean('storno_retry'),
|
||||||
# end of mem_bank_transaction_fields
|
# end of mem_bank_transaction_fields
|
||||||
@@ -1366,13 +1438,16 @@ class banking_import_transaction(orm.Model):
|
|||||||
'residual': fields.function(
|
'residual': fields.function(
|
||||||
_get_residual, method=True, string='Residual', type='float'),
|
_get_residual, method=True, string='Residual', type='float'),
|
||||||
'writeoff_account_id': fields.many2one(
|
'writeoff_account_id': fields.many2one(
|
||||||
'account.account', 'Write-off account',
|
'account.account',
|
||||||
domain=[('type', '!=', 'view')]),
|
'Write-off account',
|
||||||
|
domain=[('type', '!=', 'view')]
|
||||||
|
),
|
||||||
'payment_option': fields.selection(
|
'payment_option': fields.selection(
|
||||||
[
|
[
|
||||||
('without_writeoff', 'Keep Open'),
|
('without_writeoff', 'Keep Open'),
|
||||||
('with_writeoff', 'Reconcile Payment Balance')
|
('with_writeoff', 'Reconcile Payment Balance')
|
||||||
], 'Payment Difference',
|
],
|
||||||
|
'Payment Difference',
|
||||||
required=True,
|
required=True,
|
||||||
help=("This field helps you to choose what you want to do with "
|
help=("This field helps you to choose what you want to do with "
|
||||||
"the eventual difference between the paid amount and the "
|
"the eventual difference between the paid amount and the "
|
||||||
@@ -1387,7 +1462,11 @@ class banking_import_transaction(orm.Model):
|
|||||||
'writeoff_analytic_id': fields.many2one(
|
'writeoff_analytic_id': fields.many2one(
|
||||||
'account.analytic.account', 'Write off analytic account'),
|
'account.analytic.account', 'Write off analytic account'),
|
||||||
'move_currency_amount': fields.function(
|
'move_currency_amount': fields.function(
|
||||||
_get_move_amount, method=True, string='Match Amount', type='float'),
|
_get_move_amount,
|
||||||
|
method=True,
|
||||||
|
string='Match Amount',
|
||||||
|
type='float',
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
_defaults = {
|
_defaults = {
|
||||||
@@ -1397,8 +1476,6 @@ class banking_import_transaction(orm.Model):
|
|||||||
'payment_option': 'without_writeoff',
|
'payment_option': 'without_writeoff',
|
||||||
}
|
}
|
||||||
|
|
||||||
banking_import_transaction()
|
|
||||||
|
|
||||||
|
|
||||||
class account_bank_statement_line(orm.Model):
|
class account_bank_statement_line(orm.Model):
|
||||||
_inherit = 'account.bank.statement.line'
|
_inherit = 'account.bank.statement.line'
|
||||||
@@ -1449,8 +1526,10 @@ class account_bank_statement_line(orm.Model):
|
|||||||
'state': fields.selection(
|
'state': fields.selection(
|
||||||
[('draft', 'Draft'), ('confirmed', 'Confirmed')], 'State',
|
[('draft', 'Draft'), ('confirmed', 'Confirmed')], 'State',
|
||||||
readonly=True, required=True),
|
readonly=True, required=True),
|
||||||
'parent_id': fields.many2one('account.bank.statement.line',
|
'parent_id': fields.many2one(
|
||||||
'Parent'),
|
'account.bank.statement.line',
|
||||||
|
'Parent',
|
||||||
|
),
|
||||||
'link_partner_ok': fields.function(
|
'link_partner_ok': fields.function(
|
||||||
_get_link_partner_ok, type='boolean',
|
_get_link_partner_ok, type='boolean',
|
||||||
string='Can link partner'),
|
string='Can link partner'),
|
||||||
@@ -1471,7 +1550,9 @@ class account_bank_statement_line(orm.Model):
|
|||||||
wizard_obj = self.pool.get('banking.transaction.wizard')
|
wizard_obj = self.pool.get('banking.transaction.wizard')
|
||||||
res_id = wizard_obj.create(
|
res_id = wizard_obj.create(
|
||||||
cr, uid, {'statement_line_id': ids[0]}, context=context)
|
cr, uid, {'statement_line_id': ids[0]}, context=context)
|
||||||
res = wizard_obj.create_act_window(cr, uid, res_id, context=context)
|
res = wizard_obj.create_act_window(
|
||||||
|
cr, uid, res_id, context=context
|
||||||
|
)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def link_partner(self, cr, uid, ids, context=None):
|
def link_partner(self, cr, uid, ids, context=None):
|
||||||
@@ -1499,8 +1580,8 @@ class account_bank_statement_line(orm.Model):
|
|||||||
{'partner_id': statement_line.partner_bank_id.partner_id.id})
|
{'partner_id': statement_line.partner_bank_id.partner_id.id})
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if (not statement_line.import_transaction_id or
|
if (not statement_line.import_transaction_id
|
||||||
not statement_line.import_transaction_id.remote_account):
|
or not statement_line.import_transaction_id.remote_account):
|
||||||
raise orm.except_orm(
|
raise orm.except_orm(
|
||||||
_("Error"),
|
_("Error"),
|
||||||
_("No bank account available to link partner to"))
|
_("No bank account available to link partner to"))
|
||||||
@@ -1555,8 +1636,9 @@ class account_bank_statement_line(orm.Model):
|
|||||||
"""
|
"""
|
||||||
Create (or update) a voucher for each statement line, and then generate
|
Create (or update) a voucher for each statement line, and then generate
|
||||||
the moves by posting the voucher.
|
the moves by posting the voucher.
|
||||||
If a line does not have a move line against it, but has an account, then
|
If a line does not have a move line against it, but has an account,
|
||||||
generate a journal entry that moves the line amount to the specified account.
|
then generate a journal entry that moves the line amount to the
|
||||||
|
specified account.
|
||||||
"""
|
"""
|
||||||
statement_pool = self.pool.get('account.bank.statement')
|
statement_pool = self.pool.get('account.bank.statement')
|
||||||
obj_seq = self.pool.get('ir.sequence')
|
obj_seq = self.pool.get('ir.sequence')
|
||||||
@@ -1576,7 +1658,8 @@ class account_bank_statement_line(orm.Model):
|
|||||||
raise orm.except_orm(
|
raise orm.except_orm(
|
||||||
_('No Analytic Journal !'),
|
_('No Analytic Journal !'),
|
||||||
_("You have to define an analytic journal on the '%s' "
|
_("You have to define an analytic journal on the '%s' "
|
||||||
"journal!") % (st_line.statement_id.journal_id.name,))
|
"journal!") % st_line.statement_id.journal_id.name
|
||||||
|
)
|
||||||
if not st_line.amount:
|
if not st_line.amount:
|
||||||
continue
|
continue
|
||||||
if not st_line.period_id:
|
if not st_line.period_id:
|
||||||
@@ -1594,10 +1677,16 @@ class account_bank_statement_line(orm.Model):
|
|||||||
if st.journal_id.sequence_id:
|
if st.journal_id.sequence_id:
|
||||||
period = st.period_id or st_line.period_id
|
period = st.period_id or st_line.period_id
|
||||||
c = {'fiscalyear_id': period.fiscalyear_id.id}
|
c = {'fiscalyear_id': period.fiscalyear_id.id}
|
||||||
st_number = obj_seq.next_by_id(cr, uid, st.journal_id.sequence_id.id, context=c)
|
st_number = obj_seq.next_by_id(
|
||||||
|
cr, uid, st.journal_id.sequence_id.id, context=c
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
st_number = obj_seq.next_by_code(cr, uid, 'account.bank.statement')
|
st_number = obj_seq.next_by_code(
|
||||||
statement_pool.write(cr, uid, [st.id], {'name': st_number}, context=context)
|
cr, uid, 'account.bank.statement'
|
||||||
|
)
|
||||||
|
statement_pool.write(
|
||||||
|
cr, uid, [st.id], {'name': st_number}, context=context
|
||||||
|
)
|
||||||
|
|
||||||
if st_line.import_transaction_id:
|
if st_line.import_transaction_id:
|
||||||
import_transaction_obj.confirm(
|
import_transaction_obj.confirm(
|
||||||
@@ -1607,7 +1696,9 @@ class account_bank_statement_line(orm.Model):
|
|||||||
cr, uid, st_number, st_line, context)
|
cr, uid, st_number, st_line, context)
|
||||||
company_currency_id = st.journal_id.company_id.currency_id.id
|
company_currency_id = st.journal_id.company_id.currency_id.id
|
||||||
statement_pool.create_move_from_st_line(
|
statement_pool.create_move_from_st_line(
|
||||||
cr, uid, st_line.id, company_currency_id, st_line_number, context)
|
cr, uid, st_line.id, company_currency_id, st_line_number,
|
||||||
|
context
|
||||||
|
)
|
||||||
self.write(
|
self.write(
|
||||||
cr, uid, st_line.id, {'state': 'confirmed'}, context)
|
cr, uid, st_line.id, {'state': 'confirmed'}, context)
|
||||||
return True
|
return True
|
||||||
@@ -1626,15 +1717,17 @@ class account_bank_statement_line(orm.Model):
|
|||||||
if st_line.statement_id.state != 'draft':
|
if st_line.statement_id.state != 'draft':
|
||||||
raise orm.except_orm(
|
raise orm.except_orm(
|
||||||
_("Cannot cancel bank transaction"),
|
_("Cannot cancel bank transaction"),
|
||||||
_("The bank statement that this transaction belongs to has "
|
_("The bank statement that this transaction belongs to "
|
||||||
"already been confirmed"))
|
"has already been confirmed"))
|
||||||
|
|
||||||
if st_line.import_transaction_id:
|
if st_line.import_transaction_id:
|
||||||
# Cancel transaction immediately.
|
# Cancel transaction immediately.
|
||||||
# If it has voucher, this will clean up
|
# If it has voucher, this will clean up
|
||||||
# the moves on the st_line.
|
# the moves on the st_line.
|
||||||
import_transaction_obj.cancel(
|
import_transaction_obj.cancel(
|
||||||
cr, uid, [st_line.import_transaction_id.id], context=context)
|
cr, uid, [st_line.import_transaction_id.id],
|
||||||
|
context=context
|
||||||
|
)
|
||||||
st_line.refresh()
|
st_line.refresh()
|
||||||
for line in st_line.move_ids:
|
for line in st_line.move_ids:
|
||||||
# We allow for people canceling and removing
|
# We allow for people canceling and removing
|
||||||
@@ -1650,7 +1743,6 @@ class account_bank_statement_line(orm.Model):
|
|||||||
cr, uid, set_draft_ids, {'state': 'draft'}, context=context)
|
cr, uid, set_draft_ids, {'state': 'draft'}, context=context)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def unlink(self, cr, uid, ids, context=None):
|
def unlink(self, cr, uid, ids, context=None):
|
||||||
"""
|
"""
|
||||||
Don't allow deletion of a confirmed statement line
|
Don't allow deletion of a confirmed statement line
|
||||||
@@ -1669,13 +1761,13 @@ class account_bank_statement_line(orm.Model):
|
|||||||
line.parent_id.write(
|
line.parent_id.write(
|
||||||
{
|
{
|
||||||
'amount': line.parent_id.amount + line.amount,
|
'amount': line.parent_id.amount + line.amount,
|
||||||
})
|
}
|
||||||
|
)
|
||||||
line.parent_id.refresh()
|
line.parent_id.refresh()
|
||||||
return super(account_bank_statement_line, self).unlink(
|
return super(account_bank_statement_line, self).unlink(
|
||||||
cr, uid, ids, context=context)
|
cr, uid, ids, context=context)
|
||||||
|
|
||||||
def create_instant_transaction(
|
def create_instant_transaction(self, cr, uid, ids, context=None):
|
||||||
self, cr, uid, ids, context=None):
|
|
||||||
"""
|
"""
|
||||||
Check for existance of import transaction on the
|
Check for existance of import transaction on the
|
||||||
bank statement lines. Create instant items if appropriate.
|
bank statement lines. Create instant items if appropriate.
|
||||||
@@ -1696,8 +1788,7 @@ class account_bank_statement_line(orm.Model):
|
|||||||
context = {}
|
context = {}
|
||||||
localcontext = context.copy()
|
localcontext = context.copy()
|
||||||
localcontext['transaction_no_duplicate_search'] = True
|
localcontext['transaction_no_duplicate_search'] = True
|
||||||
for line in self.browse(
|
for line in self.browse(cr, uid, ids, context=context):
|
||||||
cr, uid, ids, context=context):
|
|
||||||
if line.state != 'confirmed' and not line.import_transaction_id:
|
if line.state != 'confirmed' and not line.import_transaction_id:
|
||||||
res = import_transaction_pool.create(
|
res = import_transaction_pool.create(
|
||||||
cr, uid, {
|
cr, uid, {
|
||||||
@@ -1723,20 +1814,20 @@ class account_bank_statement_line(orm.Model):
|
|||||||
child_statement_ids = []
|
child_statement_ids = []
|
||||||
for this in self.browse(cr, uid, ids, context):
|
for this in self.browse(cr, uid, ids, context):
|
||||||
transaction_data = transaction_pool.copy_data(
|
transaction_data = transaction_pool.copy_data(
|
||||||
cr, uid, this.import_transaction_id.id)
|
cr, uid, this.import_transaction_id.id
|
||||||
|
)
|
||||||
transaction_data['transferred_amount'] = amount
|
transaction_data['transferred_amount'] = amount
|
||||||
transaction_data['message'] = (
|
transaction_data['message'] = ((transaction_data['message'] or '')
|
||||||
(transaction_data['message'] or '') + _(' (split)'))
|
+ _(' (split)'))
|
||||||
transaction_data['parent_id'] = this.import_transaction_id.id
|
transaction_data['parent_id'] = this.import_transaction_id.id
|
||||||
transaction_id = transaction_pool.create(
|
transaction_id = transaction_pool.create(
|
||||||
cr,
|
cr,
|
||||||
uid,
|
uid,
|
||||||
transaction_data,
|
transaction_data,
|
||||||
context=dict(
|
context=dict(context, transaction_no_duplicate_search=True)
|
||||||
context, transaction_no_duplicate_search=True))
|
)
|
||||||
|
|
||||||
statement_line_data = self.copy_data(
|
statement_line_data = self.copy_data(cr, uid, this.id)
|
||||||
cr, uid, this.id)
|
|
||||||
statement_line_data['amount'] = amount
|
statement_line_data['amount'] = amount
|
||||||
statement_line_data['name'] = (
|
statement_line_data['name'] = (
|
||||||
(statement_line_data['name'] or '') + _(' (split)'))
|
(statement_line_data['name'] or '') + _(' (split)'))
|
||||||
@@ -1785,22 +1876,30 @@ class account_bank_statement(orm.Model):
|
|||||||
line_obj = self.pool.get('account.bank.statement.line')
|
line_obj = self.pool.get('account.bank.statement.line')
|
||||||
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
|
||||||
if not self.check_status_condition(cr, uid, st.state, journal_type=j_type):
|
if not self.check_status_condition(
|
||||||
|
cr, uid, st.state, journal_type=j_type):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.balance_check(cr, uid, st.id, journal_type=j_type, context=context)
|
self.balance_check(cr, uid, st.id, journal_type=j_type,
|
||||||
|
context=context)
|
||||||
if (not st.journal_id.default_credit_account_id) \
|
if (not st.journal_id.default_credit_account_id) \
|
||||||
or (not st.journal_id.default_debit_account_id):
|
or (not st.journal_id.default_debit_account_id):
|
||||||
raise orm.except_orm(_('Configuration Error !'),
|
raise orm.except_orm(
|
||||||
_('Please verify that an account is defined in the journal.'))
|
_('Configuration Error !'),
|
||||||
|
_('Please verify that an account is defined in the '
|
||||||
|
'journal.')
|
||||||
|
)
|
||||||
|
|
||||||
# protect against misguided manual changes
|
# protect against misguided manual changes
|
||||||
for line in st.move_line_ids:
|
for line in st.move_line_ids:
|
||||||
if line.state != 'valid':
|
if line.state != 'valid':
|
||||||
raise orm.except_orm(_('Error !'),
|
raise orm.except_orm(
|
||||||
_('The account entries lines are not in valid state.'))
|
_('Error !'),
|
||||||
|
_('The account entries lines are not in valid state.')
|
||||||
|
)
|
||||||
|
|
||||||
line_obj.confirm(cr, uid, [line.id for line in st.line_ids], context)
|
line_obj.confirm(cr, uid, [line.id for line in st.line_ids],
|
||||||
|
context)
|
||||||
st.refresh()
|
st.refresh()
|
||||||
self.message_post(
|
self.message_post(
|
||||||
cr, uid, [st.id],
|
cr, uid, [st.id],
|
||||||
@@ -1841,5 +1940,3 @@ class account_bank_statement(orm.Model):
|
|||||||
'balance_end': fields.function(
|
'balance_end': fields.function(
|
||||||
_end_balance, method=True, store=True, string='Balance'),
|
_end_balance, method=True, store=True, string='Balance'),
|
||||||
}
|
}
|
||||||
|
|
||||||
account_bank_statement()
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
# Copyright (C) 2011 Therp BV (<http://therp.nl>)
|
# Copyright (C) 2011 Therp BV (<http://therp.nl>)
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU Affero General Public License as published by
|
# it under the terms of the GNU Affero General Public License as published
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# by the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
@@ -24,6 +24,7 @@ __name__ = ("account.bank.statement.line:: set new field 'state' to "
|
|||||||
"confirmed for all statement lines belonging to confirmed "
|
"confirmed for all statement lines belonging to confirmed "
|
||||||
"statements")
|
"statements")
|
||||||
|
|
||||||
|
|
||||||
def migrate(cr, version):
|
def migrate(cr, version):
|
||||||
cr.execute("UPDATE account_bank_statement_line as sl "
|
cr.execute("UPDATE account_bank_statement_line as sl "
|
||||||
" SET state = 'confirmed'"
|
" SET state = 'confirmed'"
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
|
||||||
def migrate(cr, version):
|
def migrate(cr, version):
|
||||||
if not version:
|
if not version:
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
|
||||||
def migrate(cr, version):
|
def migrate(cr, version):
|
||||||
if not version:
|
if not version:
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
|
||||||
def table_exists(cr, table):
|
def table_exists(cr, table):
|
||||||
""" Check whether a certain table or view exists """
|
""" Check whether a certain table or view exists """
|
||||||
cr.execute(
|
cr.execute(
|
||||||
@@ -26,6 +27,7 @@ def table_exists(cr, table):
|
|||||||
(table,))
|
(table,))
|
||||||
return cr.fetchone()[0] == 1
|
return cr.fetchone()[0] == 1
|
||||||
|
|
||||||
|
|
||||||
def migrate(cr, version):
|
def migrate(cr, version):
|
||||||
"""
|
"""
|
||||||
Migration script for semantic changes in account_banking_payment_export.
|
Migration script for semantic changes in account_banking_payment_export.
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
# All Rights Reserved
|
# All Rights Reserved
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU Affero General Public License as published by
|
# it under the terms of the GNU Affero General Public License as published
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# by the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
@@ -19,6 +19,6 @@
|
|||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
import models
|
from . import models
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
# All Rights Reserved
|
# All Rights Reserved
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU Affero General Public License as published by
|
# it under the terms of the GNU Affero General Public License as published
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# by the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
@@ -29,14 +29,17 @@ try:
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
from mx import DateTime as datetime
|
from mx import DateTime as datetime
|
||||||
|
|
||||||
|
|
||||||
def str2date(datestr, format='%d/%m/%y'):
|
def str2date(datestr, format='%d/%m/%y'):
|
||||||
'''Convert a string to a datatime object'''
|
'''Convert a string to a datatime object'''
|
||||||
return datetime.strptime(datestr, format)
|
return datetime.strptime(datestr, format)
|
||||||
|
|
||||||
|
|
||||||
def date2str(date, format='%Y-%m-%d'):
|
def date2str(date, format='%Y-%m-%d'):
|
||||||
'''Convert a datetime object to a string'''
|
'''Convert a datetime object to a string'''
|
||||||
return date.strftime(format)
|
return date.strftime(format)
|
||||||
|
|
||||||
|
|
||||||
def date2date(datestr, fromfmt='%d/%m/%y', tofmt='%Y-%m-%d'):
|
def date2date(datestr, fromfmt='%d/%m/%y', tofmt='%Y-%m-%d'):
|
||||||
'''
|
'''
|
||||||
Convert a date in a string to another string, in a different
|
Convert a date in a string to another string, in a different
|
||||||
@@ -44,7 +47,9 @@ def date2date(datestr, fromfmt='%d/%m/%y', tofmt='%Y-%m-%d'):
|
|||||||
'''
|
'''
|
||||||
return date2str(str2date(datestr, fromfmt), tofmt)
|
return date2str(str2date(datestr, fromfmt), tofmt)
|
||||||
|
|
||||||
_SWIFT = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/-?:().,'+ "
|
_SWIFT = ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||||
|
"/-?:().,'+ ")
|
||||||
|
|
||||||
|
|
||||||
def to_swift(astr, schemes=['utf-8', 'latin-1', 'ascii']):
|
def to_swift(astr, schemes=['utf-8', 'latin-1', 'ascii']):
|
||||||
'''
|
'''
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
import re
|
import re
|
||||||
from openerp.tools.translate import _
|
from openerp.tools.translate import _
|
||||||
|
|
||||||
|
|
||||||
class mem_bank_statement(object):
|
class mem_bank_statement(object):
|
||||||
'''
|
'''
|
||||||
A mem_bank_statement is a real life projection of a bank statement paper
|
A mem_bank_statement is a real life projection of a bank statement paper
|
||||||
@@ -34,9 +35,15 @@ class mem_bank_statement(object):
|
|||||||
'''
|
'''
|
||||||
# Lock attributes to enable parsers to trigger non-conformity faults
|
# Lock attributes to enable parsers to trigger non-conformity faults
|
||||||
__slots__ = [
|
__slots__ = [
|
||||||
'start_balance','end_balance', 'date', 'local_account',
|
'start_balance',
|
||||||
'local_currency', 'id', 'transactions'
|
'end_balance',
|
||||||
|
'date',
|
||||||
|
'local_account',
|
||||||
|
'local_currency',
|
||||||
|
'id',
|
||||||
|
'transactions'
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(mem_bank_statement, self).__init__(*args, **kwargs)
|
super(mem_bank_statement, self).__init__(*args, **kwargs)
|
||||||
self.id = ''
|
self.id = ''
|
||||||
@@ -59,6 +66,7 @@ class mem_bank_statement(object):
|
|||||||
check += float(transaction.transferred_amount)
|
check += float(transaction.transferred_amount)
|
||||||
return abs(check - float(self.end_balance)) < 0.0001
|
return abs(check - float(self.end_balance)) < 0.0001
|
||||||
|
|
||||||
|
|
||||||
class mem_bank_transaction(object):
|
class mem_bank_transaction(object):
|
||||||
'''
|
'''
|
||||||
A mem_bank_transaction is a real life copy of a bank transfer. Mapping to
|
A mem_bank_transaction is a real life copy of a bank transfer. Mapping to
|
||||||
@@ -126,7 +134,8 @@ class mem_bank_transaction(object):
|
|||||||
# The other parties postal code belonging to the address
|
# The other parties postal code belonging to the address
|
||||||
|
|
||||||
'remote_owner_country_code',
|
'remote_owner_country_code',
|
||||||
# The other parties two letter ISO country code belonging to the previous
|
# The other parties two letter ISO country code belonging to the
|
||||||
|
# previous
|
||||||
|
|
||||||
'remote_owner_custno',
|
'remote_owner_custno',
|
||||||
# The other parties customer number
|
# The other parties customer number
|
||||||
@@ -270,7 +279,7 @@ class mem_bank_transaction(object):
|
|||||||
if value in self.types:
|
if value in self.types:
|
||||||
self.transfer_type = value
|
self.transfer_type = value
|
||||||
else:
|
else:
|
||||||
raise ValueError, _('Invalid value for transfer_type')
|
raise ValueError(_('Invalid value for transfer_type'))
|
||||||
|
|
||||||
type = property(_get_type, _set_type)
|
type = property(_get_type, _set_type)
|
||||||
|
|
||||||
@@ -282,6 +291,7 @@ class mem_bank_transaction(object):
|
|||||||
return (self.execution_date and self.remote_account
|
return (self.execution_date and self.remote_account
|
||||||
and self.transferred_amount and True) or False
|
and self.transferred_amount and True) or False
|
||||||
|
|
||||||
|
|
||||||
class parser_type(type):
|
class parser_type(type):
|
||||||
'''
|
'''
|
||||||
Meta annex factory class for house keeping and collecting parsers.
|
Meta annex factory class for house keeping and collecting parsers.
|
||||||
@@ -314,11 +324,13 @@ class parser_type(type):
|
|||||||
keys.sort()
|
keys.sort()
|
||||||
return [(parsers[x].code, parsers[x].name) for x in keys]
|
return [(parsers[x].code, parsers[x].name) for x in keys]
|
||||||
|
|
||||||
|
|
||||||
def create_parser(code):
|
def create_parser(code):
|
||||||
if code in parser_type.parser_by_code:
|
if code in parser_type.parser_by_code:
|
||||||
return parser_type.parser_by_code[code]()
|
return parser_type.parser_by_code[code]()
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
class parser(object):
|
class parser(object):
|
||||||
'''
|
'''
|
||||||
A parser delivers the interface for any parser object. Inherit from
|
A parser delivers the interface for any parser object. Inherit from
|
||||||
@@ -408,5 +420,3 @@ class parser(object):
|
|||||||
raise NotImplementedError(
|
raise NotImplementedError(
|
||||||
_('This is a stub. Please implement your own.')
|
_('This is a stub. Please implement your own.')
|
||||||
)
|
)
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
# All Rights Reserved
|
# All Rights Reserved
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU Affero General Public License as published by
|
# it under the terms of the GNU Affero General Public License as published
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# by the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
@@ -31,16 +31,19 @@ from datetime import datetime, date
|
|||||||
# Correct python2.4 issues
|
# Correct python2.4 issues
|
||||||
try:
|
try:
|
||||||
datetime.strptime
|
datetime.strptime
|
||||||
|
|
||||||
def strpdate(str, format):
|
def strpdate(str, format):
|
||||||
return datetime.strptime(str, format).date()
|
return datetime.strptime(str, format).date()
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
import time
|
import time
|
||||||
|
|
||||||
def strpdate(str, format):
|
def strpdate(str, format):
|
||||||
tm = time.strptime(str, format)
|
tm = time.strptime(str, format)
|
||||||
return date(tm.tm_year, tm.tm_mon, tm.tm_mday)
|
return date(tm.tm_year, tm.tm_mon, tm.tm_mday)
|
||||||
|
|
||||||
import unicodedata
|
import unicodedata
|
||||||
|
|
||||||
|
|
||||||
class Field(object):
|
class Field(object):
|
||||||
'''Base Field class - fixed length left aligned string field in a record'''
|
'''Base Field class - fixed length left aligned string field in a record'''
|
||||||
def __init__(self, name, length=1, fillchar=' ', cast=str):
|
def __init__(self, name, length=1, fillchar=' ', cast=str):
|
||||||
@@ -57,11 +60,14 @@ class Field(object):
|
|||||||
|
|
||||||
def take(self, buffer):
|
def take(self, buffer):
|
||||||
offset = hasattr(self, 'offset') and self.offset or 0
|
offset = hasattr(self, 'offset') and self.offset or 0
|
||||||
return self.cast(buffer[offset:offset + self.length].rstrip(self.fillchar))
|
return self.cast(buffer[offset:offset + self.length].rstrip(
|
||||||
|
self.fillchar)
|
||||||
|
)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '%s "%s"' % (self.__class__.__name__, self.name)
|
return '%s "%s"' % (self.__class__.__name__, self.name)
|
||||||
|
|
||||||
|
|
||||||
class Filler(Field):
|
class Filler(Field):
|
||||||
'''Constant value field'''
|
'''Constant value field'''
|
||||||
def __init__(self, name, length=1, value=' '):
|
def __init__(self, name, length=1, value=' '):
|
||||||
@@ -76,6 +82,7 @@ class Filler(Field):
|
|||||||
self.value * (self.length / len(self.value) + 1)
|
self.value * (self.length / len(self.value) + 1)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class DateField(Field):
|
class DateField(Field):
|
||||||
'''Variable date field'''
|
'''Variable date field'''
|
||||||
def __init__(self, name, format='%Y-%m-%d', auto=False, cast=str):
|
def __init__(self, name, format='%Y-%m-%d', auto=False, cast=str):
|
||||||
@@ -98,6 +105,7 @@ class DateField(Field):
|
|||||||
return strpdate(value, self.dateformat)
|
return strpdate(value, self.dateformat)
|
||||||
return self.auto and date.today() or None
|
return self.auto and date.today() or None
|
||||||
|
|
||||||
|
|
||||||
class RightAlignedField(Field):
|
class RightAlignedField(Field):
|
||||||
'''Deviation of Field: right aligned'''
|
'''Deviation of Field: right aligned'''
|
||||||
def format(self, value):
|
def format(self, value):
|
||||||
@@ -107,7 +115,10 @@ class RightAlignedField(Field):
|
|||||||
|
|
||||||
def take(self, buffer):
|
def take(self, buffer):
|
||||||
offset = hasattr(self, 'offset') and self.offset or 0
|
offset = hasattr(self, 'offset') and self.offset or 0
|
||||||
return self.cast(buffer[offset:offset + self.length].lstrip(self.fillchar))
|
return self.cast(buffer[offset:offset + self.length].lstrip(
|
||||||
|
self.fillchar)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class NumberField(RightAlignedField):
|
class NumberField(RightAlignedField):
|
||||||
'''Deviation of Field: left zero filled'''
|
'''Deviation of Field: left zero filled'''
|
||||||
@@ -118,6 +129,7 @@ class NumberField(RightAlignedField):
|
|||||||
def format(self, value):
|
def format(self, value):
|
||||||
return super(NumberField, self).format(self.cast(value or ''))
|
return super(NumberField, self).format(self.cast(value or ''))
|
||||||
|
|
||||||
|
|
||||||
class RecordType(object):
|
class RecordType(object):
|
||||||
fields = []
|
fields = []
|
||||||
|
|
||||||
@@ -139,7 +151,7 @@ class RecordType(object):
|
|||||||
for field in self.fields:
|
for field in self.fields:
|
||||||
if field.name == key:
|
if field.name == key:
|
||||||
return field
|
return field
|
||||||
raise KeyError, 'No such field: %s' % key
|
raise KeyError('No such field: %s' % key)
|
||||||
|
|
||||||
def format(self, buffer):
|
def format(self, buffer):
|
||||||
result = []
|
result = []
|
||||||
@@ -152,6 +164,7 @@ class RecordType(object):
|
|||||||
[x.take(buffer) for x in self.fields]
|
[x.take(buffer) for x in self.fields]
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
class Record(object):
|
class Record(object):
|
||||||
_recordtype = None
|
_recordtype = None
|
||||||
|
|
||||||
@@ -159,7 +172,7 @@ class Record(object):
|
|||||||
if hasattr(self, '_fields') and self._fields:
|
if hasattr(self, '_fields') and self._fields:
|
||||||
self._recordtype = RecordType(self._fields)
|
self._recordtype = RecordType(self._fields)
|
||||||
if not self._recordtype and not recordtype:
|
if not self._recordtype and not recordtype:
|
||||||
raise ValueError, 'No recordtype specified'
|
raise ValueError('No recordtype specified')
|
||||||
if not self._recordtype:
|
if not self._recordtype:
|
||||||
self._recordtype = recordtype()
|
self._recordtype = recordtype()
|
||||||
self._length = len(self._recordtype)
|
self._length = len(self._recordtype)
|
||||||
@@ -173,9 +186,11 @@ class Record(object):
|
|||||||
super(Record, self).__setattr__(attr, value)
|
super(Record, self).__setattr__(attr, value)
|
||||||
else:
|
else:
|
||||||
field = self._recordtype[attr]
|
field = self._recordtype[attr]
|
||||||
self._value = self._value[:field.offset] + \
|
self._value = (
|
||||||
field.format(value) + \
|
self._value[:field.offset] +
|
||||||
|
field.format(value) +
|
||||||
self._value[field.offset + field.length:]
|
self._value[field.offset + field.length:]
|
||||||
|
)
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
def __getattr__(self, attr):
|
||||||
if attr.startswith('_'):
|
if attr.startswith('_'):
|
||||||
@@ -189,7 +204,6 @@ class Record(object):
|
|||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return unicode(self.cast(self))
|
return unicode(self.cast(self))
|
||||||
|
|
||||||
|
|
||||||
def asciify(str):
|
def asciify(str):
|
||||||
return unicodedata.normalize('NFKD', str).encode('ascii', 'ignore')
|
return unicodedata.normalize('NFKD', str).encode('ascii', 'ignore')
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
|
|
||||||
__all__ = ['IBAN', 'BBAN']
|
__all__ = ['IBAN', 'BBAN']
|
||||||
|
|
||||||
|
|
||||||
def modulo_97_base10(abuffer):
|
def modulo_97_base10(abuffer):
|
||||||
'''
|
'''
|
||||||
Calculate the modulo 97 value of a string in base10
|
Calculate the modulo 97 value of a string in base10
|
||||||
@@ -55,6 +56,7 @@ def modulo_97_base10(abuffer):
|
|||||||
checksum %= 97
|
checksum %= 97
|
||||||
return checksum
|
return checksum
|
||||||
|
|
||||||
|
|
||||||
def base36_to_base10str(abuffer):
|
def base36_to_base10str(abuffer):
|
||||||
'''
|
'''
|
||||||
Convert a base36 string value to a string of base10 digits.
|
Convert a base36 string value to a string of base10 digits.
|
||||||
@@ -67,6 +69,7 @@ def base36_to_base10str(abuffer):
|
|||||||
result += digit
|
result += digit
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
class BBANFormat(object):
|
class BBANFormat(object):
|
||||||
'''
|
'''
|
||||||
A BBANFormat is an auxilliary class for IBAN. It represents the composition
|
A BBANFormat is an auxilliary class for IBAN. It represents the composition
|
||||||
@@ -178,6 +181,7 @@ class BBANFormat(object):
|
|||||||
i += 1
|
i += 1
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
class IBAN(str):
|
class IBAN(str):
|
||||||
'''
|
'''
|
||||||
A IBAN string represents a SEPA bank account number. This class provides
|
A IBAN string represents a SEPA bank account number. This class provides
|
||||||
@@ -272,7 +276,7 @@ class IBAN(str):
|
|||||||
if item.isalnum():
|
if item.isalnum():
|
||||||
init += item
|
init += item
|
||||||
elif item not in ' \t.-':
|
elif item not in ' \t.-':
|
||||||
raise ValueError, 'Invalid chars found in IBAN number'
|
raise ValueError('Invalid chars found in IBAN number')
|
||||||
return str.__new__(cls, init)
|
return str.__new__(cls, init)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
@@ -287,8 +291,7 @@ class IBAN(str):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls, BIC=None, countrycode=None, BBAN=None, bankcode=None,
|
def create(cls, BIC=None, countrycode=None, BBAN=None, bankcode=None,
|
||||||
branchcode=None, account=None
|
branchcode=None, account=None):
|
||||||
):
|
|
||||||
'''
|
'''
|
||||||
Create a IBAN number from a BBAN and a country code. Optionaly create
|
Create a IBAN number from a BBAN and a country code. Optionaly create
|
||||||
a BBAN from BBAN components before generation.
|
a BBAN from BBAN components before generation.
|
||||||
@@ -304,20 +307,17 @@ class IBAN(str):
|
|||||||
if countrycode:
|
if countrycode:
|
||||||
countrycode = countrycode.upper()
|
countrycode = countrycode.upper()
|
||||||
else:
|
else:
|
||||||
raise ValueError, \
|
raise ValueError('Either BIC or countrycode is required')
|
||||||
'Either BIC or countrycode is required'
|
|
||||||
|
|
||||||
if countrycode not in cls.countries:
|
if countrycode not in cls.countries:
|
||||||
raise ValueError, \
|
raise ValueError('%s is not a SEPA country' % countrycode)
|
||||||
'%s is not a SEPA country' % countrycode
|
|
||||||
format = cls.BBAN_formats[countrycode]
|
format = cls.BBAN_formats[countrycode]
|
||||||
|
|
||||||
if BBAN:
|
if BBAN:
|
||||||
if len(BBAN) == len(format._iban):
|
if len(BBAN) == len(format._iban):
|
||||||
ibanno = cls(countrycode + '00' + BBAN)
|
ibanno = cls(countrycode + '00' + BBAN)
|
||||||
return cls(countrycode + ibanno.checksum + BBAN)
|
return cls(countrycode + ibanno.checksum + BBAN)
|
||||||
raise ValueError, \
|
raise ValueError('Insufficient data to generate IBAN')
|
||||||
'Insufficient data to generate IBAN'
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def valid(self):
|
def valid(self):
|
||||||
@@ -325,8 +325,10 @@ class IBAN(str):
|
|||||||
Check if the string + check digits deliver a valid checksum
|
Check if the string + check digits deliver a valid checksum
|
||||||
'''
|
'''
|
||||||
_buffer = self[4:] + self[:4]
|
_buffer = self[4:] + self[:4]
|
||||||
return self.countrycode in self.countries and \
|
return (
|
||||||
int(base36_to_base10str(_buffer)) % 97 == 1
|
self.countrycode in self.countries
|
||||||
|
and int(base36_to_base10str(_buffer)) % 97 == 1
|
||||||
|
)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
'''
|
'''
|
||||||
@@ -421,6 +423,7 @@ class IBAN(str):
|
|||||||
'''
|
'''
|
||||||
return self[4:]
|
return self[4:]
|
||||||
|
|
||||||
|
|
||||||
class BBAN(object):
|
class BBAN(object):
|
||||||
'''
|
'''
|
||||||
Class to reformat a local BBAN account number to IBAN specs.
|
Class to reformat a local BBAN account number to IBAN specs.
|
||||||
@@ -433,7 +436,8 @@ class BBAN(object):
|
|||||||
Internal method to calculate the length of a parameter in a
|
Internal method to calculate the length of a parameter in a
|
||||||
formatted string
|
formatted string
|
||||||
'''
|
'''
|
||||||
i = 0; max_i = len(fmt._iban)
|
i = 0
|
||||||
|
max_i = len(fmt._iban)
|
||||||
while i < max_i:
|
while i < max_i:
|
||||||
if fmt._iban[i] == element:
|
if fmt._iban[i] == element:
|
||||||
next = i + 1
|
next = i + 1
|
||||||
@@ -453,7 +457,10 @@ class BBAN(object):
|
|||||||
if countrycode.upper() in IBAN.countries:
|
if countrycode.upper() in IBAN.countries:
|
||||||
self._fmt = IBAN.BBAN_formats[countrycode.upper()]
|
self._fmt = IBAN.BBAN_formats[countrycode.upper()]
|
||||||
res = ''
|
res = ''
|
||||||
i = 0; j = 0; max_i = len(self._fmt._bban); max_j = len(bban)
|
i = 0
|
||||||
|
j = 0
|
||||||
|
max_i = len(self._fmt._bban)
|
||||||
|
max_j = len(bban)
|
||||||
while i < max_i and j < max_j:
|
while i < max_i and j < max_j:
|
||||||
while bban[j] in ' \t' and j < max_j:
|
while bban[j] in ' \t' and j < max_j:
|
||||||
j += 1
|
j += 1
|
||||||
@@ -512,15 +519,16 @@ class BBAN(object):
|
|||||||
'''Simple check if BBAN is in the right format'''
|
'''Simple check if BBAN is in the right format'''
|
||||||
return self._bban and True or False
|
return self._bban and True or False
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import sys
|
import sys
|
||||||
for arg in sys.argv[1:]:
|
for arg in sys.argv[1:]:
|
||||||
iban = IBAN(arg)
|
iban = IBAN(arg)
|
||||||
print 'IBAN:', iban
|
print('IBAN:', iban)
|
||||||
print 'country code:', iban.countrycode
|
print('country code:', iban.countrycode)
|
||||||
print 'bank code:', iban.bankcode
|
print('bank code:', iban.bankcode)
|
||||||
print 'branch code:', iban.branchcode
|
print('branch code:', iban.branchcode)
|
||||||
print 'BBAN:', iban.BBAN
|
print('BBAN:', iban.BBAN)
|
||||||
print 'localized BBAN:', iban.localized_BBAN
|
print('localized BBAN:', iban.localized_BBAN)
|
||||||
print 'check digits:', iban.checkdigits
|
print('check digits:', iban.checkdigits)
|
||||||
print 'checksum:', iban.checksum
|
print('checksum:', iban.checksum)
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
# All Rights Reserved
|
# All Rights Reserved
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU Affero General Public License as published by
|
# it under the terms of the GNU Affero General Public License as published
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# by the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
@@ -27,6 +27,7 @@ import re
|
|||||||
|
|
||||||
__all__ = ['split', 'get', 'PostalCode']
|
__all__ = ['split', 'get', 'PostalCode']
|
||||||
|
|
||||||
|
|
||||||
class PostalCode(object):
|
class PostalCode(object):
|
||||||
'''
|
'''
|
||||||
The PostalCode class is a wrapper around PostCodeFormat and an internal
|
The PostalCode class is a wrapper around PostCodeFormat and an internal
|
||||||
@@ -99,7 +100,8 @@ class PostalCode(object):
|
|||||||
'IM': '@# #@@|@## #@@|@@# #@@|@@## #@@|@#@ #@@|@@#@ #@@|GIR0AA',
|
'IM': '@# #@@|@## #@@|@@# #@@|@@## #@@|@#@ #@@|@@#@ #@@|GIR0AA',
|
||||||
'IL': '#####', 'IT': '####', 'JM': '', 'JP': '###-####',
|
'IL': '#####', 'IT': '####', 'JM': '', 'JP': '###-####',
|
||||||
'JE': '@# #@@|@## #@@|@@# #@@|@@## #@@|@#@ #@@|@@#@ #@@|GIR0AA',
|
'JE': '@# #@@|@## #@@|@@# #@@|@@## #@@|@#@ #@@|@@#@ #@@|GIR0AA',
|
||||||
'JO': '#####', 'KZ': '######', 'KE': '#####', 'KI': '', 'KP': '###-###',
|
'JO': '#####', 'KZ': '######', 'KE': '#####', 'KI': '',
|
||||||
|
'KP': '###-###',
|
||||||
'KR': 'SEOUL ###-###', 'KW': '#####', 'KG': '######', 'LA': '#####',
|
'KR': 'SEOUL ###-###', 'KW': '#####', 'KG': '######', 'LA': '#####',
|
||||||
'LV': 'LV-####', 'LB': '#### ####|####', 'LS': '###', 'LR': '####',
|
'LV': 'LV-####', 'LB': '#### ####|####', 'LS': '###', 'LR': '####',
|
||||||
'LY': '', 'LI': '####', 'LT': 'LT-#####', 'LU': '####', 'MO': '',
|
'LY': '', 'LI': '####', 'LT': 'LT-#####', 'LU': '####', 'MO': '',
|
||||||
@@ -155,14 +157,12 @@ class PostalCode(object):
|
|||||||
|
|
||||||
# Find optimum (= max length postalcode) when iso code is unknown
|
# Find optimum (= max length postalcode) when iso code is unknown
|
||||||
all = {}
|
all = {}
|
||||||
opt_iso = ''
|
|
||||||
max_l = 0
|
max_l = 0
|
||||||
for key in cls._formats.iterkeys():
|
for key in cls._formats.iterkeys():
|
||||||
i, p, c = cls.split(str_, key)
|
i, p, c = cls.split(str_, key)
|
||||||
l = len(p)
|
l = len(p)
|
||||||
if l > max_l:
|
if l > max_l:
|
||||||
max_l = l
|
max_l = l
|
||||||
opt_iso = i
|
|
||||||
if l in all:
|
if l in all:
|
||||||
all[l].append((i, p, c))
|
all[l].append((i, p, c))
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
# All Rights Reserved
|
# All Rights Reserved
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU Affero General Public License as published by
|
# it under the terms of the GNU Affero General Public License as published
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# by the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Define a struct class which behaves like a dict, but allows using
|
Define a struct class which behaves like a dict, but allows using
|
||||||
object.attr alongside object['attr'].
|
object.attr alongside object['attr'].
|
||||||
@@ -25,6 +26,7 @@ object.attr alongside object['attr'].
|
|||||||
|
|
||||||
__all__ = ['struct']
|
__all__ = ['struct']
|
||||||
|
|
||||||
|
|
||||||
class struct(dict):
|
class struct(dict):
|
||||||
'''
|
'''
|
||||||
Ease working with dicts. Allow dict.key alongside dict['key']
|
Ease working with dicts. Allow dict.key alongside dict['key']
|
||||||
@@ -52,4 +54,4 @@ class struct(dict):
|
|||||||
else:
|
else:
|
||||||
fmt = '%*.*s%%s: %%s' % (indent, indent, '')
|
fmt = '%*.*s%%s: %%s' % (indent, indent, '')
|
||||||
for item in self.iteritems():
|
for item in self.iteritems():
|
||||||
print fmt % item
|
print(fmt % item)
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
# All Rights Reserved
|
# All Rights Reserved
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU Affero General Public License as published by
|
# it under the terms of the GNU Affero General Public License as published
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# by the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
@@ -18,8 +18,7 @@
|
|||||||
# 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 bank_import
|
|
||||||
import banking_transaction_wizard
|
|
||||||
import link_partner
|
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
from . import bank_import
|
||||||
|
from . import banking_transaction_wizard
|
||||||
|
from . import link_partner
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
# All Rights Reserved
|
# All Rights Reserved
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU Affero General Public License as published by
|
# it under the terms of the GNU Affero General Public License as published
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# by the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
@@ -23,11 +23,13 @@
|
|||||||
# Kaspars Vilkens (KNdati): lenghty discussions, bugreports and bugfixes
|
# Kaspars Vilkens (KNdati): lenghty discussions, bugreports and bugfixes
|
||||||
# Stefan Rijnhart (Therp): bugreport and bugfix
|
# Stefan Rijnhart (Therp): bugreport and bugfix
|
||||||
#
|
#
|
||||||
|
|
||||||
'''
|
'''
|
||||||
This module contains the business logic of the wizard account_banking_import.
|
This module contains the business logic of the wizard account_banking_import.
|
||||||
The parsing is done in the parser modules. Every parser module is required to
|
The parsing is done in the parser modules. Every parser module is required to
|
||||||
use parser.models as a mean of communication with the business logic.
|
use parser.models as a mean of communication with the business logic.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
import datetime
|
import datetime
|
||||||
from openerp.osv import orm, fields
|
from openerp.osv import orm, fields
|
||||||
@@ -44,6 +46,7 @@ bt = models.mem_bank_transaction
|
|||||||
# the real payment date. This can occur with online transactions (web shops).
|
# the real payment date. This can occur with online transactions (web shops).
|
||||||
payment_window = datetime.timedelta(days=10)
|
payment_window = datetime.timedelta(days=10)
|
||||||
|
|
||||||
|
|
||||||
def parser_types(*args, **kwargs):
|
def parser_types(*args, **kwargs):
|
||||||
'''Delay evaluation of parser types until start of wizard, to allow
|
'''Delay evaluation of parser types until start of wizard, to allow
|
||||||
depending modules to initialize and add their parsers to the list
|
depending modules to initialize and add their parsers to the list
|
||||||
@@ -57,7 +60,10 @@ class banking_import_line(orm.TransientModel):
|
|||||||
_columns = {
|
_columns = {
|
||||||
'name': fields.char('Name', size=64),
|
'name': fields.char('Name', size=64),
|
||||||
'date': fields.date('Date', readonly=True),
|
'date': fields.date('Date', readonly=True),
|
||||||
'amount': fields.float('Amount', digits_compute=dp.get_precision('Account')),
|
'amount': fields.float(
|
||||||
|
'Amount',
|
||||||
|
digits_compute=dp.get_precision('Account'),
|
||||||
|
),
|
||||||
'statement_line_id': fields.many2one(
|
'statement_line_id': fields.many2one(
|
||||||
'account.bank.statement.line',
|
'account.bank.statement.line',
|
||||||
'Resulting statement line', readonly=True),
|
'Resulting statement line', readonly=True),
|
||||||
@@ -67,8 +73,13 @@ class banking_import_line(orm.TransientModel):
|
|||||||
('general', 'General')
|
('general', 'General')
|
||||||
], 'Type', required=True),
|
], 'Type', required=True),
|
||||||
'partner_id': fields.many2one('res.partner', 'Partner'),
|
'partner_id': fields.many2one('res.partner', 'Partner'),
|
||||||
'statement_id': fields.many2one('account.bank.statement', 'Statement',
|
'statement_id': fields.many2one(
|
||||||
select=True, required=True, ondelete='cascade'),
|
'account.bank.statement',
|
||||||
|
'Statement',
|
||||||
|
select=True,
|
||||||
|
required=True,
|
||||||
|
ondelete='cascade',
|
||||||
|
),
|
||||||
'ref': fields.char('Reference', size=32),
|
'ref': fields.char('Reference', size=32),
|
||||||
'note': fields.text('Notes'),
|
'note': fields.text('Notes'),
|
||||||
'period_id': fields.many2one('account.period', 'Period'),
|
'period_id': fields.many2one('account.period', 'Period'),
|
||||||
@@ -83,13 +94,16 @@ class banking_import_line(orm.TransientModel):
|
|||||||
'account.invoice', 'banking_import_line_invoice_rel',
|
'account.invoice', 'banking_import_line_invoice_rel',
|
||||||
'line_id', 'invoice_id'),
|
'line_id', 'invoice_id'),
|
||||||
'partner_bank_id': fields.many2one('res.partner.bank', 'Bank Account'),
|
'partner_bank_id': fields.many2one('res.partner.bank', 'Bank Account'),
|
||||||
'transaction_type': fields.selection([
|
'transaction_type': fields.selection(
|
||||||
|
[
|
||||||
# TODO: payment terminal etc...
|
# TODO: payment terminal etc...
|
||||||
('invoice', 'Invoice payment'),
|
('invoice', 'Invoice payment'),
|
||||||
('storno', 'Canceled debit order'),
|
('storno', 'Canceled debit order'),
|
||||||
('bank_costs', 'Bank costs'),
|
('bank_costs', 'Bank costs'),
|
||||||
('unknown', 'Unknown'),
|
('unknown', 'Unknown'),
|
||||||
], 'Transaction type'),
|
],
|
||||||
|
'Transaction type',
|
||||||
|
),
|
||||||
'duplicate': fields.boolean('Duplicate'),
|
'duplicate': fields.boolean('Duplicate'),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +133,8 @@ class banking_import(orm.TransientModel):
|
|||||||
if not parser:
|
if not parser:
|
||||||
raise orm.except_orm(
|
raise orm.except_orm(
|
||||||
_('ERROR!'),
|
_('ERROR!'),
|
||||||
_('Unable to import parser %(parser)s. Parser class not found.') %
|
_('Unable to import parser %(parser)s. Parser class not '
|
||||||
|
'found.') %
|
||||||
{'parser': parser_code}
|
{'parser': parser_code}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -133,7 +148,8 @@ class banking_import(orm.TransientModel):
|
|||||||
if any([x for x in statements if not x.is_valid()]):
|
if any([x for x in statements if not x.is_valid()]):
|
||||||
raise orm.except_orm(
|
raise orm.except_orm(
|
||||||
_('ERROR!'),
|
_('ERROR!'),
|
||||||
_('The imported statements appear to be invalid! Check your file.')
|
_('The imported statements appear to be invalid! Check your '
|
||||||
|
'file.')
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create the file now, as the statements need to be linked to it
|
# Create the file now, as the statements need to be linked to it
|
||||||
@@ -175,7 +191,9 @@ class banking_import(orm.TransientModel):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# Create fallback currency code
|
# Create fallback currency code
|
||||||
currency_code = statement.local_currency or company.currency_id.name
|
currency_code = (
|
||||||
|
statement.local_currency or company.currency_id.name
|
||||||
|
)
|
||||||
|
|
||||||
# Check cache for account info/currency
|
# Check cache for account info/currency
|
||||||
if statement.local_account in info and \
|
if statement.local_account in info and \
|
||||||
@@ -190,8 +208,10 @@ class banking_import(orm.TransientModel):
|
|||||||
)
|
)
|
||||||
if not account_info:
|
if not account_info:
|
||||||
results.log.append(
|
results.log.append(
|
||||||
_('Statements found for unknown account %(bank_account)s') %
|
_('Statements found for unknown account '
|
||||||
{'bank_account': statement.local_account}
|
'%(bank_account)s') % {
|
||||||
|
'bank_account': statement.local_account
|
||||||
|
}
|
||||||
)
|
)
|
||||||
error_accounts[statement.local_account] = True
|
error_accounts[statement.local_account] = True
|
||||||
results.error_cnt += 1
|
results.error_cnt += 1
|
||||||
@@ -210,7 +230,7 @@ class banking_import(orm.TransientModel):
|
|||||||
currency_code = account_info.currency_id.name
|
currency_code = account_info.currency_id.name
|
||||||
|
|
||||||
# Cache results
|
# Cache results
|
||||||
if not statement.local_account in info:
|
if statement.local_account not in info:
|
||||||
info[statement.local_account] = {
|
info[statement.local_account] = {
|
||||||
currency_code: account_info
|
currency_code: account_info
|
||||||
}
|
}
|
||||||
@@ -251,7 +271,8 @@ class banking_import(orm.TransientModel):
|
|||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Get the period for the statement (as bank statement object checks this)
|
# Get the period for the statement (as bank statement object
|
||||||
|
# checks this)
|
||||||
period_ids = period_obj.search(
|
period_ids = period_obj.search(
|
||||||
cr, uid, [
|
cr, uid, [
|
||||||
('company_id', '=', company.id),
|
('company_id', '=', company.id),
|
||||||
@@ -294,7 +315,8 @@ class banking_import(orm.TransientModel):
|
|||||||
values = {}
|
values = {}
|
||||||
for attr in transaction.__slots__ + ['type']:
|
for attr in transaction.__slots__ + ['type']:
|
||||||
if attr in import_transaction_obj.column_map:
|
if attr in import_transaction_obj.column_map:
|
||||||
values[import_transaction_obj.column_map[attr]] = eval('transaction.%s' % attr)
|
values[import_transaction_obj.column_map[attr]] = \
|
||||||
|
eval('transaction.%s' % attr)
|
||||||
elif attr in import_transaction_obj._columns:
|
elif attr in import_transaction_obj._columns:
|
||||||
values[attr] = eval('transaction.%s' % attr)
|
values[attr] = eval('transaction.%s' % attr)
|
||||||
values['statement_id'] = statement_id
|
values['statement_id'] = statement_id
|
||||||
@@ -308,32 +330,14 @@ class banking_import(orm.TransientModel):
|
|||||||
|
|
||||||
results.stat_loaded_cnt += 1
|
results.stat_loaded_cnt += 1
|
||||||
|
|
||||||
import_transaction_obj.match(cr, uid, transaction_ids, results=results, context=context)
|
import_transaction_obj.match(
|
||||||
|
cr, uid, transaction_ids, results=results, context=context
|
||||||
|
)
|
||||||
|
|
||||||
# recompute statement end_balance for validation
|
# recompute statement end_balance for validation
|
||||||
statement_obj.button_dummy(
|
statement_obj.button_dummy(
|
||||||
cr, uid, imported_statement_ids, context=context)
|
cr, uid, imported_statement_ids, context=context)
|
||||||
|
|
||||||
|
|
||||||
# Original code. Didn't take workflow logistics into account...
|
|
||||||
#
|
|
||||||
#cr.execute(
|
|
||||||
# "UPDATE payment_order o "
|
|
||||||
# "SET state = 'done', "
|
|
||||||
# "date_done = '%s' "
|
|
||||||
# "FROM payment_line l "
|
|
||||||
# "WHERE o.state = 'sent' "
|
|
||||||
# "AND o.id = l.order_id "
|
|
||||||
# "AND l.id NOT IN ("
|
|
||||||
# "SELECT DISTINCT id FROM payment_line "
|
|
||||||
# "WHERE date_done IS NULL "
|
|
||||||
# "AND id IN (%s)"
|
|
||||||
# ")" % (
|
|
||||||
# time.strftime('%Y-%m-%d'),
|
|
||||||
# ','.join([str(x) for x in payment_line_ids])
|
|
||||||
# )
|
|
||||||
#)
|
|
||||||
|
|
||||||
report = [
|
report = [
|
||||||
'%s: %s' % (_('Total number of statements'),
|
'%s: %s' % (_('Total number of statements'),
|
||||||
results.stat_skipped_cnt + results.stat_loaded_cnt),
|
results.stat_skipped_cnt + results.stat_loaded_cnt),
|
||||||
@@ -360,13 +364,16 @@ class banking_import(orm.TransientModel):
|
|||||||
text_log = '\n'.join(report + results.log)
|
text_log = '\n'.join(report + results.log)
|
||||||
state = results.error_cnt and 'error' or 'ready'
|
state = results.error_cnt and 'error' or 'ready'
|
||||||
statement_file_obj.write(cr, uid, import_id, dict(
|
statement_file_obj.write(cr, uid, import_id, dict(
|
||||||
state = state, log = text_log,
|
state=state,
|
||||||
|
log=text_log,
|
||||||
), context)
|
), context)
|
||||||
if not imported_statement_ids or not results.trans_loaded_cnt:
|
if not imported_statement_ids or not results.trans_loaded_cnt:
|
||||||
# file state can be 'ready' while import state is 'error'
|
# file state can be 'ready' while import state is 'error'
|
||||||
state = 'error'
|
state = 'error'
|
||||||
self.write(cr, uid, [ids[0]], dict(
|
self.write(cr, uid, [ids[0]], dict(
|
||||||
import_id = import_id, log = text_log, state = state,
|
import_id=import_id,
|
||||||
|
log=text_log,
|
||||||
|
state=state,
|
||||||
statement_ids=[(6, 0, imported_statement_ids)],
|
statement_ids=[(6, 0, imported_statement_ids)],
|
||||||
), context)
|
), context)
|
||||||
return {
|
return {
|
||||||
@@ -393,13 +400,15 @@ class banking_import(orm.TransientModel):
|
|||||||
),
|
),
|
||||||
'file_name': fields.char('File name', size=256),
|
'file_name': fields.char('File name', size=256),
|
||||||
'file': fields.binary(
|
'file': fields.binary(
|
||||||
'Statements File', required=True,
|
'Statements File',
|
||||||
help = ('The Transactions File to import. Please note that while it is '
|
required=True,
|
||||||
'perfectly safe to reload the same file multiple times or to load in '
|
help=('The Transactions File to import. Please note that while it '
|
||||||
'timeframe overlapping statements files, there are formats that may '
|
'is perfectly safe to reload the same file multiple times '
|
||||||
'introduce different sequencing, which may create double entries.\n\n'
|
'or to load in timeframe overlapping statements files, '
|
||||||
'To stay on the safe side, always load bank statements files using the '
|
'there are formats that may introduce different '
|
||||||
'same format.'),
|
'sequencing, which may create double entries.\n\n'
|
||||||
|
'To stay on the safe side, always load bank statements '
|
||||||
|
'files using the same format.'),
|
||||||
states={
|
states={
|
||||||
'ready': [('readonly', True)],
|
'ready': [('readonly', True)],
|
||||||
'error': [('readonly', True)],
|
'error': [('readonly', True)],
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
# All Rights Reserved
|
# All Rights Reserved
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU Affero General Public License as published by
|
# it under the terms of the GNU Affero General Public License as published
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# by the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
@@ -128,10 +128,15 @@ class banking_transaction_wizard(orm.TransientModel):
|
|||||||
wiz.import_transaction_id.invoice_id):
|
wiz.import_transaction_id.invoice_id):
|
||||||
transaction_obj.write(
|
transaction_obj.write(
|
||||||
cr, uid, wiz.import_transaction_id.id,
|
cr, uid, wiz.import_transaction_id.id,
|
||||||
{ 'move_line_id': move_line.id, }, context=context)
|
{'move_line_id': move_line.id, },
|
||||||
|
context=context
|
||||||
|
)
|
||||||
statement_line_obj.write(
|
statement_line_obj.write(
|
||||||
cr, uid, wiz.import_transaction_id.statement_line_id.id,
|
cr, uid,
|
||||||
{ 'partner_id': move_line.partner_id.id or False,
|
wiz.import_transaction_id.statement_line_id.id,
|
||||||
|
{
|
||||||
|
'partner_id': (
|
||||||
|
move_line.partner_id.id or False),
|
||||||
'account_id': move_line.account_id.id,
|
'account_id': move_line.account_id.id,
|
||||||
}, context=context)
|
}, context=context)
|
||||||
found = True
|
found = True
|
||||||
@@ -155,7 +160,8 @@ class banking_transaction_wizard(orm.TransientModel):
|
|||||||
if manual_move_line_ids:
|
if manual_move_line_ids:
|
||||||
manual_move_line_ids = (
|
manual_move_line_ids = (
|
||||||
[i[1] for i in manual_move_line_ids if i[0] == 4] +
|
[i[1] for i in manual_move_line_ids if i[0] == 4] +
|
||||||
[j for i in manual_move_line_ids if i[0]==6 for j in i[2]])
|
[j for i in manual_move_line_ids
|
||||||
|
if i[0] == 6 for j in i[2]])
|
||||||
for wiz in self.browse(cr, uid, ids, context=context):
|
for wiz in self.browse(cr, uid, ids, context=context):
|
||||||
# write can be called multiple times for the same values
|
# write can be called multiple times for the same values
|
||||||
# that doesn't hurt above, but it does here
|
# that doesn't hurt above, but it does here
|
||||||
@@ -171,7 +177,8 @@ class banking_transaction_wizard(orm.TransientModel):
|
|||||||
found_move_line = False
|
found_move_line = False
|
||||||
if invoice.move_id:
|
if invoice.move_id:
|
||||||
for line in invoice.move_id.line_id:
|
for line in invoice.move_id.line_id:
|
||||||
if line.account_id.type in ('receivable', 'payable'):
|
if line.account_id.type in ('receivable',
|
||||||
|
'payable'):
|
||||||
todo.append((invoice.id, line.id))
|
todo.append((invoice.id, line.id))
|
||||||
found_move_line = True
|
found_move_line = True
|
||||||
break
|
break
|
||||||
@@ -186,7 +193,8 @@ class banking_transaction_wizard(orm.TransientModel):
|
|||||||
uid,
|
uid,
|
||||||
move_line_id,
|
move_line_id,
|
||||||
['invoice'],
|
['invoice'],
|
||||||
context=context)
|
context=context
|
||||||
|
)
|
||||||
if move_line['invoice']:
|
if move_line['invoice']:
|
||||||
todo_entry[0] = move_line['invoice'][0]
|
todo_entry[0] = move_line['invoice'][0]
|
||||||
todo.append(todo_entry)
|
todo.append(todo_entry)
|
||||||
@@ -205,14 +213,16 @@ class banking_transaction_wizard(orm.TransientModel):
|
|||||||
cr,
|
cr,
|
||||||
uid,
|
uid,
|
||||||
statement_line_id,
|
statement_line_id,
|
||||||
context=context).import_transaction_id.id
|
context=context
|
||||||
|
).import_transaction_id.id
|
||||||
|
|
||||||
vals = {
|
vals = {
|
||||||
'move_line_id': todo_entry[1],
|
'move_line_id': todo_entry[1],
|
||||||
'move_line_ids': [(6, 0, [todo_entry[1]])],
|
'move_line_ids': [(6, 0, [todo_entry[1]])],
|
||||||
'invoice_id': todo_entry[0],
|
'invoice_id': todo_entry[0],
|
||||||
'invoice_ids': [(6, 0,
|
'invoice_ids': [
|
||||||
[todo_entry[0]] if todo_entry[0] else [])],
|
(6, 0, [todo_entry[0]] if todo_entry[0] else [])
|
||||||
|
],
|
||||||
'match_type': 'manual',
|
'match_type': 'manual',
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,22 +265,19 @@ class banking_transaction_wizard(orm.TransientModel):
|
|||||||
# Get the bank account setting record, to reset the account
|
# Get the bank account setting record, to reset the account
|
||||||
account_id = False
|
account_id = False
|
||||||
journal_id = wiz.statement_line_id.statement_id.journal_id.id
|
journal_id = wiz.statement_line_id.statement_id.journal_id.id
|
||||||
setting_ids = settings_pool.find(cr, uid, journal_id, context=context)
|
setting_ids = settings_pool.find(
|
||||||
|
cr, uid, journal_id, context=context
|
||||||
|
)
|
||||||
|
|
||||||
# Restore partner id from the bank account or else reset
|
# Restore partner id from the bank account or else reset
|
||||||
partner_id = False
|
partner_id = False
|
||||||
if (wiz.statement_line_id.partner_bank_id and
|
if (wiz.statement_line_id.partner_bank_id and
|
||||||
wiz.statement_line_id.partner_bank_id.partner_id):
|
wiz.statement_line_id.partner_bank_id.partner_id):
|
||||||
partner_id = wiz.statement_line_id.partner_bank_id.partner_id.id
|
partner_id = (
|
||||||
|
wiz.statement_line_id.partner_bank_id.partner_id.id
|
||||||
|
)
|
||||||
wiz.write({'partner_id': partner_id})
|
wiz.write({'partner_id': partner_id})
|
||||||
|
|
||||||
# Select account type by parter customer or supplier,
|
|
||||||
# or default based on amount sign
|
|
||||||
if wiz.amount < 0:
|
|
||||||
account_type = 'payable'
|
|
||||||
else:
|
|
||||||
account_type = 'receivable'
|
|
||||||
|
|
||||||
bank_partner = False
|
bank_partner = False
|
||||||
if partner_id:
|
if partner_id:
|
||||||
bank_partner = wiz.statement_line_id.partner_bank_id.partner_id
|
bank_partner = wiz.statement_line_id.partner_bank_id.partner_id
|
||||||
@@ -297,11 +304,16 @@ class banking_transaction_wizard(orm.TransientModel):
|
|||||||
if wiz.statement_line_id:
|
if wiz.statement_line_id:
|
||||||
# delete splits causing an unsplit if this is a split
|
# delete splits causing an unsplit if this is a split
|
||||||
# transaction
|
# transaction
|
||||||
statement_pool.unlink(cr, uid,
|
statement_pool.unlink(
|
||||||
statement_pool.search(cr, uid,
|
cr,
|
||||||
|
uid,
|
||||||
|
statement_pool.search(
|
||||||
|
cr, uid,
|
||||||
[('parent_id', '=', wiz.statement_line_id.id)],
|
[('parent_id', '=', wiz.statement_line_id.id)],
|
||||||
context=context),
|
context=context
|
||||||
context=context)
|
),
|
||||||
|
context=context
|
||||||
|
)
|
||||||
|
|
||||||
if wiz.import_transaction_id:
|
if wiz.import_transaction_id:
|
||||||
wiz.import_transaction_id.clear_and_write()
|
wiz.import_transaction_id.clear_and_write()
|
||||||
@@ -363,8 +375,12 @@ class banking_transaction_wizard(orm.TransientModel):
|
|||||||
'import_transaction_id', 'invoice_ids', string="Matching invoices",
|
'import_transaction_id', 'invoice_ids', string="Matching invoices",
|
||||||
type='many2many', relation='account.invoice'),
|
type='many2many', relation='account.invoice'),
|
||||||
'invoice_id': fields.related(
|
'invoice_id': fields.related(
|
||||||
'import_transaction_id', 'invoice_id', string="Invoice to reconcile",
|
'import_transaction_id',
|
||||||
type='many2one', relation='account.invoice'),
|
'invoice_id',
|
||||||
|
string="Invoice to reconcile",
|
||||||
|
type='many2one',
|
||||||
|
relation='account.invoice',
|
||||||
|
),
|
||||||
'move_line_ids': fields.related(
|
'move_line_ids': fields.related(
|
||||||
'import_transaction_id', 'move_line_ids', string="Entry lines",
|
'import_transaction_id', 'move_line_ids', string="Entry lines",
|
||||||
type='many2many', relation='account.move.line'),
|
type='many2many', relation='account.move.line'),
|
||||||
@@ -372,13 +388,18 @@ class banking_transaction_wizard(orm.TransientModel):
|
|||||||
'import_transaction_id', 'move_line_id', string="Entry line",
|
'import_transaction_id', 'move_line_id', string="Entry line",
|
||||||
type='many2one', relation='account.move.line'),
|
type='many2one', relation='account.move.line'),
|
||||||
'duplicate': fields.related(
|
'duplicate': fields.related(
|
||||||
'import_transaction_id', 'duplicate', string='Flagged as duplicate',
|
'import_transaction_id',
|
||||||
type='boolean'),
|
'duplicate',
|
||||||
|
string='Flagged as duplicate',
|
||||||
|
type='boolean',
|
||||||
|
),
|
||||||
'match_multi': fields.related(
|
'match_multi': fields.related(
|
||||||
'import_transaction_id', 'match_multi',
|
'import_transaction_id', 'match_multi',
|
||||||
type="boolean", string='Multiple matches'),
|
type="boolean", string='Multiple matches'),
|
||||||
'match_type': fields.related(
|
'match_type': fields.related(
|
||||||
'import_transaction_id', 'match_type', type='selection',
|
'import_transaction_id',
|
||||||
|
'match_type',
|
||||||
|
type='selection',
|
||||||
selection=[
|
selection=[
|
||||||
('move', 'Move'),
|
('move', 'Move'),
|
||||||
('invoice', 'Invoice'),
|
('invoice', 'Invoice'),
|
||||||
@@ -389,7 +410,9 @@ class banking_transaction_wizard(orm.TransientModel):
|
|||||||
('payment_manual', 'Payment line (manual)'),
|
('payment_manual', 'Payment line (manual)'),
|
||||||
('payment_order_manual', 'Payment order (manual)'),
|
('payment_order_manual', 'Payment order (manual)'),
|
||||||
],
|
],
|
||||||
string='Match type', readonly=True),
|
string='Match type',
|
||||||
|
readonly=True,
|
||||||
|
),
|
||||||
'manual_invoice_ids': fields.many2many(
|
'manual_invoice_ids': fields.many2many(
|
||||||
'account.invoice',
|
'account.invoice',
|
||||||
'banking_transaction_wizard_account_invoice_rel',
|
'banking_transaction_wizard_account_invoice_rel',
|
||||||
@@ -401,8 +424,17 @@ class banking_transaction_wizard(orm.TransientModel):
|
|||||||
'wizard_id', 'move_line_id', string='Or match one or more entries',
|
'wizard_id', 'move_line_id', string='Or match one or more entries',
|
||||||
domain=[('account_id.reconcile', '=', True),
|
domain=[('account_id.reconcile', '=', True),
|
||||||
('reconcile_id', '=', False)]),
|
('reconcile_id', '=', False)]),
|
||||||
'payment_option': fields.related('import_transaction_id','payment_option', string='Payment Difference', type='selection', required=True,
|
'payment_option': fields.related(
|
||||||
selection=[('without_writeoff', 'Keep Open'),('with_writeoff', 'Reconcile Payment Balance')]),
|
'import_transaction_id',
|
||||||
|
'payment_option',
|
||||||
|
string='Payment Difference',
|
||||||
|
type='selection',
|
||||||
|
required=True,
|
||||||
|
selection=[
|
||||||
|
('without_writeoff', 'Keep Open'),
|
||||||
|
('with_writeoff', 'Reconcile Payment Balance')
|
||||||
|
],
|
||||||
|
),
|
||||||
'writeoff_analytic_id': fields.related(
|
'writeoff_analytic_id': fields.related(
|
||||||
'import_transaction_id', 'writeoff_analytic_id',
|
'import_transaction_id', 'writeoff_analytic_id',
|
||||||
type='many2one', relation='account.analytic.account',
|
type='many2one', relation='account.analytic.account',
|
||||||
@@ -411,9 +443,11 @@ class banking_transaction_wizard(orm.TransientModel):
|
|||||||
'statement_line_id', 'analytic_account_id',
|
'statement_line_id', 'analytic_account_id',
|
||||||
type='many2one', relation='account.analytic.account',
|
type='many2one', relation='account.analytic.account',
|
||||||
string="Analytic Account"),
|
string="Analytic Account"),
|
||||||
'move_currency_amount': fields.related('import_transaction_id','move_currency_amount',
|
'move_currency_amount': fields.related(
|
||||||
type='float', string='Match Currency Amount', readonly=True),
|
'import_transaction_id',
|
||||||
|
'move_currency_amount',
|
||||||
|
type='float',
|
||||||
|
string='Match Currency Amount',
|
||||||
|
readonly=True,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
banking_transaction_wizard()
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
# All Rights Reserved
|
# All Rights Reserved
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU Affero General Public License as published by
|
# it under the terms of the GNU Affero General Public License as published
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
# by the Free Software Foundation, either version 3 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
@@ -32,6 +32,7 @@ __all__ = [
|
|||||||
'create_bank_account',
|
'create_bank_account',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def get_period(pool, cr, uid, date, company, log=None):
|
def get_period(pool, cr, uid, date, company, log=None):
|
||||||
'''
|
'''
|
||||||
Wrapper over account_period.find() to log exceptions of
|
Wrapper over account_period.find() to log exceptions of
|
||||||
@@ -43,7 +44,7 @@ def get_period(pool, cr, uid, date, company, log=None):
|
|||||||
try:
|
try:
|
||||||
period_ids = pool.get('account.period').find(
|
period_ids = pool.get('account.period').find(
|
||||||
cr, uid, dt=date, context=context)
|
cr, uid, dt=date, context=context)
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
if log is None:
|
if log is None:
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
@@ -51,6 +52,7 @@ def get_period(pool, cr, uid, date, company, log=None):
|
|||||||
return False
|
return False
|
||||||
return period_ids[0]
|
return period_ids[0]
|
||||||
|
|
||||||
|
|
||||||
def get_bank_accounts(pool, cr, uid, account_number, log, fail=False):
|
def get_bank_accounts(pool, cr, uid, account_number, log, fail=False):
|
||||||
'''
|
'''
|
||||||
Get the bank account with account number account_number
|
Get the bank account with account number account_number
|
||||||
@@ -72,6 +74,7 @@ def get_bank_accounts(pool, cr, uid, account_number, log, fail=False):
|
|||||||
return []
|
return []
|
||||||
return partner_bank_obj.browse(cr, uid, bank_account_ids)
|
return partner_bank_obj.browse(cr, uid, bank_account_ids)
|
||||||
|
|
||||||
|
|
||||||
def _has_attr(obj, attr):
|
def _has_attr(obj, attr):
|
||||||
# Needed for dangling addresses and a weird exception scheme in
|
# Needed for dangling addresses and a weird exception scheme in
|
||||||
# OpenERP's orm.
|
# OpenERP's orm.
|
||||||
@@ -80,6 +83,7 @@ def _has_attr(obj, attr):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def get_partner(pool, cr, uid, name, address, postal_code, city,
|
def get_partner(pool, cr, uid, name, address, postal_code, city,
|
||||||
country_id, log, context=None):
|
country_id, log, context=None):
|
||||||
'''
|
'''
|
||||||
@@ -115,7 +119,8 @@ def get_partner(pool, cr, uid, name, address, postal_code, city,
|
|||||||
key = name.lower()
|
key = name.lower()
|
||||||
partners = []
|
partners = []
|
||||||
for partner in partner_obj.read(
|
for partner in partner_obj.read(
|
||||||
cr, uid, partner_search_ids, ['name', 'commercial_partner_id'], context=context):
|
cr, uid, partner_search_ids, ['name', 'commercial_partner_id'],
|
||||||
|
context=context):
|
||||||
if (len(partner['name']) > 3 and partner['name'].lower() in key):
|
if (len(partner['name']) > 3 and partner['name'].lower() in key):
|
||||||
partners.append(partner)
|
partners.append(partner)
|
||||||
partners.sort(key=lambda x: len(x['name']), reverse=True)
|
partners.sort(key=lambda x: len(x['name']), reverse=True)
|
||||||
@@ -126,6 +131,7 @@ def get_partner(pool, cr, uid, name, address, postal_code, city,
|
|||||||
'name %(name)s') % {'name': name})
|
'name %(name)s') % {'name': name})
|
||||||
return partner_ids and partner_ids[0] or False
|
return partner_ids and partner_ids[0] or False
|
||||||
|
|
||||||
|
|
||||||
def get_company_bank_account(pool, cr, uid, account_number, currency,
|
def get_company_bank_account(pool, cr, uid, account_number, currency,
|
||||||
company, log):
|
company, log):
|
||||||
'''
|
'''
|
||||||
@@ -139,8 +145,8 @@ def get_company_bank_account(pool, cr, uid, account_number, currency,
|
|||||||
return False
|
return False
|
||||||
elif len(bank_accounts) != 1:
|
elif len(bank_accounts) != 1:
|
||||||
log.append(
|
log.append(
|
||||||
_('More than one bank account was found with the same number %(account_no)s')
|
_('More than one bank account was found with the same number '
|
||||||
% dict(account_no = account_number)
|
'%(account_no)s') % dict(account_no=account_number)
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
if bank_accounts[0].partner_id.id != company.partner_id.id:
|
if bank_accounts[0].partner_id.id != company.partner_id.id:
|
||||||
@@ -189,8 +195,9 @@ def get_company_bank_account(pool, cr, uid, account_number, currency,
|
|||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|
||||||
def get_or_create_bank(pool, cr, uid, bic, online=False, code=None,
|
def get_or_create_bank(pool, cr, uid, bic, online=False, code=None,
|
||||||
name=None):
|
name=None, context=None):
|
||||||
'''
|
'''
|
||||||
Find or create the bank with the provided BIC code.
|
Find or create the bank with the provided BIC code.
|
||||||
When online, the SWIFT database will be consulted in order to
|
When online, the SWIFT database will be consulted in order to
|
||||||
@@ -231,7 +238,9 @@ def get_or_create_bank(pool, cr, uid, bic, online=False, code=None,
|
|||||||
bank_id = False
|
bank_id = False
|
||||||
|
|
||||||
if online:
|
if online:
|
||||||
info, address = bank_obj.online_bank_info(cr, uid, bic, context=context)
|
info, address = bank_obj.online_bank_info(
|
||||||
|
cr, uid, bic, context=context
|
||||||
|
)
|
||||||
if info:
|
if info:
|
||||||
bank_id = bank_obj.create(cr, uid, dict(
|
bank_id = bank_obj.create(cr, uid, dict(
|
||||||
code=info.code,
|
code=info.code,
|
||||||
@@ -248,13 +257,14 @@ def get_or_create_bank(pool, cr, uid, bic, online=False, code=None,
|
|||||||
|
|
||||||
if not online or not bank_id:
|
if not online or not bank_id:
|
||||||
bank_id = bank_obj.create(cr, uid, dict(
|
bank_id = bank_obj.create(cr, uid, dict(
|
||||||
code = info.code or 'UNKNOW',
|
code=info.code or 'UNKNOW', # FIXME: Typo?
|
||||||
name=info.name or _('Unknown Bank'),
|
name=info.name or _('Unknown Bank'),
|
||||||
country=country_id,
|
country=country_id,
|
||||||
bic=bic,
|
bic=bic,
|
||||||
))
|
))
|
||||||
return bank_id, country_id
|
return bank_id, country_id
|
||||||
|
|
||||||
|
|
||||||
def get_country_id(pool, cr, uid, transaction, context=None):
|
def get_country_id(pool, cr, uid, transaction, context=None):
|
||||||
"""
|
"""
|
||||||
Derive a country id from the info on the transaction.
|
Derive a country id from the info on the transaction.
|
||||||
@@ -283,6 +293,7 @@ def get_country_id(pool, cr, uid, transaction, context=None):
|
|||||||
country_id = company.partner_id.country.id
|
country_id = company.partner_id.country.id
|
||||||
return country_id
|
return country_id
|
||||||
|
|
||||||
|
|
||||||
def create_bank_account(pool, cr, uid, partner_id,
|
def create_bank_account(pool, cr, uid, partner_id,
|
||||||
account_number, holder_name, address, city,
|
account_number, holder_name, address, city,
|
||||||
country_id, bic=False,
|
country_id, bic=False,
|
||||||
@@ -325,5 +336,3 @@ def create_bank_account(pool, cr, uid, partner_id,
|
|||||||
# Create bank account and return
|
# Create bank account and return
|
||||||
return pool.get('res.partner.bank').create(
|
return pool.get('res.partner.bank').create(
|
||||||
cr, uid, values, context=context)
|
cr, uid, values, context=context)
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ from openerp.tools.translate import _
|
|||||||
from openerp.addons.account_banking.wizard import banktools
|
from openerp.addons.account_banking.wizard import banktools
|
||||||
import ast
|
import ast
|
||||||
|
|
||||||
|
|
||||||
class link_partner(orm.TransientModel):
|
class link_partner(orm.TransientModel):
|
||||||
_name = 'banking.link_partner'
|
_name = 'banking.link_partner'
|
||||||
_description = 'Link partner'
|
_description = 'Link partner'
|
||||||
@@ -205,5 +206,3 @@ class link_partner(orm.TransientModel):
|
|||||||
'res_id': ids[0],
|
'res_id': ids[0],
|
||||||
'nodestroy': nodestroy,
|
'nodestroy': nodestroy,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user