[MERGE] with main branch revno 202

This commit is contained in:
Alexis de Lattre
2013-11-07 12:54:02 +01:00
76 changed files with 2896 additions and 1234 deletions

View File

@@ -0,0 +1 @@
import model

View File

@@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2012 - 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/>.
#
##############################################################################
{
'name': 'Apply a tax on bank statement lines',
'version': '0.1',
'license': 'AGPL-3',
'author': 'Therp BV',
'website': 'https://launchpad.net/banking-addons',
'category': 'Banking addons',
'depends': [
'account',
],
'data': [
'view/account_bank_statement.xml',
],
'description': '''
Allow an (inclusive) tax to be set on a bank statement line. When the
statement is confirmed, the tax will be processed like a tax set on a
move line.
This module is co-funded by BAS Solutions.
''',
'installable': True,
}

View File

@@ -0,0 +1,38 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * account_bank_statement_tax
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 7.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-10-04 05:03+0000\n"
"PO-Revision-Date: 2013-10-06 13:13+0100\n"
"Last-Translator: Erwin van der Ploeg | Endian Solutions "
"<erwin@endiansolutions.nl>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: \n"
"X-Generator: Poedit 1.5.7\n"
#. module: account_bank_statement_tax
#: model:ir.model,name:account_bank_statement_tax.model_account_bank_statement_line
msgid "Bank Statement Line"
msgstr "Bankafschriftregel"
#. module: account_bank_statement_tax
#: field:account.bank.statement.line,tax_id:0
msgid "Tax"
msgstr "Belasting"
#. module: account_bank_statement_tax
#: help:account.bank.statement.line,tax_id:0
msgid "Apply an (inclusive) tax from the bank statement line"
msgstr "Voeg een inclusief belasting tarief toe aan de afschriftregel."
#. module: account_bank_statement_tax
#: model:ir.model,name:account_bank_statement_tax.model_account_bank_statement
msgid "Bank Statement"
msgstr "Bankafschrift"

View File

@@ -0,0 +1,2 @@
import account_bank_statement_line
import account_bank_statement

View File

@@ -0,0 +1,109 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2012 - 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
from openerp.tools import ustr
class AccountBankStatement(orm.Model):
_inherit = 'account.bank.statement'
def get_tax_move_lines(
self, cr, uid, st_line, defaults,
company_currency_id, context=None):
"""
Process inclusive taxes on bank statement lines.
@param st_line: browse record of the statement line
@param defaults: dictionary of default move line values. Usually
the same as the originating move line.
return one or more serialized tax move lines and a set of values to
update the originating move line with, containing the new amount.
"""
if not st_line.tax_id:
return False, False
tax_obj = self.pool.get('account.tax')
move_lines = []
update_move_line = {}
base_amount = -defaults['credit'] or defaults['debit']
tax_obj = self.pool.get('account.tax')
fiscal_position = (
st_line.partner_id.property_account_position
if st_line.partner_id and
st_line.partner_id.property_account_position
else False)
tax_ids = self.pool.get('account.fiscal.position').map_tax(
cr, uid, fiscal_position, [st_line.tax_id])
taxes = tax_obj.browse(cr, uid, tax_ids, context=context)
computed_taxes = tax_obj.compute_all(
cr, uid, taxes, base_amount, 1.00)
for tax in computed_taxes['taxes']:
if tax['tax_code_id']:
if not update_move_line.get('tax_code_id'):
update_move_line['tax_code_id'] = tax['base_code_id']
update_move_line['tax_amount'] = tax['base_sign'] * (
computed_taxes.get('total', 0.0))
# As the tax is inclusive, we need to correct the amount on the
# original move line
amount = computed_taxes.get('total', 0.0)
update_move_line['credit'] = ((amount < 0) and -amount) or 0.0
update_move_line['debit'] = ((amount > 0) and amount) or 0.0
move_lines.append({
'move_id': defaults['move_id'],
'name': defaults.get('name', '') + ' ' + ustr(tax['name'] or ''),
'date': defaults.get('date', False),
'partner_id': defaults.get('partner_id', False),
'ref': defaults.get('ref', False),
'statement_id': defaults.get('statement_id'),
'tax_code_id': tax['tax_code_id'],
'tax_amount': tax['tax_sign'] * tax.get('amount', 0.0),
'account_id': tax.get('account_collected_id', defaults['account_id']),
'credit': tax['amount'] < 0 and - tax['amount'] or 0.0,
'debit': tax['amount'] > 0 and tax['amount'] or 0.0,
'account_id': tax.get('account_collected_id', defaults['account_id']),
})
return move_lines, update_move_line
def _prepare_bank_move_line(
self, cr, uid, st_line, move_id, amount, company_currency_id,
context=None):
"""
Overload of the original method from the account module. Create
the tax move lines.
"""
res = super(AccountBankStatement, self)._prepare_bank_move_line(
cr, uid, st_line, move_id, amount, company_currency_id,
context=context)
if st_line.tax_id:
tax_move_lines, counterpart_update_vals = self.get_tax_move_lines(
cr, uid, st_line, res, company_currency_id, context=context)
res.update(counterpart_update_vals)
for tax_move_line in tax_move_lines:
self.pool.get('account.move.line').create(
cr, uid, tax_move_line, context=context)
return res

View File

@@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2012 - 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
class AccountBankStatementLine(orm.Model):
_inherit = 'account.bank.statement.line'
_columns = {
'tax_id': fields.many2one(
'account.tax', 'Tax',
domain=[('price_include','=', True)],
help="Apply an (inclusive) tax from the bank statement line",
),
}

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_bank_statement_form" model="ir.ui.view">
<field name="name">Add tax to the embedded bank statement line form</field>
<field name="inherit_id" ref="account.view_bank_statement_form" />
<field name="model">account.bank.statement</field>
<field name="arch" type="xml">
<xpath expr="//field[@name='line_ids']/tree/field[@name='amount']"
position="after">
<field name="tax_id"
domain="[('parent_id', '=', False), ('price_include', '=', True), ('type_tax_use', 'in', (amount and amount &gt; 0 and ('sale', 'all') or ('purchase', 'all')))]"
/>
</xpath>
</field>
</record>
</data>
</openerp>

View File

@@ -63,6 +63,7 @@ Modifications are extensive:
'''
from openerp.osv import orm, fields
from openerp.osv.osv import except_osv
from openerp.tools.translate import _
from openerp import netsvc, SUPERUSER_ID
from openerp.addons.decimal_precision import decimal_precision as dp
@@ -274,17 +275,18 @@ account_banking_imported_file()
class account_bank_statement(orm.Model):
'''
Extensions from account_bank_statement:
1. Removed period_id (transformed to optional boolean) - as it is no
longer needed.
NB! because of #1. changes required to account_voucher!
2. Extended 'button_confirm' trigger to cope with the period per
statement_line situation.
3. Added optional relation with imported statements file
4. Ordering is based on auto generated id.
Implement changes to this model for the following features:
* bank statement lines have their own period_id, derived from
their effective date. The period and date are propagated to
the move lines created from each statement line
* bank statement lines have their own state. When a statement
is confirmed, all lines are confirmed too. When a statement
is reopened, lines remain confirmed until reopened individually.
* upon confirmation of a statement line, the move line is
created and reconciled according to the matched entry(/ies)
'''
_inherit = 'account.bank.statement'
_order = 'id'
_columns = {
'period_id': fields.many2one('account.period', 'Period',
@@ -468,9 +470,27 @@ class account_bank_statement_line(orm.Model):
_description = 'Bank Transaction'
def _get_period(self, cr, uid, context=None):
date = context.get('date', None)
periods = self.pool.get('account.period').find(cr, uid, dt=date)
return periods and periods[0] or False
"""
Get a non-opening period for today or a date specified in
the context.
Used in this model's _defaults, so it is always triggered
on installation or module upgrade. For that reason, we need
to be tolerant and allow for the situation in which no period
exists for the current date (i.e. when no date is specified).
"""
if context is None:
context = {}
date = context.get('date', False)
local_ctx = dict(context)
local_ctx['account_period_prefer_normal'] = True
try:
return self.pool.get('account.period').find(
cr, uid, dt=date, context=local_ctx)[0]
except except_osv:
if date:
raise
return False
def _get_currency(self, cr, uid, context=None):
'''

View File

@@ -72,7 +72,7 @@ class banking_import_transaction(orm.Model):
invoice_ids = invoice_obj.search(cr, uid, [
'&',
('type', '=', 'in_invoice'),
('partner_id', '=', account_info.bank_partner_id.id),
('partner_id', 'child_of', account_info.bank_partner_id.id),
('company_id', '=', account_info.company_id.id),
('date_invoice', '=', trans.effective_date),
('reference', '=', reference),
@@ -193,6 +193,10 @@ class banking_import_transaction(orm.Model):
iname = invoice.name.upper()
if iname in ref or iname in msg:
return True
if invoice.supplier_invoice_number and len(invoice.supplier_invoice_number) > 2:
supp_ref = invoice.supplier_invoice_number.upper()
if supp_ref in ref or supp_ref in msg:
return True
elif invoice.type.startswith('out_'):
# External id's possible and likely
inum = invoice.number.upper()
@@ -1112,21 +1116,23 @@ class banking_import_transaction(orm.Model):
# the internal type of these accounts to either 'payable'
# or 'receivable' to enable usage like this.
if transaction.statement_line_id.amount < 0:
if len(partner_banks) == 1:
account_id = (
partner_banks[0].partner_id.property_account_payable and
partner_banks[0].partner_id.property_account_payable.id)
if len(partner_banks) != 1 or not account_id or account_id == def_pay_account_id:
account_id = (account_info.default_credit_account_id and
account_info.default_credit_account_id.id)
account_type = 'payable'
else:
if len(partner_banks) == 1:
account_id = (
partner_banks[0].partner_id.property_account_receivable and
partner_banks[0].partner_id.property_account_receivable.id)
if len(partner_banks) != 1 or not account_id or account_id == def_rec_account_id:
account_id = (account_info.default_debit_account_id and
account_info.default_debit_account_id.id)
account_type = 'receivable'
if len(partner_banks) == 1:
partner = partner_banks[0].partner_id
if partner.supplier and not partner.customer:
account_type = 'payable'
elif partner.customer and not partner.supplier:
account_type = 'receivable'
if partner['property_account_' + account_type]:
account_id = partner['property_account_' + account_type].id
if not account_id or account_id in (def_pay_account_id, def_rec_account_id):
if account_type == 'payable':
account_id = account_info.default_credit_account_id.id
else:
account_id = account_info.default_debit_account_id.id
values = {'account_id': account_id}
self_values = {}
if move_info:
@@ -1211,8 +1217,6 @@ class banking_import_transaction(orm.Model):
'match_type',
'move_line_id',
'invoice_id',
'manual_invoice_id',
'manual_move_line_id',
]] +
[(x, [(6, 0, [])]) for x in [
'move_line_ids',
@@ -1299,9 +1303,9 @@ class banking_import_transaction(orm.Model):
'exchange_rate': fields.float('exchange_rate'),
'transferred_amount': fields.float('transferred_amount'),
'message': fields.char('message', size=1024),
'remote_owner': fields.char('remote_owner', size=24),
'remote_owner_address': fields.char('remote_owner_address', size=24),
'remote_owner_city': fields.char('remote_owner_city', size=24),
'remote_owner': fields.char('remote_owner', size=128),
'remote_owner_address': fields.char('remote_owner_address', size=256),
'remote_owner_city': fields.char('remote_owner_city', size=128),
'remote_owner_postalcode': fields.char('remote_owner_postalcode', size=24),
'remote_owner_country_code': fields.char('remote_owner_country_code', size=24),
'remote_owner_custno': fields.char('remote_owner_custno', size=24),
@@ -1497,7 +1501,7 @@ class account_bank_statement_line(orm.Model):
if (not statement_line.import_transaction_id or
not statement_line.import_transaction_id.remote_account):
raise osv.except_osv(
raise orm.except_orm(
_("Error"),
_("No bank account available to link partner to"))

View File

@@ -13,12 +13,5 @@
<field eval="False" name="required"/>
<field eval="False" name="readonly"/>
</record>
<!--
BIC is not legally required
See https://bugs.launchpad.net/bugs/933472
-->
<record id="base_iban.bank_swift_field" model="res.partner.bank.type.field">
<field eval="False" name="required"/>
</record>
</data>
</openerp>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 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/>.
#
##############################################################################
def migrate(cr, version):
if not version:
return
# workflow state moved to another, new module
cr.execute(
"""
UPDATE ir_model_data
SET module = 'account_banking_payment'
WHERE name = 'trans_done_sent'
AND module = 'account_direct_debit'
""")

View File

@@ -19,6 +19,7 @@
#
##############################################################################
import re
from tools.translate import _
class mem_bank_statement(object):
@@ -34,7 +35,7 @@ class mem_bank_statement(object):
# Lock attributes to enable parsers to trigger non-conformity faults
__slots__ = [
'start_balance','end_balance', 'date', 'local_account',
'local_currency', 'id', 'statements'
'local_currency', 'id', 'transactions'
]
def __init__(self, *args, **kwargs):
super(mem_bank_statement, self).__init__(*args, **kwargs)
@@ -353,6 +354,33 @@ class parser(object):
name = "%s-%d" % (base, suffix)
return name
def get_unique_account_identifier(self, cr, account):
"""
Get an identifier for a local bank account, based on the last
characters of the account number with minimum length 3.
The identifier should be unique amongst the company accounts
Presumably, the bank account is one of the company accounts
itself but importing bank statements for non-company accounts
is not prevented anywhere else in the system so the 'account'
param being a company account is not enforced here either.
"""
def normalize(account_no):
return re.sub('\s', '', account_no)
account = normalize(account)
cr.execute(
"""SELECT acc_number FROM res_partner_bank
WHERE company_id IS NOT NULL""")
accounts = [normalize(row[0]) for row in cr.fetchall()]
tail_length = 3
while tail_length <= len(account):
tail = account[-tail_length:]
if len([acc for acc in accounts if acc.endswith(tail)]) < 2:
return tail
tail_length += 1
return account
def parse(self, cr, data):
'''
Parse data.

View File

@@ -190,7 +190,7 @@ class IBAN(str):
BBAN_formats = {
'AL': BBANFormat('CCBBBBVAAAAAAAAAAAAAAAAAA', '%B%A'),
'AD': BBANFormat('CCCCBBBBAAAAAAAAAAAA', '%A'),
'AT': BBANFormat('BBBBBAAAAAAAAAAA', '%A BLZ %C'),
'AT': BBANFormat('BBBBBAAAAAAAAAAA', '%A BLZ %B'),
'BE': BBANFormat('CCCAAAAAAAVV', '%C-%A-%V'),
'BA': BBANFormat('BBBCCCAAAAAAAA', '%I'),
'BG': BBANFormat('BBBBCCCCAAAAAAAAAA', '%I'),
@@ -214,7 +214,7 @@ class IBAN(str):
'GR': BBANFormat('BBBCCCCAAAAAAAAAAAAAAAA', '%B-%C-%A', nolz=True),
'HR': BBANFormat('BBBBBBBAAAAAAAAAA', '%B-%A'),
'HU': BBANFormat('BBBCCCCXAAAAAAAAAAAAAAAV', '%B%C%X %A%V'),
'IE': BBANFormat('BBBBCCCCCCAAAAAAAAV', '%C %A%V'),
'IE': BBANFormat('BBBBCCCCCCAAAAAAAA', '%C %A'),
'IL': BBANFormat('BBBCCCAAAAAAAAAAAAA', '%C%A'),
# Iceland uses an extra identification number, split in two on
# display. Coded here as %P%V.

View File

@@ -131,7 +131,7 @@ class banking_transaction_wizard(orm.TransientModel):
{ 'move_line_id': move_line.id, }, context=context)
statement_line_obj.write(
cr, uid, wiz.import_transaction_id.statement_line_id.id,
{ 'partner_id': move_line.invoice.partner_id.id,
{ 'partner_id': move_line.partner_id.id or False,
'account_id': move_line.account_id.id,
}, context=context)
found = True
@@ -226,9 +226,9 @@ class banking_transaction_wizard(orm.TransientModel):
}
if todo_entry[0]:
st_line_vals['partner_id'] = invoice_obj.read(
cr, uid, todo_entry[0],
['partner_id'], context=context)['partner_id'][0]
st_line_vals['partner_id'] = invoice_obj.browse(
cr, uid, todo_entry[0], context=context
).partner_id.commercial_partner_id.id
statement_line_obj.write(
cr, uid, statement_line_id,
@@ -256,14 +256,7 @@ class banking_transaction_wizard(orm.TransientModel):
account_id = False
journal_id = wiz.statement_line_id.statement_id.journal_id.id
setting_ids = settings_pool.find(cr, uid, journal_id, context=context)
if len(setting_ids)>0:
setting = settings_pool.browse(cr, uid, setting_ids[0], context=context)
if wiz.amount < 0:
account_id = setting.default_credit_account_id and setting.default_credit_account_id.id
else:
account_id = setting.default_debit_account_id and setting.default_debit_account_id.id
statement_pool.write(cr, uid, wiz.statement_line_id.id, {'account_id':account_id})
# Restore partner id from the bank account or else reset
partner_id = False
if (wiz.statement_line_id.partner_bank_id and
@@ -271,6 +264,38 @@ class banking_transaction_wizard(orm.TransientModel):
partner_id = wiz.statement_line_id.partner_bank_id.partner_id.id
wiz.write({'partner_id': partner_id})
# Select account type by parter customer or supplier,
# or default based on amount sign
if wiz.amount < 0:
account_type = 'payable'
else:
account_type = 'receivable'
if partner_id:
partner = wiz.statement_line_id.partner_bank_id.partner_id
if partner.supplier and not partner.customer:
account_type = 'payable'
elif partner.customer and not partner.supplier:
account_type = 'receivable'
if partner['property_account_' + account_type]:
account_id = partner['property_account_' + account_type].id
company_partner = wiz.statement_line_id.statement_id.company_id.partner_id
if len(setting_ids) and (
not account_id
or account_id in (
company_partner.property_account_payable.id,
company_partner.property_account_receivable.id)
):
setting = settings_pool.browse(cr, uid, setting_ids[0], context=context)
if account_type == 'payable':
account_id = setting.default_credit_account_id.id
else:
account_id = setting.default_debit_account_id.id
if account_id:
wiz.statement_line_id.write({'account_id': account_id})
if wiz.statement_line_id:
#delete splits causing an unsplit if this is a split
#transaction
@@ -314,6 +339,10 @@ class banking_transaction_wizard(orm.TransientModel):
'ref': fields.related(
'statement_line_id', 'ref', type='char', size=32,
string="Reference", readonly=True),
'message': fields.related(
'statement_line_id', 'import_transaction_id', 'message',
type='char', size=1024,
string="Message", readonly=True),
'partner_id': fields.related(
'statement_line_id', 'partner_id',
type='many2one', relation='res.partner',
@@ -363,13 +392,6 @@ class banking_transaction_wizard(orm.TransientModel):
('payment_order_manual', 'Payment order (manual)'),
],
string='Match type', readonly=True),
'manual_invoice_id': fields.many2one(
'account.invoice', 'Match this invoice',
domain=[('reconciled', '=', False)]),
'manual_move_line_id': fields.many2one(
'account.move.line', 'Or match this entry',
domain=[('account_id.reconcile', '=', True),
('reconcile_id', '=', False)]),
'manual_invoice_ids': fields.many2many(
'account.invoice',
'banking_transaction_wizard_account_invoice_rel',

View File

@@ -17,8 +17,9 @@
<separator string="Transaction data" colspan="4"/>
<field name="partner_id"/>
<field name="date"/>
<field name="ref"/>
<field name="amount"/>
<field name="ref"/>
<field name="message" colspan="4"/>
</group>
<!-- (semi-) automatic matching and selection -->

View File

@@ -97,8 +97,11 @@ def get_partner(pool, cr, uid, name, address, postal_code, city,
TODO: revive the search by lines from the address argument
'''
partner_obj = pool.get('res.partner')
partner_ids = partner_obj.search(cr, uid, [('name', 'ilike', name)],
context=context)
partner_ids = partner_obj.search(
cr, uid, [
'|', ('is_company', '=', True), ('parent_id', '=', False),
('name', 'ilike', name),
], context=context)
if not partner_ids:
# Try brute search on address and then match reverse
criteria = []
@@ -118,11 +121,11 @@ def get_partner(pool, cr, uid, name, address, postal_code, city,
key = name.lower()
partners = []
for partner in partner_obj.read(
cr, uid, partner_search_ids, ['name'], context=context):
cr, uid, partner_search_ids, ['name', 'commercial_partner_id'], context=context):
if (len(partner['name']) > 3 and partner['name'].lower() in key):
partners.append(partner)
partners.sort(key=lambda x: len(x['name']), reverse=True)
partner_ids = [x['id'] for x in partners]
partner_ids = [x['commercial_partner_id'][0] for x in partners]
if len(partner_ids) > 1:
log.append(
_('More than one possible match found for partner with '

View File

@@ -22,6 +22,7 @@
from openerp.osv import orm, fields
from openerp.tools.translate import _
from openerp.addons.account_banking.wizard import banktools
import ast
class link_partner(orm.TransientModel):
_name = 'banking.link_partner'
@@ -33,10 +34,23 @@ class link_partner(orm.TransientModel):
'supplier': fields.boolean('Supplier'),
'customer': fields.boolean('Customer'),
'partner_id': fields.many2one(
'res.partner', 'or link existing partner'),
'res.partner', 'or link existing partner',
domain=['|', ('is_company', '=', True),
('parent_id', '=', False)],
),
'statement_line_id': fields.many2one(
'account.bank.statement.line',
'Statement line', required=True),
'amount': fields.related(
'statement_line_id', 'amount', type='float',
string="Amount", readonly=True),
'ref': fields.related(
'statement_line_id', 'ref', type='char', size=32,
string="Reference", readonly=True),
'message': fields.related(
'statement_line_id', 'import_transaction_id', 'message',
type='char', size=1024,
string="Message", readonly=True),
'remote_account': fields.char(
'Account number', size=24, readonly=True),
# Partner values
@@ -50,6 +64,11 @@ class link_partner(orm.TransientModel):
'phone': fields.char('Phone', size=64),
'fax': fields.char('Fax', size=64),
'mobile': fields.char('Mobile', size=64),
'is_company': fields.boolean('Is a Company'),
}
_defaults = {
'is_company': True,
}
def create(self, cr, uid, vals, context=None):
@@ -79,9 +98,19 @@ class link_partner(orm.TransientModel):
if 'customer' not in vals and statement_line.amount > 0:
vals['customer'] = True
if not vals.get('street'):
vals['street'] = transaction.remote_owner_address
if not vals.get('street'):
address_list = []
try:
address_list = ast.literal_eval(
transaction.remote_owner_address or [])
except ValueError:
pass
if address_list and not vals.get('street'):
vals['street'] = address_list.pop(0)
if address_list and not vals.get('street2'):
vals['street2'] = address_list.pop(0)
if transaction.remote_owner_postalcode and not vals.get('zip'):
vals['zip'] = transaction.remote_owner_postalcode
if transaction.remote_owner_city and not vals.get('city'):
vals['city'] = transaction.remote_owner_city
if not vals.get('country_id'):
vals['country_id'] = banktools.get_country_id(
@@ -101,10 +130,12 @@ class link_partner(orm.TransientModel):
:param wizard: read record of wizard (with load='_classic_write')
:param values: the dictionary of partner values that will be updated
"""
for field in ['name',
for field in ['is_company',
'name',
'street',
'street2',
'zip',
'city',
'country_id',
'state_id',
'phone',
@@ -126,10 +157,7 @@ class link_partner(orm.TransientModel):
else:
wiz_read = self.read(
cr, uid, ids[0], context=context, load='_classic_write')
partner_fields = self.pool.get(
'res.partner')._columns.keys()
partner_vals = {
'is_company': True,
'type': 'default',
}
self.update_partner_values(

View File

@@ -7,15 +7,24 @@
<field name="model">banking.link_partner</field>
<field name="arch" type="xml">
<form string="Link partner">
<group colspan="4" col="6">
<group colspan="4" col="6" string="Transaction data">
<field name="ref" />
<field name="amount" />
<field name="remote_account" />
<field name="message" colspan="6"/>
</group>
<group colspan="4" col="4" string="Create or link partner">
<field name="name"
attrs="{'readonly': [('partner_id', '!=', False)]}" />
<field name="partner_id"/>
<field name="remote_account" />
</group>
<group colspan="2">
<field name="is_company" />
</group>
<group colspan="4"
string="Address"
attrs="{'invisible': [('partner_id', '!=', False)]}">
attrs="{'invisible': [('partner_id', '!=', False)]}"
col="4">
<group colspan="2" col="2">
<field name="street"/>
<field name="street2"/>

View File

@@ -0,0 +1 @@
import camt

View File

@@ -0,0 +1,33 @@
##############################################################################
#
# Copyright (C) 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/>.
#
##############################################################################
{
'name': 'CAMT Format Bank Statements Import',
'version': '0.1',
'license': 'AGPL-3',
'author': 'Therp BV',
'website': 'https://launchpad.net/banking-addons',
'category': 'Banking addons',
'depends': ['account_banking'],
'description': '''
Module to import SEPA CAMT.053 Format bank statement files. Based
on the Banking addons framework.
''',
'installable': True,
}

View File

@@ -0,0 +1,278 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 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 lxml import etree
from openerp.osv.orm import except_orm
from account_banking.parsers import models
from account_banking.parsers.convert import str2date
bt = models.mem_bank_transaction
class transaction(models.mem_bank_transaction):
def __init__(self, values, *args, **kwargs):
super(transaction, self).__init__(*args, **kwargs)
for attr in values:
setattr(self, attr, values[attr])
def is_valid(self):
return not self.error_message
class parser(models.parser):
code = 'CAMT'
country_code = 'NL'
name = 'Generic CAMT Format'
doc = '''\
CAMT Format parser
'''
def tag(self, node):
"""
Return the tag of a node, stripped from its namespace
"""
return node.tag[len(self.ns):]
def assert_tag(self, node, expected):
"""
Get node's stripped tag and compare with expected
"""
assert self.tag(node) == expected, (
"Expected tag '%s', got '%s' instead" %
(self.tag(node), expected))
def xpath(self, node, expr):
"""
Wrap namespaces argument into call to Element.xpath():
self.xpath(node, './ns:Acct/ns:Id')
"""
return node.xpath(expr, namespaces={'ns': self.ns[1:-1]})
def find(self, node, expr):
"""
Like xpath(), but return first result if any or else False
Return None to test nodes for being truesy
"""
result = node.xpath(expr, namespaces={'ns': self.ns[1:-1]})
if result:
return result[0]
return None
def get_balance_type_node(self, node, balance_type):
"""
:param node: BkToCstmrStmt/Stmt/Bal node
:param balance type: one of 'OPBD', 'PRCD', 'ITBD', 'CLBD'
"""
code_expr = './ns:Bal/ns:Tp/ns:CdOrPrtry/ns:Cd[text()="%s"]/../../..' % balance_type
return self.xpath(node, code_expr)
def parse_amount(self, node):
"""
Parse an element that contains both Amount and CreditDebitIndicator
:return: signed amount
:returntype: float
"""
sign = -1 if node.find(self.ns + 'CdtDbtInd').text == 'DBIT' else 1
return sign * float(node.find(self.ns + 'Amt').text)
def get_start_balance(self, node):
"""
Find the (only) balance node with code OpeningBalance, or
the only one with code 'PreviousClosingBalance'
or the first balance node with code InterimBalance in
the case of preceeding pagination.
:param node: BkToCstmrStmt/Stmt/Bal node
"""
nodes = (
self.get_balance_type_node(node, 'OPBD') or
self.get_balance_type_node(node, 'PRCD') or
self.get_balance_type_node(node, 'ITBD'))
return self.parse_amount(nodes[0])
def get_end_balance(self, node):
"""
Find the (only) balance node with code ClosingBalance, or
the second (and last) balance node with code InterimBalance in
the case of continued pagination.
:param node: BkToCstmrStmt/Stmt/Bal node
"""
nodes = (
self.get_balance_type_node(node, 'CLBD') or
self.get_balance_type_node(node, 'ITBD'))
return self.parse_amount(nodes[-1])
def parse_Stmt(self, cr, node):
"""
Parse a single Stmt node.
Be sure to craft a unique, but short enough statement identifier,
as it is used as the basis of the generated move lines' names
which overflow when using the full IBAN and CAMT statement id.
"""
statement = models.mem_bank_statement()
statement.local_account = (
self.xpath(node, './ns:Acct/ns:Id/ns:IBAN')[0].text
if self.xpath(node, './ns:Acct/ns:Id/ns:IBAN')
else self.xpath(node, './ns:Acct/ns:Id/ns:Othr/ns:Id')[0].text)
identifier = node.find(self.ns + 'Id').text
if identifier.upper().startswith('CAMT053'):
identifier = identifier[7:]
statement.id = self.get_unique_statement_id(
cr, "%s-%s" % (
self.get_unique_account_identifier(
cr, statement.local_account),
identifier)
)
statement.local_currency = self.xpath(node, './ns:Acct/ns:Ccy')[0].text
statement.start_balance = self.get_start_balance(node)
statement.end_balance = self.get_end_balance(node)
number = 0
for Ntry in self.xpath(node, './ns:Ntry'):
transaction_detail = self.parse_Ntry(Ntry)
if number == 0:
# Take the statement date from the first transaction
statement.date = str2date(
transaction_detail['execution_date'], "%Y-%m-%d")
number += 1
transaction_detail['id'] = str(number).zfill(4)
statement.transactions.append(
transaction(transaction_detail))
return statement
def get_transfer_type(self, node):
"""
Map entry descriptions to transfer types. To extend with
proper mapping from BkTxCd/Domn/Cd/Fmly/Cd to transfer types
if we can get our hands on real life samples.
For now, leave as a hook for bank specific overrides to map
properietary codes from BkTxCd/Prtry/Cd.
:param node: Ntry node
"""
return bt.ORDER
def parse_Ntry(self, node):
"""
:param node: Ntry node
"""
entry_details = {
'execution_date': self.xpath(node, './ns:BookgDt/ns:Dt')[0].text,
'effective_date': self.xpath(node, './ns:ValDt/ns:Dt')[0].text,
'transfer_type': self.get_transfer_type(node),
'transferred_amount': self.parse_amount(node)
}
TxDtls = self.xpath(node, './ns:NtryDtls/ns:TxDtls')
if len(TxDtls) == 1:
vals = self.parse_TxDtls(TxDtls[0], entry_details)
else:
vals = entry_details
return vals
def get_party_values(self, TxDtls):
"""
Determine to get either the debtor or creditor party node
and extract the available data from it
"""
vals = {}
party_type = self.find(
TxDtls, '../../ns:CdtDbtInd').text == 'CRDT' and 'Dbtr' or 'Cdtr'
party_node = self.find(TxDtls, './ns:RltdPties/ns:%s' % party_type)
account_node = self.find(
TxDtls, './ns:RltdPties/ns:%sAcct/ns:Id' % party_type)
bic_node = self.find(
TxDtls,
'./ns:RltdAgts/ns:%sAgt/ns:FinInstnId/ns:BIC' % party_type)
if party_node is not None:
name_node = self.find(party_node, './ns:Nm')
vals['remote_owner'] = (
name_node.text if name_node is not None else False)
country_node = self.find(party_node, './ns:PstlAdr/ns:Ctry')
vals['remote_owner_country'] = (
country_node.text if country_node is not None else False)
address_node = self.find(party_node, './ns:PstlAdr/ns:AdrLine')
if address_node is not None:
vals['remote_owner_address'] = [address_node.text]
if account_node is not None:
iban_node = self.find(account_node, './ns:IBAN')
if iban_node is not None:
vals['remote_account'] = iban_node.text
if bic_node is not None:
vals['remote_bank_bic'] = bic_node.text
else:
domestic_node = self.find(account_node, './ns:Othr/ns:Id')
vals['remote_account'] = (
domestic_node.text if domestic_node is not None else False)
return vals
def parse_TxDtls(self, TxDtls, entry_values):
"""
Parse a single TxDtls node
"""
vals = dict(entry_values)
unstructured = self.xpath(TxDtls, './ns:RmtInf/ns:Ustrd')
if unstructured:
vals['message'] = ' '.join([x.text for x in unstructured])
structured = self.find(
TxDtls, './ns:RmtInf/ns:Strd/ns:CdtrRefInf/ns:Ref')
if structured is None or not structured.text:
structured = self.find(TxDtls, './ns:Refs/ns:EndToEndId')
if structured is not None:
vals['reference'] = structured.text
else:
if vals.get('message'):
vals['reference'] = vals['message']
vals.update(self.get_party_values(TxDtls))
return vals
def check_version(self):
"""
Sanity check the document's namespace
"""
if not self.ns.startswith('{urn:iso:std:iso:20022:tech:xsd:camt.'):
raise except_orm(
"Error",
"This does not seem to be a CAMT format bank statement.")
if not self.ns.startswith('{urn:iso:std:iso:20022:tech:xsd:camt.053.'):
raise except_orm(
"Error",
"Only CAMT.053 is supported at the moment.")
return True
def parse(self, cr, data):
"""
Parse a CAMT053 XML file
"""
root = etree.fromstring(data)
self.ns = root.tag[:root.tag.index("}") + 1]
self.check_version()
self.assert_tag(root[0][0], 'GrpHdr')
statements = []
for node in root[0][1:]:
statements.append(self.parse_Stmt(cr, node))
return statements

View File

@@ -2,7 +2,7 @@
##############################################################################
#
# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>)
# 2011 Therp BV (<http://therp.nl>)
# 2011 - 2013 Therp BV (<http://therp.nl>)
#
# All Rights Reserved
#
@@ -256,9 +256,9 @@ class transaction(models.mem_bank_transaction):
if self.transfer_type == 'SEPA':
sepa_dict = get_sepa_dict(''.join(fields))
sepa_type = sepa_dict.get('TRTP')
if sepa_type != 'SEPA OVERBOEKING':
raise ValueError,_('Sepa transaction type %s not handled yet')
sepa_type = sepa_dict.get('TRTP') or ''
if sepa_type.upper() != 'SEPA OVERBOEKING':
raise ValueError, _('Sepa transaction type %s not handled yet') % sepa_type
self.remote_account = sepa_dict.get('IBAN',False)
self.remote_bank_bic = sepa_dict.get('BIC', False)
self.remote_owner = sepa_dict.get('NAME', False)

View File

@@ -32,17 +32,14 @@
'category': 'Banking addons',
'depends': [
'account_banking',
'account_payment',
'account_banking_payment_export',
],
'data': [
'view/account_payment.xml',
'view/banking_transaction_wizard.xml',
'view/payment_mode.xml',
'view/payment_mode_type.xml',
'view/bank_payment_manual.xml',
'data/payment_mode_type.xml',
'workflow/account_payment.xml',
'security/ir.model.access.csv',
],
'description': '''
This addon adds payment infrastructure to the Banking Addons.

View File

@@ -0,0 +1,213 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * account_banking_payment
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 7.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-10-15 12:29+0000\n"
"PO-Revision-Date: 2013-10-17 10:46+0100\n"
"Last-Translator: Erwin van der Ploeg (BAS Solutions) <erwin@bas-solutions."
"nl>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: \n"
"X-Generator: Poedit 1.5.7\n"
#. module: account_banking_payment
#: view:payment.order:0
msgid ""
"{\n"
" 'readonly': [('state', '=', 'normal')]\n"
" }"
msgstr ""
"{\n"
" 'readonly': [('state', '=', 'normal')]\n"
" }"
#. module: account_banking_payment
#: model:ir.model,name:account_banking_payment.model_payment_order
msgid "Payment Order"
msgstr "Betalingsopdracht"
#. module: account_banking_payment
#: field:payment.mode.type,payment_order_type:0
#: field:payment.order,payment_order_type:0
msgid "Payment order type"
msgstr "Type betaalopdracht"
#. module: account_banking_payment
#: help:payment.mode,payment_term_ids:0
msgid "Limit selected invoices to invoices with these payment terms"
msgstr "Beperk de geselecteerde facturen tot facturen met deze betaalconditie"
#. module: account_banking_payment
#: model:ir.model,name:account_banking_payment.model_payment_line
msgid "Payment Line"
msgstr "Betaalregel"
#. module: account_banking_payment
#: model:ir.model,name:account_banking_payment.model_payment_mode
msgid "Payment Mode"
msgstr "Betaalwijze"
#. module: account_banking_payment
#: field:payment.line,date_done:0
msgid "Date Confirmed"
msgstr "Datum bevestigd"
#. module: account_banking_payment
#: field:banking.transaction.wizard,manual_payment_order_id:0
msgid "Match this payment order"
msgstr "Match deze betaalopdracht"
#. module: account_banking_payment
#: model:ir.model,name:account_banking_payment.model_payment_mode_type
msgid "Payment Mode Type"
msgstr "Betaalmode soort"
#. module: account_banking_payment
#: view:payment.order:0
msgid ""
"{\n"
" 'invisible':[('state','!=','draft')]\n"
" }"
msgstr ""
"{\n"
" 'invisible':[('state','!=','draft')]\n"
" }"
#. module: account_banking_payment
#: field:banking.import.transaction,payment_order_id:0
#: field:banking.transaction.wizard,payment_order_id:0
msgid "Payment order to reconcile"
msgstr "Betaalopdracht ter aflettering"
#. module: account_banking_payment
#: selection:payment.mode.type,payment_order_type:0
#: selection:payment.order,payment_order_type:0
msgid "Payment"
msgstr "Betaling"
#. module: account_banking_payment
#: field:payment.mode,payment_term_ids:0
msgid "Payment terms"
msgstr "Betaalconditie"
#. module: account_banking_payment
#: view:payment.mode:0
msgid "Transfer move settings"
msgstr "Overschrijving instellingen"
#. module: account_banking_payment
#: selection:payment.mode.type,payment_order_type:0
#: selection:payment.order,payment_order_type:0
msgid "Direct debit"
msgstr "Incasso-opdracht"
#. module: account_banking_payment
#: model:ir.model,name:account_banking_payment.model_banking_import_transaction
msgid "Bank import transaction"
msgstr "Geïmporteerde bankmutatie"
#. module: account_banking_payment
#: view:payment.mode:0
msgid "Optional filter by payment term"
msgstr "Optioneel filter op betaalconditie"
#. module: account_banking_payment
#: field:banking.import.transaction,payment_order_ids:0
msgid "Payment orders"
msgstr "Betaalopdrachten"
#. module: account_banking_payment
#: model:ir.model,name:account_banking_payment.model_payment_order_create
msgid "payment.order.create"
msgstr "payment.order.create"
#. module: account_banking_payment
#: field:payment.mode,transfer_account_id:0
msgid "Transfer account"
msgstr "Overschrijf bedrag"
#. module: account_banking_payment
#: field:banking.transaction.wizard,payment_line_id:0
msgid "Matching payment or storno"
msgstr "Gevonden betaling of storno"
#. module: account_banking_payment
#: field:payment.order,date_sent:0
msgid "Send date"
msgstr "Datum verstuurd"
#. module: account_banking_payment
#: model:ir.model,name:account_banking_payment.model_banking_import_line
msgid "Bank import lines"
msgstr "Bankimportregels"
#. module: account_banking_payment
#: field:banking.transaction.wizard,manual_payment_line_id:0
msgid "Match this payment line"
msgstr "Match deze betaalregel"
#. module: account_banking_payment
#: field:banking.transaction.wizard,payment_order_ids:0
msgid "Matching payment orders"
msgstr "Gekoppelde betaalopdrachten"
#. module: account_banking_payment
#: field:payment.line,transit_move_line_id:0
msgid "Debit move line"
msgstr "Debit regel"
#. module: account_banking_payment
#: field:banking.import.line,payment_order_id:0
msgid "Payment order"
msgstr "Betaalopdracht"
#. module: account_banking_payment
#: field:payment.mode,transfer_journal_id:0
msgid "Transfer journal"
msgstr "Overschrijf dagboek"
#. module: account_banking_payment
#: help:payment.mode,transfer_journal_id:0
msgid ""
"Journal to write payment entries when confirming a debit order of this mode"
msgstr ""
"Dagboek voor het boeken van betalingen bij het bevestigen van een incasso in "
"deze mode"
#. module: account_banking_payment
#: help:payment.mode,transfer_account_id:0
msgid ""
"Pay off lines in sent orders with a move on this account. For debit type "
"modes only. You can only select accounts of type regular that are marked for "
"reconciliation"
msgstr ""
"Betaalregels in verzonden opdrachten met een mutatie op deze rekening. "
"Alleen voor incasso's. U kunt alleen een rekening selecteren van het "
"standaard soort, welke zijn gemarkeerd voor afletteren."
#. module: account_banking_payment
#: field:banking.import.transaction,payment_line_id:0
msgid "Payment line"
msgstr "Betaling"
#. module: account_banking_payment
#: model:ir.model,name:account_banking_payment.model_banking_transaction_wizard
msgid "Match transaction"
msgstr "Match deze mutatie"
#. module: account_banking_payment
#: help:payment.line,transit_move_line_id:0
msgid "Move line through which the debit order pays the invoice"
msgstr "Mutatie waardoor de incasso opdracht de factuur betaald."
#. module: account_banking_payment
#: field:payment.line,msg:0
msgid "Message"
msgstr "Bericht"

View File

@@ -5,5 +5,4 @@ import payment_mode_type
import payment_order_create
import banking_import_transaction
import banking_transaction_wizard
import bank_payment_manual
import banking_import_line

View File

@@ -115,49 +115,6 @@ class payment_order(orm.Model):
'payment_order_type': 'payment',
}
def launch_wizard(self, cr, uid, ids, context=None):
"""
Search for a wizard to launch according to the type.
If type is manual. just confirm the order.
Previously (pre-v6) in account_payment/wizard/wizard_pay.py
"""
if context == None:
context = {}
result = {}
orders = self.browse(cr, uid, ids, context)
order = orders[0]
# check if a wizard is defined for the first order
if order.mode.type and order.mode.type.ir_model_id:
context['active_ids'] = ids
wizard_model = order.mode.type.ir_model_id.model
wizard_obj = self.pool.get(wizard_model)
wizard_id = wizard_obj.create(cr, uid, {}, context)
result = {
'name': wizard_obj._description or _('Payment Order Export'),
'view_type': 'form',
'view_mode': 'form',
'res_model': wizard_model,
'domain': [],
'context': context,
'type': 'ir.actions.act_window',
'target': 'new',
'res_id': wizard_id,
'nodestroy': True,
}
else:
# should all be manual orders without type or wizard model
for order in orders[1:]:
if order.mode.type and order.mode.type.ir_model_id:
raise orm.except_orm(
_('Error'),
_('You can only combine payment orders of the same type')
)
# process manual payments
wf_service = netsvc.LocalService('workflow')
for order_id in ids:
wf_service.trg_validate(uid, 'payment.order', order_id, 'sent', cr)
return result
def _write_payment_lines(self, cr, uid, ids, **kwargs):
'''
ORM method for setting attributes of corresponding payment.line objects.
@@ -284,6 +241,8 @@ class payment_order(orm.Model):
'debit': _('Direct debit order'),
}
for order in self.browse(cr, uid, ids, context=context):
if not order.mode.transfer_journal_id or not order.mode.transfer_account_id:
continue
for line in order.line_ids:
# basic checks
if not line.move_line_id:
@@ -301,7 +260,7 @@ class payment_order(orm.Model):
'journal_id': order.mode.transfer_journal_id.id,
'name': '%s %s' % (labels[order.payment_order_type],
line.move_line_id.move_id.name),
'reference': '%s%s' % (order.payment_order_type[:3].upper(),
'ref': '%s%s' % (order.payment_order_type[:3].upper(),
line.move_line_id.move_id.name),
}, context=context)

View File

@@ -151,8 +151,8 @@ class payment_line(orm.Model):
if torec_move_line.reconcile_partial_id:
line_ids = [
x.id for x in
transit_move_line.reconcile_partial_id.line_partial_ids
] + [torec_move_line.id]
torec_move_line.reconcile_partial_id.line_partial_ids
] + [transit_move_line.id]
total = move_line_obj.get_balance(cr, uid, line_ids)
vals = {

View File

@@ -27,28 +27,9 @@ from openerp.osv import orm, fields
class payment_mode(orm.Model):
''' Restoring the payment type from version 5,
used to select the export wizard (if any) '''
_inherit = "payment.mode"
def suitable_bank_types(self, cr, uid, payment_mode_id=None, context=None):
""" Reinstates functional code for suitable bank type filtering.
Current code in account_payment is disfunctional.
"""
res = []
payment_mode = self.browse(
cr, uid, payment_mode_id, context)
if (payment_mode and payment_mode.type and
payment_mode.type.suitable_bank_types):
res = [type.code for type in payment_mode.type.suitable_bank_types]
return res
_columns = {
'type': fields.many2one(
'payment.mode.type', 'Payment type',
required=True,
help='Select the Payment Type for the Payment Mode.'
),
'transfer_account_id': fields.many2one(
'account.account', 'Transfer account',
domain=[('type', '=', 'other'),

View File

@@ -27,30 +27,9 @@ from openerp.osv import orm, fields
class payment_mode_type(orm.Model):
_name = 'payment.mode.type'
_description = 'Payment Mode Type'
_inherit = 'payment.mode.type'
_columns = {
'name': fields.char(
'Name', size=64, required=True,
help='Payment Type'
),
'code': fields.char(
'Code', size=64, required=True,
help='Specify the Code for Payment Type'
),
# Setting suitable_bank_types to required pending
# https://bugs.launchpad.net/openobject-addons/+bug/786845
'suitable_bank_types': fields.many2many(
'res.partner.bank.type',
'bank_type_payment_type_rel',
'pay_type_id','bank_type_id',
'Suitable bank types', required=True),
'ir_model_id': fields.many2one(
'ir.model', 'Payment wizard',
help=('Select the Payment Wizard for payments of this type. '
'Leave empty for manual processing'),
domain=[('osv_memory', '=', True)],
),
'payment_order_type': fields.selection(
[('payment', 'Payment'),('debit', 'Direct debit')],
'Payment order type', required=True,

View File

@@ -23,9 +23,7 @@
#
##############################################################################
from datetime import datetime
from openerp.osv import orm, fields
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT
from openerp.tools.translate import _

View File

@@ -17,10 +17,6 @@
'invisible':[('state','!=','draft')]
}</attribute>
</xpath>
<xpath expr="//button[@string='Make Payments']"
position="attributes">
<attribute name="name">launch_wizard</attribute>
</xpath>
<!-- Communication only used for 'structured' communication -->
<xpath expr="//field[@name='line_ids']/form//field[@name='communication']"
position="attributes">

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_payment_manual_form" model="ir.ui.view">
<field name="name">Form for manual payment wizard</field>
<field name="model">payment.manual</field>
<field name="arch" type="xml">
<form string="Manual payment">
<label string="Payment order(s) have been set to 'sent'"/>
<button special="cancel" icon="gtk-ok" string="OK"/>
</form>
</field>
</record>
</data>
</openerp>

View File

@@ -8,10 +8,9 @@
<record id="view_payment_mode_form_inherit" model="ir.ui.view">
<field name="name">payment.mode.form.inherit</field>
<field name="model">payment.mode</field>
<field name="inherit_id" ref="account_payment.view_payment_mode_form"/>
<field name="inherit_id" ref="account_banking_payment_export.view_payment_mode_form_inherit"/>
<field name="arch" type="xml">
<field name="company_id" position="after">
<field name="type"/>
<field name="type" position="after">
<group colspan="4" col="4">
<group colspan="2">
<separator colspan="2"

View File

@@ -2,29 +2,14 @@
<openerp>
<data>
<record id="view_payment_mode_tree_inherit" model="ir.ui.view">
<field name="name">payment.mode.tree.inherit</field>
<field name="model">payment.mode</field>
<field name="inherit_id" ref="account_payment.view_payment_mode_tree"/>
<field name="arch" type="xml">
<field name="company_id" position="after">
<field name="type"/>
</field>
</field>
</record>
<!-- basic view for payment mode type -->
<record model="ir.ui.view" id="view_payment_mode_type_form">
<record model="ir.ui.view" id="view_payment_mode_type_form_inherit">
<field name="name">view.payment.mode.type.form</field>
<field name="model">payment.mode.type</field>
<field name="inherit_id" ref="account_banking_payment_export.view_payment_mode_type_form"/>
<field name="arch" type="xml">
<form string="Payment mode">
<field name="name" />
<field name="code" />
<field name="suitable_bank_types"/>
<field name="payment_order_type"/>
<field name="ir_model_id"/>
</form>
<field name="suitable_bank_types" position="after">
<field name="payment_order_type"/>
</field>
</field>
</record>

View File

@@ -29,6 +29,12 @@ write({'state':'rejected'})</field>
<field name="act_to" ref="account_banking.act_sent"/>
<field name="signal">sent</field>
</record>
<!-- the done signal continues to work but goes to sent -->
<record id="account_banking.trans_open_done" model="workflow.transition">
<field name="act_from" ref="account_payment.act_open"/>
<field name="act_to" ref="account_banking.act_sent"/>
<field name="signal">done</field>
</record>
<!-- From sent straight to sent_wait -->
<record id="account_banking.trans_sent_sent_wait" model="workflow.transition">
<field name="act_from" ref="account_banking.act_sent"/>

View File

@@ -0,0 +1 @@
from . import model

View File

@@ -0,0 +1,69 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
# (C) 2011 - 2013 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/>.
#
##############################################################################
{
'name': 'Account Banking - Payments Export Infrastructure',
'version': '0.1.164',
'license': 'AGPL-3',
'author': 'Banking addons community',
'website': 'https://launchpad.net/banking-addons',
'category': 'Banking addons',
'depends': [
'account_payment',
'base_iban', # for manual_bank_tranfer
],
'conflicts': [
# lp:account-payment/account_payment_extension also adds
# a type field to payment.mode, with a very similar purpose.
# We can't add a dependency on account_payment_extension here
# because account_payment_extension adds many other features
# that probably conflict with other parts of lp:banking-addons.
# Proposal to resolve: make account_payment_extension depend
# on the present account_banking_payment_export module.
'account_payment_extension',
],
'data': [
'view/account_payment.xml',
'view/bank_payment_manual.xml',
'view/payment_mode.xml',
'view/payment_mode_type.xml',
'data/payment_mode_type.xml',
'security/ir.model.access.csv',
],
'description': '''
Infrastructure to export payment orders.
This technical module provides the base infrastructure to export
payment orders for electronic banking. It provides the following
technical features:
* a new payment.mode.type model
* payment.mode now has a mandatory type
* a better implementation of payment_mode.suitable_bank_types() based on payment.mode.type
* the "make payment" button launches a wizard depending on the payment.mode.type
* a manual payment mode type is provided as an example, with a default "do nothing" wizard
''',
'auto_install': True,
'installable': True,
}

View File

@@ -2,13 +2,13 @@
<openerp>
<data>
<!-- Add manual bank transfer as default payment option -->
<record model="payment.mode.type" id="account_banking.manual_bank_tranfer">
<record model="payment.mode.type" id="manual_bank_tranfer">
<field name="name">Manual Bank Transfer</field>
<field name="code">BANKMAN</field>
<field name="suitable_bank_types"
eval="[(6,0,[ref('base.bank_normal'),ref('base_iban.bank_iban'),])]" />
<field name="ir_model_id"
ref="account_banking_payment.model_payment_manual"/>
ref="model_payment_manual"/>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,135 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * account_banking_payment_export
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 7.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-10-15 12:36+0000\n"
"PO-Revision-Date: 2013-10-17 10:50+0100\n"
"Last-Translator: Erwin van der Ploeg (BAS Solutions) <erwin@bas-solutions."
"nl>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: \n"
"X-Generator: Poedit 1.5.7\n"
#. module: account_banking_payment_export
#: help:payment.mode.type,name:0
msgid "Payment Type"
msgstr "Betaaltype"
#. module: account_banking_payment_export
#: model:ir.model,name:account_banking_payment_export.model_payment_order
msgid "Payment Order"
msgstr "Betalingsopdracht"
#. module: account_banking_payment_export
#: view:payment.manual:0
msgid ""
"Please execute payment order manually, and click OK when succesfully sent."
msgstr ""
"Sluit de betaalopdracht handmatig uit en klik ok, wanneer succesvol "
"verzonden."
#. module: account_banking_payment_export
#: model:ir.model,name:account_banking_payment_export.model_payment_mode
msgid "Payment Mode"
msgstr "Betaalwijze"
#. module: account_banking_payment_export
#: model:ir.model,name:account_banking_payment_export.model_payment_mode_type
msgid "Payment Mode Type"
msgstr "Betaalwijze soort"
#. module: account_banking_payment_export
#: model:ir.model,name:account_banking_payment_export.model_account_move_line
msgid "Journal Items"
msgstr "Boekingen"
#. module: account_banking_payment_export
#: model:ir.model,name:account_banking_payment_export.model_payment_manual
msgid "Send payment order(s) manually"
msgstr "Verzend betaalopdrachten handmatig"
#. module: account_banking_payment_export
#: field:payment.mode.type,name:0
msgid "Name"
msgstr "Naam"
#. module: account_banking_payment_export
#: help:payment.mode.type,ir_model_id:0
msgid ""
"Select the Payment Wizard for payments of this type. Leave empty for manual "
"processing"
msgstr ""
"Selecteer de wizard voor het verwerken van betalingen van dit type. Laat "
"leeg voor handmatige verwerking."
#. module: account_banking_payment_export
#: view:payment.manual:0
msgid "Manual payment"
msgstr "Handmatige betaling"
#. module: account_banking_payment_export
#: field:payment.manual,payment_order_ids:0
msgid "Payment orders"
msgstr "Betaalopdrachten"
#. module: account_banking_payment_export
#: help:payment.mode,type:0
msgid "Select the Payment Type for the Payment Mode."
msgstr "Selecteer het type van de betaalmodus."
#. module: account_banking_payment_export
#: view:payment.order:0
msgid "launch_wizard"
msgstr "launch_wizard"
#. module: account_banking_payment_export
#: help:payment.mode.type,code:0
msgid "Specify the Code for Payment Type"
msgstr "Geef de code op voor het betaaltype"
#. module: account_banking_payment_export
#: model:ir.model,name:account_banking_payment_export.model_payment_order_create
msgid "payment.order.create"
msgstr "payment.order.create"
#. module: account_banking_payment_export
#: field:payment.mode.type,ir_model_id:0
msgid "Payment wizard"
msgstr "Betaalwizard"
#. module: account_banking_payment_export
#: field:payment.mode,type:0
msgid "Payment type"
msgstr "Betaaltype"
#. module: account_banking_payment_export
#: field:payment.mode.type,code:0
msgid "Code"
msgstr "Code"
#. module: account_banking_payment_export
#: view:payment.manual:0
msgid "OK"
msgstr "OK"
#. module: account_banking_payment_export
#: view:payment.mode.type:0
msgid "Payment mode"
msgstr "Betaalwijze"
#. module: account_banking_payment_export
#: view:payment.manual:0
msgid "Cancel"
msgstr "Annuleren"
#. module: account_banking_payment_export
#: field:payment.mode.type,suitable_bank_types:0
msgid "Suitable bank types"
msgstr "Geschikte banktypen"

View File

@@ -0,0 +1,5 @@
from . import account_payment
from . import bank_payment_manual
from . import payment_mode
from . import payment_mode_type
from . import payment_order_create

View File

@@ -0,0 +1,75 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
# (C) 2011 - 2013 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.osv import orm
from openerp.tools.translate import _
from openerp import netsvc
class payment_order(orm.Model):
_inherit = 'payment.order'
def launch_wizard(self, cr, uid, ids, context=None):
"""
Search for a wizard to launch according to the type.
If type is manual. just confirm the order.
Previously (pre-v6) in account_payment/wizard/wizard_pay.py
"""
if context == None:
context = {}
result = {}
orders = self.browse(cr, uid, ids, context)
order = orders[0]
# check if a wizard is defined for the first order
if order.mode.type and order.mode.type.ir_model_id:
context['active_ids'] = ids
wizard_model = order.mode.type.ir_model_id.model
wizard_obj = self.pool.get(wizard_model)
wizard_id = wizard_obj.create(cr, uid, {}, context)
result = {
'name': wizard_obj._description or _('Payment Order Export'),
'view_type': 'form',
'view_mode': 'form',
'res_model': wizard_model,
'domain': [],
'context': context,
'type': 'ir.actions.act_window',
'target': 'new',
'res_id': wizard_id,
'nodestroy': True,
}
else:
# should all be manual orders without type or wizard model
for order in orders[1:]:
if order.mode.type and order.mode.type.ir_model_id:
raise orm.except_orm(
_('Error'),
_('You can only combine payment orders of the same type')
)
# process manual payments
wf_service = netsvc.LocalService('workflow')
for order_id in ids:
wf_service.trg_validate(uid, 'payment.order', order_id, 'done', cr)
return result

View File

@@ -24,7 +24,7 @@
##############################################################################
'''
This module contains a single "wizard" for including a 'sent' state for manual
This module contains a single "wizard" for confirming manual
bank transfers.
'''
@@ -34,20 +34,26 @@ from openerp import netsvc
class payment_manual(orm.TransientModel):
_name = 'payment.manual'
_description = 'Set payment orders to \'sent\' manually'
def default_get(self, cr, uid, fields_list, context=None):
if context and context.get('active_ids'):
payment_order_obj = self.pool.get('payment.order')
wf_service = netsvc.LocalService('workflow')
for order_id in context['active_ids']:
wf_service.trg_validate(
uid, 'payment.order', order_id, 'sent', cr)
return super(payment_manual, self).default_get(
cr, uid, fields_list, context=None)
_description = 'Send payment order(s) manually'
_columns = {
# dummy field, to trigger a call to default_get
'name': fields.char('Name', size=1),
'payment_order_ids': fields.many2many('payment.order',
'wiz_manual_payorders_rel', 'wizard_id', 'payment_order_id',
'Payment orders', readonly=True),
}
def create(self, cr, uid, vals, context=None):
payment_order_ids = context.get('active_ids', [])
vals.update({
'payment_order_ids': [[6, 0, payment_order_ids]],
})
return super(payment_manual, self).create(cr, uid,
vals, context=context)
def button_ok(self, cr, uid, ids, context=None):
wf_service = netsvc.LocalService('workflow')
for wiz in self.browse(cr, uid, ids, context=context):
for order_id in wiz.payment_order_ids:
wf_service.trg_validate(
uid, 'payment.order', order_id.id, 'done', cr)
return {'type': 'ir.actions.act_window_close'}

View File

@@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
# (C) 2011 - 2013 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.osv import orm, fields
class payment_mode(orm.Model):
''' Restoring the payment type from version 5,
used to select the export wizard (if any) '''
_inherit = "payment.mode"
def suitable_bank_types(self, cr, uid, payment_mode_id=None, context=None):
""" Reinstates functional code for suitable bank type filtering.
Current code in account_payment is disfunctional.
"""
res = []
payment_mode = self.browse(
cr, uid, payment_mode_id, context)
if (payment_mode and payment_mode.type and
payment_mode.type.suitable_bank_types):
res = [t.code for t in payment_mode.type.suitable_bank_types]
return res
_columns = {
'type': fields.many2one(
'payment.mode.type', 'Payment type',
required=True,
help='Select the Payment Type for the Payment Mode.'
),
}

View File

@@ -0,0 +1,61 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
# (C) 2011 - 2013 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.osv import orm, fields
class payment_mode_type(orm.Model):
_name = 'payment.mode.type'
_description = 'Payment Mode Type'
_columns = {
'name': fields.char(
'Name', size=64, required=True,
help='Payment Type'
),
'code': fields.char(
'Code', size=64, required=True,
help='Specify the Code for Payment Type'
),
'suitable_bank_types': fields.many2many(
'res.partner.bank.type',
'bank_type_payment_type_rel',
'pay_type_id','bank_type_id',
'Suitable bank types', required=True),
'ir_model_id': fields.many2one(
'ir.model', 'Payment wizard',
help=('Select the Payment Wizard for payments of this type. '
'Leave empty for manual processing'),
domain=[('osv_memory', '=', True)],
),
}
def _auto_init(self, cr, context=None):
r = super(payment_mode_type, self)._auto_init(cr, context=context)
# migrate xmlid from manual_bank_transfer to avoid dependency on account_banking
cr.execute("""UPDATE ir_model_data SET module='account_banking_payment_export'
WHERE module='account_banking' AND
name='manual_bank_tranfer' AND
model='payment.mode.type'""")
return r

View File

@@ -0,0 +1,58 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2013 ACSONE SA/NV (<http://acsone.eu>);.
#
# 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.osv import orm
class payment_order_create(orm.TransientModel):
_inherit = 'payment.order.create'
def create_payment(self, cr, uid, ids, context=None):
'''This method adapts the core create_payment()
to pass the payment mode to line2bank() through the context,
so it is in turn propagated to suitable_bank_types().
This is necessary because the core does not propagate the payment mode to line2bank: t = None in
http://bazaar.launchpad.net/~openerp/openobject-addons/7.0/view/head:/account_payment/wizard/account_payment_order.py#L72
Hack idea courtesy Stefan Rijnhart.
'''
if context is None:
context = {}
order_obj = self.pool.get('payment.order')
payment = order_obj.browse(cr, uid, context['active_id'], context=context)
context['_fix_payment_mode_id'] = payment.mode.id
return super(payment_order_create, self).create_payment(cr, uid, ids, context=context)
class account_move_line(orm.Model):
_inherit = 'account.move.line'
def line2bank(self, cr, uid, ids, payment_mode_id=None, context=None):
'''Obtain payment_type from context, see create_payment above'''
if context is None:
context = {}
payment_mode_id = payment_mode_id or context.get('_fix_payment_mode_id')
return super(account_move_line, self).line2bank(cr, uid, ids, payment_mode_id, context=context)

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- restore wizard functionality when making payments
-->
<record id="view_banking_payment_order_form_1" model="ir.ui.view">
<field name="name">account.payment.order.form.banking-1</field>
<field name="inherit_id" ref="account_payment.view_payment_order_form" />
<field name="model">payment.order</field>
<field name="arch" type="xml">
<data>
<xpath expr="//button[@string='Make Payments']"
position="attributes">
<attribute name="name">launch_wizard</attribute>
</xpath>
</data>
</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_payment_manual_form" model="ir.ui.view">
<field name="name">Form for manual payment wizard</field>
<field name="model">payment.manual</field>
<field name="arch" type="xml">
<form string="Manual payment" version="7.0">
<label string="Please execute payment order manually, and click OK when succesfully sent."/>
<footer>
<button name="button_ok" type="object" string="OK" class="oe_highlight"/>
<button special="cancel" string="Cancel" class="oe_link"/>
</footer>
</form>
</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!--
Add the payment mode type and transfer settings
-->
<record id="view_payment_mode_form_inherit" model="ir.ui.view">
<field name="name">payment.mode.form.inherit</field>
<field name="model">payment.mode</field>
<field name="inherit_id" ref="account_payment.view_payment_mode_form"/>
<field name="arch" type="xml">
<field name="company_id" position="after">
<field name="type"/>
</field>
</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_payment_mode_tree_inherit" model="ir.ui.view">
<field name="name">payment.mode.tree.inherit</field>
<field name="model">payment.mode</field>
<field name="inherit_id" ref="account_payment.view_payment_mode_tree"/>
<field name="arch" type="xml">
<field name="company_id" position="after">
<field name="type"/>
</field>
</field>
</record>
<!-- basic view for payment mode type -->
<record model="ir.ui.view" id="view_payment_mode_type_form">
<field name="name">view.payment.mode.type.form</field>
<field name="model">payment.mode.type</field>
<field name="arch" type="xml">
<form string="Payment mode">
<field name="name" />
<field name="code" />
<field name="suitable_bank_types"/>
<field name="ir_model_id"/>
</form>
</field>
</record>
</data>
</openerp>

View File

@@ -26,7 +26,7 @@
'author': 'Akretion',
'website': 'http://www.akretion.com',
'category': 'Banking addons',
'depends': ['account_banking_payment'],
'depends': ['account_banking_payment_export'],
'data': [
'account_banking_sepa_view.xml',
'wizard/export_sepa_view.xml',

View File

@@ -20,8 +20,6 @@
##############################################################################
from openerp.osv import orm, fields
import time
from openerp.tools.translate import _
from openerp.addons.decimal_precision import decimal_precision as dp

View File

@@ -65,7 +65,7 @@
<menuitem id="menu_account_banking_sepa"
parent="account_banking.menu_finance_banking_actions"
parent="account_payment.menu_main_payment"
action="action_account_banking_sepa"
sequence="15"
/>

View File

@@ -0,0 +1,259 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * account_banking_sepa_credit_transfer
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 7.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-10-15 12:40+0000\n"
"PO-Revision-Date: 2013-10-17 11:07+0100\n"
"Last-Translator: Erwin van der Ploeg (BAS Solutions) <erwin@bas-solutions."
"nl>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: \n"
"X-Generator: Poedit 1.5.7\n"
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,file:0 field:banking.export.sepa.wizard,file_id:0
msgid "SEPA XML file"
msgstr "SEPA XML bestand"
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,nb_transactions:0
#: field:banking.export.sepa.wizard,nb_transactions:0
msgid "Number of transactions"
msgstr "Aantal transacties"
#. module: account_banking_sepa_credit_transfer
#: selection:banking.export.sepa.wizard,state:0
msgid "Create"
msgstr "Aanmaken"
#. module: account_banking_sepa_credit_transfer
#: help:banking.export.sepa.wizard,msg_identification:0
msgid ""
"This is the message identification of the entire SEPA XML file. 35 "
"characters max."
msgstr ""
"Dit is een bericht identificatie van het gehele SEPA XML bestand. Maximaal "
"35 karakters."
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,filename:0
#: field:banking.export.sepa.wizard,filename:0
msgid "Filename"
msgstr "Bestandsnaam"
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,state:0 field:banking.export.sepa.wizard,state:0
msgid "State"
msgstr "Status"
#. module: account_banking_sepa_credit_transfer
#: selection:banking.export.sepa,state:0
msgid "Draft"
msgstr "Concept"
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,prefered_exec_date:0
#: field:banking.export.sepa.wizard,prefered_exec_date:0
msgid "Prefered execution date"
msgstr "Voorkeurs uitvoerdatum"
#. module: account_banking_sepa_credit_transfer
#: selection:banking.export.sepa,charge_bearer:0
#: selection:banking.export.sepa.wizard,charge_bearer:0
msgid "Shared"
msgstr "Gedeeld"
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,generation_date:0
msgid "Generation date"
msgstr "Aanmaakdatum"
#. module: account_banking_sepa_credit_transfer
#: model:ir.model,name:account_banking_sepa_credit_transfer.model_banking_export_sepa_wizard
msgid "Export SEPA Credit Transfer XML file"
msgstr "Exporteer SEPA XML overschrijvingsbestand"
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa:0
msgid "SEPA Credit Transfer"
msgstr "SEPA overschrijving"
#. module: account_banking_sepa_credit_transfer
#: selection:banking.export.sepa.wizard,state:0
msgid "Finish"
msgstr "Gereed"
#. module: account_banking_sepa_credit_transfer
#: selection:banking.export.sepa,state:0
msgid "Reconciled"
msgstr "Afgeletterd"
#. module: account_banking_sepa_credit_transfer
#: selection:banking.export.sepa,state:0
msgid "Sent"
msgstr "Verstuur"
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa.wizard:0
msgid "Validate"
msgstr "Bevestig"
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa.wizard:0
msgid "Generate"
msgstr "Genereer"
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,msg_identification:0
#: field:banking.export.sepa.wizard,msg_identification:0
msgid "Message identification"
msgstr "Bericht identificatie"
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,total_amount:0
#: field:banking.export.sepa.wizard,total_amount:0
msgid "Total amount"
msgstr "Totaal bedrag"
#. module: account_banking_sepa_credit_transfer
#: selection:banking.export.sepa,charge_bearer:0
#: selection:banking.export.sepa.wizard,charge_bearer:0
msgid "Borne by creditor"
msgstr "Rekening van schuldeiser"
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,payment_order_ids:0
#: field:banking.export.sepa.wizard,payment_order_ids:0
msgid "Payment orders"
msgstr "Betaalopdrachten"
#. module: account_banking_sepa_credit_transfer
#: model:ir.actions.act_window,name:account_banking_sepa_credit_transfer.act_banking_export_sepa_payment_order
msgid "Generated SEPA Credit Transfer files"
msgstr "Gegenereerde SEPA overschrijfbestanden"
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa.wizard:0
msgid "SEPA XML file generation"
msgstr "SEPA XML bestand generatie"
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa.wizard:0
msgid "Reference for further communication"
msgstr "Referentie voor verdere communicatie"
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa.wizard:0
msgid "Processing details"
msgstr "Verwerkings details"
#. module: account_banking_sepa_credit_transfer
#: model:ir.model,name:account_banking_sepa_credit_transfer.model_banking_export_sepa
msgid "SEPA export"
msgstr "SEPA export"
#. module: account_banking_sepa_credit_transfer
#: selection:banking.export.sepa,charge_bearer:0
#: selection:banking.export.sepa.wizard,charge_bearer:0
msgid "Borne by debtor"
msgstr "Rekening van schuldenaar"
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa:0
msgid "Payment order"
msgstr "Betaalopdracht"
#. module: account_banking_sepa_credit_transfer
#: selection:banking.export.sepa,charge_bearer:0
#: selection:banking.export.sepa.wizard,charge_bearer:0
msgid "Following service level"
msgstr "Volg service level"
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa:0
msgid "Payment Orders"
msgstr "Betaalopdrachten"
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa:0
msgid "General Information"
msgstr "Algemene informatie"
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,charge_bearer:0
#: field:banking.export.sepa.wizard,charge_bearer:0
msgid "Charge bearer"
msgstr "Kostenverdeling"
#. module: account_banking_sepa_credit_transfer
#: help:banking.export.sepa,batch_booking:0
#: help:banking.export.sepa.wizard,batch_booking:0
msgid ""
"If true, the bank statement will display only one debit line for all the "
"wire transfers of the SEPA XML file ; if false, the bank statement will "
"display one debit line per wire transfer of the SEPA XML file."
msgstr ""
"Indien aangevinkt zal het beankafschrift maar één debet regel weergeven voor "
"alle overgeschrijvingen van het SEPA XML bestand. Indien uitgevinkt, zal het "
"beankafschrift een debet regel weergeven per SEPA XML bestand."
#. module: account_banking_sepa_credit_transfer
#: help:banking.export.sepa.wizard,prefered_exec_date:0
msgid ""
"This is the date on which the file should be processed by the bank. 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 ""
"Dit is de datum waarop het bestand zou moeten worden verwerkt door de bank. "
"Houdt u er rekening mee dat banken alleen op werkdagen de bestanden "
"verwerken en veelal een vertraging hebben van 2 dagen tussne de "
"verwerkingsdatum en de effectieve overschrijfdatum."
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa.wizard,file:0
msgid "File"
msgstr "Bestand"
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa.wizard:0
msgid "Cancel"
msgstr "Annuleren"
#. module: account_banking_sepa_credit_transfer
#: help:banking.export.sepa,charge_bearer:0
#: help:banking.export.sepa.wizard,charge_bearer:0
msgid ""
"Shared : transaction charges on the sender side are to be borne by the "
"debtor, transaction charges on the receiver side are to be borne by the "
"creditor (most transfers use this). Borne by creditor : all transaction "
"charges are to be borne by the creditor. Borne by debtor : all transaction "
"charges are to be borne by the debtor. Following service level : transaction "
"charges are to be applied following the rules agreed in the service level "
"and/or scheme."
msgstr ""
"Gedeeld : De transactiekosten aan de verzender kant zijn voor de "
"schuldeiser, transactiekosten aan de ontvanger kant zijn voor de schuldenaar "
"(deze keuze wordt het meest gebruikt). Rekening van de schuldenaar: Alle "
"transactie kosten zijn voor rekening van de schuldenaar. Rekening van de "
"schuldeiser: Alle transactie kosten zijn voor rekening van de schuldeiser. "
"Volg service level: Transactie kosten worden toegepast volgens de "
"afgesporken regels in het service level en/of schema."
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,batch_booking:0
#: field:banking.export.sepa.wizard,batch_booking:0
msgid "Batch booking"
msgstr "Batch boeking"
#. module: account_banking_sepa_credit_transfer
#: model:ir.actions.act_window,name:account_banking_sepa_credit_transfer.action_account_banking_sepa
#: model:ir.ui.menu,name:account_banking_sepa_credit_transfer.menu_account_banking_sepa
msgid "Generated SEPA Credit Transfer XML files"
msgstr "Gengenereerde SEPA XML overschrijf bestanden"

View File

@@ -101,8 +101,6 @@ class banking_export_sepa_wizard(orm.TransientModel):
'''
Creates the SEPA Credit Transfer file. That's the important code !
'''
payment_order_obj = self.pool.get('payment.order')
sepa_export = self.browse(cr, uid, ids[0], context=context)
my_company_name = sepa_export.payment_order_ids[0].mode.bank_id.partner_id.name
@@ -140,7 +138,8 @@ class banking_export_sepa_wizard(orm.TransientModel):
if sepa_export.prefered_exec_date:
my_requested_exec_date = sepa_export.prefered_exec_date
else:
my_requested_exec_date = datetime.strftime(datetime.today() + timedelta(days=1), '%Y-%m-%d')
my_requested_exec_date = fields.date.context_today(
self, cr, uid, context=context)
pain_ns = {
'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
@@ -211,8 +210,9 @@ class banking_export_sepa_wizard(orm.TransientModel):
debtor_account_iban.text = my_company_iban
debtor_agent = etree.SubElement(payment_info, 'DbtrAgt')
debtor_agent_institution = etree.SubElement(debtor_agent, 'FinInstnId')
debtor_agent_bic = etree.SubElement(debtor_agent_institution, bic_xml_tag)
debtor_agent_bic.text = my_company_bic
if my_company_bic:
debtor_agent_bic = etree.SubElement(debtor_agent_institution, bic_xml_tag)
debtor_agent_bic.text = my_company_bic
charge_bearer = etree.SubElement(payment_info, 'ChrgBr')
charge_bearer.text = sepa_export.charge_bearer
@@ -238,10 +238,11 @@ class banking_export_sepa_wizard(orm.TransientModel):
amount_control_sum += line.amount_currency
creditor_agent = etree.SubElement(credit_transfer_transaction_info, 'CdtrAgt')
creditor_agent_institution = etree.SubElement(creditor_agent, 'FinInstnId')
creditor_agent_bic = etree.SubElement(creditor_agent_institution, bic_xml_tag)
if not line.bank_id:
raise orm.except_orm(_('Error :'), _("Missing Bank Account on invoice '%s' (payment order line reference '%s').") %(line.ml_inv_ref.number, line.name))
creditor_agent_bic.text = line.bank_id.bank.bic
if line.bank_id.bank.bic:
creditor_agent_bic = etree.SubElement(creditor_agent_institution, bic_xml_tag)
creditor_agent_bic.text = line.bank_id.bank.bic
creditor = etree.SubElement(credit_transfer_transaction_info, 'Cdtr')
creditor_name = etree.SubElement(creditor, 'Nm')
creditor_name.text = self._limit_size(cr, uid, line.partner_id.name, name_maxsize, context=context)
@@ -328,12 +329,15 @@ class banking_export_sepa_wizard(orm.TransientModel):
def save_sepa(self, cr, uid, ids, context=None):
'''
Save the SEPA PAIN: mark all payments in the file as 'sent'.
Save the SEPA PAIN: send the done signal to all payment orders in the file.
With the default workflow, they will transition to 'done', while with the
advanced workflow in account_banking_payment they will transition to 'sent'
waiting reconciliation.
'''
sepa_export = self.browse(cr, uid, ids[0], context=context)
sepa_file = self.pool.get('banking.export.sepa').write(cr, uid,
self.pool.get('banking.export.sepa').write(cr, uid,
sepa_export.file_id.id, {'state': 'sent'}, context=context)
wf_service = netsvc.LocalService('workflow')
for order in sepa_export.payment_order_ids:
wf_service.trg_validate(uid, 'payment.order', order.id, 'sent', cr)
wf_service.trg_validate(uid, 'payment.order', order.id, 'done', cr)
return {'type': 'ir.actions.act_window_close'}

View File

View File

@@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2013 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 - Tests',
'version': '0.1',
'license': 'AGPL-3',
'author': 'Therp BV',
'website': 'https://launchpad.net/banking-addons',
'category': 'Banking addons',
'depends': [
'account_accountant',
'account_banking',
'account_banking_sepa_credit_transfer',
],
'description': '''
This addon adds unit tests for the Banking addons. Installing this
module will not give you any benefit other than having the tests'
dependencies installed, so that you can run the tests. If you only
run the tests manually, you don't even have to install this module,
only its dependencies.
''',
'auto_install': False,
'installable': True,
}

View File

@@ -0,0 +1,5 @@
import test_payment_roundtrip
fast_suite = [
test_payment_roundtrip,
]

View File

@@ -0,0 +1,328 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2013 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 datetime import datetime
from openerp.tests.common import SingleTransactionCase
from openerp import netsvc
class TestPaymentRoundtrip(SingleTransactionCase):
def assert_payment_order_state(self, expected):
"""
Check that the state of our payment order is
equal to the 'expected' parameter
"""
state = self.registry('payment.order').read(
self.cr, self.uid, self.payment_order_id, ['state'])['state']
assert state == expected, \
'Payment order does not go into state \'%s\'.' % expected
def assert_invoices_state(self, expected):
"""
Check that the state of our invoices is
equal to the 'expected' parameter
"""
for invoice in self.registry('account.invoice').read(
self.cr, self.uid, self.invoice_ids, ['state']):
assert invoice['state'] == expected, \
'Invoice does not go into state \'%s\'' % expected
def setup_company(self, reg, cr, uid):
"""
Set up a company with a bank account and configure the
current user to work with that company
"""
data_model = reg('ir.model.data')
self.country_id = data_model.get_object_reference(
cr, uid, 'base', 'nl')[1]
self.currency_id = data_model.get_object_reference(
cr, uid, 'base', 'EUR')[1]
self.bank_id = reg('res.bank').create(
cr, uid, {
'name': 'ING Bank',
'bic': 'INGBNL2A',
'country': self.country_id,
})
self.company_id = reg('res.company').create(
cr, uid, {
'name': '_banking_addons_test_company',
'currency_id': self.currency_id,
'country_id': self.country_id,
})
self.partner_id = reg('res.company').read(
cr, uid, self.company_id, ['partner_id'])['partner_id'][0]
self.partner_bank_id = reg('res.partner.bank').create(
cr, uid, {
'state': 'iban',
'acc_number': 'NL08INGB0000000555',
'bank': self.bank_id,
'bank_bic': 'INGBNL2A',
'partner_id': self.partner_id,
'company_id': self.company_id,
})
reg('res.users').write(
cr, uid, [uid], {
'company_ids': [(4, self.company_id)]})
reg('res.users').write(
cr, uid, [uid], {
'company_id': self.company_id})
def setup_chart(self, reg, cr, uid):
"""
Set up the configurable chart of accounts and create periods
"""
data_model = reg('ir.model.data')
chart_setup_model = reg('wizard.multi.charts.accounts')
chart_template_id = data_model.get_object_reference(
cr, uid, 'account', 'configurable_chart_template')[1]
chart_values = {
'company_id': self.company_id,
'currency_id': self.currency_id,
'chart_template_id': chart_template_id}
chart_values.update(
chart_setup_model.onchange_chart_template_id(
cr, uid, [], 1)['value'])
chart_setup_id = chart_setup_model.create(
cr, uid, chart_values)
chart_setup_model.execute(
cr, uid, [chart_setup_id])
year = datetime.now().strftime('%Y')
fiscalyear_id = reg('account.fiscalyear').create(
cr, uid, {
'name': year,
'code': year,
'company_id': self.company_id,
'date_start': '%s-01-01' % year,
'date_stop': '%s-12-31' % year,
})
reg('account.fiscalyear').create_period(
cr, uid, [fiscalyear_id])
def setup_payables(self, reg, cr, uid):
"""
Set up suppliers and invoice them. Check that the invoices
can be validated properly.
"""
partner_model = reg('res.partner')
supplier1 = partner_model.create(
cr, uid, {
'name': 'Supplier 1',
'supplier': True,
'country_id': self.country_id,
'bank_ids': [(0, False, {
'state': 'iban',
'acc_number': 'NL42INGB0000454000',
'bank': self.bank_id,
'bank_bic': 'INGBNL2A',
})],
})
supplier2 = partner_model.create(
cr, uid, {
'name': 'Supplier 2',
'supplier': True,
'country_id': self.country_id,
'bank_ids': [(0, False, {
'state': 'iban',
'acc_number': 'NL86INGB0002445588',
'bank': self.bank_id,
'bank_bic': 'INGBNL2A',
})],
})
self.payable_id = reg('account.account').search(
cr, uid, [
('company_id', '=', self.company_id),
('code', '=', '120000')])[0]
expense_id = reg('account.account').search(
cr, uid, [
('company_id', '=', self.company_id),
('code', '=', '123000')])[0]
invoice_model = reg('account.invoice')
values = {
'type': 'in_invoice',
'partner_id': supplier1,
'account_id': self.payable_id,
'invoice_line': [(0, False, {
'name': 'Purchase 1',
'price_unit': 100.0,
'quantity': 1,
'account_id': expense_id,})],
}
self.invoice_ids = [
invoice_model.create(
cr, uid, values, context={
'type': 'in_invoice',
})]
values.update({
'partner_id': supplier2,
'name': 'Purchase 2'})
self.invoice_ids.append(
invoice_model.create(
cr, uid, values, context={
'type': 'in_invoice'}))
wf_service = netsvc.LocalService('workflow')
for invoice_id in self.invoice_ids:
wf_service.trg_validate(
uid, 'account.invoice', invoice_id, 'invoice_open', cr)
self.assert_invoices_state('open')
def setup_payment_config(self, reg, cr, uid):
"""
Configure an additional account and journal for payments
in transit and configure a payment mode with them.
"""
account_parent_id = reg('account.account').search(
cr, uid, [
('company_id', '=', self.company_id),
('parent_id', '=', False)])[0]
user_type = reg('ir.model.data').get_object_reference(
cr, uid, 'account', 'data_account_type_liability')[1]
transfer_account_id = reg('account.account').create(
cr, uid, {
'company_id': self.company_id,
'parent_id': account_parent_id,
'code': 'TRANS',
'name': 'Transfer account',
'type': 'other',
'user_type': user_type,
'reconcile': True,
})
transfer_journal_id = reg('account.journal').search(
cr, uid, [
('company_id', '=', self.company_id),
('code', '=', 'MISC')])[0]
self.bank_journal_id = reg('account.journal').search(
cr, uid, [
('company_id', '=', self.company_id),
('type', '=', 'bank')])[0]
payment_mode_type_id = reg('ir.model.data').get_object_reference(
cr, uid, 'account_banking_sepa_credit_transfer',
'export_sepa_sct_001_001_03')[1]
self.payment_mode_id = reg('payment.mode').create(
cr, uid, {
'name': 'SEPA Mode',
'bank_id': self.partner_bank_id,
'journal': self.bank_journal_id,
'company_id': self.company_id,
'transfer_account_id': transfer_account_id,
'transfer_journal_id': transfer_journal_id,
'type': payment_mode_type_id,
})
def setup_payment(self, reg, cr, uid):
"""
Create a payment order with the invoices' payable move lines.
Check that the payment order can be confirmed.
"""
self.payment_order_id = reg('payment.order').create(
cr, uid, {
'reference': 'PAY001',
'mode': self.payment_mode_id,
})
context = {'active_id': self.payment_order_id}
entries = reg('account.move.line').search(
cr, uid, [
('company_id', '=', self.company_id),
('account_id', '=', self.payable_id),
])
self.payment_order_create_id = reg('payment.order.create').create(
cr, uid, {
'entries': [(6, 0, entries)],
}, context=context)
reg('payment.order.create').create_payment(
cr, uid, [self.payment_order_create_id], context=context)
wf_service = netsvc.LocalService('workflow')
wf_service.trg_validate(
uid, 'payment.order', self.payment_order_id, 'open', cr)
self.assert_payment_order_state('open')
def export_payment(self, reg, cr, uid):
"""
Call the SEPA export wizard on the payment order
and check that the payment order and related invoices'
states are moved forward afterwards
"""
export_model = reg('banking.export.sepa.wizard')
export_id = export_model.create(
cr, uid, {
'msg_identification': 'EXP001'},
context={'active_ids': [self.payment_order_id]})
export_model.create_sepa(
cr, uid, [export_id])
export_model.save_sepa(
cr, uid, [export_id])
self.assert_payment_order_state('sent')
self.assert_invoices_state('paid')
def setup_bank_statement(self, reg, cr, uid):
"""
Create a bank statement with a single line. Call the reconciliation
wizard to match the line with the open payment order. Confirm the
bank statement. Check if the payment order is done.
"""
statement_model = reg('account.bank.statement')
line_model = reg('account.bank.statement.line')
wizard_model = reg('banking.transaction.wizard')
statement_id = statement_model.create(
cr, uid, {
'name': 'Statement',
'journal_id': self.bank_journal_id,
'balance_end_real': -200.0,
'period_id': reg('account.period').find(cr, uid)[0]
})
line_id = line_model.create(
cr, uid, {
'name': 'Statement line',
'statement_id': statement_id,
'amount': -200.0,
'account_id': self.payable_id,
})
wizard_id = wizard_model.create(
cr, uid, {'statement_line_id': line_id})
wizard_model.write(
cr, uid, [wizard_id], {
'manual_payment_order_id': self.payment_order_id})
statement_model.button_confirm_bank(cr, uid, [statement_id])
self.assert_payment_order_state('done')
def check_reconciliations(self, reg, cr, uid):
"""
Check if the payment order has any lines and that
the transit move lines of those payment lines are
reconciled by now.
"""
payment_order = reg('payment.order').browse(
cr, uid, self.payment_order_id)
assert payment_order.line_ids, 'Payment order has no payment lines'
for line in payment_order.line_ids:
assert line.transit_move_line_id, \
'Payment order has no transfer move line'
assert line.transit_move_line_id.reconcile_id, \
'Transfer move line on payment line is not reconciled'
def test_payment_roundtrip(self):
reg, cr, uid, = self.registry, self.cr, self.uid
self.setup_company(reg, cr, uid)
self.setup_chart(reg, cr, uid)
self.setup_payables(reg, cr, uid)
self.setup_payment_config(reg, cr, uid)
self.setup_payment(reg, cr, uid)
self.export_payment(reg, cr, uid)
self.setup_bank_statement(reg, cr, uid)
self.check_reconciliations(reg, cr, uid)

View File

@@ -25,7 +25,7 @@
'author': ['Therp BV', 'Smile'],
'website': 'https://launchpad.net/banking-addons',
'category': 'Banking addons',
'depends': ['account_banking'],
'depends': ['account_banking_payment'],
'data': [
'view/account_payment.xml',
'view/account_invoice.xml',

View File

@@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2013 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/>.
#
##############################################################################
def migrate(cr, version):
if not version:
return
cr.execute(
"""
UPDATE payment_line
SET transit_move_line_id = banking_addons_61_debit_move_line_id
""")
cr.execute(
"""
ALTER TABLE "payment_line"
DROP COLUMN "banking_addons_61_debit_move_line_id"
"""
)

View File

@@ -22,6 +22,9 @@
#
##############################################################################
import logging
logger = logging.getLogger()
def rename_columns(cr, column_spec):
"""
Rename table columns. Taken from OpenUpgrade.
@@ -41,17 +44,8 @@ def migrate(cr, version):
if not version:
return
# workflow state moved to another module
cr.execute(
"""
UPDATE ir_model_data
SET module = 'account_banking_payment'
WHERE name = 'trans_done_sent'
AND module = 'account_direct_debit'
""")
# rename field debit_move_line_id
rename_columns(cr, {
'payment_line': [
('debit_move_line_id', 'transit_move_line_id'),
('debit_move_line_id', 'banking_addons_61_debit_move_line_id'),
]})

View File

@@ -0,0 +1,28 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * account_iban_preserve_domestic
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 7.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-10-15 12:57+0000\n"
"PO-Revision-Date: 2013-10-17 11:08+0100\n"
"Last-Translator: Erwin van der Ploeg (BAS Solutions) <erwin@bas-solutions."
"nl>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: \n"
"X-Generator: Poedit 1.5.7\n"
#. module: account_iban_preserve_domestic
#: field:res.partner.bank,acc_number_domestic:0
msgid "Domestic Account Number"
msgstr "Nationaal rekening nummer"
#. module: account_iban_preserve_domestic
#: model:ir.model,name:account_iban_preserve_domestic.model_res_partner_bank
msgid "Bank Accounts"
msgstr "Bankrekeningen"

View File

@@ -1,19 +1,21 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * bank_statement_instant_voucher
# * bank_statement_instant_voucher
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 6.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-11-12 10:42+0000\n"
"PO-Revision-Date: 2012-11-12 10:42+0000\n"
"Last-Translator: <>\n"
"PO-Revision-Date: 2013-10-17 11:15+0100\n"
"Last-Translator: Erwin van der Ploeg (BAS Solutions) <erwin@bas-solutions."
"nl>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: \n"
"X-Generator: Poedit 1.5.7\n"
#. module: bank_statement_instant_voucher
#: view:account.voucher.instant:0
@@ -24,7 +26,7 @@ msgstr "Bevestig"
#: code:addons/bank_statement_instant_voucher/model/account_voucher_instant.py:71
#, python-format
msgid "Voucher for statement line %s.%s"
msgstr "Journaalbon voor bankafschrift %s.%s"
msgstr "Betaalbewijs voor bankafschrift %s.%s"
#. module: bank_statement_instant_voucher
#: field:account.voucher.instant,state:0
@@ -35,28 +37,28 @@ msgstr "Status"
#: code:addons/bank_statement_instant_voucher/model/account_voucher_instant.py:201
#, python-format
msgid "The voucher could not be posted."
msgstr "De journaalbon kon niet worden bevestigd."
msgstr "Het betaalbewijs kon niet worden bevestigd."
#. module: bank_statement_instant_voucher
#: selection:account.voucher.instant,state:0
msgid "ready"
msgstr "ready"
msgstr "gereed"
#. module: bank_statement_instant_voucher
#: model:ir.model,name:bank_statement_instant_voucher.model_account_voucher_instant
msgid "Instant Voucher"
msgstr "Instant journaalbon"
msgstr "Directe betaalbewijs"
#. module: bank_statement_instant_voucher
#: selection:account.voucher.instant,state:0
msgid "confirm"
msgstr "confirm"
msgstr "bevestig"
#. module: bank_statement_instant_voucher
#: view:account.bank.statement:0
#: model:ir.actions.act_window,name:bank_statement_instant_voucher.act_instant_voucher
msgid "Create matching voucher"
msgstr "Bijpassende journaalbon aanmaken"
msgstr "Bijpassende betaalbewijs aanmaken"
#. module: bank_statement_instant_voucher
#: code:addons/bank_statement_instant_voucher/model/account_voucher_instant.py:137
@@ -73,7 +75,7 @@ msgstr "init"
#: code:addons/bank_statement_instant_voucher/model/account_voucher_instant.py:209
#, python-format
msgid "The voucher's move line could not be posted."
msgstr "De journaalposten van de journaalbon konden niet geboekt worden"
msgstr "De boekingen van het betaalbewijs konden niet geboekt worden"
#. module: bank_statement_instant_voucher
#: model:ir.model,name:bank_statement_instant_voucher.model_account_bank_statement_line
@@ -83,13 +85,17 @@ msgstr "Bankafschriftregel"
#. module: bank_statement_instant_voucher
#: view:account.voucher.instant:0
msgid "Create voucher"
msgstr "Journaalbon aanmaken"
msgstr "Betaalbewijs aanmaken"
#. module: bank_statement_instant_voucher
#: code:addons/bank_statement_instant_voucher/model/account_voucher_instant.py:214
#, python-format
msgid "The amount on the bank statement line needs to be the same as on the voucher. Write-off is not yet supported."
msgstr "Het bedrag op het bankafschrift dient gelijk te zijn aan het bedrag op de journaalbon. Afschrijven is nog niet ondersteund."
msgid ""
"The amount on the bank statement line needs to be the same as on the "
"voucher. Write-off is not yet supported."
msgstr ""
"Het bedrag op het bankafschrift dient gelijk te zijn aan het bedrag op het "
"betaalbewijs. Afschrijven is nog niet ondersteund."
#. module: bank_statement_instant_voucher
#: code:addons/bank_statement_instant_voucher/model/account_voucher_instant.py:59
@@ -111,13 +117,17 @@ msgstr "Geen %s-dagboek ingesteld"
#. module: bank_statement_instant_voucher
#: constraint:account.bank.statement.line:0
msgid "The amount of the voucher must be the same amount as the one on the statement line"
msgstr "Het bedrag op de bon moet hetzelfde bedrag zijn dat vermeld staat op de afschriftregel"
msgid ""
"The amount of the voucher must be the same amount as the one on the "
"statement line"
msgstr ""
"Het bedrag op de bon moet hetzelfde bedrag zijn dat vermeld staat op de "
"afschriftregel"
#. module: bank_statement_instant_voucher
#: field:account.voucher.instant,balance:0
msgid "Balance"
msgstr "Balans"
msgstr "Saldo"
#. module: bank_statement_instant_voucher
#: field:account.voucher.instant,statement_line_id:0
@@ -132,8 +142,12 @@ msgstr "Referentie"
#. module: bank_statement_instant_voucher
#: code:addons/bank_statement_instant_voucher/model/account_voucher_instant.py:191
#, python-format
msgid "Currency on the bank statement line needs to be the same as on the voucher. Currency conversion is not yet supported."
msgstr "De valuta van de bankafschriftregel dient gelijk te zijn aan die op de journaalbon. Omrekenen tussen valuta is nog niet ondersteund."
msgid ""
"Currency on the bank statement line needs to be the same as on the voucher. "
"Currency conversion is not yet supported."
msgstr ""
"De valuta van de bankafschriftregel dient gelijk te zijn aan die op het "
"betaalbewijs. Omrekenen tussen valuta is nog niet ondersteund."
#. module: bank_statement_instant_voucher
#: code:addons/bank_statement_instant_voucher/model/account_voucher_instant.py:225
@@ -144,7 +158,7 @@ msgstr "Kan een bevestigde bankafschriftregel niet afletteren"
#. module: bank_statement_instant_voucher
#: field:account.voucher.instant,voucher_id:0
msgid "Voucher"
msgstr "Journaalbon"
msgstr "Betaalbewijs"
#. module: bank_statement_instant_voucher
#: view:account.voucher.instant:0
@@ -155,4 +169,3 @@ msgstr "Annuleer"
#: field:account.voucher.instant,partner_id:0
msgid "Partner"
msgstr "Relatie"

View File

@@ -0,0 +1 @@
import model

View File

@@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 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/>.
#
##############################################################################
{
'name': 'IBAN - Bic not required',
'version': '0.1',
'license': 'AGPL-3',
'author': 'Banking addons community',
'website': 'https://launchpad.net/banking-addons',
'category': 'Banking addons',
'depends': [
'base_iban',
],
'description': '''
The account_iban module in OpenERP mandates the presence of a BIC
code on an IBAN account number through a constraint. However, as of
Februari 2012 there is a resolution from the EU that drops this requirement
(see section 8 of [1]). This module reverts the constraint on BICs in the
base_iban module.
See also https://bugs.launchpad.net/openobject-addons/+bug/933472
[1] http://www.europarl.europa.eu/sides/getDoc.do?pubRef=-//EP//TEXT+TA+P7-TA-2012-0037+0+DOC+XML+V0//EN&language=EN#BKMD-9
''',
'data': [
'data/res_partner_bank_type_field.xml',
],
'installable': True,
}

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="base_iban.bank_swift_field"
model="res.partner.bank.type.field">
<field eval="False" name="required"/>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,34 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * base_iban_bic_not_required
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 7.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-10-15 12:59+0000\n"
"PO-Revision-Date: 2013-10-17 11:11+0100\n"
"Last-Translator: Erwin van der Ploeg (BAS Solutions) <erwin@bas-solutions."
"nl>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: \n"
"X-Generator: Poedit 1.5.7\n"
#. module: base_iban_bic_not_required
#: constraint:res.partner.bank:0
msgid ""
"\n"
"Please define BIC/Swift code on bank for bank type IBAN Account to make "
"valid payments"
msgstr ""
"\n"
"Definieer de BIC/Swift code bij de bankrekening van het type IBAN reking om "
"een betaling te kunnen maken."
#. module: base_iban_bic_not_required
#: model:ir.model,name:base_iban_bic_not_required.model_res_partner_bank
msgid "Bank Accounts"
msgstr "Bankrekeningen"

View File

@@ -0,0 +1 @@
import res_partner_bank

View File

@@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 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
class res_partner_bank(orm.Model):
_inherit = 'res.partner.bank'
def _check_bank(self, cr, uid, ids, context=None):
#suppress base_iban's constraint to enforce BICs for IBANs
#workaround for lp:933472
return True
# Redefine constraint to update its function reference
_constraints = [
(_check_bank,
'\nPlease define BIC/Swift code on bank for bank '
'type IBAN Account to make valid payments',
['bic'])
]