[FIX] After removing module account_iban_preserve_domestic, also remove

all other modules dependant on this one, or other references to
    domestic account number.
This commit is contained in:
Ronald Portier
2014-10-29 15:08:46 +01:00
parent 8b15aef945
commit 34052f7a4f
30 changed files with 2 additions and 3462 deletions

View File

@@ -35,9 +35,7 @@ class ResPartnerBank(orm.Model):
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.
Disregard spaces when comparing IBANs.
"""
def is_term(arg):
@@ -61,13 +59,6 @@ class ResPartnerBank(orm.Model):
""", (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

View File

@@ -1,3 +0,0 @@
from . import online
from . import urlagent
from . import model

View File

@@ -1,52 +0,0 @@
# -*- 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': False,
}

View File

@@ -1,2 +0,0 @@
from . import res_bank
from . import res_partner_bank

View File

@@ -1,63 +0,0 @@
# -*- 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,
)
}

View File

@@ -1,271 +0,0 @@
# -*- 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)

View File

@@ -1,298 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
# 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/>.
#
##############################################################################
'''
This module provides online bank databases for conversion between BBAN and
IBAN numbers and for consulting.
'''
import re
import urllib
import urllib2
from BeautifulSoup import BeautifulSoup
from openerp.addons.account_banking.sepa import postalcode
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
__all__ = [
'account_info',
'bank_info',
]
IBANlink_NL = 'http://www.ibannl.org/iban_check.php'
IBANlink_BE = 'http://www.ibanbic.be/'
def get_iban_bic_NL(bank_acc):
'''
Consult the Dutch online banking database to check both the account number
and the bank to which it belongs. Will not work offline, is limited to
banks operating in the Netherlands and will only convert Dutch local
account numbers.
'''
# sanity check: Dutch 7 scheme uses ING as sink and online convertor
# calculates accounts, so no need to consult it - calculate our own
number = bank_acc.lstrip('0')
if len(number) <= 7:
iban = IBAN.create(BBAN='INGB' + number.rjust(10, '0'),
countrycode='NL'
)
return struct(
iban=iban.replace(' ', ''),
account=iban.BBAN[4:],
bic='INGBNL2A',
code='INGBNL',
bank='ING Bank N.V.',
country_id='NL',
)
data = urllib.urlencode(dict(number=number, method='POST'))
request = urllib2.Request(IBANlink_NL, data)
response = urllib2.urlopen(request)
soup = BeautifulSoup(response)
result = struct()
attr = None
for _pass, td in enumerate(soup.findAll('td')):
if _pass % 2 == 1:
result[attr] = unicode(td.find('font').contents[0])
else:
attr = td.find('strong').contents[0][:4].strip().lower()
if result:
result.account = bank_acc
result.country_id = result.bic[4:6]
# Nationalized bank code
result.code = result.bic[:6]
# All Dutch banks use generic channels
# result.bic += 'XXX'
return result
return None
def get_iban_bic_BE(bank_acc):
'''
Consult the Belgian online database to check both account number and the
bank it belongs to. Will not work offline, is limited to banks operating
in Belgium and will only convert Belgian local account numbers.
'''
def contents(soup, attr):
return soup.find('input', {
'id': 'textbox%s' % attr
}).get('value').strip()
if not bank_acc.strip():
return None
# Get empty form with hidden validators
agent = URLAgent()
request = agent.open(IBANlink_BE)
# Isolate form and fill it in
soup = BeautifulSoup(request)
form = SoupForm(soup.find('form', {'id': 'form1'}))
form['textboxBBAN'] = bank_acc.strip()
form['Convert'] = 'Convert Number'
# Submit the form
response = agent.submit(form)
# Parse the results
soup = BeautifulSoup(response)
iban = contents(soup, 'IBAN')
if iban.lower().startswith('not a'):
return None
result = struct(iban=iban.replace(' ', ''))
result.bic = contents(soup, 'BIC').replace(' ', '')
result.bank = contents(soup, 'BankName')
# Add substracts
result.account = bank_acc
result.country_id = result.bic[4:6]
result.code = result.bic[:6]
return result
def BBAN_is_IBAN(bank_acc):
'''
Intelligent copy, valid for SEPA members who switched to SEPA from old
standards before SEPA actually started.
'''
if isinstance(bank_acc, IBAN):
iban_acc = bank_acc
else:
iban_acc = IBAN(bank_acc)
return struct(
iban=str(iban_acc),
account=str(bank_acc),
country_id=iban_acc.countrycode,
code=iban_acc.BIC_searchkey,
# Note: BIC can not be constructed here!
bic=False,
bank=False,
)
_account_info = {
# TODO: Add more online data banks
'BA': BBAN_is_IBAN,
'BE': get_iban_bic_BE,
'BG': BBAN_is_IBAN,
'NL': get_iban_bic_NL,
'LV': BBAN_is_IBAN,
'LT': BBAN_is_IBAN,
'LU': BBAN_is_IBAN,
'MU': BBAN_is_IBAN,
'SM': BBAN_is_IBAN,
}
def account_info(iso, bank_acc):
'''
Consult the online database for this country to obtain its
corresponding IBAN/BIC number and other info available.
Returns None when a service was found but something went wrong.
Returns a dictionary (struct) of information when found, or
False when not implemented.
'''
if iso in _account_info:
return _account_info[iso](bank_acc)
return False
bic_re = re.compile("[^']+'([^']*)'.*")
SWIFTlink = 'http://www.swift.com/bsl/freequery.do'
def bank_info(bic):
'''
Consult the free online SWIFT service to obtain the name and address of a
bank. This call may take several seconds to complete, due to the number of
requests to make. In total three HTTP requests are made per function call.
In theory one request could be stripped, but the SWIFT terms of use prevent
automated usage, so user like behavior is required.
Update January 2012: Always return None, as the SWIFT page to retrieve the
information does no longer exist.
If demand exists, maybe bite the bullet and integrate with a paid web
service such as http://www.iban-rechner.de.
lp914922 additionally suggests to make online lookup optional.
'''
return None, None
def harvest(soup):
retval = struct()
for trsoup in soup('tr'):
for stage, tdsoup in enumerate(trsoup('td')):
if stage == 0:
attr = tdsoup.contents[0].strip().replace(' ', '_')
elif stage == 2:
if tdsoup.contents:
retval[attr] = tdsoup.contents[0].strip()
else:
retval[attr] = ''
return retval
# Get form
agent = URLAgent()
request = agent.open(SWIFTlink)
soup = BeautifulSoup(request)
# Parse request form. As this form is intertwined with a table, use the
# parent as root to search for form elements.
form = SoupForm(soup.find('form', {'id': 'frmFreeSearch1'}), parent=True)
# Fill form fields
form['selected_bic'] = bic
# Get intermediate response
response = agent.submit(form)
# Parse response
soup = BeautifulSoup(response)
# Isolate the full 11 BIC - there may be more, but we only use the first
bic_button = soup.find('a', {'class': 'bigbuttonblack'})
if not bic_button:
return None, None
# Overwrite the location with 'any' ('XXX') to narrow the results to one
# or less.
# Assume this regexp will never fail...
full_bic = bic_re.match(bic_button.get('href')).groups()[0][:8] + 'XXX'
# Get the detail form
form = SoupForm(soup.find('form', {'id': 'frmDetail'}))
# Fill detail fields
form['selected_bic11'] = full_bic
# Get final response
response = agent.submit(form)
soup = BeautifulSoup(response)
# Now parse the results
tables = soup.find('div', {'id': 'Middle'}).findAll('table')
if not tables:
return None, None
tablesoup = tables[2]('table')
if not tablesoup:
return None, None
codes = harvest(tablesoup[0])
if not codes:
return None, None
bankinfo = struct(
# Most banks use the first four chars of the BIC as an identifier for
# their 'virtual bank' accross the world, containing all national
# banks world wide using the same name.
# The concatenation with the two character country code is for most
# national branches sufficient as a unique identifier.
code=full_bic[:6],
bic=full_bic,
name=codes.Institution_name,
)
address = harvest(tablesoup[1])
# The address in the SWIFT database includes a postal code.
# We need to split it into two fields...
if not address.Zip_Code:
if address.Location:
iso, address.Zip_Code, address.Location = \
postalcode.split(address.Location, full_bic[4:6])
bankaddress = struct(
street=address.Address.title(),
city=address.Location.strip().title(),
zip=address.Zip_Code,
country=address.Country.title(),
country_id=full_bic[4:6],
)
if ' ' in bankaddress.street:
bankaddress.street, bankaddress.street2 = [
x.strip() for x in bankaddress.street.split(' ', 1)
]
else:
bankaddress.street2 = ''
return bankinfo, bankaddress

View File

@@ -1,236 +0,0 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
# 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/>.
#
##############################################################################
'''
This module presents a browser like class to browse the web, fill and submit
forms and to parse the results back in. It is heavily based on BeautifulSoup.
'''
import urllib
__all__ = ['urlsplit', 'urljoin', 'pathbase', 'urlbase', 'SoupForm',
'URLAgent'
]
def urlsplit(url):
'''
Split an URL into scheme, host and path parts. Helper function.
'''
if ':' in url:
parts = url.split(':')
scheme = parts[0]
url = ':'.join(parts[1:])
else:
scheme = ''
host, path = urllib.splithost(url)
return (scheme, host, path)
def urljoin(scheme, host, path, args=None):
'''
Join scheme, host and path to a full URL.
Optional: add urlencoded args.
Helper function.
'''
url = '%s://%s/%s' % (scheme or 'http', host, path)
if args:
url += '?%s' % urllib.urlencode(args)
return url
def pathbase(path):
'''
Return the base for the path in order to satisfy relative paths.
Helper function.
'''
if path and '/' in path:
return path[:path.rfind('/') + 1]
return path
def urlbase(url):
'''
Return the base URL for url in order to satisfy relative paths.
Helper function.
'''
scheme, host, path = urlsplit(url)
return urljoin(scheme, host, pathbase(path))
class SoupForm(object):
'''
A SoupForm is a representation of a HTML Form in BeautifulSoup terms.
It has a helper method __setitem__ to set or replace form fields.
It gets initiated from a soup object.
'''
def __init__(self, soup, parent=False):
'''
Parse the form attributes and fields from the soup. Make sure
to get the action right. When parent is set, then the parent
element is used as anchor for the search for form elements.
'''
self._extra_args = {}
self.soup = soup
# Make sure to use base strings, not unicode
for attr, value in soup.attrMap.iteritems():
setattr(self, str(attr), str(value))
# Set right anchor point for harvest
if parent:
self.soup = soup.parent
# Harvest input elements.
self._args = {}
for item in self.soup.findAll('input'):
# Make sure to initialize to '' to avoid None strings to appear
# during submit
self._args[str(item.get('name'))] = item.get('value') or ''
# Harvest url
self.scheme, self.host, self.action = urlsplit(self.action)
self.action, args = urllib.splitquery(self.action)
if args:
args = args.split('&')
for arg in args:
attr, value = urllib.splitvalue(arg)
self._extra_args[str(attr)] = value or ''
def __setitem__(self, name, value, force=False):
'''
Set values for the form attributes when present
'''
if name in self._args or force:
self._extra_args[name] = value
else:
raise AttributeError('No such attribute: %s' % name)
def __getitem__(self, name):
'''
Get a value. Set values overrule got values.
'''
if name in self._extra_args:
return self._extra_args[name]
if name in self._args:
return self._args[name]
raise AttributeError('No attribute with name "%s" found.' % name)
def set(self, **kwargs):
'''
Forcibly sets an attribute to the supplied value, even if it is not
part of the parsed form.
Can be useful in situations where forms are deliberatly chunked in
order to make it difficult to automate form requests, e.g. the
SWIFT BIC service, which uses JavaScript to add form attributes to an
emtpy base form.
'''
for name, value in kwargs.iteritems():
self.__setitem__(name, value, force=True)
def args(self):
'''
Return the field values as attributes, updated with the modified
values.
'''
args = dict(self._args)
args.update(self._extra_args)
return args
class URLAgent(object):
'''
Assistent object to ease HTTP(S) requests.
Mimics a normal web browser.
'''
def __init__(self, *args, **kwargs):
super(URLAgent, self).__init__(*args, **kwargs)
self._extra_headers = {}
self.headers = {
'User-Agent': (
'Mozilla/5.0 (X11; U; Linux x86_64; us; rv:1.9.0.10) '
'Gecko/2009042708 Fedora/3.0.10-1.fc9 Firefox/3.0.10'),
'Accept': (
'text/html,application/xhtml+xml,application/xml;'
'q=0.9,*/*;q=0.8'),
'Accept-Language': 'en-us;q=1.0',
'Accept-Charset': 'UTF-8,*',
'Cache-Control': 'max-age=0'
}
def add_headers(self, **kwargs):
self._extra_headers.update(**kwargs)
def open(self, URL):
'''
Open a URL and set some vars based on the used URL.
Meant to be used on a single server.
'''
self.scheme, self.host, self.path = urlsplit(URL)
# Create agent
self.agent = urllib.URLopener()
# Remove additional and unasked for User-Agent header
# Some servers choke on multiple User-Agent headers
self.agent.addheaders = []
headers = self._extra_headers.copy()
headers.update(self.headers)
for key, value in headers.iteritems():
self.agent.addheader(key, value)
# Open webpage
request = self.agent.open(URL)
# Get and set cookies for next actions
attributes = request.info()
if 'set-cookie' in attributes:
self.agent.addheader('Cookie', attributes['set-cookie'])
# Add referer
self.agent.addheader('Referer', URL)
# Return request
return request
def submit(self, form, action=None, method=None, **kwargs):
'''
Submit a SoupForm. Override missing attributes in action from our own
initial URL.
'''
if action:
scheme, host, path = urlsplit(action)
else:
scheme = form.scheme or self.scheme
host = form.host or self.host
action = form.action
method = (method or form.method).lower()
args = urllib.urlencode(kwargs or form.args())
if not action.startswith('/'):
# Relative path
action = pathbase(self.path) + action
function = getattr(self.agent, 'open_%s' % scheme)
if method == 'post':
return function('//%s%s' % (host, action), args)
return function('//%s%s?%s' % (host, action, args))

View File

@@ -1,15 +0,0 @@
<?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>

View File

@@ -1,23 +0,0 @@
<?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>

View File

@@ -1,29 +0,0 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
# All Rights Reserved
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract EduSense BV
#
# 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 wizard
from . import account_banking_nl_clieop

View File

@@ -1,44 +0,0 @@
##############################################################################
#
# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
# 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/>.
#
##############################################################################
{
'name': 'Account Banking NL ClieOp',
'version': '0.92',
'license': 'AGPL-3',
'author': 'EduSense BV',
'website': 'http://www.edusense.nl',
'category': 'Account Banking',
'depends': [
'account_banking_payment',
'account_iban_preserve_domestic',
],
'data': [
'account_banking_nl_clieop.xml',
'wizard/export_clieop_view.xml',
'data/banking_export_clieop.xml',
'security/ir.model.access.csv',
],
'description': '''
Module to export payment orders in ClieOp format.
ClieOp format is used by Dutch banks to batch national bank transfers.
This module uses the account_banking logic.
''',
'installable': False,
}

View File

@@ -1,97 +0,0 @@
##############################################################################
#
# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
# (C) 2011 - 2013 Therp BV (<http://therp.nl>).
# 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.osv import orm, fields
from openerp.tools.translate import _
class clieop_export(orm.Model):
'''ClieOp3 Export'''
_name = 'banking.export.clieop'
_description = __doc__
_rec_name = 'identification'
_columns = {
'payment_order_ids': fields.many2many(
'payment.order',
'account_payment_order_clieop_rel',
'banking_export_clieop_id', 'account_order_id',
'Payment Orders',
readonly=True),
'testcode':
fields.selection([('T', _('Yes')), ('P', _('No'))],
'Test Run', readonly=True),
'daynumber':
fields.integer('ClieOp Transaction nr of the Day', readonly=True),
'duplicates':
fields.integer('Number of Duplicates', readonly=True),
'prefered_date':
fields.date('Prefered Processing Date', readonly=True),
'no_transactions':
fields.integer('Number of Transactions', readonly=True),
'check_no_accounts':
fields.char('Check Number Accounts', size=5, readonly=True),
'total_amount':
fields.float('Total Amount', readonly=True),
'identification':
fields.char('Identification', size=6, readonly=True, select=True),
'filetype':
fields.selection([
('CREDBET', 'Payment Batch'),
('SALARIS', 'Salary Payment Batch'),
('INCASSO', 'Direct Debit Batch'),
], 'File Type', size=7, readonly=True, select=True),
'date_generated':
fields.date('Generation Date', readonly=True, select=True),
'file':
fields.binary('ClieOp File', readonly=True,),
'filename': fields.char(
'File Name', size=32,
),
'state':
fields.selection([
('draft', 'Draft'),
('sent', 'Sent'),
('done', 'Reconciled'),
], 'State', readonly=True),
}
def get_daynr(self, cr, uid, context=None):
'''
Return highest day number
'''
last = 1
last_ids = self.search(cr, uid, [
('date_generated', '=', fields.date.context_today(
self, cr, uid, context)),
], context=context)
if last_ids:
last = 1 + max([x['daynumber'] for x in self.read(
cr, uid, last_ids, ['daynumber'], context=context)]
)
return last
_defaults = {
'date_generated': fields.date.context_today,
'duplicates': 1,
'state': 'draft',
'daynumber': get_daynr,
}

View File

@@ -1,85 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) EduSense BV <http://www.edusense.nl>
All rights reserved.
The licence is in the file __terp__.py
-->
<openerp>
<data>
<!-- Make new view on ClieOp3 Exports -->
<record id="view_banking_export_clieop_form" model="ir.ui.view">
<field name="name">account.banking.export.clieop.form</field>
<field name="model">banking.export.clieop</field>
<field name="arch" type="xml">
<form string="Client Opdrachten Export">
<notebook>
<page string="General Information">
<field name="filetype" />
<field name="identification" />
<separator string="ClieOp Information" colspan="4" />
<field name="total_amount" />
<field name="check_no_accounts" />
<field name="no_transactions" />
<separator string="Processing Information" colspan="4" />
<field name="prefered_date" />
<field name="date_generated" />
<field name="testcode" />
<newline />
<field name="filename" invisible="True"/>
<field name="file" colspan="4" filename="filename"/>
</page>
<page string="Payment Orders">
<field name="payment_order_ids" colspan="4" nolabel="1">
<tree colors="blue:state in ('draft');gray:state in ('cancel','done');black:state in ('open')" string="Payment order">
<field name="reference"/>
<field name="date_created"/>
<field name="date_done"/>
<field name="total"/>
<field name="state"/>
</tree>
</field>
</page>
</notebook>
</form>
</field>
</record>
<record id="view_banking_export_clieop_tree" model="ir.ui.view">
<field name="name">account.banking.export.clieop.tree</field>
<field name="model">banking.export.clieop</field>
<field name="arch" type="xml">
<tree string="Client Opdrachten Export">
<field name="filetype" />
<field name="identification" search="2"/>
<field name="prefered_date" search="2"/>
<field name="date_generated" />
</tree>
</field>
</record>
<record model="ir.actions.act_window" id="action_account_banking_clieops">
<field name="name">Generated ClieOp3 Files</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">banking.export.clieop</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<!-- Add a menu item for it -->
<menuitem name="Generated ClieOp3 Files"
id="menu_action_account_banking_exported_clieop_files"
parent="account_banking.menu_finance_banking_actions"
action="action_account_banking_clieops"
sequence="12"
/>
<!-- Create right menu entry to see generated files -->
<act_window name="Generated ClieOp3 Files"
domain="[('payment_order_ids', '=', active_id)]"
res_model="banking.export.clieop"
src_model="payment.order"
view_type="form"
view_mode="tree,form"
id="act_banking_export_clieop_payment_order"/>
</data>
</openerp>

View File

@@ -1,34 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<record model="payment.mode.type" id="account_banking_nl_clieop.export_clieop_inc">
<field name="name">ClieOp3 Direct Debit Batch</field>
<field name="code">CLIEOPINC</field>
<field name="suitable_bank_types"
eval="[(6,0,[ref('base_iban.bank_iban'),ref('base.bank_normal'),])]" />
<field name="ir_model_id"
ref="account_banking_nl_clieop.model_banking_export_clieop_wizard"/>
<field name="payment_order_type">debit</field>
</record>
<record model="payment.mode.type" id="account_banking_nl_clieop.export_clieop_pay">
<field name="name">ClieOp3 Payment Batch</field>
<field name="code">CLIEOPPAY</field>
<field name="suitable_bank_types"
eval="[(6,0,[ref('base_iban.bank_iban'),ref('base.bank_normal'),])]" />
<field name="ir_model_id"
ref="account_banking_nl_clieop.model_banking_export_clieop_wizard"/>
<field name="payment_order_type">payment</field>
</record>
<record model="payment.mode.type" id="account_banking_nl_clieop.export_clieop_sal">
<field name="name">ClieOp3 Salary Payment Batch</field>
<field name="code">CLIEOPSAL</field>
<field name="suitable_bank_types"
eval="[(6,0,[ref('base_iban.bank_iban'),ref('base.bank_normal'),])]" />
<field name="ir_model_id"
ref="account_banking_nl_clieop.model_banking_export_clieop_wizard"/>
<field name="payment_order_type">payment</field>
</record>
</data>
</openerp>

View File

@@ -1,331 +0,0 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * account_banking_nl_clieop
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 7.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-10-25 15:54+0000\n"
"PO-Revision-Date: 2013-10-25 15:54+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop.wizard,batchtype:0
msgid "Direct Debits"
msgstr ""
#. module: account_banking_nl_clieop
#: code:addons/account_banking_nl_clieop/account_banking_nl_clieop.py:41
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:96
#: selection:banking.export.clieop,testcode:0
#: selection:banking.export.clieop.wizard,testcode:0
#, python-format
msgid "No"
msgstr ""
#. module: account_banking_nl_clieop
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:294
#, python-format
msgid "There is insufficient information.
\n"
"Both destination address and account number must be provided"
msgstr ""
#. module: account_banking_nl_clieop
#: view:banking.export.clieop.wizard:0
#: selection:banking.export.clieop.wizard,state:0
msgid "Create"
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,no_transactions:0
#: field:banking.export.clieop.wizard,no_transactions:0
msgid "Number of Transactions"
msgstr ""
#. module: account_banking_nl_clieop
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:215
#, python-format
msgid "You can't create ClieOp orders more than 30 days in advance."
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop.wizard,filename:0
msgid "Filename"
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,state:0
#: field:banking.export.clieop.wizard,state:0
msgid "State"
msgstr ""
#. module: account_banking_nl_clieop
#: help:banking.export.clieop.wizard,test:0
msgid "Select this if you want your bank to run a test process rather then execute your orders for real."
msgstr ""
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop,state:0
msgid "Draft"
msgstr ""
#. module: account_banking_nl_clieop
#: view:banking.export.clieop:0
msgid "Processing Information"
msgstr ""
#. module: account_banking_nl_clieop
#: help:banking.export.clieop.wizard,fixed_message:0
msgid "A fixed message to apply to all transactions in addition to the individual messages."
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,check_no_accounts:0
#: field:banking.export.clieop.wizard,check_no_accounts:0
msgid "Check Number Accounts"
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop.wizard,batchtype:0
msgid "Type"
msgstr ""
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop,state:0
msgid "Sent"
msgstr ""
#. module: account_banking_nl_clieop
#: view:banking.export.clieop:0
msgid "ClieOp Information"
msgstr ""
#. module: account_banking_nl_clieop
#: model:ir.model,name:account_banking_nl_clieop.model_banking_export_clieop
msgid "ClieOp3 Export"
msgstr ""
#. module: account_banking_nl_clieop
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:220
#, python-format
msgid "You can only combine payment orders of the same type"
msgstr ""
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop,filetype:0
#: selection:banking.export.clieop.wizard,filetype:0
msgid "Salary Payment Batch"
msgstr ""
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop,state:0
msgid "Reconciled"
msgstr ""
#. module: account_banking_nl_clieop
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:256
#, python-format
msgid "Your bank account has to have a valid account number"
msgstr ""
#. module: account_banking_nl_clieop
#: view:banking.export.clieop.wizard:0
msgid "Reference for further communication"
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,duplicates:0
msgid "Number of Duplicates"
msgstr ""
#. module: account_banking_nl_clieop
#: help:banking.export.clieop.wizard,reference:0
msgid "The bank will use this reference in feedback communication to refer to this run. Only five characters are available."
msgstr ""
#. module: account_banking_nl_clieop
#: view:banking.export.clieop.wizard:0
msgid "Processing Details"
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,testcode:0
#: field:banking.export.clieop.wizard,test:0
#: field:banking.export.clieop.wizard,testcode:0
msgid "Test Run"
msgstr ""
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop,filetype:0
#: selection:banking.export.clieop.wizard,filetype:0
msgid "Direct Debit Batch"
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,prefered_date:0
#: field:banking.export.clieop.wizard,prefered_date:0
msgid "Prefered Processing Date"
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,file:0
#: field:banking.export.clieop.wizard,file_id:0
msgid "ClieOp File"
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop.wizard,file:0
msgid "File"
msgstr ""
#. module: account_banking_nl_clieop
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:317
#, python-format
msgid "You cannot send international bank transfers through ClieOp3!"
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop.wizard,execution_date:0
msgid "Execution Date"
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop.wizard,fixed_message:0
msgid "Fixed Message"
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,filetype:0
#: field:banking.export.clieop.wizard,filetype:0
msgid "File Type"
msgstr ""
#. module: account_banking_nl_clieop
#: model:ir.actions.act_window,name:account_banking_nl_clieop.act_banking_export_clieop_payment_order
#: model:ir.actions.act_window,name:account_banking_nl_clieop.action_account_banking_clieops
#: model:ir.ui.menu,name:account_banking_nl_clieop.menu_action_account_banking_exported_clieop_files
msgid "Generated ClieOp3 Files"
msgstr ""
#. module: account_banking_nl_clieop
#: view:banking.export.clieop.wizard:0
#: selection:banking.export.clieop.wizard,state:0
msgid "Finish"
msgstr ""
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop.wizard,batchtype:0
msgid "Payments"
msgstr ""
#. module: account_banking_nl_clieop
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:214
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:219
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:255
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:293
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:316
#, python-format
msgid "Error"
msgstr ""
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop.wizard,batchtype:0
msgid "Salary Payments"
msgstr ""
#. module: account_banking_nl_clieop
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:354
#: view:banking.export.clieop:0
#: view:banking.export.clieop.wizard:0
#: model:ir.model,name:account_banking_nl_clieop.model_banking_export_clieop_wizard
#, python-format
msgid "Client Opdrachten Export"
msgstr ""
#. module: account_banking_nl_clieop
#: view:banking.export.clieop.wizard:0
msgid "Additional message for all transactions"
msgstr ""
#. module: account_banking_nl_clieop
#: help:banking.export.clieop.wizard,execution_date:0
msgid "This is the date the file should be processed by the bank. Don't choose a date beyond the nearest date in your payments. The latest allowed date is 30 days from now.\n"
"Please keep in mind that banks only execute on working days and typically use a delay of two days between execution date and effective transfer date."
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,total_amount:0
#: field:banking.export.clieop.wizard,total_amount:0
msgid "Total Amount"
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop.wizard,reference:0
msgid "Reference"
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,filename:0
msgid "File Name"
msgstr ""
#. module: account_banking_nl_clieop
#: view:banking.export.clieop:0
msgid "Payment order"
msgstr ""
#. module: account_banking_nl_clieop
#: view:banking.export.clieop:0
#: field:banking.export.clieop,payment_order_ids:0
#: field:banking.export.clieop.wizard,payment_order_ids:0
msgid "Payment Orders"
msgstr ""
#. module: account_banking_nl_clieop
#: view:banking.export.clieop:0
msgid "General Information"
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,daynumber:0
msgid "ClieOp Transaction nr of the Day"
msgstr ""
#. module: account_banking_nl_clieop
#: view:banking.export.clieop.wizard:0
msgid "Cancel"
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,identification:0
#: field:banking.export.clieop.wizard,identification:0
msgid "Identification"
msgstr ""
#. module: account_banking_nl_clieop
#: code:addons/account_banking_nl_clieop/account_banking_nl_clieop.py:41
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:96
#: selection:banking.export.clieop,testcode:0
#: selection:banking.export.clieop.wizard,testcode:0
#, python-format
msgid "Yes"
msgstr ""
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop,filetype:0
#: selection:banking.export.clieop.wizard,filetype:0
msgid "Payment Batch"
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,date_generated:0
msgid "Generation Date"
msgstr ""

View File

@@ -1,20 +0,0 @@
# Danish translation for account-banking
# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010
# This file is distributed under the same license as the account-banking package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
#
msgid ""
msgstr ""
"Project-Id-Version: account-banking\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2013-11-11 17:40+0000\n"
"PO-Revision-Date: 2013-11-11 17:54+0000\n"
"Last-Translator: Pedro Manuel Baeza <pedro.baeza@gmail.com>\n"
"Language-Team: Danish <da@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-05-31 06:02+0000\n"
"X-Generator: Launchpad (build 17031)\n"

View File

@@ -1,348 +0,0 @@
# Danish translation for account-banking
# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010
# This file is distributed under the same license as the account-banking package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
#
msgid ""
msgstr ""
"Project-Id-Version: account-banking\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2010-01-08 15:36+0000\n"
"PO-Revision-Date: 2010-02-06 14:41+0000\n"
"Last-Translator: nanker <Unknown>\n"
"Language-Team: Danish <da@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-06-09 10:04+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account_banking_nl_clieop
#: constraint:ir.model:0
msgid ""
"The Object name must start with x_ and not contain any special character !"
msgstr ""
#. module: account_banking_nl_clieop
#: selection:account_banking_nl_clieop.banking_export_clieop,init,batchtype:0
msgid "Direct Debits"
msgstr ""
#. module: account_banking_nl_clieop
#: selection:account_banking_nl_clieop.banking_export_clieop,create,testcode:0
#: code:addons/account_banking_nl_clieop/account_banking_clieop.py:0
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:0
#: selection:banking.export.clieop,testcode:0
#, python-format
msgid "No"
msgstr "Nej"
#. module: account_banking_nl_clieop
#: model:ir.module.module,shortdesc:account_banking_nl_clieop.module_meta_information
msgid "Account Banking NL ClieOp"
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,no_transactions:0
#: field:banking.export.clieop,no_transactions:0
msgid "Number of Transactions"
msgstr ""
#. module: account_banking_nl_clieop
#: model:ir.actions.wizard,name:account_banking_nl_clieop.wizard_account_banking_export_clieop
msgid "Export ClieOp File"
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,prefered_date:0
#: field:banking.export.clieop,prefered_date:0
msgid "Prefered Processing Date"
msgstr ""
#. module: account_banking_nl_clieop
#: model:payment.type,name:account_banking_nl_clieop.export_clieop_pay
msgid "ClieOp3 Payment Batch"
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,state:0
msgid "State"
msgstr ""
#. module: account_banking_nl_clieop
#: help:account_banking_nl_clieop.banking_export_clieop,init,test:0
msgid ""
"Select this if you want your bank to run a test process rather then execute "
"your orders for real."
msgstr ""
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop,state:0
msgid "Draft"
msgstr "Udkast"
#. module: account_banking_nl_clieop
#: view:banking.export.clieop:0
msgid "Processing Information"
msgstr ""
#. module: account_banking_nl_clieop
#: help:account_banking_nl_clieop.banking_export_clieop,init,fixed_message:0
msgid ""
"A fixed message to apply to all transactions in addition to the individual "
"messages."
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,check_no_accounts:0
#: field:banking.export.clieop,check_no_accounts:0
msgid "Check Number Accounts"
msgstr ""
#. module: account_banking_nl_clieop
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_button:account_banking_nl_clieop.banking_export_clieop,create,save:0
msgid "Save"
msgstr "Gem"
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,init,batchtype:0
msgid "Type"
msgstr ""
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop,state:0
msgid "Sent"
msgstr "Sendt"
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,log:0
msgid "Log"
msgstr "Log"
#. module: account_banking_nl_clieop
#: view:banking.export.clieop:0
msgid "ClieOp Information"
msgstr "ClieOp information"
#. module: account_banking_nl_clieop
#: model:ir.model,name:account_banking_nl_clieop.model_banking_export_clieop
msgid "ClieOp3 Export"
msgstr "ClieOp3 eksport"
#. module: account_banking_nl_clieop
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:0
#, python-format
msgid "You can only combine payment orders of the same type"
msgstr ""
#. module: account_banking_nl_clieop
#: selection:account_banking_nl_clieop.banking_export_clieop,create,filetype:0
#: selection:banking.export.clieop,filetype:0
msgid "Salary Payment Batch"
msgstr ""
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop,state:0
msgid "Reconciled"
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_view:account_banking_nl_clieop.banking_export_clieop,init:0
msgid "Reference for further communication"
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,duplicates:0
msgid "Number of Duplicates"
msgstr ""
#. module: account_banking_nl_clieop
#: help:account_banking_nl_clieop.banking_export_clieop,init,reference:0
msgid ""
"The bank will use this reference in feedback communication to refer to this "
"run. Only five characters are available."
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_view:account_banking_nl_clieop.banking_export_clieop,init:0
msgid "Processing Details"
msgstr ""
#. module: account_banking_nl_clieop
#: model:payment.type,name:account_banking_nl_clieop.export_clieop_sal
msgid "ClieOp3 Salary Payment Batch"
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_button:account_banking_nl_clieop.banking_export_clieop,init,create:0
msgid "Create"
msgstr "Opret"
#. module: account_banking_nl_clieop
#: selection:account_banking_nl_clieop.banking_export_clieop,create,filetype:0
#: selection:banking.export.clieop,filetype:0
msgid "Direct Debit Batch"
msgstr ""
#. module: account_banking_nl_clieop
#: constraint:ir.ui.view:0
msgid "Invalid XML for View Architecture!"
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,file:0
#: field:banking.export.clieop,file:0
msgid "ClieOp File"
msgstr ""
#. module: account_banking_nl_clieop
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:0
#, python-format
msgid "You can't create ClieOp orders more than 30 days in advance."
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,init,execution_date:0
msgid "Execution Date"
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,init,fixed_message:0
msgid "Fixed Message"
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,filetype:0
#: field:banking.export.clieop,filetype:0
msgid "File Type"
msgstr "Filtype"
#. module: account_banking_nl_clieop
#: model:payment.type,name:account_banking_nl_clieop.export_clieop_inc
msgid "ClieOp3 Direct Debit Batch"
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,testcode:0
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,init,test:0
#: field:banking.export.clieop,testcode:0
msgid "Test Run"
msgstr "Testkørsel"
#. module: account_banking_nl_clieop
#: selection:account_banking_nl_clieop.banking_export_clieop,init,batchtype:0
msgid "Payments"
msgstr "Betalinger"
#. module: account_banking_nl_clieop
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:0
#, python-format
msgid "Error"
msgstr "Fejl"
#. module: account_banking_nl_clieop
#: selection:account_banking_nl_clieop.banking_export_clieop,init,batchtype:0
msgid "Salary Payments"
msgstr "Lønudbetalinger"
#. module: account_banking_nl_clieop
#: wizard_view:account_banking_nl_clieop.banking_export_clieop,create:0
#: wizard_view:account_banking_nl_clieop.banking_export_clieop,init:0
#: view:banking.export.clieop:0
msgid "Client Opdrachten Export"
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_view:account_banking_nl_clieop.banking_export_clieop,init:0
msgid "Additional message for all transactions"
msgstr ""
#. module: account_banking_nl_clieop
#: model:ir.actions.act_window,name:account_banking_nl_clieop.action_account_banking_clieops
#: model:ir.ui.menu,name:account_banking_nl_clieop.menu_action_account_banking_exported_clieop_files
msgid "Generated ClieOp3 Files"
msgstr ""
#. module: account_banking_nl_clieop
#: model:ir.module.module,description:account_banking_nl_clieop.module_meta_information
msgid ""
"\n"
" Module to export payment orders in ClieOp format.\n"
"\n"
" ClieOp format is used by Dutch banks to batch national bank transfers.\n"
" This module uses the account_banking logic.\n"
" "
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,init,reference:0
msgid "Reference"
msgstr "Reference"
#. module: account_banking_nl_clieop
#: help:account_banking_nl_clieop.banking_export_clieop,init,execution_date:0
msgid ""
"This is the date the file should be processed by the bank. Don't choose a "
"date beyond the nearest date in your payments. The latest allowed date is 30 "
"days from now.\n"
"Please keep in mind that banks only execute on working days and typically "
"use a delay of two days between execution date and effective transfer date."
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,payment_order_ids:0
msgid "Payment Orders"
msgstr "Betalingsordrer"
#. module: account_banking_nl_clieop
#: view:banking.export.clieop:0
msgid "General Information"
msgstr "Generel information"
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,total_amount:0
#: field:banking.export.clieop,total_amount:0
msgid "Total Amount"
msgstr "Totalt beløb"
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,daynumber:0
msgid "ClieOp Transaction nr of the Day"
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_button:account_banking_nl_clieop.banking_export_clieop,create,cancel:0
#: wizard_button:account_banking_nl_clieop.banking_export_clieop,init,end:0
msgid "Cancel"
msgstr "Annuller"
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,identification:0
#: field:banking.export.clieop,identification:0
msgid "Identification"
msgstr "Identifikation"
#. module: account_banking_nl_clieop
#: selection:account_banking_nl_clieop.banking_export_clieop,create,testcode:0
#: code:addons/account_banking_nl_clieop/account_banking_clieop.py:0
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:0
#: selection:banking.export.clieop,testcode:0
#, python-format
msgid "Yes"
msgstr "Ja"
#. module: account_banking_nl_clieop
#: selection:account_banking_nl_clieop.banking_export_clieop,create,filetype:0
#: selection:banking.export.clieop,filetype:0
msgid "Payment Batch"
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,date_generated:0
msgid "Generation Date"
msgstr ""

View File

@@ -1,19 +0,0 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * account_banking_nl_clieop
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 5.0.15\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2013-11-11 17:40+0000\n"
"PO-Revision-Date: 2013-11-11 17:50+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-05-31 06:02+0000\n"
"X-Generator: Launchpad (build 17031)\n"

View File

@@ -1,19 +0,0 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * account_banking_nl_clieop
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 6.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-11-11 17:40+0000\n"
"PO-Revision-Date: 2013-11-11 17:51+0000\n"
"Last-Translator: Erwin van der Ploeg | Endian Solutions <Unknown>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-05-31 06:02+0000\n"
"X-Generator: Launchpad (build 17031)\n"

View File

@@ -1,20 +0,0 @@
# Turkish translation for account-banking
# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010
# This file is distributed under the same license as the account-banking package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
#
msgid ""
msgstr ""
"Project-Id-Version: account-banking\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2013-11-11 17:40+0000\n"
"PO-Revision-Date: 2013-11-11 17:51+0000\n"
"Last-Translator: Pedro Manuel Baeza <pedro.baeza@gmail.com>\n"
"Language-Team: Turkish <tr@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-05-31 06:02+0000\n"
"X-Generator: Launchpad (build 17031)\n"

View File

@@ -1,348 +0,0 @@
# Turkish translation for account-banking
# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010
# This file is distributed under the same license as the account-banking package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
#
msgid ""
msgstr ""
"Project-Id-Version: account-banking\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2010-01-08 15:36+0000\n"
"PO-Revision-Date: 2010-10-10 11:22+0000\n"
"Last-Translator: Engin BAHADIR <Unknown>\n"
"Language-Team: Turkish <tr@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-10-11 12:32+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: account_banking_nl_clieop
#: constraint:ir.model:0
msgid ""
"The Object name must start with x_ and not contain any special character !"
msgstr ""
#. module: account_banking_nl_clieop
#: selection:account_banking_nl_clieop.banking_export_clieop,init,batchtype:0
msgid "Direct Debits"
msgstr ""
#. module: account_banking_nl_clieop
#: selection:account_banking_nl_clieop.banking_export_clieop,create,testcode:0
#: code:addons/account_banking_nl_clieop/account_banking_clieop.py:0
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:0
#: selection:banking.export.clieop,testcode:0
#, python-format
msgid "No"
msgstr "Hayır"
#. module: account_banking_nl_clieop
#: model:ir.module.module,shortdesc:account_banking_nl_clieop.module_meta_information
msgid "Account Banking NL ClieOp"
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,no_transactions:0
#: field:banking.export.clieop,no_transactions:0
msgid "Number of Transactions"
msgstr ""
#. module: account_banking_nl_clieop
#: model:ir.actions.wizard,name:account_banking_nl_clieop.wizard_account_banking_export_clieop
msgid "Export ClieOp File"
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,prefered_date:0
#: field:banking.export.clieop,prefered_date:0
msgid "Prefered Processing Date"
msgstr ""
#. module: account_banking_nl_clieop
#: model:payment.type,name:account_banking_nl_clieop.export_clieop_pay
msgid "ClieOp3 Payment Batch"
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,state:0
msgid "State"
msgstr ""
#. module: account_banking_nl_clieop
#: help:account_banking_nl_clieop.banking_export_clieop,init,test:0
msgid ""
"Select this if you want your bank to run a test process rather then execute "
"your orders for real."
msgstr ""
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop,state:0
msgid "Draft"
msgstr "Taslak"
#. module: account_banking_nl_clieop
#: view:banking.export.clieop:0
msgid "Processing Information"
msgstr "İşlem Bilgisi"
#. module: account_banking_nl_clieop
#: help:account_banking_nl_clieop.banking_export_clieop,init,fixed_message:0
msgid ""
"A fixed message to apply to all transactions in addition to the individual "
"messages."
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,check_no_accounts:0
#: field:banking.export.clieop,check_no_accounts:0
msgid "Check Number Accounts"
msgstr ""
#. module: account_banking_nl_clieop
#: constraint:ir.actions.act_window:0
msgid "Invalid model name in the action definition."
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_button:account_banking_nl_clieop.banking_export_clieop,create,save:0
msgid "Save"
msgstr "Kaydet"
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,init,batchtype:0
msgid "Type"
msgstr "Tür"
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop,state:0
msgid "Sent"
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,log:0
msgid "Log"
msgstr "Kayıt"
#. module: account_banking_nl_clieop
#: view:banking.export.clieop:0
msgid "ClieOp Information"
msgstr ""
#. module: account_banking_nl_clieop
#: model:ir.model,name:account_banking_nl_clieop.model_banking_export_clieop
msgid "ClieOp3 Export"
msgstr ""
#. module: account_banking_nl_clieop
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:0
#, python-format
msgid "You can only combine payment orders of the same type"
msgstr ""
#. module: account_banking_nl_clieop
#: selection:account_banking_nl_clieop.banking_export_clieop,create,filetype:0
#: selection:banking.export.clieop,filetype:0
msgid "Salary Payment Batch"
msgstr ""
#. module: account_banking_nl_clieop
#: selection:banking.export.clieop,state:0
msgid "Reconciled"
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_view:account_banking_nl_clieop.banking_export_clieop,init:0
msgid "Reference for further communication"
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,duplicates:0
msgid "Number of Duplicates"
msgstr ""
#. module: account_banking_nl_clieop
#: help:account_banking_nl_clieop.banking_export_clieop,init,reference:0
msgid ""
"The bank will use this reference in feedback communication to refer to this "
"run. Only five characters are available."
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_view:account_banking_nl_clieop.banking_export_clieop,init:0
msgid "Processing Details"
msgstr ""
#. module: account_banking_nl_clieop
#: model:payment.type,name:account_banking_nl_clieop.export_clieop_sal
msgid "ClieOp3 Salary Payment Batch"
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_button:account_banking_nl_clieop.banking_export_clieop,init,create:0
msgid "Create"
msgstr "Oluştur"
#. module: account_banking_nl_clieop
#: selection:account_banking_nl_clieop.banking_export_clieop,create,filetype:0
#: selection:banking.export.clieop,filetype:0
msgid "Direct Debit Batch"
msgstr ""
#. module: account_banking_nl_clieop
#: constraint:ir.ui.view:0
msgid "Invalid XML for View Architecture!"
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,file:0
#: field:banking.export.clieop,file:0
msgid "ClieOp File"
msgstr ""
#. module: account_banking_nl_clieop
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:0
#, python-format
msgid "You can't create ClieOp orders more than 30 days in advance."
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,init,execution_date:0
msgid "Execution Date"
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,init,fixed_message:0
msgid "Fixed Message"
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,filetype:0
#: field:banking.export.clieop,filetype:0
msgid "File Type"
msgstr "Dosya Türü"
#. module: account_banking_nl_clieop
#: model:payment.type,name:account_banking_nl_clieop.export_clieop_inc
msgid "ClieOp3 Direct Debit Batch"
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,testcode:0
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,init,test:0
#: field:banking.export.clieop,testcode:0
msgid "Test Run"
msgstr ""
#. module: account_banking_nl_clieop
#: selection:account_banking_nl_clieop.banking_export_clieop,init,batchtype:0
msgid "Payments"
msgstr "Ödemeler"
#. module: account_banking_nl_clieop
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:0
#, python-format
msgid "Error"
msgstr "Hata"
#. module: account_banking_nl_clieop
#: selection:account_banking_nl_clieop.banking_export_clieop,init,batchtype:0
msgid "Salary Payments"
msgstr "Maaş Ödemeleri"
#. module: account_banking_nl_clieop
#: wizard_view:account_banking_nl_clieop.banking_export_clieop,create:0
#: wizard_view:account_banking_nl_clieop.banking_export_clieop,init:0
#: view:banking.export.clieop:0
msgid "Client Opdrachten Export"
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_view:account_banking_nl_clieop.banking_export_clieop,init:0
msgid "Additional message for all transactions"
msgstr ""
#. module: account_banking_nl_clieop
#: model:ir.actions.act_window,name:account_banking_nl_clieop.action_account_banking_clieops
#: model:ir.ui.menu,name:account_banking_nl_clieop.menu_action_account_banking_exported_clieop_files
msgid "Generated ClieOp3 Files"
msgstr ""
#. module: account_banking_nl_clieop
#: model:ir.module.module,description:account_banking_nl_clieop.module_meta_information
msgid ""
"\n"
" Module to export payment orders in ClieOp format.\n"
"\n"
" ClieOp format is used by Dutch banks to batch national bank transfers.\n"
" This module uses the account_banking logic.\n"
" "
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,init,reference:0
msgid "Reference"
msgstr "Referans"
#. module: account_banking_nl_clieop
#: help:account_banking_nl_clieop.banking_export_clieop,init,execution_date:0
msgid ""
"This is the date the file should be processed by the bank. Don't choose a "
"date beyond the nearest date in your payments. The latest allowed date is 30 "
"days from now.\n"
"Please keep in mind that banks only execute on working days and typically "
"use a delay of two days between execution date and effective transfer date."
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,payment_order_ids:0
msgid "Payment Orders"
msgstr ""
#. module: account_banking_nl_clieop
#: view:banking.export.clieop:0
msgid "General Information"
msgstr "Genel Bilgi"
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,total_amount:0
#: field:banking.export.clieop,total_amount:0
msgid "Total Amount"
msgstr "Toplam Tutar"
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,daynumber:0
msgid "ClieOp Transaction nr of the Day"
msgstr ""
#. module: account_banking_nl_clieop
#: wizard_button:account_banking_nl_clieop.banking_export_clieop,create,cancel:0
#: wizard_button:account_banking_nl_clieop.banking_export_clieop,init,end:0
msgid "Cancel"
msgstr "İptal"
#. module: account_banking_nl_clieop
#: wizard_field:account_banking_nl_clieop.banking_export_clieop,create,identification:0
#: field:banking.export.clieop,identification:0
msgid "Identification"
msgstr ""
#. module: account_banking_nl_clieop
#: selection:account_banking_nl_clieop.banking_export_clieop,create,testcode:0
#: code:addons/account_banking_nl_clieop/account_banking_clieop.py:0
#: code:addons/account_banking_nl_clieop/wizard/export_clieop.py:0
#: selection:banking.export.clieop,testcode:0
#, python-format
msgid "Yes"
msgstr "Evet"
#. module: account_banking_nl_clieop
#: selection:account_banking_nl_clieop.banking_export_clieop,create,filetype:0
#: selection:banking.export.clieop,filetype:0
msgid "Payment Batch"
msgstr ""
#. module: account_banking_nl_clieop
#: field:banking.export.clieop,date_generated:0
msgid "Generation Date"
msgstr ""

View File

@@ -1,46 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2011 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/>.
#
##############################################################################
""" This script covers the migration of the payment wizards from old style to
new style (osv_memory). It guarantees an easy upgrade for early adopters
of the 6.0 branch of this OpenERP module. Note that a migration from OpenERP
5.0 to OpenERP 6.0 with respect to this module is not covered by this script.
"""
__name__ = ("payment.mode.type:: Add new style payment wizards to existing "
"payment mode types")
def migrate(cr, version):
cr.execute("UPDATE payment_mode_type"
" SET ir_model_id = data1.res_id"
" FROM ir_model_data data1,"
" ir_model_data data2"
" WHERE data2.res_id = payment_mode_type.id"
" AND data1.module = 'account_banking_nl_clieop'"
" AND data1.model = 'ir.model'"
" AND data1.name = 'model_banking_export_clieop_wizard'"
" AND data2.module = 'account_banking_nl_clieop'"
" AND data2.model = 'payment.mode.type'"
" AND data2.name IN ('export_clieop_inc',"
" 'export_clieop_pay',"
" 'export_clieop_sal'"
" )"
)

View File

@@ -1,36 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2011 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/>.
#
##############################################################################
"""r64: introduction of the payment_mode_type in order to support of debit
orders
"""
__name__ = ("payment.mode.type:: set payment_mode_type to 'debit' for Clieop "
"incasso export")
def migrate(cr, version):
cr.execute("UPDATE payment_mode_type"
" SET payment_order_type = 'debit'"
" FROM ir_model_data "
" WHERE res_id = payment_mode_type.id"
" AND module = 'account_banking_nl_clieop'"
" AND model = 'payment.mode.type'"
" AND ir_model_data.name = 'export_clieop_inc'"
)

View File

@@ -1,2 +0,0 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_banking_export_clieop","banking.export.clieop","model_banking_export_clieop","account_payment.group_account_payment",1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_banking_export_clieop banking.export.clieop model_banking_export_clieop account_payment.group_account_payment 1 1 1 1

View File

@@ -1,22 +0,0 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
# 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 . import export_clieop

View File

@@ -1,529 +0,0 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
# 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 account_banking import record
from account_banking.parsers import convert
__all__ = ['DirectDebitBatch', 'PaymentsBatch', 'DirectDebit', 'Payment',
'DirectDebitFile', 'PaymentsFile', 'SalaryPaymentsFile',
'SalaryPaymentOrder', 'PaymentOrder', 'DirectDebitOrder',
'OrdersFile',
]
class SWIFTField(record.Field):
'''
A SWIFTField does not assume 'ascii' data. It actively converts data to
SWIFT-specs.
'''
def __init__(self, *args, **kwargs):
kwargs['cast'] = convert.to_swift
super(SWIFTField, self).__init__(*args, **kwargs)
class SWIFTFieldNoLeadingWhitespace(SWIFTField):
def format(self, value):
return super(SWIFTFieldNoLeadingWhitespace, self).format(
self.cast(value).lstrip())
def eleven_test(s):
'''
Dutch eleven-test for validating 9-long local bank account numbers.
'''
r = 0
l = len(s)
for i, c in enumerate(s):
r += (l-i) * int(c)
return (r % 11) == 0
def chunk(str, length):
'''
Split a string in equal sized substrings of length <length>
'''
while str:
yield str[:length]
str = str[length:]
class HeaderRecord(record.Record):
'''ClieOp3 header record'''
_fields = [
record.Filler('recordcode', 4, '0001'),
record.Filler('variantcode', 1, 'A'),
record.DateField('creation_date', '%d%m%y', auto=True),
record.Filler('filename', 8, 'CLIEOP03'),
SWIFTField('sender_id', 5),
record.Field('file_id', 4),
record.Field('duplicatecode', 1),
record.Filler('filler', 21),
]
def __init__(self, id='1', seqno=1, duplicate=False):
super(HeaderRecord, self).__init__()
self.sender_id = id or ''
self.file_id = '%02d%02d' % (self.creation_date.day, seqno)
self.duplicatecode = duplicate and '2' or '1'
class FooterRecord(record.Record):
'''ClieOp3 footer record'''
_fields = [
record.Filler('recordcode', 4, '9999'),
record.Filler('variantcode', 1, 'A'),
record.Filler('filler', 45),
]
class BatchHeaderRecord(record.Record):
'''Header record preceding new batches'''
_fields = [
record.Filler('recordcode', 4, '0010'),
record.Field('variantcode', 1),
record.Field('transactiongroup', 2),
record.NumberField('accountno_sender', 10),
record.NumberField('batch_tracer', 4),
record.Filler('currency_order', 3, 'EUR'),
SWIFTField('batch_id', 16),
record.Filler('filler', 10),
]
class BatchFooterRecord(record.Record):
'''Closing record for batches'''
_fields = [
record.Filler('recordcode', 4, '9990'),
record.Filler('variantcode', 1, 'A'),
record.NumberField('total_amount', 18),
record.NumberField('total_accountnos', 10),
record.NumberField('nr_posts', 7),
record.Filler('filler', 10),
]
class FixedMessageRecord(record.Record):
'''Fixed message'''
_fields = [
record.Filler('recordcode', 4, '0020'),
record.Filler('variantcode', 1, 'A'),
SWIFTField('fixed_message', 32),
record.Filler('filler', 13),
]
class SenderRecord(record.Record):
'''Ordering party'''
_fields = [
record.Filler('recordcode', 4, '0030'),
record.Filler('variantcode', 1, 'B'),
# NAW = Name, Address, Residence
record.Field('NAWcode', 1),
record.DateField('preferred_execution_date', '%d%m%y', auto=True),
SWIFTField('name_sender', 35),
record.Field('testcode', 1),
record.Filler('filler', 2),
]
class TransactionRecord(record.Record):
'''Transaction'''
_fields = [
record.Filler('recordcode', 4, '0100'),
record.Filler('variantcode', 1, 'A'),
record.NumberField('transactiontype', 4),
record.NumberField('amount', 12),
record.NumberField('accountno_payer', 10),
record.NumberField('accountno_beneficiary', 10),
record.Filler('filler', 9),
]
class NamePayerRecord(record.Record):
'''Name payer'''
_fields = [
record.Filler('recordcode', 4, '0110'),
record.Filler('variantcode', 1, 'B'),
SWIFTField('name', 35),
record.Filler('filler', 10),
]
class PaymentReferenceRecord(record.Record):
'''Payment reference'''
_fields = [
record.Filler('recordcode', 4, '0150'),
record.Filler('variantcode', 1, 'A'),
SWIFTFieldNoLeadingWhitespace('paymentreference', 16),
record.Filler('filler', 29),
]
class DescriptionRecord(record.Record):
'''Description'''
_fields = [
record.Filler('recordcode', 4, '0160'),
record.Filler('variantcode', 1, 'A'),
SWIFTField('description', 32),
record.Filler('filler', 13),
]
class NameBeneficiaryRecord(record.Record):
'''Name receiving party'''
_fields = [
record.Filler('recordcode', 4, '0170'),
record.Filler('variantcode', 1, 'B'),
SWIFTField('name', 35),
record.Filler('filler', 10),
]
class OrderRecord(record.Record):
'''Order details'''
_fields = [
record.Filler('recordcode', 6, 'KAE092'),
SWIFTField('name_transactioncode', 18),
record.NumberField('total_amount', 13),
record.Field('accountno_sender', 10),
record.NumberField('total_accountnos', 5),
record.NumberField('nr_posts', 6),
record.Field('identification', 6),
record.DateField('preferred_execution_date', '%y%m%d'),
record.Field('batch_medium', 18),
record.Filler('currency', 3, 'EUR'),
record.Field('testcode', 1),
]
def __init__(self, *args, **kwargs):
super(OrderRecord, self).__init__(*args, **kwargs)
self.batch_medium = 'DATACOM'
self.name_transactioncode = self._transactioncode
class SalaryPaymentOrder(OrderRecord):
'''Salary payment batch record'''
_transactioncode = 'SALARIS'
class PaymentOrder(OrderRecord):
'''Payment batch record'''
_transactioncode = 'CREDBET'
class DirectDebitOrder(OrderRecord):
'''Direct debit payments batch record'''
_transactioncode = 'INCASSO'
class Optional(object):
'''Auxilliary class to handle optional records'''
def __init__(self, klass, max=1):
self._klass = klass
self._max = max
self._guts = []
def __setattr__(self, attr, value):
'''Check for number of records'''
if attr[0] == '_':
super(Optional, self).__setattr__(attr, value)
else:
if self._guts and len(self._guts) > self._max:
raise ValueError('Only %d lines are allowed' % self._max)
newitem = self._klass()
setattr(newitem, attr, value)
self._guts.append(newitem)
def __len__(self):
'''Return actual contents'''
return len(self._guts)
def length(self, attr):
'''Return length of optional record'''
res = [x for x in self._klass._fields if x.name == attr]
if res:
return res[0].length
raise AttributeError(attr)
def __getattr__(self, attr):
'''Only return if used'''
if attr[0] == '_':
return super(Optional, self).__getattr__(attr)
return [getattr(x, attr) for x in self._guts]
def __iter__(self):
'''Make sure to adapt'''
return self._guts.__iter__()
class OrdersFile(object):
'''A payment orders file'''
def __init__(self, *args, **kwargs):
self.orders = []
@property
def rawdata(self):
'''
Return a writeable file content object
'''
return '\r\n'.join(self.orders)
class Transaction(object):
'''Generic transaction class'''
def __init__(self, type_=0, name=None, reference=None, messages=[],
accountno_beneficiary=None, accountno_payer=None,
amount=0):
self.transaction = TransactionRecord()
self.paymentreference = Optional(PaymentReferenceRecord)
self.description = Optional(DescriptionRecord, 4)
self.transaction.transactiontype = type_
# Remove Postbank account marker 'P'
self.transaction.accountno_beneficiary = accountno_beneficiary.replace(
'P', '0')
self.transaction.accountno_payer = accountno_payer.replace('P', '0')
self.transaction.amount = int(round(amount * 100))
if reference:
self.paymentreference.paymentreference = reference
# Allow long message lines to redistribute over multiple message
# records
for msg in chunk(''.join(messages),
self.description.length('description')):
try:
self.description.description = msg
except ValueError:
break
self.name.name = name
class DirectDebit(Transaction):
'''Direct Debit Payment transaction'''
def __init__(self, *args, **kwargs):
reknr = kwargs['accountno_payer']
kwargs['type_'] = len(reknr.lstrip('0')) <= 7 and 1002 or 1001
self.name = NamePayerRecord()
super(DirectDebit, self).__init__(*args, **kwargs)
@property
def rawdata(self):
'''
Return self as writeable file content object
'''
items = [str(self.transaction)]
if self.name:
items.append(str(self.name))
for reference in self.paymentreference:
items.append(str(reference))
for description in self.description:
items.append(str(description))
return '\r\n'.join(items)
class Payment(Transaction):
'''Payment transaction'''
def __init__(self, *args, **kwargs):
reknr = kwargs['accountno_beneficiary']
if len(reknr.lstrip('0')) > 7:
if not eleven_test(reknr):
raise ValueError('%s is not a valid bank account' % reknr)
kwargs['type_'] = 5
self.name = NameBeneficiaryRecord()
super(Payment, self).__init__(*args, **kwargs)
@property
def rawdata(self):
'''
Return self as writeable file content object
'''
items = [str(self.transaction)]
for reference in self.paymentreference:
items.append(str(reference))
for description in self.description:
items.append(str(description))
if self.name:
items.append(str(self.name))
return '\r\n'.join(items)
class SalaryPayment(Payment):
'''Salary Payment transaction'''
def __init__(self, *args, **kwargs):
reknr = kwargs['accountno_beneficiary']
kwargs['type_'] = len(reknr.lstrip('0')) <= 7 and 3 or 8
super(SalaryPayment, self).__init__(*args, **kwargs)
class Batch(object):
'''Generic batch class'''
transactionclass = None
def __init__(self, sender, rekeningnr, execution_date=None,
test=True, messages=[], transactiongroup=None,
batch_tracer=1, batch_id=''):
self.header = BatchHeaderRecord()
self.fixed_message = Optional(FixedMessageRecord, 4)
self.sender = SenderRecord()
self.footer = BatchFooterRecord()
self.header.variantcode = batch_id and 'C' or 'B'
self.header.transactiongroup = transactiongroup
self.header.batch_tracer = batch_tracer
self.header.batch_id = batch_id or ''
self.header.accountno_sender = rekeningnr
self.sender.name_sender = sender
self.sender.preferred_execution_date = execution_date
self.sender.NAWcode = 1
self.sender.testcode = test and 'T' or 'P'
self.transactions = []
for message in messages:
self.fixed_message.fixed_message = message
@property
def nr_posts(self):
'''nr of posts'''
return len(self.transactions)
@property
def total_amount(self):
'''total amount transferred'''
return reduce(lambda x, y: x + int(y.transaction.amount),
self.transactions, 0)
@property
def total_accountnos(self):
'''check number on account numbers'''
return reduce(lambda x, y:
x + int(y.transaction.accountno_payer) +
int(y.transaction.accountno_beneficiary),
self.transactions, 0)
@property
def rawdata(self):
'''
Return self as writeable file content object
'''
self.footer.nr_posts = self.nr_posts
self.footer.total_amount = self.total_amount
self.footer.total_accountnos = self.total_accountnos
lines = [str(self.header)]
for msg in self.fixed_message:
lines.append(str(msg))
lines += [
str(self.sender),
'\r\n'.join([x.rawdata for x in self.transactions]),
str(self.footer)
]
return '\r\n'.join(lines)
def transaction(self, *args, **kwargs):
'''generic factory method'''
retval = self.transactionclass(*args, **kwargs)
self.transactions.append(retval)
return retval
class DirectDebitBatch(Batch):
'''Direct Debig Payment batch'''
transactionclass = DirectDebit
class PaymentsBatch(Batch):
'''Payment batch'''
transactionclass = Payment
class SalaryBatch(Batch):
'''Salary payment class'''
transactionclass = SalaryPayment
class ClieOpFile(object):
'''The grand unifying class'''
def __init__(self, identification='1', execution_date=None,
name_sender='', accountno_sender='',
test=False, seqno=1, **kwargs):
self.header = HeaderRecord(id=identification, seqno=seqno)
self.footer = FooterRecord()
self.batches = []
self._execution_date = execution_date
self._identification = identification
self._name_sender = name_sender
self._accno_sender = accountno_sender
self._test = test
@property
def rawdata(self):
'''Return self as writeable file content object'''
return '\r\n'.join(
[str(self.header)] +
[x.rawdata for x in self.batches] +
[str(self.footer)]
)
def batch(self, *args, **kwargs):
'''Create batch'''
kwargs['transactiongroup'] = self.transactiongroup
kwargs['batch_tracer'] = len(self.batches) + 1
kwargs['execution_date'] = self._execution_date
kwargs['test'] = self._test
args = (self._name_sender, self._accno_sender)
retval = self.batchclass(*args, **kwargs)
self.batches.append(retval)
return retval
@property
def order(self):
'''Produce an order to go with the file'''
total_accountnos = 0
total_amount = 0
nr_posts = 0
for batch in self.batches:
total_accountnos += batch.total_accountnos
total_amount += batch.total_amount
nr_posts += batch.nr_posts
retval = self.orderclass()
retval.identification = self._identification
retval.accountno_sender = self._accno_sender
retval.preferred_execution_date = self._execution_date
retval.testcode = self._test and 'T' or 'P'
retval.total_amount = total_amount
retval.nr_posts = nr_posts
retval.total_accountnos = total_accountnos
return retval
class DirectDebitFile(ClieOpFile):
'''Direct Debit Payments file'''
transactiongroup = '10'
batchclass = DirectDebitBatch
orderclass = DirectDebitOrder
class PaymentsFile(ClieOpFile):
'''Payments file'''
transactiongroup = '00'
batchclass = PaymentsBatch
orderclass = PaymentOrder
class SalaryPaymentsFile(PaymentsFile):
'''Salary Payments file'''
batchclass = SalaryBatch
orderclass = SalaryPaymentOrder

View File

@@ -1,401 +0,0 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
# 2011 - 2013 Therp BV (<http://therp.nl>).
# 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/>.
#
##############################################################################
import base64
from datetime import datetime, timedelta
from openerp.osv import orm, fields
from openerp.tools.translate import _
from openerp import netsvc
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT
from openerp.addons.account_banking import sepa
from openerp.addons.account_banking_nl_clieop.wizard import clieop
def strpdate(arg):
'''shortcut'''
return datetime.strptime(arg, DEFAULT_SERVER_DATE_FORMAT).date()
def strfdate(arg):
'''shortcut'''
return arg.strftime(DEFAULT_SERVER_DATE_FORMAT)
class banking_export_clieop_wizard(orm.TransientModel):
_name = 'banking.export.clieop.wizard'
_description = 'Client Opdrachten Export'
_columns = {
'state': fields.selection(
[
('create', 'Create'),
('finish', 'Finish')
],
'State',
readonly=True,
),
'reference': fields.char(
'Reference', size=5,
help=('The bank will use this reference in feedback communication '
'to refer to this run. Only five characters are available.'
),
),
'batchtype': fields.selection(
[
('CLIEOPPAY', 'Payments'),
('CLIEOPSAL', 'Salary Payments'),
('CLIEOPINC', 'Direct Debits'),
], 'Type', readonly=True,
),
'execution_date': fields.date(
'Execution Date',
help=('This is the date the file should be processed by the bank. '
'Don\'t choose a date beyond the nearest date in your '
'payments. The latest allowed date is 30 days from now.\n'
'Please keep in mind that banks only execute on working '
'days and typically use a delay of two days between '
'execution date and effective transfer date.'),
),
'test': fields.boolean(
'Test Run',
help=('Select this if you want your bank to run a test process '
'rather then execute your orders for real.'
),
),
'fixed_message': fields.char(
'Fixed Message', size=32,
help=('A fixed message to apply to all transactions in addition '
'to the individual messages.'),
),
# file fields
'file_id': fields.many2one(
'banking.export.clieop',
'ClieOp File',
readonly=True
),
# fields.related does not seem to support
# fields of type selection
'testcode': fields.selection(
[('T', _('Yes')), ('P', _('No'))],
'Test Run', readonly=True,
),
'filetype': fields.selection(
[
('CREDBET', 'Payment Batch'),
('SALARIS', 'Salary Payment Batch'),
('INCASSO', 'Direct Debit Batch'),
],
'File Type',
readonly=True,
),
'prefered_date': fields.related(
'file_id', 'prefered_date',
type='date',
string='Prefered Processing Date',
readonly=True,
),
'no_transactions': fields.related(
'file_id', 'no_transactions',
type ='integer',
string='Number of Transactions',
readonly=True,
),
'check_no_accounts': fields.related(
'file_id', 'check_no_accounts',
type='char', size=5,
string='Check Number Accounts',
readonly=True,
),
'total_amount': fields.related(
'file_id', 'total_amount',
type='float',
string='Total Amount',
readonly=True,
),
'identification': fields.related(
'file_id', 'identification',
type='char', size=6,
string='Identification',
readonly=True,
),
'file': fields.related(
'file_id', 'file', type='binary',
readonly=True,
string='File',
),
'filename': fields.related(
'file_id', 'filename',
type='char', size=32,
readonly=True,
string='Filename',
),
'payment_order_ids': fields.many2many(
'payment.order', 'rel_wiz_payorders', 'wizard_id',
'payment_order_id', 'Payment Orders',
readonly=True,
),
}
def create(self, cr, uid, vals, context=None):
'''
Retrieve a sane set of default values based on the payment orders
from the context.
'''
if 'batchtype' not in vals:
self.check_orders(cr, uid, vals, context)
return super(banking_export_clieop_wizard, self).create(
cr, uid, vals, context)
def check_orders(self, cr, uid, vals, context):
'''
Check payment type for all orders.
Combine orders into one. All parameters harvested by the wizard
will apply to all orders. This will in effect create one super
batch for ClieOp, instead of creating individual parameterized
batches. As only large companies are likely to need the individual
settings per batch, this will do for now.
Also mind that rates for batches are way higher than those for
transactions. It pays to limit the number of batches.
'''
today = strpdate(fields.date.context_today(
self, cr, uid, context=context
))
payment_order_obj = self.pool.get('payment.order')
# Payment order ids are provided in the context
payment_order_ids = context.get('active_ids', [])
runs = {}
# Only orders of same type can be combined
payment_orders = payment_order_obj.browse(cr, uid, payment_order_ids)
for payment_order in payment_orders:
payment_type = payment_order.mode.type.code
if payment_type in runs:
runs[payment_type].append(payment_order)
else:
runs[payment_type] = [payment_order]
if payment_order.date_prefered == 'fixed':
if payment_order.date_scheduled:
execution_date = strpdate(payment_order.date_scheduled)
else:
execution_date = today
elif payment_order.date_prefered == 'now':
execution_date = today
elif payment_order.date_prefered == 'due':
# Max processing date is 30 days past now, so limiting beyond
# that will catch too early payments
max_date = execution_date = today + timedelta(days=31)
for line in payment_order.line_ids:
if line.move_line_id.date_maturity:
date_maturity = strpdate(
line.move_line_id.date_maturity
)
if date_maturity < execution_date:
execution_date = date_maturity
else:
execution_date = today
if execution_date and execution_date >= max_date:
raise orm.except_orm(
_('Error'),
_('You can\'t create ClieOp orders more than 30 days '
'in advance.')
)
if len(runs) != 1:
raise orm.except_orm(
_('Error'),
_('You can only combine payment orders of the same type')
)
type = runs.keys()[0]
vals.update({
'execution_date': strfdate(max(execution_date, today)),
'batchtype': type,
'reference': runs[type][0].reference[-5:],
'payment_order_ids': [[6, 0, payment_order_ids]],
'state': 'create',
})
def create_clieop(self, cr, uid, ids, context):
'''
Wizard to actually create the ClieOp3 file
'''
clieop_export = self.browse(cr, uid, ids, context)[0]
clieopfile = None
for payment_order in clieop_export.payment_order_ids:
if not clieopfile:
# Just once: create clieop file
our_account_owner = (
payment_order.mode.bank_id.owner_name
or payment_order.mode.bank_id.partner_id.name
)
if payment_order.mode.bank_id.state == 'iban':
our_account_nr = (
payment_order.mode.bank_id.acc_number_domestic)
if not our_account_nr:
our_account_nr = sepa.IBAN(
payment_order.mode.bank_id.acc_number
).localized_BBAN
else:
our_account_nr = payment_order.mode.bank_id.acc_number
if not our_account_nr:
raise orm.except_orm(
_('Error'),
_('Your bank account has to have a valid account '
'number')
)
clieopfile = {
'CLIEOPPAY': clieop.PaymentsFile,
'CLIEOPINC': clieop.DirectDebitFile,
'CLIEOPSAL': clieop.SalaryPaymentsFile,
}[clieop_export['batchtype']](
identification=clieop_export['reference'],
execution_date=clieop_export['execution_date'],
name_sender=our_account_owner,
accountno_sender=our_account_nr,
seqno=self.pool.get('banking.export.clieop').get_daynr(
cr, uid, context=context),
test=clieop_export['test']
)
# ClieOp3 files can contain multiple batches, but we put all
# orders into one single batch. Ratio behind this is that a
# batch costs more money than a single transaction, so it is
# cheaper to combine than it is to split. As we split out all
# reported errors afterwards, there is no additional gain in
# using multiple batches.
if clieop_export['fixed_message']:
messages = [clieop_export['fixed_message']]
else:
messages = []
# The first payment order processed sets the reference of the
# batch.
batch = clieopfile.batch(
messages=messages,
batch_id=clieop_export['reference']
)
for line in payment_order.line_ids:
# Check on missing partner of bank account (this can happen!)
if not line.bank_id or not line.bank_id.partner_id:
raise orm.except_orm(
_('Error'),
_('There is insufficient information.\r\n'
'Both destination address and account '
'number must be provided'
)
)
kwargs = dict(
name=line.bank_id.owner_name
or line.bank_id.partner_id.name,
amount=line.amount_currency,
reference=line.communication or None,
)
if line.communication2:
kwargs['messages'] = [line.communication2]
other_account_nr = (
line.bank_id.state == 'iban' and
line.bank_id.acc_number_domestic or
line.bank_id.acc_number
)
iban = sepa.IBAN(other_account_nr)
# Is this an IBAN account?
if iban.valid:
if iban.countrycode != 'NL':
raise orm.except_orm(
_('Error'),
_('You cannot send international bank transfers '
'through ClieOp3!')
)
other_account_nr = iban.localized_BBAN
if clieop_export['batchtype'] == 'CLIEOPINC':
kwargs['accountno_beneficiary'] = our_account_nr
kwargs['accountno_payer'] = other_account_nr
else:
kwargs['accountno_beneficiary'] = other_account_nr
kwargs['accountno_payer'] = our_account_nr
batch.transaction(**kwargs)
# Generate the specifics of this clieopfile
order = clieopfile.order
file_id = self.pool.get('banking.export.clieop').create(
cr, uid, dict(
filetype=order.name_transactioncode,
identification=order.identification,
prefered_date=strfdate(order.preferred_execution_date),
total_amount=int(order.total_amount) / 100.0,
check_no_accounts=order.total_accountnos,
no_transactions=order.nr_posts,
testcode=order.testcode,
file=base64.encodestring(clieopfile.rawdata),
filename='Clieop03-{0}.txt'.format(order.identification),
daynumber=int(clieopfile.header.file_id[2:]),
payment_order_ids=[
[6, 0, [x.id
for x in clieop_export['payment_order_ids']]]],
), context)
self.write(cr, uid, [ids[0]], dict(
filetype=order.name_transactioncode,
testcode=order.testcode,
file_id=file_id,
state='finish',
), context)
return {
'name': _('Client Opdrachten Export'),
'view_type': 'form',
'view_mode': 'form',
'res_model': self._name,
'domain': [],
'context': dict(context, active_ids=ids),
'type': 'ir.actions.act_window',
'target': 'new',
'res_id': ids[0] or False,
}
def cancel_clieop(self, cr, uid, ids, context):
'''
Cancel the ClieOp: just drop the file
'''
clieop_export = self.read(cr, uid, ids, ['file_id'], context)[0]
self.pool.get('banking.export.clieop').unlink(
cr, uid, clieop_export['file_id'][0]
)
return {'type': 'ir.actions.act_window_close'}
def save_clieop(self, cr, uid, ids, context):
'''
Save the ClieOp: mark all payments in the file as 'sent', if not a test
'''
clieop_export = self.browse(
cr, uid, ids, context)[0]
if not clieop_export['test']:
clieop_obj = self.pool.get('banking.export.clieop')
clieop_obj.write(
cr, uid, clieop_export['file_id'].id, {'state': 'sent'}
)
wf_service = netsvc.LocalService('workflow')
for order in clieop_export['payment_order_ids']:
wf_service.trg_validate(
uid, 'payment.order', order.id, 'sent', cr
)
return {'type': 'ir.actions.act_window_close'}

View File

@@ -1,58 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="banking_export_clieop_wizard_view" model="ir.ui.view">
<field name="name">banking.export.clieop.wizard.view</field>
<field name="model">banking.export.clieop.wizard</field>
<field name="arch" type="xml">
<form string="Client Opdrachten Export">
<field name="state" invisible="True"/>
<group states="create">
<separator colspan="4" string="Processing Details" />
<field name="batchtype" />
<field name="execution_date" />
<field name="test" />
<separator colspan="4" string="Reference for further communication" />
<field name="reference" colspan="2" />
<separator colspan="4" string="Additional message for all transactions" />
<field name="fixed_message" />
<newline/>
<button icon="gtk-close"
special="cancel"
string="Cancel"
/>
<button icon="gtk-ok"
string="Create"
name="create_clieop"
type="object"
/>
</group>
<group states="finish">
<field name="filetype" />
<field name="identification" />
<field name="total_amount" />
<field name="check_no_accounts" />
<field name="no_transactions" />
<field name="prefered_date" />
<field name="testcode" />
<newline/>
<field name="filename" invisible="True"/>
<field name="file_id" />
<field name="file" filename="filename"/>
<newline/>
<button icon="gtk-close"
string="Cancel"
name="cancel_clieop"
type="object"
/>
<button icon="gtk-ok"
string="Finish"
name="save_clieop"
type="object"
/>
</group>
</form>
</field>
</record>
</data>
</openerp>

View File

@@ -124,7 +124,7 @@ class banking_import_transaction(orm.Model):
"""
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.
which checks bank account number, disregarding spaces.
:param account: string representation of a bank account number
:param partner_bank: browse record of model res.partner.bank