mirror of
https://github.com/OCA/bank-payment.git
synced 2025-02-02 10:37:31 +02:00
[MERGE] merged HEAD into current feature branch
This commit is contained in:
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_bank_statement_tax
|
||||
#: model:ir.model,name:account_bank_statement_tax.model_account_bank_statement_line
|
||||
|
||||
@@ -13,8 +13,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_bank_statement_tax
|
||||
#: model:ir.model,name:account_bank_statement_tax.model_account_bank_statement_line
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_bank_statement_tax
|
||||
#: model:ir.model,name:account_bank_statement_tax.model_account_bank_statement_line
|
||||
|
||||
@@ -31,5 +31,7 @@ import account_banking
|
||||
import parsers
|
||||
import wizard
|
||||
import res_partner
|
||||
import res_bank
|
||||
import res_partner_bank
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
@@ -26,14 +26,13 @@
|
||||
|
||||
{
|
||||
'name': 'Account Banking',
|
||||
'version': '0.1.136',
|
||||
'version': '0.2',
|
||||
'license': 'AGPL-3',
|
||||
'author': 'Banking addons community',
|
||||
'website': 'https://launchpad.net/banking-addons',
|
||||
'category': 'Banking addons',
|
||||
'depends': [
|
||||
'account_voucher',
|
||||
'account_iban_preserve_domestic',
|
||||
],
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
@@ -47,14 +46,9 @@
|
||||
'js': [
|
||||
'static/src/js/account_banking.js',
|
||||
],
|
||||
'external_dependencies': {
|
||||
'python' : ['BeautifulSoup'],
|
||||
},
|
||||
'description': '''
|
||||
Module to do banking.
|
||||
|
||||
Note: This module is depending on BeautifulSoup.
|
||||
|
||||
This modules tries to combine all current banking import and export
|
||||
schemes. Rationale for this is that it is quite common to have foreign
|
||||
bank account numbers next to national bank account numbers. The current
|
||||
|
||||
@@ -65,14 +65,8 @@ Modifications are extensive:
|
||||
from openerp.osv import orm, fields
|
||||
from openerp.osv.osv import except_osv
|
||||
from openerp.tools.translate import _
|
||||
from openerp import netsvc, SUPERUSER_ID
|
||||
from openerp import netsvc
|
||||
from openerp.addons.decimal_precision import decimal_precision as dp
|
||||
from openerp.addons.account_banking import sepa
|
||||
from openerp.addons.account_banking.wizard.banktools import get_or_create_bank
|
||||
|
||||
def warning(title, message):
|
||||
'''Convenience routine'''
|
||||
return {'warning': {'title': title, 'message': message}}
|
||||
|
||||
|
||||
class account_banking_account_settings(orm.Model):
|
||||
@@ -559,415 +553,6 @@ class account_bank_statement_line(orm.Model):
|
||||
'currency': _get_currency,
|
||||
}
|
||||
|
||||
account_bank_statement_line()
|
||||
|
||||
|
||||
class res_partner_bank(orm.Model):
|
||||
'''
|
||||
This is a hack to circumvent the very limited but widely used base_iban
|
||||
dependency. The usage of __mro__ requires inside information of
|
||||
inheritence. This code is tested and works - it bypasses base_iban
|
||||
altogether. Be sure to use 'super' for inherited classes from here though.
|
||||
|
||||
Extended functionality:
|
||||
1. BBAN and IBAN are considered equal
|
||||
2. Online databases are checked when available
|
||||
3. Banks are created on the fly when using IBAN
|
||||
4. Storage is uppercase, not lowercase
|
||||
5. Presentation is formal IBAN
|
||||
6. BBAN's are generated from IBAN when possible
|
||||
7. In the absence of online databanks, BBAN's are checked on format
|
||||
using IBAN specs.
|
||||
'''
|
||||
_inherit = 'res.partner.bank'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
'''
|
||||
Locate founder (first non inherited class) in inheritance tree.
|
||||
Defaults to super()
|
||||
Algorithm should prevent moving unknown classes between
|
||||
base.res_partner_bank and this module's res_partner_bank.
|
||||
'''
|
||||
self._founder = super(res_partner_bank, self)
|
||||
self._founder.__init__(*args, **kwargs)
|
||||
mro = self.__class__.__mro__
|
||||
for i in range(len(mro)):
|
||||
if mro[i].__module__.startswith('openerp.addons.base.'):
|
||||
self._founder = mro[i]
|
||||
break
|
||||
|
||||
def init(self, cr):
|
||||
'''
|
||||
Update existing iban accounts to comply to new regime
|
||||
'''
|
||||
|
||||
partner_bank_obj = self.pool.get('res.partner.bank')
|
||||
bank_ids = partner_bank_obj.search(
|
||||
cr, SUPERUSER_ID, [('state', '=', 'iban')], limit=0)
|
||||
for bank in partner_bank_obj.read(cr, SUPERUSER_ID, bank_ids):
|
||||
write_vals = {}
|
||||
if bank['state'] == 'iban':
|
||||
iban_acc = sepa.IBAN(bank['acc_number'])
|
||||
if iban_acc.valid:
|
||||
write_vals['acc_number_domestic'] = iban_acc.localized_BBAN
|
||||
write_vals['acc_number'] = str(iban_acc)
|
||||
elif bank['acc_number'] != bank['acc_number'].upper():
|
||||
write_vals['acc_number'] = bank['acc_number'].upper()
|
||||
if write_vals:
|
||||
partner_bank_obj.write(
|
||||
cr, SUPERUSER_ID, bank['id'], write_vals)
|
||||
|
||||
@staticmethod
|
||||
def _correct_IBAN(acc_number):
|
||||
'''
|
||||
Routine to correct IBAN values and deduce localized values when valid.
|
||||
Note: No check on validity IBAN/Country
|
||||
'''
|
||||
iban = sepa.IBAN(acc_number)
|
||||
return (str(iban), iban.localized_BBAN)
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
'''
|
||||
Create dual function IBAN account for SEPA countries
|
||||
'''
|
||||
if vals.get('state') == 'iban':
|
||||
iban = (vals.get('acc_number')
|
||||
or vals.get('acc_number_domestic', False))
|
||||
vals['acc_number'], vals['acc_number_domestic'] = (
|
||||
self._correct_IBAN(iban))
|
||||
return self._founder.create(self, cr, uid, vals, context)
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
'''
|
||||
Create dual function IBAN account for SEPA countries
|
||||
|
||||
Update the domestic account number when the IBAN is
|
||||
written, or clear the domestic number on regular account numbers.
|
||||
'''
|
||||
if ids and isinstance(ids, (int, long)):
|
||||
ids = [ids]
|
||||
for account in self.read(
|
||||
cr, uid, ids, ['state', 'acc_number']):
|
||||
if 'state' in vals or 'acc_number' in vals:
|
||||
account.update(vals)
|
||||
if account['state'] == 'iban':
|
||||
vals['acc_number'], vals['acc_number_domestic'] = (
|
||||
self._correct_IBAN(account['acc_number']))
|
||||
else:
|
||||
vals['acc_number_domestic'] = False
|
||||
self._founder.write(self, cr, uid, account['id'], vals, context)
|
||||
return True
|
||||
|
||||
def search(self, cr, uid, args, *rest, **kwargs):
|
||||
'''
|
||||
Overwrite search, as both acc_number and iban now can be filled, so
|
||||
the original base_iban 'search and search again fuzzy' tactic now can
|
||||
result in doubled findings. Also there is now enough info to search
|
||||
for local accounts when a valid IBAN was supplied.
|
||||
|
||||
Chosen strategy: create complex filter to find all results in just
|
||||
one search
|
||||
'''
|
||||
|
||||
def is_term(arg):
|
||||
'''Flag an arg as term or otherwise'''
|
||||
return isinstance(arg, (list, tuple)) and len(arg) == 3
|
||||
|
||||
def extended_filter_term(term):
|
||||
'''
|
||||
Extend the search criteria in term when appropriate.
|
||||
'''
|
||||
extra_term = None
|
||||
if term[0].lower() == 'acc_number' and term[1] in ('=', '=='):
|
||||
iban = sepa.IBAN(term[2])
|
||||
if iban.valid:
|
||||
# Some countries can't convert to BBAN
|
||||
try:
|
||||
bban = iban.localized_BBAN
|
||||
# Prevent empty search filters
|
||||
if bban:
|
||||
extra_term = ('acc_number_domestic', term[1], bban)
|
||||
except:
|
||||
pass
|
||||
if extra_term:
|
||||
return ['|', term, extra_term]
|
||||
return [term]
|
||||
|
||||
def extended_search_expression(args):
|
||||
'''
|
||||
Extend the search expression in args when appropriate.
|
||||
The expression itself is in reverse polish notation, so recursion
|
||||
is not needed.
|
||||
'''
|
||||
if not args:
|
||||
return []
|
||||
|
||||
all = []
|
||||
if is_term(args[0]) and len(args) > 1:
|
||||
# Classic filter, implicit '&'
|
||||
all += ['&']
|
||||
|
||||
for arg in args:
|
||||
if is_term(arg):
|
||||
all += extended_filter_term(arg)
|
||||
else:
|
||||
all += arg
|
||||
return all
|
||||
|
||||
# Extend search filter
|
||||
newargs = extended_search_expression(args)
|
||||
|
||||
# Original search
|
||||
results = super(res_partner_bank, self).search(
|
||||
cr, uid, newargs, *rest, **kwargs)
|
||||
return results
|
||||
|
||||
def read(
|
||||
self, cr, uid, ids, fields=None, context=None, load='_classic_read'):
|
||||
'''
|
||||
Convert IBAN electronic format to IBAN display format
|
||||
SR 2012-02-19: do we really need this? Fields are converted upon write already.
|
||||
'''
|
||||
if fields and 'state' not in fields:
|
||||
fields.append('state')
|
||||
records = self._founder.read(self, cr, uid, ids, fields, context, load)
|
||||
is_list = True
|
||||
if not isinstance(records, list):
|
||||
records = [records,]
|
||||
is_list = False
|
||||
for record in records:
|
||||
if 'acc_number' in record and record['state'] == 'iban':
|
||||
record['acc_number'] = unicode(sepa.IBAN(record['acc_number']))
|
||||
if is_list:
|
||||
return records
|
||||
return records[0]
|
||||
|
||||
def check_iban(self, cr, uid, ids, context=None):
|
||||
'''
|
||||
Check IBAN number
|
||||
'''
|
||||
for bank_acc in self.browse(cr, uid, ids, context=context):
|
||||
if bank_acc.state == 'iban' and bank_acc.acc_number:
|
||||
iban = sepa.IBAN(bank_acc.acc_number)
|
||||
if not iban.valid:
|
||||
return False
|
||||
return True
|
||||
|
||||
def get_bban_from_iban(self, cr, uid, ids, context=None):
|
||||
'''
|
||||
Return the local bank account number aka BBAN from the IBAN.
|
||||
'''
|
||||
res = {}
|
||||
for record in self.browse(cr, uid, ids, context):
|
||||
if not record.state == 'iban':
|
||||
res[record.id] = False
|
||||
else:
|
||||
iban_acc = sepa.IBAN(record.acc_number)
|
||||
try:
|
||||
res[record.id] = iban_acc.localized_BBAN
|
||||
except NotImplementedError:
|
||||
res[record.id] = False
|
||||
return res
|
||||
|
||||
def onchange_acc_number(
|
||||
self, cr, uid, ids, acc_number, acc_number_domestic,
|
||||
state, partner_id, country_id, context=None):
|
||||
if state == 'iban':
|
||||
return self.onchange_iban(
|
||||
cr, uid, ids, acc_number, acc_number_domestic,
|
||||
state, partner_id, country_id, context=None
|
||||
)
|
||||
else:
|
||||
return self.onchange_domestic(
|
||||
cr, uid, ids, acc_number,
|
||||
partner_id, country_id, context=None
|
||||
)
|
||||
|
||||
def onchange_domestic(
|
||||
self, cr, uid, ids, acc_number,
|
||||
partner_id, country_id, context=None):
|
||||
'''
|
||||
Trigger to find IBAN. When found:
|
||||
1. Reformat BBAN
|
||||
2. Autocomplete bank
|
||||
|
||||
TODO: prevent unnecessary assignment of country_ids and
|
||||
browsing of the country
|
||||
'''
|
||||
if not acc_number:
|
||||
return {}
|
||||
|
||||
values = {}
|
||||
country_obj = self.pool.get('res.country')
|
||||
country_ids = []
|
||||
country = False
|
||||
|
||||
# Pre fill country based on available data. This is just a default
|
||||
# which can be overridden by the user.
|
||||
# 1. Use provided country_id (manually filled)
|
||||
if country_id:
|
||||
country = country_obj.browse(cr, uid, country_id, context=context)
|
||||
country_ids = [country_id]
|
||||
# 2. Use country_id of found bank accounts
|
||||
# This can be usefull when there is no country set in the partners
|
||||
# addresses, but there was a country set in the address for the bank
|
||||
# account itself before this method was triggered.
|
||||
elif ids and len(ids) == 1:
|
||||
partner_bank_obj = self.pool.get('res.partner.bank')
|
||||
partner_bank_id = partner_bank_obj.browse(cr, uid, ids[0], context=context)
|
||||
if partner_bank_id.country_id:
|
||||
country = partner_bank_id.country_id
|
||||
country_ids = [country.id]
|
||||
# 3. Use country_id of default address of partner
|
||||
# The country_id of a bank account is a one time default on creation.
|
||||
# It originates in the same address we are about to check, but
|
||||
# modifications on that address afterwards are not transfered to the
|
||||
# bank account, hence the additional check.
|
||||
elif partner_id:
|
||||
partner_obj = self.pool.get('res.partner')
|
||||
country = partner_obj.browse(cr, uid, partner_id, context=context).country
|
||||
country_ids = country and [country.id] or []
|
||||
# 4. Without any of the above, take the country from the company of
|
||||
# the handling user
|
||||
if not country_ids:
|
||||
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
|
||||
# Try user companies partner (user no longer has address in 6.1)
|
||||
if (user.company_id and
|
||||
user.company_id.partner_id and
|
||||
user.company_id.partner_id.country
|
||||
):
|
||||
country_ids = [user.company_id.partner_id.country.id]
|
||||
else:
|
||||
if (user.company_id and user.company_id.partner_id and
|
||||
user.company_id.partner_id.country):
|
||||
country_ids = [user.company_id.partner_id.country.id]
|
||||
else:
|
||||
# Ok, tried everything, give up and leave it to the user
|
||||
return warning(_('Insufficient data'),
|
||||
_('Insufficient data to select online '
|
||||
'conversion database')
|
||||
)
|
||||
result = {'value': values}
|
||||
# Complete data with online database when available
|
||||
if country_ids:
|
||||
country = country_obj.browse(
|
||||
cr, uid, country_ids[0], context=context)
|
||||
values['country_id'] = country_ids[0]
|
||||
if country and country.code in sepa.IBAN.countries:
|
||||
try:
|
||||
info = sepa.online.account_info(country.code, acc_number)
|
||||
if info:
|
||||
iban_acc = sepa.IBAN(info.iban)
|
||||
if iban_acc.valid:
|
||||
values['acc_number_domestic'] = iban_acc.localized_BBAN
|
||||
values['acc_number'] = unicode(iban_acc)
|
||||
values['state'] = 'iban'
|
||||
bank_id, country_id = get_or_create_bank(
|
||||
self.pool, cr, uid,
|
||||
info.bic or iban_acc.BIC_searchkey,
|
||||
name = info.bank
|
||||
)
|
||||
if country_id:
|
||||
values['country_id'] = country_id
|
||||
values['bank'] = bank_id or False
|
||||
if info.bic:
|
||||
values['bank_bic'] = info.bic
|
||||
else:
|
||||
info = None
|
||||
if info is None:
|
||||
result.update(warning(
|
||||
_('Invalid data'),
|
||||
_('The account number appears to be invalid for %s')
|
||||
% country.name
|
||||
))
|
||||
except NotImplementedError:
|
||||
if country.code in sepa.IBAN.countries:
|
||||
acc_number_fmt = sepa.BBAN(acc_number, country.code)
|
||||
if acc_number_fmt.valid:
|
||||
values['acc_number_domestic'] = str(acc_number_fmt)
|
||||
else:
|
||||
result.update(warning(
|
||||
_('Invalid format'),
|
||||
_('The account number has the wrong format for %s')
|
||||
% country.name
|
||||
))
|
||||
return result
|
||||
|
||||
def onchange_iban(
|
||||
self, cr, uid, ids, acc_number, acc_number_domestic,
|
||||
state, partner_id, country_id, context=None):
|
||||
'''
|
||||
Trigger to verify IBAN. When valid:
|
||||
1. Extract BBAN as local account
|
||||
2. Auto complete bank
|
||||
'''
|
||||
if not acc_number:
|
||||
return {}
|
||||
|
||||
iban_acc = sepa.IBAN(acc_number)
|
||||
if iban_acc.valid:
|
||||
bank_id, country_id = get_or_create_bank(
|
||||
self.pool, cr, uid, iban_acc.BIC_searchkey,
|
||||
code=iban_acc.BIC_searchkey
|
||||
)
|
||||
return {
|
||||
'value': dict(
|
||||
acc_number_domestic = iban_acc.localized_BBAN,
|
||||
acc_number = unicode(iban_acc),
|
||||
country = country_id or False,
|
||||
bank = bank_id or False,
|
||||
)
|
||||
}
|
||||
return warning(_('Invalid IBAN account number!'),
|
||||
_("The IBAN number doesn't seem to be correct")
|
||||
)
|
||||
|
||||
res_partner_bank()
|
||||
|
||||
|
||||
class res_bank(orm.Model):
|
||||
'''
|
||||
Add a on_change trigger to automagically fill bank details from the
|
||||
online SWIFT database. Allow hand filled names to overrule SWIFT names.
|
||||
'''
|
||||
_inherit = 'res.bank'
|
||||
|
||||
def onchange_bic(self, cr, uid, ids, bic, name, context=None):
|
||||
'''
|
||||
Trigger to auto complete other fields.
|
||||
'''
|
||||
if not bic:
|
||||
return {}
|
||||
|
||||
info, address = sepa.online.bank_info(bic)
|
||||
if not info:
|
||||
return {}
|
||||
|
||||
if address and address.country_id:
|
||||
country_id = self.pool.get('res.country').search(
|
||||
cr, uid, [('code','=',address.country_id)]
|
||||
)
|
||||
country_id = country_id and country_id[0] or False
|
||||
else:
|
||||
country_id = False
|
||||
|
||||
return {
|
||||
'value': dict(
|
||||
# Only the first eight positions of BIC are used for bank
|
||||
# transfers, so ditch the rest.
|
||||
bic = info.bic[:8],
|
||||
street = address.street,
|
||||
street2 =
|
||||
address.has_key('street2') and address.street2 or False,
|
||||
zip = address.zip,
|
||||
city = address.city,
|
||||
country = country_id,
|
||||
name = name and name or info.name,
|
||||
)
|
||||
}
|
||||
|
||||
res_bank()
|
||||
|
||||
|
||||
class invoice(orm.Model):
|
||||
'''
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
action="action_account_banking_journals"
|
||||
sequence="20"
|
||||
/>
|
||||
|
||||
|
||||
<!-- Create new view on imported statement files -->
|
||||
<record model="ir.ui.view" id="view_account_banking_imported_file_form">
|
||||
<field name="name">account.banking.imported.file.form</field>
|
||||
@@ -221,7 +221,7 @@
|
||||
</xpath>
|
||||
|
||||
<!-- Add invisible field for identification of import file
|
||||
on bank statements
|
||||
on bank statements
|
||||
-->
|
||||
<field name="balance_end_real" position="after">
|
||||
<field name="banking_id" invisible="True"/>
|
||||
@@ -248,7 +248,10 @@
|
||||
position="after">
|
||||
<field name="partner_bank_id"/>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//field[@name='line_ids']/tree//field[@name='account_id']"
|
||||
position="attributes">
|
||||
<attribute name="attrs">{'readonly': ['|', ('state', '!=', 'draft'), ('match_type', '!=', '')]}</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='line_ids']/tree/field[@name='amount']"
|
||||
position="after">
|
||||
<field name="match_type"/>
|
||||
@@ -286,42 +289,13 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_partner_bank_account_banking_form_2" model="ir.ui.view">
|
||||
<field name="name">res.partner.bank.form.banking-2</field>
|
||||
<field name="model">res.partner.bank</field>
|
||||
<field name="inherit_id" ref="base.view_partner_bank_form"/>
|
||||
<field name="priority" eval="24"/>
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<field name="acc_number" position="attributes">
|
||||
<attribute name="on_change">onchange_acc_number(acc_number, acc_number_domestic, state, partner_id, country_id)</attribute>
|
||||
</field>
|
||||
<field name="acc_number_domestic" position="attributes">
|
||||
<attribute name="on_change">onchange_domestic(acc_number_domestic, partner_id, country_id)</attribute>
|
||||
</field>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Set trigger on BIC in res_bank form -->
|
||||
<record id="view_res_bank_account_banking_form_1" model="ir.ui.view">
|
||||
<field name="name">res.bank.form.banking-1</field>
|
||||
<field name="model">res.bank</field>
|
||||
<field name="inherit_id" ref="base.view_res_bank_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="bic" position="replace">
|
||||
<field name="bic" on_change="onchange_bic(bic, name)"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_bank_statement_line_tree">
|
||||
<field name="name">Bank statement line tree view</field>
|
||||
<field name="model">account.bank.statement.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Statement lines" colors="black:state == 'confirmed';darkmagenta:match_multi == True;crimson:duplicate == True;grey:state=='draft';">
|
||||
<field name="sequence" readonly="1" invisible="1"/>
|
||||
<field name="date" groups="base.group_extended"/>
|
||||
<field name="date"/>
|
||||
<field name="name"/>
|
||||
<field name="ref"/>
|
||||
<field name="partner_id" on_change="onchange_partner_id(partner_id)"/>
|
||||
@@ -336,7 +310,8 @@
|
||||
<field name="partner_bank_id"/>
|
||||
<field name="type" on_change="onchange_type(partner_id, type)"/>
|
||||
<!-- TODO note the references to parent from the statement form view -->
|
||||
<field domain="[('journal_id','=',parent.journal_id)]" name="account_id"/>
|
||||
<field domain="[('journal_id','=',parent.journal_id)]"
|
||||
attrs="{'readonly': ['|', ('state', '!=', 'draft'), ('match_type', '!=', '')]}" name="account_id"/>
|
||||
<field name="analytic_account_id" groups="analytic.group_analytic_accounting" domain="[('company_id', '=', parent.company_id), ('type', '<>', 'view')]"/>
|
||||
<field name="amount"/>
|
||||
<field name="match_type"/>
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking
|
||||
#: field:account.bank.statement.line,reconcile_id:0
|
||||
|
||||
@@ -13,8 +13,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking
|
||||
#: field:account.bank.statement.line,reconcile_id:0
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking
|
||||
#: field:account.bank.statement.line,reconcile_id:0
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking
|
||||
#: field:account.bank.statement.line,reconcile_id:0
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking
|
||||
#: field:account.bank.statement.line,reconcile_id:0
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking
|
||||
#: field:account.bank.statement.line,reconcile_id:0
|
||||
|
||||
@@ -13,8 +13,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking
|
||||
#: field:account.bank.statement.line,reconcile_id:0
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking
|
||||
#: field:account.bank.statement.line,reconcile_id:0
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking
|
||||
#: field:account.bank.statement.line,reconcile_id:0
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking
|
||||
#: field:account.bank.statement.line,reconcile_id:0
|
||||
|
||||
31
account_banking/res_bank.py
Normal file
31
account_banking/res_bank.py
Normal file
@@ -0,0 +1,31 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2011 - 2014 Therp BV (<http://therp.nl>).
|
||||
#
|
||||
# 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 the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from openerp.osv import orm
|
||||
|
||||
|
||||
class ResBank(orm.Model):
|
||||
_inherit = 'res.bank'
|
||||
|
||||
def online_bank_info(self, cr, uid, bic, context=None):
|
||||
"""
|
||||
API hook for legacy online lookup of BICs,
|
||||
to be removed in OpenERP 8.0.
|
||||
"""
|
||||
return False, False
|
||||
101
account_banking/res_partner_bank.py
Normal file
101
account_banking/res_partner_bank.py
Normal file
@@ -0,0 +1,101 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
|
||||
# (C) 2011 - 2014 Therp BV (<http://therp.nl>).
|
||||
#
|
||||
# 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 the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from openerp.osv import orm
|
||||
from openerp.addons.account_banking import sepa
|
||||
|
||||
|
||||
class ResPartnerBank(orm.Model):
|
||||
_inherit = 'res.partner.bank'
|
||||
|
||||
def online_account_info(
|
||||
self, cr, uid, country_code, acc_number, context=None):
|
||||
"""
|
||||
API hook for legacy online lookup of account info,
|
||||
to be removed in OpenERP 8.0.
|
||||
"""
|
||||
return False
|
||||
|
||||
def search(self, cr, uid, args, *rest, **kwargs):
|
||||
"""
|
||||
When a complete IBAN is searched, also search for its BBAN
|
||||
if we have the domestic column. Disregard spaces
|
||||
when comparing IBANs.
|
||||
"""
|
||||
|
||||
def is_term(arg):
|
||||
'''Flag an arg as term or otherwise'''
|
||||
return isinstance(arg, (list, tuple)) and len(arg) == 3
|
||||
|
||||
def extended_filter_term(term):
|
||||
'''
|
||||
Extend the search criteria in term when appropriate.
|
||||
'''
|
||||
result = [term]
|
||||
extra_terms = []
|
||||
if term[0].lower() == 'acc_number' and term[1] in ('=', '=='):
|
||||
iban = sepa.IBAN(term[2])
|
||||
if iban.valid:
|
||||
# Disregard spaces when comparing IBANs
|
||||
cr.execute(
|
||||
"""
|
||||
SELECT id FROM res_partner_bank
|
||||
WHERE replace(acc_number, ' ', '') = %s
|
||||
""", (term[2].replace(' ', ''),))
|
||||
ids = [row[0] for row in cr.fetchall()]
|
||||
result = [('id', 'in', ids)]
|
||||
|
||||
if 'acc_number_domestic' in self._columns:
|
||||
bban = iban.localized_BBAN
|
||||
# Prevent empty search filters
|
||||
if bban:
|
||||
extra_terms.append(
|
||||
('acc_number_domestic', term[1], bban))
|
||||
for extra_term in extra_terms:
|
||||
result = ['|'] + result + [extra_term]
|
||||
return result
|
||||
|
||||
def extended_search_expression(args):
|
||||
'''
|
||||
Extend the search expression in args when appropriate.
|
||||
The expression itself is in reverse polish notation, so recursion
|
||||
is not needed.
|
||||
'''
|
||||
if not args:
|
||||
return []
|
||||
|
||||
result = []
|
||||
if is_term(args[0]) and len(args) > 1:
|
||||
# Classic filter, implicit '&'
|
||||
result += ['&']
|
||||
|
||||
for arg in args:
|
||||
if is_term(arg):
|
||||
result += extended_filter_term(arg)
|
||||
else:
|
||||
result += arg
|
||||
return result
|
||||
|
||||
# Extend search filter
|
||||
newargs = extended_search_expression(args)
|
||||
|
||||
# Original search
|
||||
return super(ResPartnerBank, self).search(
|
||||
cr, uid, newargs, *rest, **kwargs)
|
||||
@@ -19,6 +19,5 @@
|
||||
#
|
||||
##############################################################################
|
||||
import iban
|
||||
import online
|
||||
IBAN = iban.IBAN
|
||||
BBAN = iban.BBAN
|
||||
|
||||
@@ -408,10 +408,9 @@ class IBAN(str):
|
||||
Localized format of local or Basic Bank Account Number, aka BBAN
|
||||
'''
|
||||
if self.countrycode == 'TR':
|
||||
raise NotImplementedError, (
|
||||
'The Turkish BBAN requires information that is not in the '
|
||||
'IBAN number.'
|
||||
)
|
||||
# The Turkish BBAN requires information that is not in the
|
||||
# IBAN number.
|
||||
return False
|
||||
return self.BBAN_format.BBAN(self)
|
||||
|
||||
@property
|
||||
|
||||
@@ -63,12 +63,6 @@ def get_bank_accounts(pool, cr, uid, account_number, log, fail=False):
|
||||
bank_account_ids = partner_bank_obj.search(cr, uid, [
|
||||
('acc_number', '=', account_number)
|
||||
])
|
||||
if not bank_account_ids:
|
||||
# SR 2012-02-19 does the search() override in res_partner_bank
|
||||
# provides this result on the previous query?
|
||||
bank_account_ids = partner_bank_obj.search(cr, uid, [
|
||||
('acc_number_domestic', '=', account_number)
|
||||
])
|
||||
if not bank_account_ids:
|
||||
if not fail:
|
||||
log.append(
|
||||
@@ -237,7 +231,7 @@ def get_or_create_bank(pool, cr, uid, bic, online=False, code=None,
|
||||
bank_id = False
|
||||
|
||||
if online:
|
||||
info, address = sepa.online.bank_info(bic)
|
||||
info, address = bank_obj.online_bank_info(cr, uid, bic, context=context)
|
||||
if info:
|
||||
bank_id = bank_obj.create(cr, uid, dict(
|
||||
code = info.code,
|
||||
@@ -301,7 +295,6 @@ def create_bank_account(pool, cr, uid, partner_id,
|
||||
owner_name = holder_name,
|
||||
country_id = country_id,
|
||||
)
|
||||
bankcode = None
|
||||
|
||||
# Are we dealing with IBAN?
|
||||
iban = sepa.IBAN(account_number)
|
||||
@@ -309,23 +302,20 @@ def create_bank_account(pool, cr, uid, partner_id,
|
||||
# Take as much info as possible from IBAN
|
||||
values.state = 'iban'
|
||||
values.acc_number = str(iban)
|
||||
values.acc_number_domestic = iban.BBAN
|
||||
bankcode = iban.bankcode + iban.countrycode
|
||||
else:
|
||||
# No, try to convert to IBAN
|
||||
values.state = 'bank'
|
||||
values.acc_number = values.acc_number_domestic = account_number
|
||||
values.acc_number = account_number
|
||||
|
||||
if country_id:
|
||||
country_code = pool.get('res.country').read(
|
||||
cr, uid, country_id, ['code'], context=context)['code']
|
||||
if country_code in sepa.IBAN.countries:
|
||||
account_info = sepa.online.account_info(
|
||||
country_code, values.acc_number)
|
||||
account_info = pool['res.partner.bank'].online_account_info(
|
||||
cr, uid, country_code, values.acc_number, context=context)
|
||||
if account_info:
|
||||
values.acc_number = iban = account_info.iban
|
||||
values.state = 'iban'
|
||||
bankcode = account_info.code
|
||||
bic = account_info.bic
|
||||
|
||||
if bic:
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
|
||||
from lxml import etree
|
||||
from openerp.osv.orm import except_orm
|
||||
from account_banking.parsers import models
|
||||
from account_banking.parsers.convert import str2date
|
||||
from openerp.addons.account_banking.parsers import models
|
||||
from openerp.addons.account_banking.parsers.convert import str2date
|
||||
|
||||
bt = models.mem_bank_transaction
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking_fi_patu
|
||||
#: code:addons/account_banking_fi_patu/patu.py:115
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking_fi_patu
|
||||
#: code:addons/account_banking_fi_patu/patu.py:115
|
||||
|
||||
3
account_banking_iban_lookup/__init__.py
Normal file
3
account_banking_iban_lookup/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from . import online
|
||||
from . import urlagent
|
||||
from . import model
|
||||
52
account_banking_iban_lookup/__openerp__.py
Normal file
52
account_banking_iban_lookup/__openerp__.py
Normal file
@@ -0,0 +1,52 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
|
||||
# (C) 2011 - 2014 Therp BV (<http://therp.nl>).
|
||||
#
|
||||
# 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 the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
{
|
||||
'name': 'Banking Addons - Iban lookup (legacy)',
|
||||
'version': '0.1',
|
||||
'license': 'AGPL-3',
|
||||
'author': 'Banking addons community',
|
||||
'website': 'https://launchpad.net/banking-addons',
|
||||
'category': 'Banking addons',
|
||||
'depends': [
|
||||
'account_banking',
|
||||
'account_iban_preserve_domestic',
|
||||
],
|
||||
'data': [
|
||||
'view/res_bank.xml',
|
||||
'view/res_partner_bank.xml',
|
||||
],
|
||||
'external_dependencies': {
|
||||
'python': ['BeautifulSoup'],
|
||||
},
|
||||
'description': '''
|
||||
This addons contains the legacy infrastructure for autocompletion of IBANs
|
||||
and BBANs.
|
||||
|
||||
The autocompletion was implemented for Dutch IBANs, but as it turns out
|
||||
the online database that it consults does not get updated. As a result,
|
||||
the autocompletion will come up with outdated IBANs and BICs.
|
||||
|
||||
This module is deprecated and will be dropped in OpenERP 8.0.
|
||||
''',
|
||||
'auto_install': False,
|
||||
'installable': True,
|
||||
}
|
||||
2
account_banking_iban_lookup/model/__init__.py
Normal file
2
account_banking_iban_lookup/model/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from . import res_bank
|
||||
from . import res_partner_bank
|
||||
63
account_banking_iban_lookup/model/res_bank.py
Normal file
63
account_banking_iban_lookup/model/res_bank.py
Normal file
@@ -0,0 +1,63 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
|
||||
# (C) 2011 - 2014 Therp BV (<http://therp.nl>).
|
||||
#
|
||||
# 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 the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from openerp.osv import orm
|
||||
from openerp.addons.account_banking_iban_lookup import online
|
||||
|
||||
|
||||
class ResBank(orm.Model):
|
||||
_inherit = 'res.bank'
|
||||
|
||||
def online_bank_info(self, cr, uid, bic, context=None):
|
||||
"""
|
||||
Overwrite existing API hook from account_banking
|
||||
"""
|
||||
return online.bank_info(bic)
|
||||
|
||||
def onchange_bic(
|
||||
self, cr, uid, ids, bic, name, context=None):
|
||||
|
||||
if not bic:
|
||||
return {}
|
||||
|
||||
info, address = online.bank_info(bic)
|
||||
if not info:
|
||||
return {}
|
||||
|
||||
if address and address.country_id:
|
||||
country_ids = self.pool.get('res.country').search(
|
||||
cr, uid, [('code', '=', address.country_id)])
|
||||
country_id = country_ids[0] if country_ids else False
|
||||
else:
|
||||
country_id = False
|
||||
|
||||
return {
|
||||
'value': dict(
|
||||
# Only the first eight positions of BIC are used for bank
|
||||
# transfers, so ditch the rest.
|
||||
bic=info.bic[:8],
|
||||
street=address.street,
|
||||
street2=address.get('street2', False),
|
||||
zip=address.zip,
|
||||
city=address.city,
|
||||
country=country_id,
|
||||
name=name or info.name,
|
||||
)
|
||||
}
|
||||
271
account_banking_iban_lookup/model/res_partner_bank.py
Normal file
271
account_banking_iban_lookup/model/res_partner_bank.py
Normal file
@@ -0,0 +1,271 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
|
||||
# (C) 2011 - 2014 Therp BV (<http://therp.nl>).
|
||||
#
|
||||
# All other contributions are (C) by their respective contributors
|
||||
#
|
||||
# All Rights Reserved
|
||||
#
|
||||
# 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 the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.osv import orm
|
||||
from openerp.tools.translate import _
|
||||
from openerp.addons.account_banking_iban_lookup import online
|
||||
from openerp.addons.account_banking import sepa
|
||||
from openerp.addons.account_banking.wizard.banktools import get_or_create_bank
|
||||
|
||||
|
||||
def warning(title, message):
|
||||
'''Convenience routine'''
|
||||
return {'warning': {'title': title, 'message': message}}
|
||||
|
||||
|
||||
class res_partner_bank(orm.Model):
|
||||
'''
|
||||
Extended functionality:
|
||||
1. BBAN and IBAN are considered equal
|
||||
2. Online lookup when an API is available (providing NL in this module)
|
||||
3. Banks are created on the fly when using IBAN + online
|
||||
4. IBAN formatting
|
||||
5. BBAN's are generated from IBAN when possible
|
||||
'''
|
||||
_inherit = 'res.partner.bank'
|
||||
|
||||
def init(self, cr):
|
||||
'''
|
||||
Update existing iban accounts to comply to new regime
|
||||
'''
|
||||
|
||||
partner_bank_obj = self.pool.get('res.partner.bank')
|
||||
bank_ids = partner_bank_obj.search(
|
||||
cr, SUPERUSER_ID, [('state', '=', 'iban')], limit=0)
|
||||
for bank in partner_bank_obj.read(cr, SUPERUSER_ID, bank_ids):
|
||||
write_vals = {}
|
||||
if bank['state'] == 'iban':
|
||||
iban_acc = sepa.IBAN(bank['acc_number'])
|
||||
if iban_acc.valid:
|
||||
write_vals['acc_number_domestic'] = iban_acc.localized_BBAN
|
||||
write_vals['acc_number'] = str(iban_acc)
|
||||
elif bank['acc_number'] != bank['acc_number'].upper():
|
||||
write_vals['acc_number'] = bank['acc_number'].upper()
|
||||
if write_vals:
|
||||
partner_bank_obj.write(
|
||||
cr, SUPERUSER_ID, bank['id'], write_vals)
|
||||
|
||||
@staticmethod
|
||||
def _correct_IBAN(acc_number):
|
||||
'''
|
||||
Routine to correct IBAN values and deduce localized values when valid.
|
||||
Note: No check on validity IBAN/Country
|
||||
'''
|
||||
iban = sepa.IBAN(acc_number)
|
||||
return (str(iban), iban.localized_BBAN)
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
'''
|
||||
Create dual function IBAN account for SEPA countries
|
||||
'''
|
||||
if vals.get('state') == 'iban':
|
||||
iban = (vals.get('acc_number')
|
||||
or vals.get('acc_number_domestic', False))
|
||||
vals['acc_number'], vals['acc_number_domestic'] = (
|
||||
self._correct_IBAN(iban))
|
||||
return super(res_partner_bank, self).create(
|
||||
cr, uid, vals, context)
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
'''
|
||||
Create dual function IBAN account for SEPA countries
|
||||
|
||||
Update the domestic account number when the IBAN is
|
||||
written, or clear the domestic number on regular account numbers.
|
||||
'''
|
||||
if ids and isinstance(ids, (int, long)):
|
||||
ids = [ids]
|
||||
for account in self.read(
|
||||
cr, uid, ids, ['state', 'acc_number']):
|
||||
if 'state' in vals or 'acc_number' in vals:
|
||||
account.update(vals)
|
||||
if account['state'] == 'iban':
|
||||
vals['acc_number'], vals['acc_number_domestic'] = (
|
||||
self._correct_IBAN(account['acc_number']))
|
||||
else:
|
||||
vals['acc_number_domestic'] = False
|
||||
super(res_partner_bank, self).write(
|
||||
cr, uid, account['id'], vals, context)
|
||||
return True
|
||||
|
||||
def onchange_acc_number(
|
||||
self, cr, uid, ids, acc_number, acc_number_domestic,
|
||||
state, partner_id, country_id, context=None):
|
||||
if state == 'iban':
|
||||
return self.onchange_iban(
|
||||
cr, uid, ids, acc_number, acc_number_domestic,
|
||||
state, partner_id, country_id, context=None
|
||||
)
|
||||
else:
|
||||
return self.onchange_domestic(
|
||||
cr, uid, ids, acc_number,
|
||||
partner_id, country_id, context=None
|
||||
)
|
||||
|
||||
def onchange_domestic(
|
||||
self, cr, uid, ids, acc_number,
|
||||
partner_id, country_id, context=None):
|
||||
'''
|
||||
Trigger to find IBAN. When found:
|
||||
1. Reformat BBAN
|
||||
2. Autocomplete bank
|
||||
|
||||
TODO: prevent unnecessary assignment of country_ids and
|
||||
browsing of the country
|
||||
'''
|
||||
if not acc_number:
|
||||
return {}
|
||||
|
||||
values = {}
|
||||
country_obj = self.pool.get('res.country')
|
||||
country_ids = []
|
||||
country = False
|
||||
|
||||
# Pre fill country based on available data. This is just a default
|
||||
# which can be overridden by the user.
|
||||
# 1. Use provided country_id (manually filled)
|
||||
if country_id:
|
||||
country = country_obj.browse(cr, uid, country_id, context=context)
|
||||
country_ids = [country_id]
|
||||
# 2. Use country_id of found bank accounts
|
||||
# This can be usefull when there is no country set in the partners
|
||||
# addresses, but there was a country set in the address for the bank
|
||||
# account itself before this method was triggered.
|
||||
elif ids and len(ids) == 1:
|
||||
partner_bank_obj = self.pool.get('res.partner.bank')
|
||||
partner_bank_id = partner_bank_obj.browse(
|
||||
cr, uid, ids[0], context=context)
|
||||
if partner_bank_id.country_id:
|
||||
country = partner_bank_id.country_id
|
||||
country_ids = [country.id]
|
||||
# 3. Use country_id of default address of partner
|
||||
# The country_id of a bank account is a one time default on creation.
|
||||
# It originates in the same address we are about to check, but
|
||||
# modifications on that address afterwards are not transfered to the
|
||||
# bank account, hence the additional check.
|
||||
elif partner_id:
|
||||
partner_obj = self.pool.get('res.partner')
|
||||
country = partner_obj.browse(
|
||||
cr, uid, partner_id, context=context).country
|
||||
country_ids = country and [country.id] or []
|
||||
# 4. Without any of the above, take the country from the company of
|
||||
# the handling user
|
||||
if not country_ids:
|
||||
user = self.pool.get('res.users').browse(
|
||||
cr, uid, uid, context=context)
|
||||
# Try user companies partner (user no longer has address in 6.1)
|
||||
if (user.company_id and
|
||||
user.company_id.partner_id and
|
||||
user.company_id.partner_id.country):
|
||||
country_ids = [user.company_id.partner_id.country.id]
|
||||
else:
|
||||
if (user.company_id and user.company_id.partner_id and
|
||||
user.company_id.partner_id.country):
|
||||
country_ids = [user.company_id.partner_id.country.id]
|
||||
else:
|
||||
# Ok, tried everything, give up and leave it to the user
|
||||
return warning(_('Insufficient data'),
|
||||
_('Insufficient data to select online '
|
||||
'conversion database')
|
||||
)
|
||||
result = {'value': values}
|
||||
# Complete data with online database when available
|
||||
if country_ids:
|
||||
country = country_obj.browse(
|
||||
cr, uid, country_ids[0], context=context)
|
||||
values['country_id'] = country_ids[0]
|
||||
if country and country.code in sepa.IBAN.countries:
|
||||
info = online.account_info(country.code, acc_number)
|
||||
if info:
|
||||
iban_acc = sepa.IBAN(info.iban)
|
||||
if iban_acc.valid:
|
||||
values['acc_number_domestic'] = iban_acc.localized_BBAN
|
||||
values['acc_number'] = unicode(iban_acc)
|
||||
values['state'] = 'iban'
|
||||
bank_id, country_id = get_or_create_bank(
|
||||
self.pool, cr, uid,
|
||||
info.bic or iban_acc.BIC_searchkey,
|
||||
name=info.bank)
|
||||
if country_id:
|
||||
values['country_id'] = country_id
|
||||
values['bank'] = bank_id or False
|
||||
if info.bic:
|
||||
values['bank_bic'] = info.bic
|
||||
else:
|
||||
info = None
|
||||
if info is None:
|
||||
result.update(warning(
|
||||
_('Invalid data'),
|
||||
_('The account number appears to be invalid for %s')
|
||||
% country.name
|
||||
))
|
||||
if info is False:
|
||||
if country.code in sepa.IBAN.countries:
|
||||
acc_number_fmt = sepa.BBAN(acc_number, country.code)
|
||||
if acc_number_fmt.valid:
|
||||
values['acc_number_domestic'] = str(acc_number_fmt)
|
||||
else:
|
||||
result.update(warning(
|
||||
_('Invalid format'),
|
||||
_('The account number has the wrong format for %s')
|
||||
% country.name
|
||||
))
|
||||
return result
|
||||
|
||||
def onchange_iban(
|
||||
self, cr, uid, ids, acc_number, acc_number_domestic,
|
||||
state, partner_id, country_id, context=None):
|
||||
'''
|
||||
Trigger to verify IBAN. When valid:
|
||||
1. Extract BBAN as local account
|
||||
2. Auto complete bank
|
||||
'''
|
||||
if not acc_number:
|
||||
return {}
|
||||
|
||||
iban_acc = sepa.IBAN(acc_number)
|
||||
if iban_acc.valid:
|
||||
bank_id, country_id = get_or_create_bank(
|
||||
self.pool, cr, uid, iban_acc.BIC_searchkey,
|
||||
code=iban_acc.BIC_searchkey
|
||||
)
|
||||
return {
|
||||
'value': dict(
|
||||
acc_number_domestic=iban_acc.localized_BBAN,
|
||||
acc_number=unicode(iban_acc),
|
||||
country=country_id or False,
|
||||
bank=bank_id or False,
|
||||
)
|
||||
}
|
||||
return warning(
|
||||
_('Invalid IBAN account number!'),
|
||||
_("The IBAN number doesn't seem to be correct"))
|
||||
|
||||
def online_account_info(
|
||||
self, cr, uid, country_code, acc_number, context=None):
|
||||
"""
|
||||
Overwrite API hook from account_banking
|
||||
"""
|
||||
return online.account_info(country_code, acc_number)
|
||||
@@ -1,4 +1,4 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
|
||||
@@ -26,7 +26,7 @@ import re
|
||||
import urllib, urllib2
|
||||
from BeautifulSoup import BeautifulSoup
|
||||
from openerp.addons.account_banking.sepa import postalcode
|
||||
from openerp.addons.account_banking.sepa.urlagent import URLAgent, SoupForm
|
||||
from openerp.addons.account_banking_iban_lookup.urlagent import URLAgent, SoupForm
|
||||
from openerp.addons.account_banking.sepa.iban import IBAN
|
||||
from openerp.addons.account_banking.struct import struct
|
||||
|
||||
@@ -157,13 +157,13 @@ def account_info(iso, bank_acc):
|
||||
'''
|
||||
Consult the online database for this country to obtain its
|
||||
corresponding IBAN/BIC number and other info available.
|
||||
Raise NotImplemented when no information service could be found.
|
||||
Returns None when a service was found but something went wrong.
|
||||
Returns a dictionary (struct) of information when found.
|
||||
Returns a dictionary (struct) of information when found, or
|
||||
False when not implemented.
|
||||
'''
|
||||
if iso in _account_info:
|
||||
return _account_info[iso](bank_acc)
|
||||
raise NotImplementedError()
|
||||
return False
|
||||
|
||||
bic_re = re.compile("[^']+'([^']*)'.*")
|
||||
SWIFTlink = 'http://www.swift.com/bsl/freequery.do'
|
||||
@@ -25,7 +25,6 @@ forms and to parse the results back in. It is heavily based on BeautifulSoup.
|
||||
'''
|
||||
|
||||
import urllib
|
||||
from BeautifulSoup import BeautifulSoup
|
||||
|
||||
__all__ = ['urlsplit', 'urljoin', 'pathbase', 'urlbase', 'SoupForm',
|
||||
'URLAgent'
|
||||
15
account_banking_iban_lookup/view/res_bank.xml
Normal file
15
account_banking_iban_lookup/view/res_bank.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="view_res_bank_account_banking_form_1" model="ir.ui.view">
|
||||
<field name="name">Add BIC lookup to bank form</field>
|
||||
<field name="model">res.bank</field>
|
||||
<field name="inherit_id" ref="base.view_res_bank_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="bic" position="replace">
|
||||
<field name="bic" on_change="onchange_bic(bic, name)"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
23
account_banking_iban_lookup/view/res_partner_bank.xml
Normal file
23
account_banking_iban_lookup/view/res_partner_bank.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="view_partner_bank_account_banking_form_2" model="ir.ui.view">
|
||||
<field name="name">Add autocompletion methods to partner bank form</field>
|
||||
<field name="model">res.partner.bank</field>
|
||||
<field name="inherit_id" ref="base.view_partner_bank_form"/>
|
||||
<field name="priority" eval="24"/>
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<field name="acc_number" position="attributes">
|
||||
<attribute name="on_change">onchange_acc_number(acc_number, acc_number_domestic, state, partner_id, country_id)</attribute>
|
||||
</field>
|
||||
<field name="acc_number_domestic" position="attributes">
|
||||
<attribute name="on_change">onchange_domestic(acc_number_domestic, partner_id, country_id)</attribute>
|
||||
</field>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
|
||||
21
account_banking_mt940/__init__.py
Normal file
21
account_banking_mt940/__init__.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# This module copyright (C) 2014 Therp BV (<http://therp.nl>).
|
||||
#
|
||||
# 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 the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from . import mt940
|
||||
53
account_banking_mt940/__openerp__.py
Normal file
53
account_banking_mt940/__openerp__.py
Normal file
@@ -0,0 +1,53 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# This module copyright (C) 2014 Therp BV (<http://therp.nl>).
|
||||
#
|
||||
# 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 the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
{
|
||||
"name" : "MT940",
|
||||
"version" : "1.0",
|
||||
"author" : "Therp BV",
|
||||
"complexity": "expert",
|
||||
"description": """
|
||||
This addon provides a generic parser for MT940 files. Given that MT940 is a
|
||||
non-open non-standard of pure evil in the way that every bank cooks up its own
|
||||
interpretation of it, this addon alone won't help you much. It is rather
|
||||
intended to be used by other addons to implement the dialect specific to a
|
||||
certain bank.
|
||||
|
||||
See account_banking_nl_ing_mt940 for an example on how to use it.
|
||||
""",
|
||||
"category" : "Dependency",
|
||||
"depends" : [
|
||||
'account_banking',
|
||||
],
|
||||
"data" : [
|
||||
],
|
||||
"js": [
|
||||
],
|
||||
"css": [
|
||||
],
|
||||
"qweb": [
|
||||
],
|
||||
"auto_install": False,
|
||||
"installable": True,
|
||||
"application": False,
|
||||
"external_dependencies" : {
|
||||
'python' : [],
|
||||
},
|
||||
}
|
||||
217
account_banking_mt940/mt940.py
Normal file
217
account_banking_mt940/mt940.py
Normal file
@@ -0,0 +1,217 @@
|
||||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# This module copyright (C) 2014 Therp BV (<http://therp.nl>).
|
||||
#
|
||||
# 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 the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
"""
|
||||
Parser for MT940 format files
|
||||
"""
|
||||
import re
|
||||
import datetime
|
||||
import logging
|
||||
try:
|
||||
from openerp.addons.account_banking.parsers.models import\
|
||||
mem_bank_statement, mem_bank_transaction
|
||||
from openerp.tools.misc import DEFAULT_SERVER_DATE_FORMAT
|
||||
except ImportError:
|
||||
#this allows us to run this file standalone, see __main__ at the end
|
||||
class mem_bank_statement:
|
||||
def __init__(self):
|
||||
self.transactions = []
|
||||
class mem_bank_transaction:
|
||||
pass
|
||||
DEFAULT_SERVER_DATE_FORMAT = "%Y-%m-%d"
|
||||
|
||||
class MT940(object):
|
||||
'''Inherit this class in your account_banking.parsers.models.parser,
|
||||
define functions to handle the tags you need to handle and adjust static
|
||||
variables as needed.
|
||||
|
||||
Note that order matters: You need to do your_parser(MT940, parser), not the
|
||||
other way around!
|
||||
|
||||
At least, you should override handle_tag_61 and handle_tag_86. Don't forget
|
||||
to call super.
|
||||
handle_tag_* functions receive the remainder of the the line (that is,
|
||||
without ':XX:') and are supposed to write into self.current_transaction'''
|
||||
|
||||
header_lines = 3
|
||||
'''One file can contain multiple statements, each with its own poorly
|
||||
documented header. For now, the best thing to do seems to skip that'''
|
||||
|
||||
footer_regex = '^-}$'
|
||||
footer_regex = '^-XXX$'
|
||||
'The line that denotes end of message, we need to create a new statement'
|
||||
|
||||
tag_regex = '^:[0-9]{2}[A-Z]*:'
|
||||
'The beginning of a record, should be anchored to beginning of the line'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(MT940, self).__init__(*args, **kwargs)
|
||||
'state variables'
|
||||
self.current_statement = None
|
||||
'type account_banking.parsers.models.mem_bank_statement'
|
||||
self.current_transaction = None
|
||||
'type account_banking.parsers.models.mem_bank_transaction'
|
||||
self.statements = []
|
||||
'parsed statements up to now'
|
||||
|
||||
def parse(self, cr, data):
|
||||
'implements account_banking.parsers.models.parser.parse()'
|
||||
iterator = data.split('\r\n').__iter__()
|
||||
line = None
|
||||
record_line = ''
|
||||
try:
|
||||
while True:
|
||||
if not self.current_statement:
|
||||
self.handle_header(cr, line, iterator)
|
||||
line = iterator.next()
|
||||
if not self.is_tag(cr, line) and not self.is_footer(cr, line):
|
||||
record_line = self.append_continuation_line(
|
||||
cr, record_line, line)
|
||||
continue
|
||||
if record_line:
|
||||
self.handle_record(cr, record_line)
|
||||
if self.is_footer(cr, line):
|
||||
self.handle_footer(cr, line, iterator)
|
||||
record_line = ''
|
||||
continue
|
||||
record_line = line
|
||||
except StopIteration:
|
||||
pass
|
||||
return self.statements
|
||||
|
||||
def append_continuation_line(self, cr, line, continuation_line):
|
||||
'''append a continuation line for a multiline record.
|
||||
Override and do data cleanups as necessary.'''
|
||||
return line + continuation_line
|
||||
|
||||
def create_statement(self, cr):
|
||||
'''create a mem_bank_statement - override if you need a custom
|
||||
implementation'''
|
||||
return mem_bank_statement()
|
||||
|
||||
def create_transaction(self, cr):
|
||||
'''create a mem_bank_transaction - override if you need a custom
|
||||
implementation'''
|
||||
return mem_bank_transaction()
|
||||
|
||||
def is_footer(self, cr, line):
|
||||
'''determine if a line is the footer of a statement'''
|
||||
return line and bool(re.match(self.footer_regex, line))
|
||||
|
||||
def is_tag(self, cr, line):
|
||||
'''determine if a line has a tag'''
|
||||
return line and bool(re.match(self.tag_regex, line))
|
||||
|
||||
def handle_header(self, cr, line, iterator):
|
||||
'''skip header lines, create current statement'''
|
||||
for i in range(self.header_lines):
|
||||
iterator.next()
|
||||
self.current_statement = self.create_statement(cr)
|
||||
|
||||
def handle_footer(self, cr, line, iterator):
|
||||
'''add current statement to list, reset state'''
|
||||
self.statements.append(self.current_statement)
|
||||
self.current_statement = None
|
||||
|
||||
def handle_record(self, cr, line):
|
||||
'''find a function to handle the record represented by line'''
|
||||
tag_match = re.match(self.tag_regex, line)
|
||||
tag = tag_match.group(0).strip(':')
|
||||
if not hasattr(self, 'handle_tag_%s' % tag):
|
||||
logging.error('Unknown tag %s', tag)
|
||||
logging.error(line)
|
||||
return
|
||||
handler = getattr(self, 'handle_tag_%s' % tag)
|
||||
handler(cr, line[tag_match.end():])
|
||||
|
||||
def handle_tag_20(self, cr, data):
|
||||
'''ignore reference number'''
|
||||
pass
|
||||
|
||||
def handle_tag_25(self, cr, data):
|
||||
'''get account owner information'''
|
||||
self.current_statement.local_account = data
|
||||
|
||||
def handle_tag_28C(self, cr, data):
|
||||
'''get sequence number _within_this_batch_ - this alone
|
||||
doesn't provide a unique id!'''
|
||||
self.current_statement.id = data
|
||||
|
||||
def handle_tag_60F(self, cr, data):
|
||||
'''get start balance and currency'''
|
||||
self.current_statement.local_currency = data[7:10]
|
||||
self.current_statement.date = str2date(data[1:7])
|
||||
self.current_statement.start_balance = \
|
||||
(1 if data[0] == 'C' else -1) * str2float(data[10:])
|
||||
self.current_statement.id = '%s/%s' % (
|
||||
self.current_statement.date.strftime('%Y'),
|
||||
self.current_statement.id)
|
||||
|
||||
def handle_tag_62F(self, cr, data):
|
||||
'''get ending balance'''
|
||||
self.current_statement.end_balance = \
|
||||
(1 if data[0] == 'C' else -1) * str2float(data[10:])
|
||||
|
||||
def handle_tag_64(self, cr, data):
|
||||
'''get current balance in currency'''
|
||||
pass
|
||||
|
||||
def handle_tag_65(self, cr, data):
|
||||
'''get future balance in currency'''
|
||||
pass
|
||||
|
||||
def handle_tag_61(self, cr, data):
|
||||
'''get transaction values'''
|
||||
transaction = self.create_transaction(cr)
|
||||
self.current_statement.transactions.append(transaction)
|
||||
self.current_transaction = transaction
|
||||
transaction.execution_date = str2date(data[:6])
|
||||
transaction.effective_date = str2date(data[:6])
|
||||
'...and the rest already is highly bank dependent'
|
||||
|
||||
def handle_tag_86(self, cr, data):
|
||||
'''details for previous transaction, here most differences between
|
||||
banks occur'''
|
||||
pass
|
||||
|
||||
'utility functions'
|
||||
def str2date(string, fmt='%y%m%d'):
|
||||
return datetime.datetime.strptime(string, fmt)
|
||||
|
||||
def str2float(string):
|
||||
return float(string.replace(',', '.'))
|
||||
|
||||
'testing'
|
||||
def main(filename):
|
||||
parser = MT940()
|
||||
parser.parse(None, open(filename, 'r').read())
|
||||
for statement in parser.statements:
|
||||
print '''statement found for %(local_account)s at %(date)s
|
||||
with %(local_currency)s%(start_balance)s to %(end_balance)s
|
||||
''' % statement.__dict__
|
||||
for transaction in statement.transactions:
|
||||
print '''
|
||||
transaction on %(execution_date)s''' % transaction.__dict__
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
main(*sys.argv[1:])
|
||||
BIN
account_banking_mt940/static/src/img/icon.png
Normal file
BIN
account_banking_mt940/static/src/img/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
@@ -13,8 +13,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking_nl_abnamro
|
||||
#: code:addons/account_banking_nl_abnamro/abnamro.py:122
|
||||
|
||||
@@ -13,8 +13,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking_nl_abnamro
|
||||
#: code:addons/account_banking_nl_abnamro/abnamro.py:122
|
||||
|
||||
@@ -24,7 +24,10 @@
|
||||
'author': 'EduSense BV',
|
||||
'website': 'http://www.edusense.nl',
|
||||
'category': 'Account Banking',
|
||||
'depends': ['account_banking_payment'],
|
||||
'depends': [
|
||||
'account_banking_payment',
|
||||
'account_iban_preserve_domestic',
|
||||
],
|
||||
'data': [
|
||||
'account_banking_nl_clieop.xml',
|
||||
'wizard/export_clieop_view.xml',
|
||||
|
||||
@@ -14,7 +14,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking_nl_girotel
|
||||
#: code:addons/account_banking_nl_girotel/girotel.py:325
|
||||
|
||||
@@ -13,8 +13,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking_nl_girotel
|
||||
#: code:addons/account_banking_nl_girotel/girotel.py:325
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking_nl_girotel
|
||||
#: code:addons/account_banking_nl_girotel/girotel.py:325
|
||||
|
||||
@@ -13,8 +13,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking_nl_ing
|
||||
#: code:addons/account_banking_nl_ing/ing.py:257
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking_nl_ing
|
||||
#: code:addons/account_banking_nl_ing/ing.py:257
|
||||
|
||||
21
account_banking_nl_ing_mt940/__init__.py
Normal file
21
account_banking_nl_ing_mt940/__init__.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# This module copyright (C) 2014 Therp BV (<http://therp.nl>).
|
||||
#
|
||||
# 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 the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from . import account_banking_nl_ing_mt940
|
||||
48
account_banking_nl_ing_mt940/__openerp__.py
Normal file
48
account_banking_nl_ing_mt940/__openerp__.py
Normal file
@@ -0,0 +1,48 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# This module copyright (C) 2014 Therp BV (<http://therp.nl>).
|
||||
#
|
||||
# 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 the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
{
|
||||
"name" : "MT940 import for Dutch ING",
|
||||
"version" : "1.0",
|
||||
"author" : "Therp BV",
|
||||
"complexity": "normal",
|
||||
"description": """
|
||||
This addon imports the structured MT940 format as offered by the Dutch ING
|
||||
bank.
|
||||
""",
|
||||
"category" : "Account Banking",
|
||||
"depends" : [
|
||||
'account_banking_mt940',
|
||||
],
|
||||
"data" : [
|
||||
],
|
||||
"js": [
|
||||
],
|
||||
"css": [
|
||||
],
|
||||
"qweb": [
|
||||
],
|
||||
"auto_install": False,
|
||||
"installable": True,
|
||||
"application": False,
|
||||
"external_dependencies" : {
|
||||
'python' : [],
|
||||
},
|
||||
}
|
||||
100
account_banking_nl_ing_mt940/account_banking_nl_ing_mt940.py
Normal file
100
account_banking_nl_ing_mt940/account_banking_nl_ing_mt940.py
Normal file
@@ -0,0 +1,100 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# This module copyright (C) 2014 Therp BV (<http://therp.nl>).
|
||||
#
|
||||
# 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 the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
import re
|
||||
from openerp.tools.translate import _
|
||||
from openerp.addons.account_banking.parsers.models import parser,\
|
||||
mem_bank_transaction
|
||||
from openerp.addons.account_banking_mt940.mt940 import MT940, str2float
|
||||
|
||||
|
||||
class transaction(mem_bank_transaction):
|
||||
def is_valid(self):
|
||||
'''allow transactions without remote account'''
|
||||
return bool(self.execution_date) and bool(self.transferred_amount)
|
||||
|
||||
class IngMT940Parser(MT940, parser):
|
||||
name = _('ING MT940 (structured)')
|
||||
country_code = 'NL'
|
||||
code = 'INT_MT940_STRUC'
|
||||
|
||||
tag_61_regex = re.compile(
|
||||
'^(?P<date>\d{6})(?P<sign>[CD])(?P<amount>\d+,\d{2})N(?P<type>\d{3})'
|
||||
'(?P<reference>\w{1,16})')
|
||||
|
||||
def create_transaction(self, cr):
|
||||
return transaction()
|
||||
|
||||
def handle_tag_60F(self, cr, data):
|
||||
super(IngMT940Parser, self).handle_tag_60F(cr, data)
|
||||
self.current_statement.id = '%s-%s' % (
|
||||
self.get_unique_account_identifier(
|
||||
cr, self.current_statement.local_account),
|
||||
self.current_statement.id)
|
||||
|
||||
def handle_tag_61(self, cr, data):
|
||||
super(IngMT940Parser, self).handle_tag_61(cr, data)
|
||||
parsed_data = self.tag_61_regex.match(data).groupdict()
|
||||
self.current_transaction.transferred_amount = \
|
||||
(-1 if parsed_data['sign'] == 'D' else 1) * str2float(
|
||||
parsed_data['amount'])
|
||||
self.current_transaction.reference = parsed_data['reference']
|
||||
|
||||
def handle_tag_86(self, cr, data):
|
||||
if not self.current_transaction:
|
||||
return
|
||||
super(IngMT940Parser, self).handle_tag_86(cr, data)
|
||||
codewords = ['RTRN', 'BENM', 'ORDP', 'CSID', 'BUSP', 'MARF', 'EREF',
|
||||
'PREF', 'REMI', 'ID', 'PURP', 'ULTB', 'ULTD']
|
||||
subfields = {}
|
||||
current_codeword = None
|
||||
for word in data.split('/'):
|
||||
if not word and not current_codeword:
|
||||
continue
|
||||
if word in codewords:
|
||||
current_codeword = word
|
||||
subfields[current_codeword] = []
|
||||
continue
|
||||
subfields[current_codeword].append(word)
|
||||
|
||||
if 'BENM' in subfields:
|
||||
self.current_transaction.remote_account = subfields['BENM'][0]
|
||||
self.current_transaction.remote_bank_bic = subfields['BENM'][1]
|
||||
self.current_transaction.remote_owner = subfields['BENM'][2]
|
||||
self.current_transaction.remote_owner_city = subfields['BENM'][3]
|
||||
|
||||
if 'ORDP' in subfields:
|
||||
self.current_transaction.remote_account = subfields['ORDP'][0]
|
||||
self.current_transaction.remote_bank_bic = subfields['ORDP'][1]
|
||||
self.current_transaction.remote_owner = subfields['ORDP'][2]
|
||||
self.current_transaction.remote_owner_city = subfields['ORDP'][3]
|
||||
|
||||
if 'REMI' in subfields:
|
||||
self.current_transaction.message = '/'.join(
|
||||
filter(lambda x: bool(x), subfields['REMI']))
|
||||
|
||||
if self.current_transaction.reference in subfields:
|
||||
self.current_transaction.reference = ''.join(
|
||||
subfields[self.current_transaction.reference])
|
||||
|
||||
if not subfields:
|
||||
self.current_transaction.message = data
|
||||
|
||||
self.current_transaction = None
|
||||
BIN
account_banking_nl_ing_mt940/static/src/img/icon.png
Normal file
BIN
account_banking_nl_ing_mt940/static/src/img/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
@@ -20,7 +20,7 @@
|
||||
##############################################################################
|
||||
|
||||
{
|
||||
'name': 'Account Banking',
|
||||
'name': 'Account Banking - NL Multibank import',
|
||||
'version': '0.62',
|
||||
'license': 'AGPL-3',
|
||||
'author': 'EduSense BV',
|
||||
|
||||
@@ -13,8 +13,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking_nl_multibank
|
||||
#: code:addons/account_banking_nl_multibank/multibank.py:292
|
||||
|
||||
@@ -13,8 +13,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking_nl_multibank
|
||||
#: code:addons/account_banking_nl_multibank/multibank.py:292
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking_nl_multibank
|
||||
#: code:addons/account_banking_nl_multibank/multibank.py:292
|
||||
|
||||
@@ -13,8 +13,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking_nl_triodos
|
||||
#: code:addons/account_banking_nl_triodos/triodos.py:183
|
||||
|
||||
@@ -13,8 +13,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking_nl_triodos
|
||||
#: code:addons/account_banking_nl_triodos/triodos.py:183
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking_nl_triodos
|
||||
#: code:addons/account_banking_nl_triodos/triodos.py:183
|
||||
|
||||
@@ -45,8 +45,12 @@ class res_company(orm.Model):
|
||||
company = self.browse(cr, uid, company_id, context=context)
|
||||
company_vat = company.vat
|
||||
party_identifier = False
|
||||
if company_vat and company_vat[0:2].upper() in ['BE']:
|
||||
party_identifier = company_vat[2:].replace(' ', '')
|
||||
if company_vat:
|
||||
country_code = company_vat[0:2].upper()
|
||||
if country_code == 'BE':
|
||||
party_identifier = company_vat[2:].replace(' ', '')
|
||||
elif country_code == 'ES':
|
||||
party_identifier = company.sepa_creditor_identifier
|
||||
return party_identifier
|
||||
|
||||
def _initiating_party_issuer_default(self, cr, uid, context=None):
|
||||
|
||||
@@ -13,8 +13,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking_pain_base
|
||||
#: field:res.company,initiating_party_issuer:0
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-12 06:27+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking_pain_base
|
||||
#: field:res.company,initiating_party_issuer:0
|
||||
|
||||
@@ -13,8 +13,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking_partner_journal_account
|
||||
#: model:ir.model,name:account_banking_partner_journal_account.model_res_partner
|
||||
|
||||
@@ -13,8 +13,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking_payment
|
||||
#: model:ir.model,name:account_banking_payment.model_payment_order_create
|
||||
|
||||
@@ -116,14 +116,26 @@ class banking_import_transaction(orm.Model):
|
||||
'''
|
||||
# TODO: Not sure what side effects are created when payments are done
|
||||
# for credited customer invoices, which will be matched later on too.
|
||||
|
||||
def bank_match(account, partner_bank):
|
||||
"""
|
||||
Returns whether a given account number is equivalent to a
|
||||
partner bank in the database. We simply call the search method,
|
||||
which checks IBAN, domestic and disregards from spaces in IBANs.
|
||||
|
||||
:param account: string representation of a bank account number
|
||||
:param partner_bank: browse record of model res.partner.bank
|
||||
"""
|
||||
return partner_bank.id in self.pool['res.partner.bank'].search(
|
||||
cr, uid, [('acc_number', '=', account)])
|
||||
|
||||
digits = dp.get_precision('Account')(cr)[1]
|
||||
candidates = [
|
||||
x for x in payment_lines
|
||||
if x.communication == trans.reference
|
||||
and round(x.amount, digits) == -round(
|
||||
trans.statement_line_id.amount, digits)
|
||||
and trans.remote_account in (x.bank_id.acc_number,
|
||||
x.bank_id.acc_number_domestic)
|
||||
line for line in payment_lines
|
||||
if (line.communication == trans.reference
|
||||
and round(line.amount, digits) == -round(
|
||||
trans.statement_line_id.amount, digits)
|
||||
and bank_match(trans.remote_account, line.bank_id))
|
||||
]
|
||||
if len(candidates) == 1:
|
||||
candidate = candidates[0]
|
||||
|
||||
@@ -13,8 +13,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking_payment_export
|
||||
#: help:payment.mode.type,name:0
|
||||
|
||||
@@ -187,6 +187,7 @@ class payment_order_create(orm.TransientModel):
|
||||
or line.journal_id.currency.id
|
||||
or line.journal_id.company_id.currency_id.id),
|
||||
}, context=context)
|
||||
# Force reload of payment order view as a workaround for lp:1155525
|
||||
return {'name': _('Payment Orders'),
|
||||
'context': context,
|
||||
'view_type': 'form',
|
||||
|
||||
@@ -13,8 +13,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking_sepa_credit_transfer
|
||||
#: selection:banking.export.sepa.wizard,state:0
|
||||
|
||||
@@ -13,8 +13,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking_sepa_credit_transfer
|
||||
#: selection:banking.export.sepa.wizard,state:0
|
||||
|
||||
@@ -13,8 +13,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: model:mail.message.subtype,description:account_banking_sepa_direct_debit.mandate_valid
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-12 06:27+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_banking_sepa_direct_debit
|
||||
#: model:mail.message.subtype,description:account_banking_sepa_direct_debit.mandate_valid
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_direct_debit
|
||||
#: model:account.payment.term,note:account_direct_debit.payment_term_direct_debit
|
||||
|
||||
@@ -13,8 +13,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_iban_preserve_domestic
|
||||
#: field:res.partner.bank,acc_number_domestic:0
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: account_iban_preserve_domestic
|
||||
#: field:res.partner.bank,acc_number_domestic:0
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import payment_order
|
||||
from . import payment_order
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
##############################################################################
|
||||
{
|
||||
'name': 'Account Payment Invoice Selection Shortcut',
|
||||
'version': '6.1.1.134',
|
||||
'version': '1.134',
|
||||
'license': 'AGPL-3',
|
||||
'author': 'Smile / Therp BV',
|
||||
'website': 'https://launchpad.net/banking-addons',
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import orm
|
||||
from openerp.osv import orm
|
||||
|
||||
class payment_order_create(orm.TransientModel):
|
||||
_inherit = 'payment.order.create'
|
||||
|
||||
@@ -13,8 +13,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: base_iban_bic_not_required
|
||||
#: constraint:res.partner.bank:0
|
||||
|
||||
@@ -14,8 +14,8 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-11 06:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-21 06:57+0000\n"
|
||||
"X-Generator: Launchpad (build 16967)\n"
|
||||
|
||||
#. module: base_iban_bic_not_required
|
||||
#: constraint:res.partner.bank:0
|
||||
|
||||
Reference in New Issue
Block a user