Merge pull request #35 from pedrobaeza/8.0-sepa-migration

[MIG] Migration and enhancement of all modules involved in SEPA
This commit is contained in:
Pedro M. Baeza
2014-11-16 18:30:47 +01:00
180 changed files with 5338 additions and 3025 deletions

View File

@@ -13,6 +13,7 @@ virtualenv:
install:
- git clone https://github.com/OCA/maintainer-quality-tools.git ${HOME}/maintainer-quality-tools
- export PATH=${HOME}/maintainer-quality-tools/travis:${PATH}
- sudo pip install unidecode
- travis_install_nightly
script:

View File

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

View File

@@ -1,145 +0,0 @@
# 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-25 15:58+0000\n"
"PO-Revision-Date: 2013-10-25 15:58+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: account_banking_payment_export
#: help:payment.mode.type,name:0
msgid "Payment Type"
msgstr ""
#. module: account_banking_payment_export
#: model:ir.model,name:account_banking_payment_export.model_payment_order
msgid "Payment Order"
msgstr ""
#. module: account_banking_payment_export
#: view:payment.manual:0
msgid "Please execute payment order manually, and click OK when succesfully sent."
msgstr ""
#. module: account_banking_payment_export
#: model:ir.model,name:account_banking_payment_export.model_payment_mode
msgid "Payment Mode"
msgstr ""
#. module: account_banking_payment_export
#: code:addons/account_banking_payment_export/model/account_payment.py:69
#, python-format
msgid "You can only combine payment orders of the same type"
msgstr ""
#. module: account_banking_payment_export
#: model:ir.model,name:account_banking_payment_export.model_payment_mode_type
msgid "Payment Mode Type"
msgstr ""
#. module: account_banking_payment_export
#: model:ir.model,name:account_banking_payment_export.model_account_move_line
msgid "Journal Items"
msgstr ""
#. module: account_banking_payment_export
#: model:ir.model,name:account_banking_payment_export.model_payment_manual
msgid "Send payment order(s) manually"
msgstr ""
#. module: account_banking_payment_export
#: field:payment.mode.type,name:0
msgid "Name"
msgstr ""
#. 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 ""
#. module: account_banking_payment_export
#: view:payment.manual:0
msgid "Manual payment"
msgstr ""
#. module: account_banking_payment_export
#: field:payment.manual,payment_order_ids:0
msgid "Payment orders"
msgstr ""
#. module: account_banking_payment_export
#: code:addons/account_banking_payment_export/model/account_payment.py:52
#, python-format
msgid "Payment Order Export"
msgstr ""
#. module: account_banking_payment_export
#: help:payment.mode,type:0
msgid "Select the Payment Type for the Payment Mode."
msgstr ""
#. module: account_banking_payment_export
#: view:payment.order:0
msgid "launch_wizard"
msgstr ""
#. module: account_banking_payment_export
#: help:payment.mode.type,code:0
msgid "Specify the Code for Payment Type"
msgstr ""
#. module: account_banking_payment_export
#: model:ir.model,name:account_banking_payment_export.model_payment_order_create
msgid "payment.order.create"
msgstr ""
#. module: account_banking_payment_export
#: code:addons/account_banking_payment_export/model/account_payment.py:68
#, python-format
msgid "Error"
msgstr ""
#. module: account_banking_payment_export
#: field:payment.mode.type,ir_model_id:0
msgid "Payment wizard"
msgstr ""
#. module: account_banking_payment_export
#: field:payment.mode,type:0
msgid "Payment type"
msgstr ""
#. module: account_banking_payment_export
#: field:payment.mode.type,code:0
msgid "Code"
msgstr ""
#. module: account_banking_payment_export
#: view:payment.manual:0
msgid "OK"
msgstr ""
#. module: account_banking_payment_export
#: view:payment.mode.type:0
msgid "Payment mode"
msgstr ""
#. module: account_banking_payment_export
#: view:payment.manual:0
msgid "Cancel"
msgstr ""
#. module: account_banking_payment_export
#: field:payment.mode.type,suitable_bank_types:0
msgid "Suitable bank types"
msgstr ""

View File

@@ -1,33 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2014 Akretion (http://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
#
# 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 communication = communication2, "
"communication2 = null "
"FROM payment_order "
"WHERE payment_line.order_id = payment_order.id "
"AND payment_order.state in ('draft', 'open') "
"AND payment_line.state = 'normal' "
"AND communication2 is not null")

View File

@@ -1,65 +0,0 @@
# -*- 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/>.
#
##############################################################################
'''
This module contains a single "wizard" for confirming manual
bank transfers.
'''
from openerp.osv import orm, fields
from openerp import netsvc
class payment_manual(orm.TransientModel):
_name = 'payment.manual'
_description = 'Send payment order(s) manually'
_columns = {
'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

@@ -1,73 +0,0 @@
# -*- 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)],
),
'payment_order_type': fields.selection(
[('payment', 'Payment'), ('debit', 'Direct debit')],
'Payment order type', required=True,
),
'active': fields.boolean('Active'),
}
_defaults = {
'payment_order_type': 'payment',
'active': 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

@@ -1,201 +0,0 @@
# -*- 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
from openerp.tools.translate import _
class payment_order_create(orm.TransientModel):
_inherit = 'payment.order.create'
def extend_payment_order_domain(
self, cr, uid, payment_order, domain, context=None):
if payment_order.payment_order_type == 'payment':
domain += [
('account_id.type', 'in', ('payable', 'receivable')),
('amount_to_pay', '>', 0)
]
return True
def search_entries(self, cr, uid, ids, context=None):
"""
This method taken from account_payment module.
We adapt the domain based on the payment_order_type
"""
line_obj = self.pool.get('account.move.line')
mod_obj = self.pool.get('ir.model.data')
if context is None:
context = {}
data = self.read(cr, uid, ids, ['duedate'], context=context)[0]
search_due_date = data['duedate']
# start account_banking_payment
payment = self.pool.get('payment.order').browse(
cr, uid, context['active_id'], context=context)
# Search for move line to pay:
domain = [
('move_id.state', '=', 'posted'),
('reconcile_id', '=', False),
('company_id', '=', payment.mode.company_id.id),
]
self.extend_payment_order_domain(
cr, uid, payment, domain, context=context)
# end account_direct_debit
domain = domain + [
'|', ('date_maturity', '<=', search_due_date),
('date_maturity', '=', False)
]
line_ids = line_obj.search(cr, uid, domain, context=context)
context.update({'line_ids': line_ids})
model_data_ids = mod_obj.search(
cr, uid, [
('model', '=', 'ir.ui.view'),
('name', '=', 'view_create_payment_order_lines')],
context=context)
resource_id = mod_obj.read(
cr, uid, model_data_ids, fields=['res_id'],
context=context)[0]['res_id']
return {
'name': _('Entry Lines'),
'context': context,
'view_type': 'form',
'view_mode': 'form',
'res_model': 'payment.order.create',
'views': [(resource_id, 'form')],
'type': 'ir.actions.act_window',
'target': 'new',
}
def _prepare_payment_line(self, cr, uid, payment, line, context=None):
'''This function is designed to be inherited
The resulting dict is passed to the create method of payment.line'''
_today = fields.date.context_today(self, cr, uid, context=context)
if payment.date_prefered == "now":
# no payment date => immediate payment
date_to_pay = False
elif payment.date_prefered == 'due':
# account_banking
# date_to_pay = line.date_maturity
date_to_pay = (
line.date_maturity
if line.date_maturity and line.date_maturity > _today
else False)
# end account banking
elif payment.date_prefered == 'fixed':
# account_banking
# date_to_pay = payment.date_scheduled
date_to_pay = (
payment.date_scheduled
if payment.date_scheduled and payment.date_scheduled > _today
else False)
# end account banking
# account_banking
state = 'normal'
communication = line.ref or '-'
if line.invoice:
if line.invoice.type in ('in_invoice', 'in_refund'):
if line.invoice.reference_type == 'structured':
state = 'structured'
communication = line.invoice.reference
else:
if line.invoice.reference:
communication = line.invoice.reference
elif line.invoice.supplier_invoice_number:
communication = line.invoice.supplier_invoice_number
else:
# Make sure that the communication includes the
# customer invoice number (in the case of debit order)
communication = line.invoice.number.replace('/', '')
state = 'structured'
# support debit orders when enabled
if (payment.payment_order_type == 'debit'
and 'amount_to_receive' in line):
amount_currency = line.amount_to_receive
else:
amount_currency = line.amount_to_pay
# end account_banking
# account banking
# t = None
# line2bank = line_obj.line2bank(cr, uid, line_ids, t, context)
line2bank = self.pool['account.move.line'].line2bank(
cr, uid, [line.id], payment.mode.id, context)
# end account banking
res = {
'move_line_id': line.id,
'amount_currency': amount_currency,
'bank_id': line2bank.get(line.id),
'order_id': payment.id,
'partner_id': line.partner_id and line.partner_id.id or False,
# account banking
# 'communication': line.ref or '/'
'communication': communication,
'state': state,
# end account banking
'date': date_to_pay,
'currency': (line.invoice and line.invoice.currency_id.id
or line.journal_id.currency.id
or line.journal_id.company_id.currency_id.id),
}
return res
def create_payment(self, cr, uid, ids, context=None):
'''
This method is a slightly modified version of the existing method on
this model in account_payment.
- pass the payment mode to line2bank()
- allow invoices to create influence on the payment process: not only
'Free' references are allowed, but others as well
- check date_to_pay is not in the past.
'''
if context is None:
context = {}
data = self.read(cr, uid, ids, [], context=context)[0]
line_ids = data['entries']
if not line_ids:
return {'type': 'ir.actions.act_window_close'}
payment = self.pool['payment.order'].browse(
cr, uid, context['active_id'], context=context)
# Populate the current payment with new lines:
for line in self.pool['account.move.line'].browse(
cr, uid, line_ids, context=context):
vals = self._prepare_payment_line(
cr, uid, payment, line, context=context)
self.pool['payment.line'].create(cr, uid, vals, context=context)
# Force reload of payment order view as a workaround for lp:1155525
return {
'name': _('Payment Orders'),
'context': context,
'view_type': 'form',
'view_mode': 'form,tree',
'res_model': 'payment.order',
'res_id': context['active_id'],
'type': 'ir.actions.act_window',
}

View File

@@ -1,90 +0,0 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# SEPA Credit Transfer module for OpenERP
# Copyright (C) 2010-2013 Akretion (http://www.akretion.com)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import orm, fields
from openerp.addons.decimal_precision import decimal_precision as dp
from unidecode import unidecode
class banking_export_sepa(orm.Model):
'''SEPA export'''
_name = 'banking.export.sepa'
_description = __doc__
_rec_name = 'filename'
def _generate_filename(self, cr, uid, ids, name, arg, context=None):
res = {}
for sepa_file in self.browse(cr, uid, ids, context=context):
ref = sepa_file.payment_order_ids[0].reference
if ref:
label = unidecode(ref.replace('/', '-'))
else:
label = 'error'
res[sepa_file.id] = 'sct_%s.xml' % label
return res
_columns = {
'payment_order_ids': fields.many2many(
'payment.order',
'account_payment_order_sepa_rel',
'banking_export_sepa_id', 'account_order_id',
'Payment Orders',
readonly=True),
'nb_transactions': fields.integer(
'Number of Transactions', readonly=True),
'total_amount': fields.float(
'Total Amount', digits_compute=dp.get_precision('Account'),
readonly=True),
'batch_booking': fields.boolean(
'Batch Booking', readonly=True,
help="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."),
'charge_bearer': fields.selection([
('SLEV', 'Following Service Level'),
('SHAR', 'Shared'),
('CRED', 'Borne by Creditor'),
('DEBT', 'Borne by Debtor'),
], 'Charge Bearer', readonly=True,
help="Following service level : transaction charges are to be "
"applied following the rules agreed in the service level and/or "
"scheme (SEPA Core messages must use this). Shared : "
"transaction charges on the creditor side are to be borne by "
"the creditor, transaction charges on the debtor side are to "
"be borne by the debtor. 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."),
'create_date': fields.datetime('Generation Date', readonly=True),
'file': fields.binary('SEPA XML File', readonly=True),
'filename': fields.function(
_generate_filename, type='char', size=256, string='Filename',
readonly=True),
'state': fields.selection([
('draft', 'Draft'),
('sent', 'Sent'),
], 'State', readonly=True),
}
_defaults = {
'state': 'draft',
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

View File

@@ -1,440 +0,0 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# SEPA Direct Debit module for OpenERP
# Copyright (C) 2013 Akretion (http://www.akretion.com)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import orm, fields
from openerp.tools.translate import _
from openerp.addons.decimal_precision import decimal_precision as dp
from unidecode import unidecode
from datetime import datetime
from dateutil.relativedelta import relativedelta
import logging
NUMBER_OF_UNUSED_MONTHS_BEFORE_EXPIRY = 36
logger = logging.getLogger(__name__)
class banking_export_sdd(orm.Model):
'''SEPA Direct Debit export'''
_name = 'banking.export.sdd'
_description = __doc__
_rec_name = 'filename'
def _generate_filename(self, cr, uid, ids, name, arg, context=None):
res = {}
for sepa_file in self.browse(cr, uid, ids, context=context):
ref = sepa_file.payment_order_ids[0].reference
if ref:
label = unidecode(ref.replace('/', '-'))
else:
label = 'error'
res[sepa_file.id] = 'sdd_%s.xml' % label
return res
_columns = {
'payment_order_ids': fields.many2many(
'payment.order',
'account_payment_order_sdd_rel',
'banking_export_sepa_id', 'account_order_id',
'Payment Orders',
readonly=True),
'nb_transactions': fields.integer(
'Number of Transactions', readonly=True),
'total_amount': fields.float(
'Total Amount', digits_compute=dp.get_precision('Account'),
readonly=True),
'batch_booking': fields.boolean(
'Batch Booking', readonly=True,
help="If true, the bank statement will display only one credit "
"line for all the direct debits of the SEPA file ; if false, "
"the bank statement will display one credit line per direct "
"debit of the SEPA file."),
'charge_bearer': fields.selection([
('SLEV', 'Following Service Level'),
('SHAR', 'Shared'),
('CRED', 'Borne by Creditor'),
('DEBT', 'Borne by Debtor'),
], 'Charge Bearer', readonly=True,
help="Following service level : transaction charges are to be "
"applied following the rules agreed in the service level and/or "
"scheme (SEPA Core messages must use this). Shared : "
"transaction charges on the creditor side are to be borne by "
"the creditor, transaction charges on the debtor side are to be "
"borne by the debtor. 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."),
'create_date': fields.datetime('Generation Date', readonly=True),
'file': fields.binary('SEPA File', readonly=True),
'filename': fields.function(
_generate_filename, type='char', size=256,
string='Filename', readonly=True, store=True),
'state': fields.selection([
('draft', 'Draft'),
('sent', 'Sent'),
], 'State', readonly=True),
}
_defaults = {
'state': 'draft',
}
class sdd_mandate(orm.Model):
'''SEPA Direct Debit Mandate'''
_name = 'sdd.mandate'
_description = __doc__
_rec_name = 'unique_mandate_reference'
_inherit = ['mail.thread']
_order = 'signature_date desc'
_track = {
'state': {
'account_banking_sepa_direct_debit.mandate_valid':
lambda self, cr, uid, obj, ctx=None:
obj['state'] == 'valid',
'account_banking_sepa_direct_debit.mandate_expired':
lambda self, cr, uid, obj, ctx=None:
obj['state'] == 'expired',
'account_banking_sepa_direct_debit.mandate_cancel':
lambda self, cr, uid, obj, ctx=None:
obj['state'] == 'cancel',
},
'recurrent_sequence_type': {
'account_banking_sepa_direct_debit.recurrent_sequence_type_first':
lambda self, cr, uid, obj, ctx=None:
obj['recurrent_sequence_type'] == 'first',
'account_banking_sepa_direct_debit.'
'recurrent_sequence_type_recurring':
lambda self, cr, uid, obj, ctx=None:
obj['recurrent_sequence_type'] == 'recurring',
'account_banking_sepa_direct_debit.recurrent_sequence_type_final':
lambda self, cr, uid, obj, ctx=None:
obj['recurrent_sequence_type'] == 'final',
}
}
_columns = {
'partner_bank_id': fields.many2one(
'res.partner.bank', 'Bank Account', track_visibility='onchange'),
'partner_id': fields.related(
'partner_bank_id', 'partner_id', type='many2one',
relation='res.partner', string='Partner', readonly=True),
'company_id': fields.many2one('res.company', 'Company', required=True),
'unique_mandate_reference': fields.char(
'Unique Mandate Reference', size=35, readonly=True,
track_visibility='always'),
'type': fields.selection([
('recurrent', 'Recurrent'),
('oneoff', 'One-Off'),
], 'Type of Mandate', required=True, track_visibility='always'),
'recurrent_sequence_type': fields.selection([
('first', 'First'),
('recurring', 'Recurring'),
('final', 'Final'),
], 'Sequence Type for Next Debit', track_visibility='onchange',
help="This field is only used for Recurrent mandates, not for "
"One-Off mandates."),
'signature_date': fields.date(
'Date of Signature of the Mandate', track_visibility='onchange'),
'scan': fields.binary('Scan of the Mandate'),
'last_debit_date': fields.date(
'Date of the Last Debit', readonly=True),
'state': fields.selection([
('draft', 'Draft'),
('valid', 'Valid'),
('expired', 'Expired'),
('cancel', 'Cancelled'),
], 'Status',
help="Only valid mandates can be used in a payment line. A "
"cancelled mandate is a mandate that has been cancelled by "
"the customer. A one-off mandate expires after its first use. "
"A recurrent mandate expires after it's final use or if it "
"hasn't been used for 36 months."),
'payment_line_ids': fields.one2many(
'payment.line', 'sdd_mandate_id', "Related Payment Lines"),
'sepa_migrated': fields.boolean(
'Migrated to SEPA', track_visibility='onchange',
help="If this field is not active, the mandate section of the "
"next direct debit file that include this mandate will contain "
"the 'Original Mandate Identification' and the 'Original "
"Creditor Scheme Identification'. This is required in a few "
"countries (Belgium for instance), but not in all countries. "
"If this is not required in your country, you should keep this "
"field always active."),
'original_mandate_identification': fields.char(
'Original Mandate Identification', size=35,
track_visibility='onchange',
help="When the field 'Migrated to SEPA' is not active, this "
"field will be used as the Original Mandate Identification in "
"the Direct Debit file."),
}
_defaults = {
'company_id': lambda self, cr, uid, context:
self.pool['res.company']._company_default_get(
cr, uid, 'sdd.mandate', context=context),
'unique_mandate_reference': '/',
'state': 'draft',
'sepa_migrated': True,
}
_sql_constraints = [(
'mandate_ref_company_uniq',
'unique(unique_mandate_reference, company_id)',
'A Mandate with the same reference already exists for this company !'
)]
def create(self, cr, uid, vals, context=None):
if vals.get('unique_mandate_reference', '/') == '/':
vals['unique_mandate_reference'] = \
self.pool['ir.sequence'].next_by_code(
cr, uid, 'sdd.mandate.reference', context=context)
return super(sdd_mandate, self).create(cr, uid, vals, context=context)
def _check_sdd_mandate(self, cr, uid, ids):
for mandate in self.browse(cr, uid, ids):
if (mandate.signature_date and
mandate.signature_date >
datetime.today().strftime('%Y-%m-%d')):
raise orm.except_orm(
_('Error:'),
_("The date of signature of mandate '%s' is in the "
"future !")
% mandate.unique_mandate_reference)
if mandate.state == 'valid' and not mandate.signature_date:
raise orm.except_orm(
_('Error:'),
_("Cannot validate the mandate '%s' without a date of "
"signature.")
% mandate.unique_mandate_reference)
if mandate.state == 'valid' and not mandate.partner_bank_id:
raise orm.except_orm(
_('Error:'),
_("Cannot validate the mandate '%s' because it is not "
"attached to a bank account.")
% mandate.unique_mandate_reference)
if (mandate.signature_date and mandate.last_debit_date and
mandate.signature_date > mandate.last_debit_date):
raise orm.except_orm(
_('Error:'),
_("The mandate '%s' can't have a date of last debit "
"before the date of signature.")
% mandate.unique_mandate_reference)
if (mandate.type == 'recurrent'
and not mandate.recurrent_sequence_type):
raise orm.except_orm(
_('Error:'),
_("The recurrent mandate '%s' must have a sequence type.")
% mandate.unique_mandate_reference)
if (mandate.type == 'recurrent' and not mandate.sepa_migrated
and mandate.recurrent_sequence_type != 'first'):
raise orm.except_orm(
_('Error:'),
_("The recurrent mandate '%s' which is not marked as "
"'Migrated to SEPA' must have its recurrent sequence "
"type set to 'First'.")
% mandate.unique_mandate_reference)
if (mandate.type == 'recurrent' and not mandate.sepa_migrated
and not mandate.original_mandate_identification):
raise orm.except_orm(
_('Error:'),
_("You must set the 'Original Mandate Identification' "
"on the recurrent mandate '%s' which is not marked "
"as 'Migrated to SEPA'.")
% mandate.unique_mandate_reference)
return True
_constraints = [
(_check_sdd_mandate, "Error msg in raise", [
'last_debit_date', 'signature_date', 'state', 'partner_bank_id',
'type', 'recurrent_sequence_type', 'sepa_migrated',
'original_mandate_identification',
]),
]
def mandate_type_change(self, cr, uid, ids, type):
if type == 'recurrent':
recurrent_sequence_type = 'first'
else:
recurrent_sequence_type = False
res = {'value': {'recurrent_sequence_type': recurrent_sequence_type}}
return res
def mandate_partner_bank_change(
self, cr, uid, ids, partner_bank_id, type, recurrent_sequence_type,
last_debit_date, state):
res = {'value': {}}
if partner_bank_id:
partner_bank_read = self.pool['res.partner.bank'].read(
cr, uid, partner_bank_id, ['partner_id'])['partner_id']
if partner_bank_read:
res['value']['partner_id'] = partner_bank_read[0]
if (state == 'valid' and partner_bank_id
and type == 'recurrent'
and recurrent_sequence_type != 'first'):
res['value']['recurrent_sequence_type'] = 'first'
res['warning'] = {
'title': _('Mandate update'),
'message': _(
"As you changed the bank account attached to this "
"mandate, the 'Sequence Type' has been set back to "
"'First'."),
}
return res
def validate(self, cr, uid, ids, context=None):
to_validate_ids = []
for mandate in self.browse(cr, uid, ids, context=context):
assert mandate.state == 'draft', 'Mandate should be in draft state'
to_validate_ids.append(mandate.id)
self.write(
cr, uid, to_validate_ids, {'state': 'valid'}, context=context)
return True
def cancel(self, cr, uid, ids, context=None):
to_cancel_ids = []
for mandate in self.browse(cr, uid, ids, context=context):
assert mandate.state in ('draft', 'valid'),\
'Mandate should be in draft or valid state'
to_cancel_ids.append(mandate.id)
self.write(
cr, uid, to_cancel_ids, {'state': 'cancel'}, context=context)
return True
def back2draft(self, cr, uid, ids, context=None):
to_draft_ids = []
for mandate in self.browse(cr, uid, ids, context=context):
assert mandate.state == 'cancel',\
'Mandate should be in cancel state'
to_draft_ids.append(mandate.id)
self.write(
cr, uid, to_draft_ids, {'state': 'draft'}, context=context)
return True
def _sdd_mandate_set_state_to_expired(self, cr, uid, context=None):
logger.info('Searching for SDD Mandates that must be set to Expired')
expire_limit_date = datetime.today() + \
relativedelta(months=-NUMBER_OF_UNUSED_MONTHS_BEFORE_EXPIRY)
expire_limit_date_str = expire_limit_date.strftime('%Y-%m-%d')
expired_mandate_ids = self.search(cr, uid, [
'|',
('last_debit_date', '=', False),
('last_debit_date', '<=', expire_limit_date_str),
('state', '=', 'valid'),
('signature_date', '<=', expire_limit_date_str),
], context=context)
if expired_mandate_ids:
self.write(
cr, uid, expired_mandate_ids, {'state': 'expired'},
context=context)
logger.info(
'The following SDD Mandate IDs has been set to expired: %s'
% expired_mandate_ids)
else:
logger.info('0 SDD Mandates must be set to Expired')
return True
class res_partner_bank(orm.Model):
_inherit = 'res.partner.bank'
_columns = {
'sdd_mandate_ids': fields.one2many(
'sdd.mandate', 'partner_bank_id', 'SEPA Direct Debit Mandates'),
}
class payment_line(orm.Model):
_inherit = 'payment.line'
_columns = {
'sdd_mandate_id': fields.many2one(
'sdd.mandate', 'SEPA Direct Debit Mandate',
domain=[('state', '=', 'valid')]),
}
def create(self, cr, uid, vals, context=None):
'''If the customer invoice has a mandate, take it
otherwise, take the first valid mandate of the bank account'''
if context is None:
context = {}
if not vals:
vals = {}
partner_bank_id = vals.get('bank_id')
move_line_id = vals.get('move_line_id')
if (context.get('default_payment_order_type') == 'debit'
and 'sdd_mandate_id' not in vals):
if move_line_id:
line = self.pool['account.move.line'].browse(
cr, uid, move_line_id, context=context)
if (line.invoice and line.invoice.type == 'out_invoice'
and line.invoice.sdd_mandate_id):
vals.update({
'sdd_mandate_id': line.invoice.sdd_mandate_id.id,
'bank_id':
line.invoice.sdd_mandate_id.partner_bank_id.id,
})
if partner_bank_id and 'sdd_mandate_id' not in vals:
mandate_ids = self.pool['sdd.mandate'].search(cr, uid, [
('partner_bank_id', '=', partner_bank_id),
('state', '=', 'valid'),
], context=context)
if mandate_ids:
vals['sdd_mandate_id'] = mandate_ids[0]
return super(payment_line, self).create(cr, uid, vals, context=context)
def _check_mandate_bank_link(self, cr, uid, ids):
for payline in self.browse(cr, uid, ids):
if (payline.sdd_mandate_id and payline.bank_id
and payline.sdd_mandate_id.partner_bank_id.id !=
payline.bank_id.id):
raise orm.except_orm(
_('Error:'),
_("The payment line with reference '%s' has the bank "
"account '%s' which is not attached to the mandate "
"'%s' (this mandate is attached to the bank account "
"'%s').") % (
payline.name,
self.pool['res.partner.bank'].name_get(
cr, uid, [payline.bank_id.id])[0][1],
payline.sdd_mandate_id.unique_mandate_reference,
self.pool['res.partner.bank'].name_get(
cr, uid,
[payline.sdd_mandate_id.partner_bank_id.id])[0][1],
))
return True
_constraints = [
(_check_mandate_bank_link, 'Error msg in raise',
['sdd_mandate_id', 'bank_id']),
]
class account_invoice(orm.Model):
_inherit = 'account.invoice'
_columns = {
'sdd_mandate_id': fields.many2one(
'sdd.mandate', 'SEPA Direct Debit Mandate',
domain=[('state', '=', 'valid')], readonly=True,
states={'draft': [('readonly', False)]})
}

View File

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<record id="sdd_mandate_seq_type" model="ir.sequence.type">
<field name="name">SDD Mandate Reference</field>
<field name="code">sdd.mandate.reference</field>
</record>
<record id="sdd_mandate_seq" model="ir.sequence">
<field name="name">SDD Mandate Reference</field>
<field name="code">sdd.mandate.reference</field>
<field name="prefix">RUM</field>
<field name="padding" eval="7"/>
<!-- remember that max size for the mandate ref is 35 -->
</record>
</data>
</openerp>

View File

@@ -1,26 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2013 Akretion (http://www.akretion.com/)
@author Alexis de Lattre <alexis.delattre@akretion.com>
The licence is in the file __openerp__.py
-->
<openerp>
<data noupdate="1"> <!-- noupdate = 1 for the 'active' field -->
<record id="sdd_mandate_expire_cron" model="ir.cron">
<field name="name">Set SEPA Direct Debit Mandates to Expired</field>
<field name="active" eval="True"/>
<field name="user_id" ref="base.user_root"/>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field> <!-- don't limit the number of calls -->
<field name="doall" eval="False"/>
<field name="model" eval="'sdd.mandate'"/>
<field name="function" eval="'_sdd_mandate_set_state_to_expired'" />
<field name="args" eval="'()'"/>
</record>
</data>
</openerp>

View File

@@ -1,152 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2013 Akretion (http://www.akretion.com)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
The licence is in the file __openerp__.py
-->
<openerp>
<data>
<record id="sdd_mandate_form" model="ir.ui.view">
<field name="name">sdd.mandate.form</field>
<field name="model">sdd.mandate</field>
<field name="arch" type="xml">
<form string="SEPA Direct Debit Mandate" version="7.0">
<header>
<button name="validate" type="object" string="Validate" states="draft" class="oe_highlight"/>
<button name="cancel" type="object" string="Cancel" states="draft,valid"/>
<button name="back2draft" type="object" string="Back to Draft"
states="cancel" groups="account.group_account_manager"
confirm="You should set a mandate back to draft only if you cancelled it by mistake. Do you want to continue ?"/>
<field name="state" widget="statusbar"/>
</header>
<sheet>
<div class="oe_title">
<h1>
<field name="unique_mandate_reference" class="oe_inline"/>
</h1>
</div>
<group name="main">
<field name="company_id" groups="base.group_multi_company"/>
<field name="partner_bank_id"
on_change="mandate_partner_bank_change(partner_bank_id, type, recurrent_sequence_type, last_debit_date, state)"
invisible="context.get('sdd_mandate_bank_partner_view')"
/>
<field name="partner_id" invisible="context.get('sdd_mandate_bank_partner_view')"/>
<field name="type" on_change="mandate_type_change(type)"/>
<field name="recurrent_sequence_type" attrs="{'invisible': [('type', '=', 'oneoff')], 'required': [('type', '=', 'recurrent')]}"/>
<field name="signature_date"/>
<field name="scan"/>
<field name="last_debit_date"/>
<field name="sepa_migrated" groups="account_banking_sepa_direct_debit.group_original_mandate_required"/>
<field name="original_mandate_identification" attrs="{'invisible': [('sepa_migrated', '=', True)], 'required': [('sepa_migrated', '=', False)]}" groups="account_banking_sepa_direct_debit.group_original_mandate_required"/>
</group>
<group name="payment_lines" string="Related Payment Lines">
<field name="payment_line_ids" nolabel="1"/>
</group>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
</record>
<record id="sdd_mandate_tree" model="ir.ui.view">
<field name="name">sdd.mandate.tree</field>
<field name="model">sdd.mandate</field>
<field name="arch" type="xml">
<tree string="SEPA Direct Debit Mandate" colors="blue:state=='draft';black:state in ('expired', 'cancel')">
<field name="company_id" groups="base.group_multi_company"/>
<field name="partner_id" invisible="context.get('sdd_mandate_bank_partner_view')"/>
<field name="unique_mandate_reference" string="Reference"/>
<field name="type" string="Type"/>
<field name="signature_date" string="Signature Date"/>
<field name="last_debit_date"/>
<field name="state"/>
</tree>
</field>
</record>
<record id="sdd_mandate_search" model="ir.ui.view">
<field name="name">sdd.mandate.search</field>
<field name="model">sdd.mandate</field>
<field name="arch" type="xml">
<search string="Search SEPA Direct Debit Mandates">
<field name="partner_id"/>
<filter name="draft" string="Draft" domain="[('state', '=', 'draft')]" />
<filter name="valid" string="Valid" domain="[('state', '=', 'valid')]" />
<filter name="cancel" string="Cancelled" domain="[('state', '=', 'cancel')]" />
<filter name="expired" string="Expired" domain="[('state', '=', 'expired')]" />
<filter name="oneoff" string="One-Off" domain="[('type', '=', 'oneoff')]" />
<filter name="recurrent" string="Recurrent" domain="[('type', '=', 'recurrent')]" />
</search>
</field>
</record>
<record id="sdd_mandate_action" model="ir.actions.act_window">
<field name="name">SEPA Direct Debit Mandates</field>
<field name="res_model">sdd.mandate</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new SEPA Direct Debit Mandate.
</p><p>
A SEPA Direct Debit Mandate is a document signed by your customer that gives you the autorization to do one or several direct debits on his bank account.
</p>
</field>
</record>
<menuitem id="sdd_mandate_menu"
parent="account_payment.menu_main_payment"
action="sdd_mandate_action"
sequence="20"
/>
<!-- notifications in the chatter -->
<record id="mandate_valid" model="mail.message.subtype">
<field name="name">Mandate Validated</field>
<field name="res_model">sdd.mandate</field>
<field name="default" eval="False"/>
<field name="description">SEPA Direct Debit Mandate Validated</field>
</record>
<record id="mandate_expired" model="mail.message.subtype">
<field name="name">Mandate Expired</field>
<field name="res_model">sdd.mandate</field>
<field name="default" eval="False"/>
<field name="description">SEPA Direct Debit Mandate has Expired</field>
</record>
<record id="mandate_cancel" model="mail.message.subtype">
<field name="name">Mandate Cancelled</field>
<field name="res_model">sdd.mandate</field>
<field name="default" eval="False"/>
<field name="description">SEPA Direct Debit Mandate Cancelled</field>
</record>
<record id="recurrent_sequence_type_first" model="mail.message.subtype">
<field name="name">Sequence Type set to First</field>
<field name="res_model">sdd.mandate</field>
<field name="default" eval="False"/>
<field name="description">Sequence Type set to First</field>
</record>
<record id="recurrent_sequence_type_recurring" model="mail.message.subtype">
<field name="name">Sequence Type set to Recurring</field>
<field name="res_model">sdd.mandate</field>
<field name="default" eval="False"/>
<field name="description">Sequence Type set to Recurring</field>
</record>
<record id="recurrent_sequence_type_final" model="mail.message.subtype">
<field name="name">Sequence Type set to Final</field>
<field name="res_model">sdd.mandate</field>
<field name="default" eval="False"/>
<field name="description">Sequence Type set to Final</field>
</record>
</data>
</openerp>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

View File

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

View File

@@ -1,53 +0,0 @@
# -*- 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/>.
#
##############################################################################
import logging
logger = logging.getLogger()
def rename_columns(cr, column_spec):
"""
Rename table columns. Taken from OpenUpgrade.
:param column_spec: a hash with table keys, with lists of tuples as \
values. Tuples consist of (old_name, new_name).
"""
for table in column_spec.keys():
for (old, new) in column_spec[table]:
logger.info("table %s, column %s: renaming to %s", table, old, new)
cr.execute('ALTER TABLE %s RENAME %s TO %s', (table, old, new,))
cr.execute('DROP INDEX IF EXISTS "%s_%s_index"' % (table, old))
def migrate(cr, version):
if not version:
return
# rename field debit_move_line_id
rename_columns(cr, {
'payment_line': [
('debit_move_line_id', 'banking_addons_61_debit_move_line_id'),
]
})

View File

@@ -1,5 +0,0 @@
import account_payment
import payment_line
import account_move_line
import account_invoice
import payment_order_create

View File

@@ -1,38 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2014 Akretion (http://www.akretion.com/)
@author Alexis de Lattre <alexis.delattre@akretion.com>
The licence is in the file __openerp__.py
-->
<openerp>
<data>
<record id="invoice_form" model="ir.ui.view">
<field name="name">account_payment_partner.invoice_form</field>
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.invoice_form" />
<field name="arch" type="xml">
<field name="partner_bank_id" position="after">
<field name="payment_mode_id"/>
</field>
</field>
</record>
<record id="invoice_supplier_form" model="ir.ui.view">
<field name="name">account_payment_partner.invoice_supplier_form</field>
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.invoice_supplier_form" />
<field name="arch" type="xml">
<field name="partner_bank_id" position="after">
<field name="payment_mode_id"/>
</field>
</field>
</record>
</data>
</openerp>

View File

@@ -1,82 +0,0 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Account Payment Purchase module for OpenERP
# Copyright (C) 2014 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
#
# 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 purchase_order(orm.Model):
_inherit = "purchase.order"
_columns = {
'supplier_partner_bank_id': fields.many2one(
'res.partner.bank', 'Supplier Bank Account',
help="Select the bank account of your supplier on which "
"your company should send the payment. This field is copied "
"from the partner and will be copied to the supplier invoice."),
'payment_mode_id': fields.many2one(
'payment.mode', 'Payment Mode'),
}
def _get_default_supplier_partner_bank(
self, cr, uid, partner, context=None):
'''This function is designed to be inherited'''
if partner.bank_ids:
return partner.bank_ids[0].id
else:
return False
def onchange_partner_id(self, cr, uid, ids, partner_id):
res = super(purchase_order, self).onchange_partner_id(
cr, uid, ids, partner_id)
if partner_id:
partner = self.pool['res.partner'].browse(
cr, uid, partner_id)
res['value'].update({
'supplier_partner_bank_id':
self._get_default_supplier_partner_bank(
cr, uid, partner),
'payment_mode_id':
partner.supplier_payment_mode.id or False,
})
else:
res['value'].update({
'supplier_partner_bank_id': False,
'payment_mode_id': False,
})
return res
def action_invoice_create(self, cr, uid, ids, context=None):
"""Copy bank partner + payment type from PO to invoice"""
# as of OpenERP 7.0, there is no _prepare function for
# the invoice (the _prepare function only exists for invoice lines)
res = super(purchase_order, self).action_invoice_create(
cr, uid, ids, context=context)
for order in self.browse(cr, uid, ids, context=context):
for invoice in order.invoice_ids:
if invoice.state == 'draft':
invoice.write({
'partner_bank_id':
order.supplier_partner_bank_id.id or False,
'payment_mode_id':
order.payment_mode_id.id or False,
}, context=context)
return res

View File

@@ -1,43 +0,0 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Account Payment Sale Stock module for OpenERP
# Copyright (C) 2014 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
#
# 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 stock_picking(orm.Model):
_inherit = "stock.picking"
def _prepare_invoice(
self, cr, uid, picking, partner, inv_type, journal_id,
context=None):
"""Copy payment mode from sale order to invoice"""
invoice_vals = super(stock_picking, self)._prepare_invoice(
cr, uid, picking, partner, inv_type, journal_id, context=context)
if picking.sale_id:
invoice_vals.update({
'partner_bank_id':
picking.sale_id.payment_mode_id and
picking.sale_id.payment_mode_id.bank_id.id or False,
'payment_mode_id':
picking.sale_id.payment_mode_id.id or False,
})
return invoice_vals

View File

@@ -1,2 +0,0 @@
# -*- coding: utf-8 -*-
from . import payment_order

View File

@@ -1,34 +0,0 @@
##############################################################################
#
# Copyright (C) 2011 Therp BV (<http://therp.nl>).
# 2011 Smile BV (<http://smile.fr>).
# 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 Payment Invoice Selection Shortcut',
'version': '1.134',
'license': 'AGPL-3',
'author': 'Smile / Therp BV',
'website': 'https://launchpad.net/banking-addons',
'category': 'Banking addons',
'depends': ['account_payment'],
'description': '''
When composing a payment order, select all candidates by default
(in the second step of the "Select invoices to pay" wizard).
''',
'installable': False,
}

View File

@@ -1,54 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (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
class payment_order_create(orm.TransientModel):
_inherit = 'payment.order.create'
def default_get(self, cr, uid, fields_list, context=None):
"""
Automatically add the candidate move lines to
the payment order, instead of only applying them
to the domain.
We make use of the fact that the search_entries
method passes an action without a res_id so that a
new instance is created. Inject the line_ids, which have
been placed in the context at object
creation time.
"""
if context is None:
context = {}
res = super(payment_order_create, self).default_get(
cr, uid, fields_list, context=context)
if (fields_list
and 'entries' in fields_list
and 'entries' not in res
and context.get('line_ids', False)):
res['entries'] = context['line_ids']
return res

View File

@@ -0,0 +1,22 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Mandate module for openERP
# Copyright (C) 2014 Compassion CH (http://www.compassion.ch)
# @author: Cyril Sester <csester@compassion.ch>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from . import models

View File

@@ -0,0 +1,57 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Mandate module for openERP
# Copyright (C) 2014 Compassion CH (http://www.compassion.ch)
# @author: Cyril Sester <csester@compassion.ch>,
# Alexis de Lattre <alexis.delattre@akretion.com>
#
# 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 Mandate',
'summary': 'Banking mandates',
'version': '0.1',
'license': 'AGPL-3',
'author': 'Compassion CH',
'website': 'http://www.compassion.ch',
'contributors': ['Pedro M. Baeza <pedro.baeza@serviciosbaeza.com>'],
'category': 'Banking addons',
'depends': [
'account_payment',
],
'data': [
'views/account_banking_mandate_view.xml',
'views/account_invoice_view.xml',
'views/account_payment_view.xml',
'views/res_partner_bank_view.xml',
'data/mandate_reference_sequence.xml',
'security/ir.model.access.csv',
],
'demo': [],
'test': ['test/banking_mandate.yml'],
'description': '''
This module adds a generic model for banking mandates.
These mandates can be specialized to fit any banking mandates (such as
sepa or lsv).
A banking mandate is attached to a bank account and represents an
authorization that the bank account owner gives to a company for a
specific operation (such as direct debit).
You can setup mandates from the accounting menu or directly from a bank
account.
''',
'installable': True,
}

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<record id="dd_mandate_seq_type" model="ir.sequence.type">
<field name="name">DD Mandate Reference</field>
<field name="code">account.banking.mandate</field>
</record>
<record id="dd_mandate_seq" model="ir.sequence">
<field name="name">DD Mandate Reference</field>
<field name="code">account.banking.mandate</field>
<field name="prefix">BM</field>
<field name="padding" eval="7"/>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,355 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_banking_mandate
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-10-31 23:00+0000\n"
"PO-Revision-Date: 2014-10-31 23:00+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: account_banking_mandate
#: model:ir.actions.act_window,help:account_banking_mandate.mandate_action
msgid "<p class=\"oe_view_nocontent_create\">\n"
" Click to create a new Banking Mandate.\n"
" </p><p>\n"
" A Banking Mandate is a document signed by your customer that gives you the autorization to do one or several operations on his bank account.\n"
" </p>\n"
" "
msgstr ""
#. module: account_banking_mandate
#: sql_constraint:account.banking.mandate:0
msgid "A Mandate with the same reference already exists for this company !"
msgstr ""
#. module: account_banking_mandate
#: model:ir.model,name:account_banking_mandate.model_account_banking_mandate
msgid "A generic banking mandate"
msgstr ""
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_form
msgid "Back to Draft"
msgstr ""
#. module: account_banking_mandate
#: field:account.banking.mandate,partner_bank_id:0
msgid "Bank Account"
msgstr ""
#. module: account_banking_mandate
#: model:ir.model,name:account_banking_mandate.model_res_partner_bank
msgid "Bank Accounts"
msgstr ""
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_form
#: view:account.banking.mandate:account_banking_mandate.view_mandate_tree
msgid "Banking Mandate"
msgstr ""
#. module: account_banking_mandate
#: model:mail.message.subtype,description:account_banking_mandate.mandate_cancel
msgid "Banking Mandate Cancelled"
msgstr ""
#. module: account_banking_mandate
#: model:mail.message.subtype,description:account_banking_mandate.mandate_valid
msgid "Banking Mandate Validated"
msgstr ""
#. module: account_banking_mandate
#: model:mail.message.subtype,description:account_banking_mandate.mandate_expired
msgid "Banking Mandate has Expired"
msgstr ""
#. module: account_banking_mandate
#: model:ir.actions.act_window,name:account_banking_mandate.mandate_action
msgid "Banking Mandates"
msgstr ""
#. module: account_banking_mandate
#: help:res.partner.bank,mandate_ids:0
msgid "Banking mandates represents an authorization that the bank account owner gives to a company for a specific operation"
msgstr ""
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_form
msgid "Cancel"
msgstr ""
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_search
msgid "Cancelled"
msgstr ""
#. module: account_banking_mandate
#: code:addons/account_banking_mandate/models/account_banking_mandate.py:110
#, python-format
msgid "Cannot validate the mandate '%s' because it is not attached to a bank account."
msgstr ""
#. module: account_banking_mandate
#: code:addons/account_banking_mandate/models/account_banking_mandate.py:106
#, python-format
msgid "Cannot validate the mandate '%s' without a date of signature."
msgstr ""
#. module: account_banking_mandate
#: field:account.banking.mandate,company_id:0
msgid "Company"
msgstr ""
#. module: account_banking_mandate
#: field:account.banking.mandate,create_uid:0
msgid "Created by"
msgstr ""
#. module: account_banking_mandate
#: field:account.banking.mandate,create_date:0
msgid "Created on"
msgstr ""
#. module: account_banking_mandate
#: view:payment.order:account_banking_mandate.view_mandate_payment_order_form
msgid "DD Mandate"
msgstr ""
#. module: account_banking_mandate
#: view:res.partner:account_banking_mandate.mandate_partner_form
#: view:res.partner.bank:account_banking_mandate.mandate_partner_bank_tree
msgid "DD Mandates"
msgstr ""
#. module: account_banking_mandate
#: field:account.banking.mandate,signature_date:0
msgid "Date of Signature of the Mandate"
msgstr ""
#. module: account_banking_mandate
#: field:account.banking.mandate,last_debit_date:0
msgid "Date of the Last Debit"
msgstr ""
#. module: account_banking_mandate
#: help:account.banking.mandate,message_last_post:0
msgid "Date of the last message posted on the record."
msgstr ""
#. module: account_banking_mandate
#: field:account.invoice,mandate_id:0
#: field:payment.line,mandate_id:0
msgid "Direct Debit Mandate"
msgstr ""
#. module: account_banking_mandate
#: view:res.partner.bank:account_banking_mandate.mandate_partner_bank_form
#: field:res.partner.bank,mandate_ids:0
msgid "Direct Debit Mandates"
msgstr ""
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_search
msgid "Draft"
msgstr ""
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_search
msgid "Expired"
msgstr ""
#. module: account_banking_mandate
#: field:account.banking.mandate,message_follower_ids:0
msgid "Followers"
msgstr ""
#. module: account_banking_mandate
#: help:account.banking.mandate,message_summary:0
msgid "Holds the Chatter summary (number of messages, ...). This summary is directly in html format in order to be inserted in kanban views."
msgstr ""
#. module: account_banking_mandate
#: field:account.banking.mandate,id:0
msgid "ID"
msgstr ""
#. module: account_banking_mandate
#: help:account.banking.mandate,message_unread:0
msgid "If checked new messages require your attention."
msgstr ""
#. module: account_banking_mandate
#: model:ir.model,name:account_banking_mandate.model_account_invoice
msgid "Invoice"
msgstr ""
#. module: account_banking_mandate
#: field:account.banking.mandate,message_is_follower:0
msgid "Is a Follower"
msgstr ""
#. module: account_banking_mandate
#: field:account.banking.mandate,message_last_post:0
msgid "Last Message Date"
msgstr ""
#. module: account_banking_mandate
#: field:account.banking.mandate,write_uid:0
msgid "Last Updated by"
msgstr ""
#. module: account_banking_mandate
#: field:account.banking.mandate,write_date:0
msgid "Last Updated on"
msgstr ""
#. module: account_banking_mandate
#: model:mail.message.subtype,name:account_banking_mandate.mandate_cancel
msgid "Mandate Cancelled"
msgstr ""
#. module: account_banking_mandate
#: model:mail.message.subtype,name:account_banking_mandate.mandate_expired
msgid "Mandate Expired"
msgstr ""
#. module: account_banking_mandate
#: model:mail.message.subtype,name:account_banking_mandate.mandate_valid
msgid "Mandate Validated"
msgstr ""
#. module: account_banking_mandate
#: code:addons/account_banking_mandate/models/account_banking_mandate.py:152
#, python-format
msgid "Mandate should be in cancel state"
msgstr ""
#. module: account_banking_mandate
#: code:addons/account_banking_mandate/models/account_banking_mandate.py:140
#, python-format
msgid "Mandate should be in draft or valid state"
msgstr ""
#. module: account_banking_mandate
#: code:addons/account_banking_mandate/models/account_banking_mandate.py:131
#, python-format
msgid "Mandate should be in draft state"
msgstr ""
#. module: account_banking_mandate
#: field:account.banking.mandate,message_ids:0
msgid "Messages"
msgstr ""
#. module: account_banking_mandate
#: help:account.banking.mandate,message_ids:0
msgid "Messages and communication history"
msgstr ""
#. module: account_banking_mandate
#: help:account.banking.mandate,state:0
msgid "Only valid mandates can be used in a payment line. A cancelled mandate is a mandate that has been cancelled by the customer."
msgstr ""
#. module: account_banking_mandate
#: field:account.banking.mandate,partner_id:0
msgid "Partner"
msgstr ""
#. module: account_banking_mandate
#: model:ir.model,name:account_banking_mandate.model_payment_line
msgid "Payment Line"
msgstr ""
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_tree
msgid "Reference"
msgstr ""
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_form
#: field:account.banking.mandate,payment_line_ids:0
msgid "Related Payment Lines"
msgstr ""
#. module: account_banking_mandate
#: model:ir.ui.menu,name:account_banking_mandate.mandate_menu
msgid "SEPA Direct Debit Mandates"
msgstr ""
#. module: account_banking_mandate
#: field:account.banking.mandate,scan:0
msgid "Scan of the Mandate"
msgstr ""
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_search
msgid "Search Banking Mandates"
msgstr ""
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_tree
msgid "Signature Date"
msgstr ""
#. module: account_banking_mandate
#: field:account.banking.mandate,state:0
msgid "Status"
msgstr ""
#. module: account_banking_mandate
#: field:account.banking.mandate,message_summary:0
msgid "Summary"
msgstr ""
#. module: account_banking_mandate
#: code:addons/account_banking_mandate/models/account_banking_mandate.py:92
#, python-format
msgid "The date of signature of mandate '%s' is in the future !"
msgstr ""
#. module: account_banking_mandate
#: code:addons/account_banking_mandate/models/account_banking_mandate.py:97
#, python-format
msgid "The mandate '%s' can't have a date of last debit before the date of signature."
msgstr ""
#. module: account_banking_mandate
#: code:addons/account_banking_mandate/models/payment_line.py:68
#, python-format
msgid "The payment line with reference '%s' has the bank account '%s' which is not attached to the mandate '%s' (this mandate is attached to the bank account '%s')."
msgstr ""
#. module: account_banking_mandate
#: field:account.banking.mandate,unique_mandate_reference:0
msgid "Unique Mandate Reference"
msgstr ""
#. module: account_banking_mandate
#: field:account.banking.mandate,message_unread:0
msgid "Unread Messages"
msgstr ""
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_search
msgid "Valid"
msgstr ""
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_form
msgid "Validate"
msgstr ""
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_form
msgid "You should set a mandate back to draft only if you cancelled it by mistake. Do you want to continue?"
msgstr ""

View File

@@ -0,0 +1,360 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_banking_mandate
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-10-31 23:00+0000\n"
"PO-Revision-Date: 2014-10-31 23:00+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: account_banking_mandate
#: model:ir.actions.act_window,help:account_banking_mandate.mandate_action
msgid "<p class=\"oe_view_nocontent_create\">\n"
" Click to create a new Banking Mandate.\n"
" </p><p>\n"
" A Banking Mandate is a document signed by your customer that gives you the autorization to do one or several operations on his bank account.\n"
" </p>\n"
" "
msgstr "<p class=\"oe_view_nocontent_create\">\n"
" Pulse para crear un nuevo mandato bancario.\n"
" </p><p>\n"
" Un mandato bancario es un documento firmado por su cliente que le da autorización a hacer una o varias operaciones en su cuenta bancaria.\n"
" </p>\n"
" "
#. module: account_banking_mandate
#: sql_constraint:account.banking.mandate:0
msgid "A Mandate with the same reference already exists for this company !"
msgstr "Ya existe un mandato con la misma referencia para esta compañía"
#. module: account_banking_mandate
#: model:ir.model,name:account_banking_mandate.model_account_banking_mandate
msgid "A generic banking mandate"
msgstr "Un mandato bancario genérico"
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_form
msgid "Back to Draft"
msgstr "Volver a borrador"
#. module: account_banking_mandate
#: field:account.banking.mandate,partner_bank_id:0
msgid "Bank Account"
msgstr "Cuenta bancaria"
#. module: account_banking_mandate
#: model:ir.model,name:account_banking_mandate.model_res_partner_bank
msgid "Bank Accounts"
msgstr "Cuentas bancarias"
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_form
#: view:account.banking.mandate:account_banking_mandate.view_mandate_tree
msgid "Banking Mandate"
msgstr "Mandato bancario"
#. module: account_banking_mandate
#: model:mail.message.subtype,description:account_banking_mandate.mandate_cancel
msgid "Banking Mandate Cancelled"
msgstr "Mandato bancario cancelado"
#. module: account_banking_mandate
#: model:mail.message.subtype,description:account_banking_mandate.mandate_valid
msgid "Banking Mandate Validated"
msgstr "Mandato bancario validado"
#. module: account_banking_mandate
#: model:mail.message.subtype,description:account_banking_mandate.mandate_expired
msgid "Banking Mandate has Expired"
msgstr "El mandato bancario ha expirado"
#. module: account_banking_mandate
#: model:ir.actions.act_window,name:account_banking_mandate.mandate_action
msgid "Banking Mandates"
msgstr "Mandatos bancarios"
#. module: account_banking_mandate
#: help:res.partner.bank,mandate_ids:0
msgid "Banking mandates represents an authorization that the bank account owner gives to a company for a specific operation"
msgstr "Los mandatos bancarios representan una autorización que el propietario de la cuenta bancaria da a la compañía para un operación específica"
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_form
msgid "Cancel"
msgstr "Cancelar"
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_search
msgid "Cancelled"
msgstr "Cancelado"
#. module: account_banking_mandate
#: code:addons/account_banking_mandate/models/account_banking_mandate.py:110
#, python-format
msgid "Cannot validate the mandate '%s' because it is not attached to a bank account."
msgstr "No se puede validar el mandato '%s' porque no tiene ninguna cuenta bancaria asociada."
#. module: account_banking_mandate
#: code:addons/account_banking_mandate/models/account_banking_mandate.py:106
#, python-format
msgid "Cannot validate the mandate '%s' without a date of signature."
msgstr "No se puede validar el mandato '%s' sin una fecha de firma."
#. module: account_banking_mandate
#: field:account.banking.mandate,company_id:0
msgid "Company"
msgstr "Compañía"
#. module: account_banking_mandate
#: field:account.banking.mandate,create_uid:0
msgid "Created by"
msgstr "Creado por"
#. module: account_banking_mandate
#: field:account.banking.mandate,create_date:0
msgid "Created on"
msgstr "Creado en"
#. module: account_banking_mandate
#: view:payment.order:account_banking_mandate.view_mandate_payment_order_form
msgid "DD Mandate"
msgstr "Mandato bancario"
#. module: account_banking_mandate
#: view:res.partner:account_banking_mandate.mandate_partner_form
#: view:res.partner.bank:account_banking_mandate.mandate_partner_bank_tree
msgid "DD Mandates"
msgstr "Mandatos bancarios"
#. module: account_banking_mandate
#: field:account.banking.mandate,signature_date:0
msgid "Date of Signature of the Mandate"
msgstr "Fecha de la firma del mandato"
#. module: account_banking_mandate
#: field:account.banking.mandate,last_debit_date:0
msgid "Date of the Last Debit"
msgstr "Fecha del último cobro"
#. module: account_banking_mandate
#: help:account.banking.mandate,message_last_post:0
msgid "Date of the last message posted on the record."
msgstr "Fecha del último mensaje publicado en el registro."
#. module: account_banking_mandate
#: field:account.invoice,mandate_id:0
#: field:payment.line,mandate_id:0
msgid "Direct Debit Mandate"
msgstr "Mandato de adeudo directo"
#. module: account_banking_mandate
#: view:res.partner.bank:account_banking_mandate.mandate_partner_bank_form
#: field:res.partner.bank,mandate_ids:0
msgid "Direct Debit Mandates"
msgstr "Mandatos de adeudo directo"
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_search
msgid "Draft"
msgstr "Borrador"
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_search
msgid "Expired"
msgstr "Expirado"
#. module: account_banking_mandate
#: field:account.banking.mandate,message_follower_ids:0
msgid "Followers"
msgstr "Seguidores"
#. module: account_banking_mandate
#: help:account.banking.mandate,message_summary:0
msgid "Holds the Chatter summary (number of messages, ...). This summary is directly in html format in order to be inserted in kanban views."
msgstr "Contiene el resumen del chatter (nº de mensajes, ...). Este resumen está directamente en formato html para ser insertado en vistas kanban."
#. module: account_banking_mandate
#: field:account.banking.mandate,id:0
msgid "ID"
msgstr "ID"
#. module: account_banking_mandate
#: help:account.banking.mandate,message_unread:0
msgid "If checked new messages require your attention."
msgstr "Si está marcado, hay nuevos mensajes que requieren su atención"
#. module: account_banking_mandate
#: model:ir.model,name:account_banking_mandate.model_account_invoice
msgid "Invoice"
msgstr "Factura"
#. module: account_banking_mandate
#: field:account.banking.mandate,message_is_follower:0
msgid "Is a Follower"
msgstr "Es un seguidor"
#. module: account_banking_mandate
#: field:account.banking.mandate,message_last_post:0
msgid "Last Message Date"
msgstr "Fecha del último mensaje"
#. module: account_banking_mandate
#: field:account.banking.mandate,write_uid:0
msgid "Last Updated by"
msgstr "Última actualización por"
#. module: account_banking_mandate
#: field:account.banking.mandate,write_date:0
msgid "Last Updated on"
msgstr "Última actualización en"
#. module: account_banking_mandate
#: model:mail.message.subtype,name:account_banking_mandate.mandate_cancel
msgid "Mandate Cancelled"
msgstr "Mandato cancelado"
#. module: account_banking_mandate
#: model:mail.message.subtype,name:account_banking_mandate.mandate_expired
msgid "Mandate Expired"
msgstr "Mandato expirado"
#. module: account_banking_mandate
#: model:mail.message.subtype,name:account_banking_mandate.mandate_valid
msgid "Mandate Validated"
msgstr "Mandato validado"
#. module: account_banking_mandate
#: code:addons/account_banking_mandate/models/account_banking_mandate.py:152
#, python-format
msgid "Mandate should be in cancel state"
msgstr "El mandato debe estar en estado cancelado"
#. module: account_banking_mandate
#: code:addons/account_banking_mandate/models/account_banking_mandate.py:140
#, python-format
msgid "Mandate should be in draft or valid state"
msgstr "El mandato debe estar en estado borrador o validado"
#. module: account_banking_mandate
#: code:addons/account_banking_mandate/models/account_banking_mandate.py:131
#, python-format
msgid "Mandate should be in draft state"
msgstr "El mandato debe estar en estado borrador"
#. module: account_banking_mandate
#: field:account.banking.mandate,message_ids:0
msgid "Messages"
msgstr "Mensajes"
#. module: account_banking_mandate
#: help:account.banking.mandate,message_ids:0
msgid "Messages and communication history"
msgstr "Mensajes e historial de comunicación"
#. module: account_banking_mandate
#: help:account.banking.mandate,state:0
msgid "Only valid mandates can be used in a payment line. A cancelled mandate is a mandate that has been cancelled by the customer."
msgstr "Sólo se pueden usar mandatos validados en una línea de pago. Un mandato cancelado en un mandato que ha sido invalidado por el cliente."
#. module: account_banking_mandate
#: field:account.banking.mandate,partner_id:0
msgid "Partner"
msgstr "Empresa"
#. module: account_banking_mandate
#: model:ir.model,name:account_banking_mandate.model_payment_line
msgid "Payment Line"
msgstr "Línea de pago"
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_tree
msgid "Reference"
msgstr "Referencia"
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_form
#: field:account.banking.mandate,payment_line_ids:0
msgid "Related Payment Lines"
msgstr "Líneas de pago relacionadas"
#. module: account_banking_mandate
#: model:ir.ui.menu,name:account_banking_mandate.mandate_menu
msgid "SEPA Direct Debit Mandates"
msgstr "Mandatos de adeudo directo SEPA"
#. module: account_banking_mandate
#: field:account.banking.mandate,scan:0
msgid "Scan of the Mandate"
msgstr "Escaneado del mandato"
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_search
msgid "Search Banking Mandates"
msgstr "Buscar mandatos bancarios"
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_tree
msgid "Signature Date"
msgstr "Fecha de firma"
#. module: account_banking_mandate
#: field:account.banking.mandate,state:0
msgid "Status"
msgstr "Estado"
#. module: account_banking_mandate
#: field:account.banking.mandate,message_summary:0
msgid "Summary"
msgstr "Resumen"
#. module: account_banking_mandate
#: code:addons/account_banking_mandate/models/account_banking_mandate.py:92
#, python-format
msgid "The date of signature of mandate '%s' is in the future !"
msgstr "La fecha de firma del mandato '%s' no puede ser superior a la actual"
#. module: account_banking_mandate
#: code:addons/account_banking_mandate/models/account_banking_mandate.py:97
#, python-format
msgid "The mandate '%s' can't have a date of last debit before the date of signature."
msgstr "El mandato '%s' no puede tener una fecha de último cobro antes de la fecha de firma."
#. module: account_banking_mandate
#: code:addons/account_banking_mandate/models/payment_line.py:68
#, python-format
msgid "The payment line with reference '%s' has the bank account '%s' which is not attached to the mandate '%s' (this mandate is attached to the bank account '%s')."
msgstr "La línea de pago con referencia '%s' tiene la cuenta bancaria '%s', que no está puesta en el mandato '%s' (este mandato tiene como cuenta bancaria '%s')."
#. module: account_banking_mandate
#: field:account.banking.mandate,unique_mandate_reference:0
msgid "Unique Mandate Reference"
msgstr "Referencia única del mandato"
#. module: account_banking_mandate
#: field:account.banking.mandate,message_unread:0
msgid "Unread Messages"
msgstr "Mensajes sin leer"
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_search
msgid "Valid"
msgstr "Válido"
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_form
msgid "Validate"
msgstr "Validar"
#. module: account_banking_mandate
#: view:account.banking.mandate:account_banking_mandate.view_mandate_form
msgid "You should set a mandate back to draft only if you cancelled it by mistake. Do you want to continue?"
msgstr "Debe establecer un mandato de vuelta a borrador sólo si lo cancelo por error. ¿Desea continuar?"

View File

@@ -0,0 +1,26 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Mandate module for openERP
# Copyright (C) 2014 Compassion CH (http://www.compassion.ch)
# @author: Cyril Sester <csester@compassion.ch>,
# Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from . import account_banking_mandate
from . import account_invoice
from . import res_partner_bank
from . import payment_line

View File

@@ -0,0 +1,154 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Mandate module for openERP
# Copyright (C) 2014 Compassion CH (http://www.compassion.ch)
# @author: Cyril Sester <csester@compassion.ch>,
# Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, fields, exceptions, api, _
class AccountBankingMandate(models.Model):
''' The banking mandate is attached to a bank account and represents an
authorization that the bank account owner gives to a company for a
specific operation (such as direct debit)
'''
_name = 'account.banking.mandate'
_description = "A generic banking mandate"
_rec_name = 'unique_mandate_reference'
_inherit = ['mail.thread']
_order = 'signature_date desc'
_track = {
'state': {
'account_banking_mandate.mandate_valid': (
lambda self, cr, uid, obj, ctx=None: obj['state'] == 'valid'),
'account_banking_mandate.mandate_expired': (
lambda self, cr, uid, obj, ctx=None:
obj['state'] == 'expired'),
'account_banking_mandate.mandate_cancel': (
lambda self, cr, uid, obj, ctx=None: obj['state'] == 'cancel'),
},
}
def _get_states(self):
return [('draft', 'Draft'),
('valid', 'Valid'),
('expired', 'Expired'),
('cancel', 'Cancelled')]
partner_bank_id = fields.Many2one(
comodel_name='res.partner.bank', string='Bank Account',
track_visibility='onchange')
partner_id = fields.Many2one(
comodel_name='res.partner', related='partner_bank_id.partner_id',
string='Partner', store=True)
company_id = fields.Many2one(
comodel_name='res.company', string='Company', required=True,
default=lambda self: self.env['res.company']._company_default_get(
'account.banking.mandate'))
unique_mandate_reference = fields.Char(
string='Unique Mandate Reference', track_visibility='always',
default='/')
signature_date = fields.Date(string='Date of Signature of the Mandate',
track_visibility='onchange')
scan = fields.Binary(string='Scan of the Mandate')
last_debit_date = fields.Date(string='Date of the Last Debit',
readonly=True)
state = fields.Selection(
_get_states, string='Status', default='draft',
help="Only valid mandates can be used in a payment line. A cancelled "
"mandate is a mandate that has been cancelled by the customer.")
payment_line_ids = fields.One2many(
comodel_name='payment.line', inverse_name='mandate_id',
string="Related Payment Lines")
_sql_constraints = [(
'mandate_ref_company_uniq',
'unique(unique_mandate_reference, company_id)',
'A Mandate with the same reference already exists for this company !')]
@api.one
@api.constrains('signature_date', 'last_debit_date')
def _check_dates(self):
if (self.signature_date and
self.signature_date > fields.Date.context_today(self)):
raise exceptions.Warning(
_("The date of signature of mandate '%s' is in the future !")
% self.unique_mandate_reference)
if (self.signature_date and self.last_debit_date and
self.signature_date > self.last_debit_date):
raise exceptions.Warning(
_("The mandate '%s' can't have a date of last debit before "
"the date of signature.") % self.unique_mandate_reference)
@api.one
@api.constrains('state', 'partner_bank_id')
def _check_valid_state(self):
if self.state == 'valid':
if not self.signature_date:
raise exceptions.Warning(
_("Cannot validate the mandate '%s' without a date of "
"signature.") % self.unique_mandate_reference)
if not self.partner_bank_id:
raise exceptions.Warning(
_("Cannot validate the mandate '%s' because it is not "
"attached to a bank account.") %
self.unique_mandate_reference)
@api.model
def create(self, vals=None):
if vals.get('unique_mandate_reference', '/') == '/':
vals['unique_mandate_reference'] = \
self.env['ir.sequence'].next_by_code('account.banking.mandate')
return super(AccountBankingMandate, self).create(vals)
@api.one
@api.onchange('partner_bank_id')
def mandate_partner_bank_change(self):
self.partner_id = self.partner_bank_id.partner_id
@api.multi
def validate(self):
for mandate in self:
if mandate.state != 'draft':
raise exceptions.Warning(
_('Mandate should be in draft state'))
self.write({'state': 'valid'})
return True
@api.multi
def cancel(self):
for mandate in self:
if mandate.state not in ('draft', 'valid'):
raise exceptions.Warning(
_('Mandate should be in draft or valid state'))
self.write({'state': 'cancel'})
return True
@api.multi
def back2draft(self):
"""Allows to set the mandate back to the draft state.
This is for mandates cancelled by mistake.
"""
for mandate in self:
if mandate.state != 'cancel':
raise exceptions.Warning(
_('Mandate should be in cancel state'))
self.write({'state': 'draft'})
return True

View File

@@ -0,0 +1,33 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Mandate module for openERP
# Copyright (C) 2014 Compassion CH (http://www.compassion.ch)
# @author: Cyril Sester <csester@compassion.ch>,
# Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, fields
class AccountInvoice(models.Model):
_inherit = 'account.invoice'
mandate_id = fields.Many2one(
'account.banking.mandate', string='Direct Debit Mandate',
domain=[('state', '=', 'valid')], readonly=True,
states={'draft': [('readonly', False)]})

View File

@@ -0,0 +1,76 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Mandate module for openERP
# Copyright (C) 2014 Compassion CH (http://www.compassion.ch)
# @author: Cyril Sester <csester@compassion.ch>,
# Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, fields, api, exceptions, _
class PaymentLine(models.Model):
_inherit = 'payment.line'
mandate_id = fields.Many2one(
comodel_name='account.banking.mandate', string='Direct Debit Mandate',
domain=[('state', '=', 'valid')])
@api.multi
def create(self, vals=None):
"""If the customer invoice has a mandate, take it
otherwise, take the first valid mandate of the bank account
"""
if vals is None:
vals = {}
partner_bank_id = vals.get('bank_id')
move_line_id = vals.get('move_line_id')
if (self.env.context.get('search_payment_order_type') == 'debit'
and 'mandate_id' not in vals):
if move_line_id:
line = self.env['account.move.line'].browse(move_line_id)
if (line.invoice and line.invoice.type == 'out_invoice'
and line.invoice.mandate_id):
vals.update({
'mandate_id': line.invoice.mandate_id.id,
'bank_id': line.invoice.mandate_id.partner_bank_id.id,
})
if partner_bank_id and 'mandate_id' not in vals:
mandates = self.env['account.banking.mandate'].search(
[('partner_bank_id', '=', partner_bank_id),
('state', '=', 'valid')])
if mandates:
vals['mandate_id'] = mandates[0].id
return super(PaymentLine, self).create(vals)
@api.one
@api.constrains('mandate_id', 'bank_id')
def _check_mandate_bank_link(self):
if (self.mandate_id and self.bank_id
and self.mandate_id.partner_bank_id.id !=
self.bank_id.id):
raise exceptions.Warning(
_("The payment line with reference '%s' has the bank account "
"'%s' which is not attached to the mandate '%s' (this "
"mandate is attached to the bank account '%s').") %
(self.name,
self.env['res.partner.bank'].name_get(
[self.bank_id.id])[0][1],
self.mandate_id.unique_mandate_reference,
self.env['res.partner.bank'].name_get(
[self.mandate_id.partner_bank_id.id])[0][1]))

View File

@@ -0,0 +1,34 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Mandate module for openERP
# Copyright (C) 2014 Compassion CH (http://www.compassion.ch)
# @author: Cyril Sester <csester@compassion.ch>,
# Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, fields
class ResPartnerBank(models.Model):
_inherit = 'res.partner.bank'
mandate_ids = fields.One2many(
comodel_name='account.banking.mandate', inverse_name='partner_bank_id',
string='Direct Debit Mandates',
help='Banking mandates represents an authorization that the bank '
'account owner gives to a company for a specific operation')

View File

@@ -0,0 +1,3 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_account_banking_mandate","Full access on account.banking.mandate","model_account_banking_mandate","account_payment.group_account_payment",1,1,1,1
"access_account_banking_mandate_read","Read access on account.banking.mandate","model_account_banking_mandate","base.group_user",1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_account_banking_mandate Full access on account.banking.mandate model_account_banking_mandate account_payment.group_account_payment 1 1 1 1
3 access_account_banking_mandate_read Read access on account.banking.mandate model_account_banking_mandate base.group_user 1 0 0 0

View File

@@ -0,0 +1,36 @@
-
In order to test mandate, I create a partner with a bank account.
Then, I create a mandate, validate it, cancel it and the set it back to draft
I create a partner
-
!record {model: res.partner, id: mandate_partner, view: False}:
name: "Mandate test"
-
I create a partner bank account
-
!record {model: res.partner.bank, id: mandate_partner_bank, view: False}:
state: 'bank'
acc_number: '1234'
partner_id: mandate_partner
-
I create a mandate on 1st January
-
!record {model: account.banking.mandate, id: test_mandate, view: False}:
partner_bank_id: mandate_partner_bank
signature_date: "2014-01-01"
-
I check that the state field is automatically set by default
-
!assert {model: account.banking.mandate, id: test_mandate}:
- state == 'draft'
-
I go through all states by clicking on buttons and check that cancel state is reached
-
!python {model: account.banking.mandate}: |
self.validate(cr, uid, [ref('test_mandate')])
self.cancel(cr, uid, [ref('test_mandate')])
mandate = self.browse(cr, uid, ref('test_mandate'))
assert mandate.state == 'cancel', 'Mandate is not in cancel state'
self.back2draft(cr, uid, [ref('test_mandate')])

View File

@@ -0,0 +1,122 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2013 Akretion (http://www.akretion.com)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
The licence is in the file __openerp__.py
-->
<openerp>
<data>
<record id="view_mandate_form" model="ir.ui.view">
<field name="name">view.mandate.form</field>
<field name="model">account.banking.mandate</field>
<field name="arch" type="xml">
<form string="Banking Mandate" version="7.0">
<header>
<button name="validate" type="object" string="Validate" states="draft" class="oe_highlight"/>
<button name="cancel" type="object" string="Cancel" states="draft,valid"/>
<button name="back2draft" type="object" string="Back to Draft"
states="cancel" groups="account.group_account_manager"
confirm="You should set a mandate back to draft only if you cancelled it by mistake. Do you want to continue?"/>
<field name="state" widget="statusbar"/>
</header>
<sheet>
<div class="oe_title">
<h1>
<field name="unique_mandate_reference"
class="oe_inline"
readonly="1"/>
</h1>
</div>
<group name="main">
<field name="company_id" groups="base.group_multi_company"/>
<field name="partner_bank_id"
invisible="context.get('mandate_bank_partner_view')" />
<field name="partner_id" invisible="context.get('mandate_bank_partner_view')" readonly="True"/>
<field name="signature_date"/>
<field name="scan"/>
<field name="last_debit_date"/>
</group>
<group name="payment_lines" string="Related Payment Lines">
<field name="payment_line_ids" nolabel="1"/>
</group>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
</record>
<record id="view_mandate_tree" model="ir.ui.view">
<field name="name">view.mandate.tree</field>
<field name="model">account.banking.mandate</field>
<field name="arch" type="xml">
<tree string="Banking Mandate" colors="blue:state=='draft';black:state in ('expired', 'cancel')">
<field name="company_id" groups="base.group_multi_company"/>
<field name="partner_id" invisible="context.get('mandate_bank_partner_view')"/>
<field name="unique_mandate_reference" string="Reference"/>
<field name="signature_date" string="Signature Date"/>
<field name="last_debit_date"/>
<field name="state"/>
</tree>
</field>
</record>
<record id="view_mandate_search" model="ir.ui.view">
<field name="name">view.mandate.search</field>
<field name="model">account.banking.mandate</field>
<field name="arch" type="xml">
<search string="Search Banking Mandates">
<field name="partner_id"/>
<filter name="draft" string="Draft" domain="[('state', '=', 'draft')]" />
<filter name="valid" string="Valid" domain="[('state', '=', 'valid')]" />
<filter name="cancel" string="Cancelled" domain="[('state', '=', 'cancel')]" />
<filter name="expired" string="Expired" domain="[('state', '=', 'expired')]" />
</search>
</field>
</record>
<record id="mandate_action" model="ir.actions.act_window">
<field name="name">Banking Mandates</field>
<field name="res_model">account.banking.mandate</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new Banking Mandate.
</p><p>
A Banking Mandate is a document signed by your customer that gives you the autorization to do one or several operations on his bank account.
</p>
</field>
</record>
<menuitem id="mandate_menu"
parent="account_payment.menu_main_payment"
action="mandate_action"
sequence="20"
/>
<!-- notifications in the chatter -->
<record id="mandate_valid" model="mail.message.subtype">
<field name="name">Mandate Validated</field>
<field name="res_model">account.banking.mandate</field>
<field name="default" eval="False"/>
<field name="description">Banking Mandate Validated</field>
</record>
<record id="mandate_expired" model="mail.message.subtype">
<field name="name">Mandate Expired</field>
<field name="res_model">account.banking.mandate</field>
<field name="default" eval="False"/>
<field name="description">Banking Mandate has Expired</field>
</record>
<record id="mandate_cancel" model="mail.message.subtype">
<field name="name">Mandate Cancelled</field>
<field name="res_model">account.banking.mandate</field>
<field name="default" eval="False"/>
<field name="description">Banking Mandate Cancelled</field>
</record>
</data>
</openerp>

View File

@@ -8,12 +8,12 @@
<data>
<record id="invoice_form" model="ir.ui.view">
<field name="name">add.sdd.mandate.on.customer.invoice.form</field>
<field name="name">add.mandate.on.customer.invoice.form</field>
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.invoice_form"/>
<field name="arch" type="xml">
<field name="partner_bank_id" position="after">
<field name="sdd_mandate_id" domain="[('partner_id', '=', partner_id), ('state', '=', 'valid')]" attrs="{'invisible': [('type', '=', 'out_refund')]}"/>
<field name="mandate_id" domain="[('partner_id', '=', partner_id), ('state', '=', 'valid')]" attrs="{'invisible': [('type', '=', 'out_refund')]}"/>
</field>
</field>
</record>

View File

@@ -7,17 +7,17 @@
<openerp>
<data>
<record id="sdd_view_payment_order_form" model="ir.ui.view">
<field name="name">sdd.payment.order.form</field>
<record id="view_mandate_payment_order_form" model="ir.ui.view">
<field name="name">mandate.payment.order.form</field>
<field name="model">payment.order</field>
<field name="inherit_id" ref="account_payment.view_payment_order_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='line_ids']/form/notebook/page/group/field[@name='bank_id']" position="after">
<field name="sdd_mandate_id" domain="[('partner_bank_id', '=', bank_id), ('state', '=', 'valid')]" invisible="context.get('default_payment_order_type')!='debit'" context="{'default_partner_bank_id': bank_id}"/>
<field name="mandate_id" domain="[('partner_bank_id', '=', bank_id), ('state', '=', 'valid')]" invisible="context.get('search_payment_order_type')!='debit'" context="{'default_partner_bank_id': bank_id}"/>
<newline />
</xpath>
<xpath expr="//field[@name='line_ids']/tree/field[@name='bank_id']" position="after">
<field name="sdd_mandate_id" string="SDD Mandate" invisible="context.get('default_payment_order_type')!='debit'"/>
<field name="mandate_id" string="DD Mandate" invisible="context.get('search_payment_order_type')!='debit'"/>
</xpath>
</field>
</record>

View File

@@ -7,39 +7,39 @@
<openerp>
<data>
<record id="sdd_mandate_partner_bank_form" model="ir.ui.view">
<field name="name">sdd.mandate.res.partner.bank.form</field>
<record id="mandate_partner_bank_form" model="ir.ui.view">
<field name="name">mandate.res.partner.bank.form</field>
<field name="model">res.partner.bank</field>
<field name="inherit_id" ref="base.view_partner_bank_form"/>
<field name="arch" type="xml">
<group name="bank" position="after">
<group name="sdd_mandates" string="SEPA Direct Debit Mandates" colspan="4">
<field name="sdd_mandate_ids" context="{'default_partner_bank_id': active_id, 'sdd_mandate_bank_partner_view': True}" nolabel="1"/>
<group name="mandates" string="Direct Debit Mandates" colspan="4">
<field name="mandate_ids" context="{'default_partner_bank_id': active_id, 'mandate_bank_partner_view': True}" nolabel="1"/>
</group>
</group>
</field>
</record>
<record id="sdd_mandate_partner_bank_tree" model="ir.ui.view">
<field name="name">sdd.mandate.res.partner.bank.tree</field>
<record id="mandate_partner_bank_tree" model="ir.ui.view">
<field name="name">mandate.res.partner.bank.tree</field>
<field name="model">res.partner.bank</field>
<field name="inherit_id" ref="base.view_partner_bank_tree"/>
<field name="arch" type="xml">
<field name="partner_id" position="after">
<field name="sdd_mandate_ids" string="SDD Mandates"/>
<field name="mandate_ids" string="DD Mandates"/>
</field>
</field>
</record>
<!-- add number of mandates in this list of bank accounts
on the partner form -->
<record id="sdd_mandate_partner_form" model="ir.ui.view">
<field name="name">sdd.mandate.partner.form</field>
<record id="mandate_partner_form" model="ir.ui.view">
<field name="name">mandate.partner.form</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="account.view_partner_property_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='bank_ids']/tree/field[@name='owner_name']" position="after">
<field name="sdd_mandate_ids" string="SDD Mandates"/>
<field name="mandate_ids" string="DD Mandates"/>
</xpath>
</field>
</record>

View File

@@ -1,9 +1,9 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Account Payment Sale module for OpenERP
# Copyright (C) 2014 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# PAIN Base module for OpenERP
# Copyright (C) 2013 Akretion (http://www.akretion.com)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -20,4 +20,4 @@
#
##############################################################################
from . import sale
from . import models

View File

@@ -26,15 +26,16 @@
'license': 'AGPL-3',
'author': 'Akretion, Noviat',
'website': 'http://openerp-community-association.org/',
'contributors': ['Pedro M. Baeza <pedro.baeza@serviciosbaeza.com>'],
'category': 'Hidden',
'depends': ['account_banking_payment_export'],
'external_dependencies': {
'python': ['unidecode', 'lxml'],
},
},
'data': [
'payment_line_view.xml',
'payment_mode_view.xml',
'company_view.xml',
'views/payment_line_view.xml',
'views/payment_mode_view.xml',
'views/res_company_view.xml',
],
'description': '''
Base module for PAIN file generation
@@ -43,14 +44,10 @@ Base module for PAIN file generation
This module contains fields and functions that are used by the module for SEPA
Credit Transfer (account_banking_sepa_credit_transfer) and SEPA Direct Debit
(account_banking_sepa_direct_debit). This module doesn't provide any
functionnality by itself.
functionality by itself.
This module is part of the banking addons:
https://www.github.com/OCA/banking-addons
This module was started during the Akretion-Noviat code sprint of
November 21st 2013 in Epiais les Louvres (France).
This module was started during the Akretion-Noviat code sprint of November
21st 2013 in Epiais les Louvres (France).
''',
'active': False,
'installable': False,
'installable': True,
}

View File

@@ -1,13 +1,13 @@
# Translation of OpenERP Server.
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_banking_pain_base
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 7.0\n"
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-12-23 21:26+0000\n"
"PO-Revision-Date: 2013-12-23 21:26+0000\n"
"POT-Creation-Date: 2014-10-31 22:52+0000\n"
"PO-Revision-Date: 2014-10-31 22:52+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@@ -15,20 +15,80 @@ msgstr ""
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: account_banking_pain_base
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:74
#, python-format
msgid "Cannot compute the '%s' of the Payment Line with reference '%s'."
msgstr ""
#. module: account_banking_pain_base
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:80
#, python-format
msgid "Cannot compute the '%s'."
msgstr ""
#. module: account_banking_pain_base
#: model:ir.model,name:account_banking_pain_base.model_res_company
msgid "Companies"
msgstr ""
#. module: account_banking_pain_base
#: field:payment.mode,convert_to_ascii:0
msgid "Convert to ASCII"
msgstr ""
#. module: account_banking_pain_base
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:47
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:73
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:79
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:89
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:124
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:303
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:385
#, python-format
msgid "Error:"
msgstr ""
#. module: account_banking_pain_base
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:83
#, python-format
msgid "Field type error:"
msgstr ""
#. module: account_banking_pain_base
#: selection:payment.line,priority:0
msgid "High"
msgstr ""
#. module: account_banking_pain_base
#: field:banking.export.pain,id:0
msgid "ID"
msgstr ""
#. module: account_banking_pain_base
#: help:payment.mode,convert_to_ascii:0
msgid "If active, Odoo will convert each accented caracter to the corresponding unaccented caracter, so that only ASCII caracters are used in the generated PAIN file."
msgstr ""
#. module: account_banking_pain_base
#: field:res.company,initiating_party_issuer:0
msgid "Initiating Party Issuer"
msgstr ""
#. module: account_banking_pain_base
#: code:addons/account_banking_pain_base/banking_export_pain.py:122
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:386
#, python-format
msgid "The generated XML file is not valid against the official XML Schema Definition. The generated XML file and the full error have been written in the server logs. Here is the error, which may give you an idea on the cause of the problem : %s"
msgid "Missing 'Structured Communication Type' on payment line with reference '%s'."
msgstr ""
#. module: account_banking_pain_base
#: field:payment.line,priority:0
msgid "Priority"
#: selection:payment.line,priority:0
msgid "Normal"
msgstr ""
#. module: account_banking_pain_base
#: view:res.company:account_banking_pain_base.view_company_form
msgid "Payment Initiation"
msgstr ""
#. module: account_banking_pain_base
@@ -42,65 +102,8 @@ msgid "Payment Mode"
msgstr ""
#. module: account_banking_pain_base
#: help:res.company,initiating_party_issuer:0
msgid "This will be used as the 'Initiating Party Issuer' in the PAIN files generated by OpenERP."
msgstr ""
#. module: account_banking_pain_base
#: code:addons/account_banking_pain_base/banking_export_pain.py:351
#, python-format
msgid "Missing 'Structured Communication Type' on payment line with reference '%s'."
msgstr ""
#. module: account_banking_pain_base
#: selection:payment.line,priority:0
msgid "Normal"
msgstr ""
#. module: account_banking_pain_base
#: code:addons/account_banking_pain_base/banking_export_pain.py:70
#, python-format
msgid "Cannot compute the '%s' of the Payment Line with reference '%s'."
msgstr ""
#. module: account_banking_pain_base
#: code:addons/account_banking_pain_base/banking_export_pain.py:77
#, python-format
msgid "Cannot compute the '%s'."
msgstr ""
#. module: account_banking_pain_base
#: code:addons/account_banking_pain_base/banking_export_pain.py:81
#, python-format
msgid "The type of the field '%s' is %s. It should be a string or unicode."
msgstr ""
#. module: account_banking_pain_base
#: code:addons/account_banking_pain_base/banking_export_pain.py:47
#: code:addons/account_banking_pain_base/banking_export_pain.py:69
#: code:addons/account_banking_pain_base/banking_export_pain.py:76
#: code:addons/account_banking_pain_base/banking_export_pain.py:86
#: code:addons/account_banking_pain_base/banking_export_pain.py:121
#: code:addons/account_banking_pain_base/banking_export_pain.py:350
#, python-format
msgid "Error:"
msgstr ""
#. module: account_banking_pain_base
#: model:ir.model,name:account_banking_pain_base.model_res_company
msgid "Companies"
msgstr ""
#. module: account_banking_pain_base
#: code:addons/account_banking_pain_base/banking_export_pain.py:47
#, python-format
msgid "This IBAN is not valid : %s"
msgstr ""
#. module: account_banking_pain_base
#: code:addons/account_banking_pain_base/banking_export_pain.py:80
#, python-format
msgid "Field type error:"
#: field:payment.line,priority:0
msgid "Priority"
msgstr ""
#. module: account_banking_pain_base
@@ -109,19 +112,33 @@ msgid "Structured Communication Type"
msgstr ""
#. module: account_banking_pain_base
#: code:addons/account_banking_pain_base/banking_export_pain.py:87
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:90
#, python-format
msgid "The '%s' is empty or 0. It should have a non-null value."
msgstr ""
#. module: account_banking_pain_base
#: model:ir.model,name:account_banking_pain_base.model_banking_export_pain
msgid "banking.export.pain"
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:304
#, python-format
msgid "The bank account with IBAN '%s' of partner '%s' must have an associated BIC because it is a cross-border SEPA operation."
msgstr ""
#. module: account_banking_pain_base
#: help:payment.mode,convert_to_ascii:0
msgid "If active, OpenERP will convert each accented caracter to the corresponding unaccented caracter, so that only ASCII caracters are used in the generated PAIN file."
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:125
#, python-format
msgid "The generated XML file is not valid against the official XML Schema Definition. The generated XML file and the full error have been written in the server logs. Here is the error, which may give you an idea on the cause of the problem : %s"
msgstr ""
#. module: account_banking_pain_base
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:84
#, python-format
msgid "The type of the field '%s' is %s. It should be a string or unicode."
msgstr ""
#. module: account_banking_pain_base
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:47
#, python-format
msgid "This IBAN is not valid : %s"
msgstr ""
#. module: account_banking_pain_base
@@ -130,17 +147,7 @@ msgid "This field will be used as the 'Instruction Priority' in the generated PA
msgstr ""
#. module: account_banking_pain_base
#: view:res.company:0
msgid "Payment Initiation"
msgstr ""
#. module: account_banking_pain_base
#: selection:payment.line,priority:0
msgid "High"
msgstr ""
#. module: account_banking_pain_base
#: field:payment.mode,convert_to_ascii:0
msgid "Convert to ASCII"
#: help:res.company,initiating_party_issuer:0
msgid "This will be used as the 'Initiating Party Issuer' in the PAIN files generated by Odoo."
msgstr ""

View File

@@ -0,0 +1,153 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_banking_pain_base
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-10-31 22:52+0000\n"
"PO-Revision-Date: 2014-10-31 22:52+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: account_banking_pain_base
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:74
#, python-format
msgid "Cannot compute the '%s' of the Payment Line with reference '%s'."
msgstr "No se puede procesar el campo '%s' de la línea de pago con referencia '%s'."
#. module: account_banking_pain_base
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:80
#, python-format
msgid "Cannot compute the '%s'."
msgstr "No se puede procesar el campo '%s'."
#. module: account_banking_pain_base
#: model:ir.model,name:account_banking_pain_base.model_res_company
msgid "Companies"
msgstr "Compañías"
#. module: account_banking_pain_base
#: field:payment.mode,convert_to_ascii:0
msgid "Convert to ASCII"
msgstr "Convertir a ASCII"
#. module: account_banking_pain_base
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:47
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:73
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:79
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:89
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:124
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:303
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:385
#, python-format
msgid "Error:"
msgstr "Error:"
#. module: account_banking_pain_base
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:83
#, python-format
msgid "Field type error:"
msgstr ""
#. module: account_banking_pain_base
#: selection:payment.line,priority:0
msgid "High"
msgstr "Alta"
#. module: account_banking_pain_base
#: field:banking.export.pain,id:0
msgid "ID"
msgstr "ID"
#. module: account_banking_pain_base
#: help:payment.mode,convert_to_ascii:0
msgid "If active, Odoo will convert each accented caracter to the corresponding unaccented caracter, so that only ASCII caracters are used in the generated PAIN file."
msgstr "Si está marcado, Odoo convertirá cada carácter acentuado en el correspondiente carácter no acentuado, para que sólo se usen caracteres ASCII en el archivo PAIN generado."
#. module: account_banking_pain_base
#: field:res.company,initiating_party_issuer:0
msgid "Initiating Party Issuer"
msgstr "Emisor de la transacción"
#. module: account_banking_pain_base
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:386
#, python-format
msgid "Missing 'Structured Communication Type' on payment line with reference '%s'."
msgstr "Falta el campo 'Tipo de comunicación estructurada' en la línea de pago con referencia '%s'."
#. module: account_banking_pain_base
#: selection:payment.line,priority:0
msgid "Normal"
msgstr "Normal"
#. module: account_banking_pain_base
#: view:res.company:account_banking_pain_base.view_company_form
msgid "Payment Initiation"
msgstr "Iniciación del pago"
#. module: account_banking_pain_base
#: model:ir.model,name:account_banking_pain_base.model_payment_line
msgid "Payment Line"
msgstr "Línea de pago"
#. module: account_banking_pain_base
#: model:ir.model,name:account_banking_pain_base.model_payment_mode
msgid "Payment Mode"
msgstr "Modo de pago"
#. module: account_banking_pain_base
#: field:payment.line,priority:0
msgid "Priority"
msgstr "Prioridad"
#. module: account_banking_pain_base
#: field:payment.line,struct_communication_type:0
msgid "Structured Communication Type"
msgstr "Tipo de comunicación estructurada"
#. module: account_banking_pain_base
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:90
#, python-format
msgid "The '%s' is empty or 0. It should have a non-null value."
msgstr "'%s' está vacío o es 0. Debería tener un valor no nulo."
#. module: account_banking_pain_base
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:304
#, python-format
msgid "The bank account with IBAN '%s' of partner '%s' must have an associated BIC because it is a cross-border SEPA operation."
msgstr "La cuenta bancaria con IBAN '%s' de la empresa '%s' debe tener un BIC asociado, porque es una operación SEPA transfronteriza."
#. module: account_banking_pain_base
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:125
#, python-format
msgid "The generated XML file is not valid against the official XML Schema Definition. The generated XML file and the full error have been written in the server logs. Here is the error, which may give you an idea on the cause of the problem : %s"
msgstr "El archivo XML generado no se puede validar contra la definición de esquema XML oficial. El archivo XML generado el error completo se ha escrito en los registros del servidor. Aquí está el error, que le puede dar una idea de la causa del problema : %s"
#. module: account_banking_pain_base
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:84
#, python-format
msgid "The type of the field '%s' is %s. It should be a string or unicode."
msgstr "El tipo del campo '%s' es %s. Debería ser una cadena o unicode."
#. module: account_banking_pain_base
#: code:addons/account_banking_pain_base/models/banking_export_pain.py:47
#, python-format
msgid "This IBAN is not valid : %s"
msgstr "Este IBAN no es válido: %s"
#. module: account_banking_pain_base
#: help:payment.line,priority:0
msgid "This field will be used as the 'Instruction Priority' in the generated PAIN file."
msgstr "Este campo se usará como 'Prioridad de instrucción' en el archivo PAIN generado."
#. module: account_banking_pain_base
#: help:res.company,initiating_party_issuer:0
msgid "This will be used as the 'Initiating Party Issuer' in the PAIN files generated by Odoo."
msgstr "Este campo se usará como 'Emisor de la transacción' en los archivos PAIN generados por Odoo."

View File

@@ -22,5 +22,5 @@
from . import payment_line
from . import payment_mode
from . import company
from . import res_company
from . import banking_export_pain

View File

@@ -33,12 +33,12 @@ import base64
logger = logging.getLogger(__name__)
class banking_export_pain(orm.AbstractModel):
class BankingExportPain(orm.AbstractModel):
_name = 'banking.export.pain'
def _validate_iban(self, cr, uid, iban, context=None):
'''if IBAN is valid, returns IBAN
if IBAN is NOT valid, raises an error message'''
"""if IBAN is valid, returns IBAN
if IBAN is NOT valid, raises an error message"""
partner_bank_obj = self.pool.get('res.partner.bank')
if partner_bank_obj.is_iban_valid(cr, uid, iban, context=context):
return iban.replace(' ', '')
@@ -46,10 +46,9 @@ class banking_export_pain(orm.AbstractModel):
raise orm.except_orm(
_('Error:'), _("This IBAN is not valid : %s") % iban)
def _prepare_field(
self, cr, uid, field_name, field_value, eval_ctx, max_size=0,
gen_args=None, context=None):
'''This function is designed to be inherited !'''
def _prepare_field(self, cr, uid, field_name, field_value, eval_ctx,
max_size=0, gen_args=None, context=None):
"""This function is designed to be inherited !"""
if gen_args is None:
gen_args = {}
assert isinstance(eval_ctx, dict), 'eval_ctx must contain a dict'
@@ -163,7 +162,7 @@ class banking_export_pain(orm.AbstractModel):
'res_model': self._name,
'res_id': ids[0],
'target': 'new',
}
}
return action
def generate_group_header_block(
@@ -210,6 +209,8 @@ class banking_export_pain(orm.AbstractModel):
gen_args=gen_args, context=context)
payment_method_2_2 = etree.SubElement(payment_info_2_0, 'PmtMtd')
payment_method_2_2.text = gen_args['payment_method']
nb_of_transactions_2_4 = False
control_sum_2_5 = False
if gen_args.get('pain_flavor') != 'pain.001.001.02':
batch_booking_2_3 = etree.SubElement(payment_info_2_0, 'BtchBookg')
batch_booking_2_3.text = \
@@ -282,8 +283,8 @@ class banking_export_pain(orm.AbstractModel):
def generate_party_agent(
self, cr, uid, parent_node, party_type, party_type_label,
order, party_name, iban, bic, eval_ctx, gen_args, context=None):
'''Generate the piece of the XML file corresponding to BIC
This code is mutualized between TRF and DD'''
"""Generate the piece of the XML file corresponding to BIC
This code is mutualized between TRF and DD"""
assert order in ('B', 'C'), "Order can be 'B' or 'C'"
try:
bic = self._prepare_field(
@@ -323,8 +324,8 @@ class banking_export_pain(orm.AbstractModel):
def generate_party_block(
self, cr, uid, parent_node, party_type, order, name, iban, bic,
eval_ctx, gen_args, context=None):
'''Generate the piece of the XML file corresponding to Name+IBAN+BIC
This code is mutualized between TRF and DD'''
"""Generate the piece of the XML file corresponding to Name+IBAN+BIC
This code is mutualized between TRF and DD"""
assert order in ('B', 'C'), "Order can be 'B' or 'C'"
if party_type == 'Cdtr':
party_type_label = 'Creditor'
@@ -384,7 +385,7 @@ class banking_export_pain(orm.AbstractModel):
_('Error:'),
_("Missing 'Structured Communication Type' on payment "
"line with reference '%s'.")
% (line.name))
% line.name)
remittance_info_structured_2_100 = etree.SubElement(
remittance_info_2_91, 'Strd')
creditor_ref_information_2_120 = etree.SubElement(
@@ -424,9 +425,8 @@ class banking_export_pain(orm.AbstractModel):
def generate_creditor_scheme_identification(
self, cr, uid, parent_node, identification, identification_label,
eval_ctx, scheme_name_proprietary, gen_args, context=None):
csi_id = etree.SubElement(
parent_node, 'Id')
csi_privateid = csi_id = etree.SubElement(csi_id, 'PrvtId')
csi_id = etree.SubElement(parent_node, 'Id')
csi_privateid = etree.SubElement(csi_id, 'PrvtId')
csi_other = etree.SubElement(csi_privateid, 'Othr')
csi_other_id = etree.SubElement(csi_other, 'Id')
csi_other_id.text = self._prepare_field(

View File

@@ -23,19 +23,18 @@
from openerp.osv import orm, fields
class payment_line(orm.Model):
class PaymentLine(orm.Model):
_inherit = 'payment.line'
def _get_struct_communication_types(self, cr, uid, context=None):
return [('ISO', 'ISO')]
_columns = {
'priority': fields.selection([
('NORM', 'Normal'),
('HIGH', 'High'),
], 'Priority',
'priority': fields.selection(
[('NORM', 'Normal'),
('HIGH', 'High')], 'Priority',
help="This field will be used as the 'Instruction Priority' in "
"the generated PAIN file."),
"the generated PAIN file."),
# Update size from 64 to 140, because PAIN allows 140 caracters
'communication': fields.char(
'Communication', size=140, required=True,

View File

@@ -29,7 +29,7 @@ class payment_mode(orm.Model):
_columns = {
'convert_to_ascii': fields.boolean(
'Convert to ASCII',
help="If active, OpenERP will convert each accented caracter to "
help="If active, Odoo will convert each accented caracter to "
"the corresponding unaccented caracter, so that only ASCII "
"caracters are used in the generated PAIN file."),
}

View File

@@ -25,22 +25,22 @@
from openerp.osv import orm, fields
class res_company(orm.Model):
class ResCompany(orm.Model):
_inherit = 'res.company'
_columns = {
'initiating_party_issuer': fields.char(
'Initiating Party Issuer', size=35,
help="This will be used as the 'Initiating Party Issuer' in the "
"PAIN files generated by OpenERP."),
"PAIN files generated by Odoo."),
}
def _get_initiating_party_identifier(
self, cr, uid, company_id, context=None):
'''The code here may be different from one country to another.
"""The code here may be different from one country to another.
If you need to add support for an additionnal country, you can
contribute your code here or inherit this function in the
localization modules for your country'''
localization modules for your country"""
assert isinstance(company_id, int), 'Only one company ID'
company = self.browse(cr, uid, company_id, context=context)
company_vat = company.vat
@@ -54,10 +54,10 @@ class res_company(orm.Model):
return party_identifier
def _initiating_party_issuer_default(self, cr, uid, context=None):
'''If you need to add support for an additionnal country, you can
"""If you need to add support for an additionnal country, you can
add an entry in the dict "party_issuer_per_country" here
or inherit this function in the localization modules for
your country'''
your country"""
initiating_party_issuer = ''
# If your country require the 'Initiating Party Issuer', you should
# contribute the entry for your country in the dict below

View File

@@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import models
from . import wizard

View File

@@ -34,7 +34,7 @@
'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.
@@ -44,46 +44,44 @@
# 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',
'view/payment_order_create_view.xml',
'views/account_payment.xml',
'views/payment_mode.xml',
'views/payment_mode_type.xml',
'wizard/bank_payment_manual.xml',
'wizard/payment_order_create_view.xml',
'data/payment_mode_type.xml',
'security/ir.model.access.csv',
],
'demo': ['demo/banking_demo.xml'],
'description': '''
Infrastructure to export payment orders
plus some bug fixes and obvious enhancements to payment orders
that will hopefully land in offical addons one day.
Infrastructure to export payment orders plus some bug fixes and obvious
enhancements to payment orders that will hopefully land in offical addons one
day.
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
This technical module provides the base infrastructure to export payment orders
for electronic banking. It provides the following technical features:
To enable the use of payment order to collect money for customers,
it adds a payment_order_type (payment|debit) as a basis of direct debit
support (this field becomes visible when account_direct_debit is
installed).
Refactoring note: this field should ideally go in account_direct_debit,
but account_banking_payment currently depends on it.
* 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
Bug fixes and enhancement that should land in official addons:
* make the search function of the payment export wizard extensible
* fix lp:1275478: allow payment of customer refunds
* display the maturity date of the move lines when you are in
the wizard to select the lines to pay
''',
'installable': False,
To enable the use of payment order to collect money for customers,
it adds a payment_order_type (payment|debit) as a basis of direct debit support
(this field becomes visible when account_direct_debit is installed).
Refactoring note: this field should ideally go in account_direct_debit,
but account_banking_payment currently depends on it.
Bug fixes and enhancement that should land in official addons:
* make the search function of the payment export wizard extensible
* fix lp:1275478: allow payment of customer refunds
''',
'installable': True,
}

View File

@@ -9,6 +9,7 @@
eval="[(6,0,[ref('base.bank_normal'),ref('base_iban.bank_iban'),])]" />
<field name="ir_model_id"
ref="model_payment_manual"/>
<field name="payment_order_type">payment</field>
</record>
</data>
</openerp>

View File

@@ -57,6 +57,10 @@
<field name="bank_bic">FTNOFRP1XXX</field>
</record>
<record id="account_payment.payment_mode_1" model="payment.mode">
<field name="type" ref="account_banking_payment_export.manual_bank_tranfer"/>
</record>
<record id="payment_mode_2" model="payment.mode">
<field name="name">Credit Trf Banque Postale</field>
<field name="journal" ref="account.bank_journal"/>

View File

@@ -0,0 +1,236 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_banking_payment_export
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-10-31 22:52+0000\n"
"PO-Revision-Date: 2014-10-31 22:52+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: account_banking_payment_export
#: field:payment.mode,active:0
#: field:payment.mode.type,active:0
msgid "Active"
msgstr ""
#. module: account_banking_payment_export
#: field:payment.mode,sale_ok:0
msgid "Selectable on sale operations"
msgstr ""
#. module: account_banking_payment_export
#: field:payment.mode,purchase_ok:0
msgid "Selectable on purchase operations"
msgstr ""
#. module: account_banking_payment_export
#: field:account.move.line,amount_to_pay:0
msgid "Amount to pay"
msgstr ""
#. module: account_banking_payment_export
#: view:payment.manual:account_banking_payment_export.view_payment_manual_form
msgid "Cancel"
msgstr ""
#. module: account_banking_payment_export
#: field:payment.mode.type,code:0
msgid "Code"
msgstr ""
#. module: account_banking_payment_export
#: field:payment.manual,create_uid:0
#: field:payment.mode.type,create_uid:0
msgid "Created by"
msgstr ""
#. module: account_banking_payment_export
#: field:payment.manual,create_date:0
#: field:payment.mode.type,create_date:0
msgid "Created on"
msgstr ""
#. module: account_banking_payment_export
#: selection:payment.mode.type,payment_order_type:0
msgid "Debit"
msgstr ""
#. module: account_banking_payment_export
#: selection:payment.order,payment_order_type:0
msgid "Direct debit"
msgstr ""
#. module: account_banking_payment_export
#: code:addons/account_banking_payment_export/wizard/payment_order_create.py:77
#, python-format
msgid "Entry Lines"
msgstr ""
#. module: account_banking_payment_export
#: code:addons/account_banking_payment_export/models/account_payment.py:68
#, python-format
msgid "Error"
msgstr ""
#. module: account_banking_payment_export
#: field:payment.mode,type:0
msgid "Export type"
msgstr ""
#. module: account_banking_payment_export
#: field:payment.manual,id:0
#: field:payment.mode.type,id:0
msgid "ID"
msgstr ""
#. module: account_banking_payment_export
#: model:ir.model,name:account_banking_payment_export.model_account_move_line
msgid "Journal Items"
msgstr ""
#. module: account_banking_payment_export
#: field:payment.manual,write_uid:0
#: field:payment.mode.type,write_uid:0
msgid "Last Updated by"
msgstr ""
#. module: account_banking_payment_export
#: field:payment.manual,write_date:0
#: field:payment.mode.type,write_date:0
msgid "Last Updated on"
msgstr ""
#. module: account_banking_payment_export
#: view:payment.manual:account_banking_payment_export.view_payment_manual_form
msgid "Manual payment"
msgstr ""
#. module: account_banking_payment_export
#: field:payment.mode.type,name:0
msgid "Name"
msgstr ""
#. module: account_banking_payment_export
#: field:payment.mode.type,payment_order_type:0
msgid "Order type"
msgstr ""
#. module: account_banking_payment_export
#: selection:payment.mode.type,payment_order_type:0
#: selection:payment.order,payment_order_type:0
msgid "Payment"
msgstr ""
#. module: account_banking_payment_export
#: model:ir.actions.act_window,name:account_banking_payment_export.action_payment_mode_type
#: model:ir.ui.menu,name:account_banking_payment_export.menu_payment_mode_type
msgid "Payment Export Types"
msgstr ""
#. module: account_banking_payment_export
#: model:ir.model,name:account_banking_payment_export.model_payment_mode
msgid "Payment Mode"
msgstr ""
#. module: account_banking_payment_export
#: model:ir.model,name:account_banking_payment_export.model_payment_mode_type
msgid "Payment Mode Type"
msgstr ""
#. module: account_banking_payment_export
#: model:ir.model,name:account_banking_payment_export.model_payment_order
msgid "Payment Order"
msgstr ""
#. module: account_banking_payment_export
#: code:addons/account_banking_payment_export/models/account_payment.py:53
#, python-format
msgid "Payment Order Export"
msgstr ""
#. module: account_banking_payment_export
#: code:addons/account_banking_payment_export/wizard/payment_order_create.py:169
#, python-format
msgid "Payment Orders"
msgstr ""
#. module: account_banking_payment_export
#: view:payment.mode.type:account_banking_payment_export.view_payment_mode_type_form
#: help:payment.mode.type,name:0
msgid "Payment Type"
msgstr ""
#. module: account_banking_payment_export
#: view:payment.mode.type:account_banking_payment_export.view_payment_mode_type_tree
msgid "Payment Types"
msgstr ""
#. module: account_banking_payment_export
#: field:payment.order,payment_order_type:0
msgid "Payment order type"
msgstr ""
#. module: account_banking_payment_export
#: field:payment.mode.type,ir_model_id:0
msgid "Payment wizard"
msgstr ""
#. module: account_banking_payment_export
#: view:payment.manual:account_banking_payment_export.view_payment_manual_form
msgid "Please execute payment order manually, and click OK when succesfully sent."
msgstr ""
#. module: account_banking_payment_export
#: field:payment.order.create,populate_results:0
msgid "Populate results directly"
msgstr ""
#. module: account_banking_payment_export
#: help:payment.mode,type:0
msgid "Select the Export Payment Type for the Payment Mode."
msgstr ""
#. 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 ""
#. module: account_banking_payment_export
#: model:ir.model,name:account_banking_payment_export.model_payment_manual
msgid "Send payment order(s) manually"
msgstr ""
#. module: account_banking_payment_export
#: help:payment.mode.type,code:0
msgid "Specify the Code for Payment Type"
msgstr ""
#. module: account_banking_payment_export
#: view:payment.mode.type:account_banking_payment_export.view_payment_mode_type_form
#: field:payment.mode.type,suitable_bank_types:0
msgid "Suitable bank types"
msgstr ""
#. module: account_banking_payment_export
#: help:payment.mode.type,payment_order_type:0
msgid "This field determines if this type applies to customers (Debit) or suppliers (Payment)"
msgstr ""
#. module: account_banking_payment_export
#: code:addons/account_banking_payment_export/models/account_payment.py:69
#, python-format
msgid "You can only combine payment orders of the same type"
msgstr ""
#. module: account_banking_payment_export
#: view:payment.order:account_banking_payment_export.view_banking_payment_order_form_1
msgid "launch_wizard"
msgstr ""

View File

@@ -0,0 +1,236 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_banking_payment_export
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-10-31 22:52+0000\n"
"PO-Revision-Date: 2014-10-31 22:52+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: account_banking_payment_export
#: field:payment.mode,active:0
#: field:payment.mode.type,active:0
msgid "Active"
msgstr "Activo"
#. module: account_banking_payment_export
#: field:payment.mode,sale_ok:0
msgid "Selectable on sale operations"
msgstr "Seleccionable en operaciones de venta"
#. module: account_banking_payment_export
#: field:payment.mode,purchase_ok:0
msgid "Selectable on purchase operations"
msgstr "Seleccionable en operaciones de compra"
#. module: account_banking_payment_export
#: field:account.move.line,amount_to_pay:0
msgid "Amount to pay"
msgstr "Importe a pagar"
#. module: account_banking_payment_export
#: view:payment.manual:account_banking_payment_export.view_payment_manual_form
msgid "Cancel"
msgstr "Cancelar"
#. module: account_banking_payment_export
#: field:payment.mode.type,code:0
msgid "Code"
msgstr "Código"
#. module: account_banking_payment_export
#: field:payment.manual,create_uid:0
#: field:payment.mode.type,create_uid:0
msgid "Created by"
msgstr "Creado por"
#. module: account_banking_payment_export
#: field:payment.manual,create_date:0
#: field:payment.mode.type,create_date:0
msgid "Created on"
msgstr "Creado en"
#. module: account_banking_payment_export
#: selection:payment.mode.type,payment_order_type:0
msgid "Debit"
msgstr "Cobro"
#. module: account_banking_payment_export
#: selection:payment.order,payment_order_type:0
msgid "Direct debit"
msgstr "Adeudo directo (cobro)"
#. module: account_banking_payment_export
#: code:addons/account_banking_payment_export/wizard/payment_order_create.py:77
#, python-format
msgid "Entry Lines"
msgstr "Líneas de pago"
#. module: account_banking_payment_export
#: code:addons/account_banking_payment_export/models/account_payment.py:68
#, python-format
msgid "Error"
msgstr "Error"
#. module: account_banking_payment_export
#: field:payment.mode,type:0
msgid "Export type"
msgstr "Tipo de exportación"
#. module: account_banking_payment_export
#: field:payment.manual,id:0
#: field:payment.mode.type,id:0
msgid "ID"
msgstr "ID"
#. module: account_banking_payment_export
#: model:ir.model,name:account_banking_payment_export.model_account_move_line
msgid "Journal Items"
msgstr "Asientos contables"
#. module: account_banking_payment_export
#: field:payment.manual,write_uid:0
#: field:payment.mode.type,write_uid:0
msgid "Last Updated by"
msgstr "Última actualización por"
#. module: account_banking_payment_export
#: field:payment.manual,write_date:0
#: field:payment.mode.type,write_date:0
msgid "Last Updated on"
msgstr "Última actualización en"
#. module: account_banking_payment_export
#: view:payment.manual:account_banking_payment_export.view_payment_manual_form
msgid "Manual payment"
msgstr "Pago manual"
#. module: account_banking_payment_export
#: field:payment.mode.type,name:0
msgid "Name"
msgstr "Nombre"
#. module: account_banking_payment_export
#: field:payment.mode.type,payment_order_type:0
msgid "Order type"
msgstr "Tipo de orden"
#. module: account_banking_payment_export
#: selection:payment.mode.type,payment_order_type:0
#: selection:payment.order,payment_order_type:0
msgid "Payment"
msgstr "Pago"
#. module: account_banking_payment_export
#: model:ir.actions.act_window,name:account_banking_payment_export.action_payment_mode_type
#: model:ir.ui.menu,name:account_banking_payment_export.menu_payment_mode_type
msgid "Payment Export Types"
msgstr "Tipos de exportación de pagos"
#. module: account_banking_payment_export
#: model:ir.model,name:account_banking_payment_export.model_payment_mode
msgid "Payment Mode"
msgstr "Modo de pago"
#. module: account_banking_payment_export
#: model:ir.model,name:account_banking_payment_export.model_payment_mode_type
msgid "Payment Mode Type"
msgstr "Tipo del modo de pago"
#. module: account_banking_payment_export
#: model:ir.model,name:account_banking_payment_export.model_payment_order
msgid "Payment Order"
msgstr "Orden de pago"
#. module: account_banking_payment_export
#: code:addons/account_banking_payment_export/models/account_payment.py:53
#, python-format
msgid "Payment Order Export"
msgstr "Exportación de la orden de pago"
#. module: account_banking_payment_export
#: code:addons/account_banking_payment_export/wizard/payment_order_create.py:169
#, python-format
msgid "Payment Orders"
msgstr "Órdenes de pago"
#. module: account_banking_payment_export
#: view:payment.mode.type:account_banking_payment_export.view_payment_mode_type_form
#: help:payment.mode.type,name:0
msgid "Payment Type"
msgstr "Tipo de pago"
#. module: account_banking_payment_export
#: view:payment.mode.type:account_banking_payment_export.view_payment_mode_type_tree
msgid "Payment Types"
msgstr "Tipos de pago"
#. module: account_banking_payment_export
#: field:payment.order,payment_order_type:0
msgid "Payment order type"
msgstr "Tipo de la orden de pago"
#. module: account_banking_payment_export
#: field:payment.mode.type,ir_model_id:0
msgid "Payment wizard"
msgstr "Asistente de pago"
#. module: account_banking_payment_export
#: view:payment.manual:account_banking_payment_export.view_payment_manual_form
msgid "Please execute payment order manually, and click OK when succesfully sent."
msgstr "Ejecute la orden de pago manualmente (fuera del sistema), y pulse en Aceptar cuando la haya tramitado correctamente."
#. module: account_banking_payment_export
#: field:payment.order.create,populate_results:0
msgid "Populate results directly"
msgstr "Incluir directamente los resultados"
#. module: account_banking_payment_export
#: help:payment.mode,type:0
msgid "Select the Export Payment Type for the Payment Mode."
msgstr "Seleccione el tipo de exportación de pago para el modo de pago."
#. 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 "Seleccione el asistente de pago para los pagos de este tipo. Déjelo vacío para un procesado manual."
#. module: account_banking_payment_export
#: model:ir.model,name:account_banking_payment_export.model_payment_manual
msgid "Send payment order(s) manually"
msgstr "Enviar la(s) orden(es) de pago manualmente"
#. module: account_banking_payment_export
#: help:payment.mode.type,code:0
msgid "Specify the Code for Payment Type"
msgstr "Especifica el código para el tipo de pago"
#. module: account_banking_payment_export
#: view:payment.mode.type:account_banking_payment_export.view_payment_mode_type_form
#: field:payment.mode.type,suitable_bank_types:0
msgid "Suitable bank types"
msgstr "Tipos de cuentas bancarias adecuadas"
#. module: account_banking_payment_export
#: help:payment.mode.type,payment_order_type:0
msgid "This field determines if this type applies to customers (Debit) or suppliers (Payment)"
msgstr "Este campo determina si este tipo aplica a clientes (Cobro) o a proveedores (Pago)"
#. module: account_banking_payment_export
#: code:addons/account_banking_payment_export/models/account_payment.py:69
#, python-format
msgid "You can only combine payment orders of the same type"
msgstr "Sólo puede combinar órdenes de pago del mismo tipo"
#. module: account_banking_payment_export
#: view:payment.order:account_banking_payment_export.view_banking_payment_order_form_1
msgid "launch_wizard"
msgstr "Asistente"

View File

@@ -1,7 +1,5 @@
# -*- coding: utf-8 -*-
from . import account_move_line
from . import account_payment
from . import bank_payment_manual
from . import payment_mode
from . import payment_mode_type
from . import payment_order_create
from . import account_move_line

View File

@@ -32,10 +32,10 @@ from operator import itemgetter
# https://bugs.launchpad.net/openobject-addons/+bug/1275478
# is integrated in addons/account_payment, then we will be able to remove this
# file. -- Alexis de Lattre
class account_move_line(orm.Model):
class AccountMoveLine(orm.Model):
_inherit = 'account.move.line'
def amount_to_pay(self, cr, uid, ids, name, arg=None, context=None):
def _amount_to_pay(self, cr, uid, ids, name, arg=None, context=None):
""" Return the amount still to pay regarding all the payemnt orders
(excepting cancelled orders)"""
if not ids:
@@ -72,24 +72,20 @@ class account_move_line(orm.Model):
AND po.state != 'cancel'
) %(operator)s %%s ''' % {'operator': x[1]}, args))
sql_args = tuple(map(itemgetter(2), args))
cr.execute(
('''\
SELECT id
'''SELECT id
FROM account_move_line l
WHERE account_id IN (select id
FROM account_account
WHERE type in %s AND active)
AND reconcile_id IS null
AND credit > 0
AND ''' + where + ' and ' + query
), (('payable', 'receivable'), ) + sql_args
)
AND ''' + where + ' and ' + query,
(('payable', 'receivable'),) + sql_args)
# The patch we have compared to the original function in
# addons/account_payment is just above :
# original code : type = 'payable'
# fixed code : type in ('payable', 'receivable')
res = cr.fetchall()
if not res:
return [('id', '=', '0')]
@@ -97,9 +93,6 @@ class account_move_line(orm.Model):
_columns = {
'amount_to_pay': fields.function(
amount_to_pay,
type='float',
string='Amount to pay',
fnct_search=_to_pay_search
),
_amount_to_pay, type='float', string='Amount to pay',
fnct_search=_to_pay_search),
}

View File

@@ -23,47 +23,33 @@
#
##############################################################################
from openerp.osv import orm, fields
from openerp.tools.translate import _
from openerp import netsvc
from openerp import models, fields, api, exceptions, workflow, _
class payment_order(orm.Model):
class PaymentOrder(models.Model):
_inherit = 'payment.order'
_columns = {
'payment_order_type': fields.selection(
[('payment', 'Payment'), ('debit', 'Direct debit')],
'Payment order type', required=True,
readonly=True, states={'draft': [('readonly', False)]},
),
'mode_type': fields.related(
'mode', 'type', type='many2one', relation='payment.mode.type',
string='Payment Type'),
}
payment_order_type = fields.Selection(
[('payment', 'Payment'), ('debit', 'Direct debit')],
'Payment order type', required=True, default='payment',
readonly=True, states={'draft': [('readonly', False)]})
mode_type = fields.Many2one('payment.mode.type', related='mode.type',
string='Payment Type')
_defaults = {
'payment_order_type': 'payment',
}
def launch_wizard(self, cr, uid, ids, context=None):
"""
Search for a wizard to launch according to the type.
@api.multi
def launch_wizard(self):
"""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 is None:
context = {}
result = {}
orders = self.browse(cr, uid, ids, context)
order = orders[0]
context = self.env.context.copy()
order = self[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
context['active_ids'] = self.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 = {
wizard_obj = self.env[wizard_model]
return {
'name': wizard_obj._description or _('Payment Order Export'),
'view_type': 'form',
'view_mode': 'form',
@@ -72,22 +58,18 @@ class payment_order(orm.Model):
'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:]:
for order in self[1:]:
if order.mode.type and order.mode.type.ir_model_id:
raise orm.except_orm(
raise exceptions.Warning(
_('Error'),
_('You can only combine payment orders of the same '
'type')
)
'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
for order_id in self.ids:
workflow.trg_validate(self.env.uid, 'payment.order',
order_id, 'done', self.env.cr)
return {}

View File

@@ -23,12 +23,13 @@
#
##############################################################################
from openerp.osv import orm, fields
from openerp import models, fields
class payment_mode(orm.Model):
''' Restoring the payment type from version 5,
used to select the export wizard (if any) '''
class PaymentMode(models.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):
@@ -36,27 +37,22 @@ class payment_mode(orm.Model):
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):
payment_mode = self.browse(cr, uid, payment_mode_id, context=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.'
),
'payment_order_type': fields.related(
'type', 'payment_order_type', readonly=True, type='selection',
selection=[('payment', 'Payment'), ('debit', 'Direct debit')],
string="Payment Order Type"),
'active': fields.boolean('Active'),
}
_defaults = {
'active': True,
}
type = fields.Many2one(
'payment.mode.type', string='Export type', required=True,
help='Select the Export Payment Type for the Payment Mode.')
payment_order_type = fields.Selection(
related='type.payment_order_type', readonly=True, string="Order Type",
selection=[('payment', 'Payment'), ('debit', 'Debit')],
help="This field, that comes from export type, determines if this "
"mode can be selected for customers or suppliers.")
active = fields.Boolean(string='Active', default=True)
sale_ok = fields.Boolean(string='Selectable on sale operations',
default=True)
purchase_ok = fields.Boolean(string='Selectable on purchase operations',
default=True)

View File

@@ -0,0 +1,63 @@
# -*- 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 import models, fields
class PaymentModeType(models.Model):
_name = 'payment.mode.type'
_description = 'Payment Mode Type'
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(
comodel_name='res.partner.bank.type',
relation='bank_type_payment_type_rel', column1='pay_type_id',
column2='bank_type_id', string='Suitable bank types', required=True)
ir_model_id = fields.Many2one(
'ir.model', string='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', 'Debit')],
string='Order type', required=True, default='payment',
help="This field determines if this type applies to customers "
"(Debit) or suppliers (Payment)")
active = fields.Boolean(string='Active', default=True)
def _auto_init(self, cr, context=None):
res = super(PaymentModeType, 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 res

View File

@@ -2,7 +2,7 @@
<openerp>
<data>
<!--
<!--
Add the payment mode type and transfer settings
-->
<record id="view_payment_mode_form_inherit" model="ir.ui.view">
@@ -13,6 +13,8 @@
<field name="company_id" position="after">
<field name="active"/>
<field name="type"/>
<field name="purchase_ok"/>
<field name="sale_ok"/>
</field>
</field>
</record>

View File

@@ -20,11 +20,18 @@
<field name="arch" type="xml">
<form string="Payment Type" version="7.0">
<group name="main">
<field name="name"/>
<field name="code"/>
<field name="active"/>
<field name="ir_model_id"/>
<field name="suitable_bank_types"/>
<group>
<field name="name"/>
<field name="ir_model_id"/>
</group>
<group>
<field name="code"/>
<field name="active"/>
</group>
</group>
<group string="Suitable bank types">
<field name="suitable_bank_types"
nolabel="1"/>
</group>
</form>
</field>
@@ -44,7 +51,7 @@
</record>
<record id="action_payment_mode_type" model="ir.actions.act_window">
<field name="name">Payment Type</field>
<field name="name">Payment Export Types</field>
<field name="res_model">payment.mode.type</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>

View File

@@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import payment_order_create
from . import bank_payment_manual

View File

@@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2013 Therp BV (<http://therp.nl>).
# 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
#
@@ -22,18 +23,20 @@
#
##############################################################################
"""This module contains a single "wizard" for confirming manual
bank transfers.
"""
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"
"""
)
from openerp import models, api, workflow
class PaymentManual(models.TransientModel):
_name = 'payment.manual'
_description = 'Send payment order(s) manually'
@api.multi
def button_ok(self):
for order_id in self.env.context.get('active_ids', []):
workflow.trg_validate(self.env.uid, 'payment.order', order_id,
'done', self.env.cr)
return {'type': 'ir.actions.act_window_close'}

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,175 @@
# -*- 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 import models, fields, api, _
class PaymentOrderCreate(models.TransientModel):
_inherit = 'payment.order.create'
populate_results = fields.Boolean(string="Populate results directly",
default=True)
@api.model
def default_get(self, field_list):
res = super(PaymentOrderCreate, self).default_get(field_list)
context = self.env.context
if ('entries' in field_list and context.get('line_ids') and
context.get('populate_results')):
res.update({'entries': context['line_ids']})
return res
@api.model
def extend_payment_order_domain(self, payment_order, domain):
if payment_order.payment_order_type == 'payment':
domain += [('account_id.type', 'in', ('payable', 'receivable')),
('amount_to_pay', '>', 0)]
return True
@api.multi
def search_entries(self):
"""This method taken from account_payment module.
We adapt the domain based on the payment_order_type
"""
line_obj = self.env['account.move.line']
model_data_obj = self.env['ir.model.data']
# -- start account_banking_payment --
payment = self.env['payment.order'].browse(
self.env.context['active_id'])
# Search for move line to pay:
domain = [('move_id.state', '=', 'posted'),
('reconcile_id', '=', False),
('company_id', '=', payment.mode.company_id.id)]
self.extend_payment_order_domain(payment, domain)
# -- end account_direct_debit --
domain += ['|',
('date_maturity', '<=', self.duedate),
('date_maturity', '=', False)]
lines = line_obj.search(domain)
context = self.env.context.copy()
context['line_ids'] = lines.ids
context['populate_results'] = self.populate_results
model_datas = model_data_obj.search(
[('model', '=', 'ir.ui.view'),
('name', '=', 'view_create_payment_order_lines')])
return {'name': _('Entry Lines'),
'context': context,
'view_type': 'form',
'view_mode': 'form',
'res_model': 'payment.order.create',
'views': [(model_datas[0].res_id, 'form')],
'type': 'ir.actions.act_window',
'target': 'new',
}
@api.model
def _prepare_payment_line(self, payment, line):
"""This function is designed to be inherited
The resulting dict is passed to the create method of payment.line"""
_today = fields.Date.context_today(self)
date_to_pay = False # no payment date => immediate payment
if payment.date_prefered == 'due':
# -- account_banking
# date_to_pay = line.date_maturity
date_to_pay = (
line.date_maturity
if line.date_maturity and line.date_maturity > _today
else False)
# -- end account banking
elif payment.date_prefered == 'fixed':
# -- account_banking
# date_to_pay = payment.date_scheduled
date_to_pay = (
payment.date_scheduled
if payment.date_scheduled and payment.date_scheduled > _today
else False)
# -- end account banking
# -- account_banking
state = 'normal'
communication = line.ref or '-'
if line.invoice:
if line.invoice.type in ('in_invoice', 'in_refund'):
if line.invoice.reference_type == 'structured':
state = 'structured'
communication = line.invoice.reference
else:
if line.invoice.reference:
communication = line.invoice.reference
elif line.invoice.supplier_invoice_number:
communication = line.invoice.supplier_invoice_number
else:
# Make sure that the communication includes the
# customer invoice number (in the case of debit order)
communication = line.invoice.number.replace('/', '')
state = 'structured'
# support debit orders when enabled
if (payment.payment_order_type == 'debit' and
'amount_to_receive' in line):
amount_currency = line.amount_to_receive
else:
amount_currency = line.amount_to_pay
line2bank = line.line2bank(payment.mode.id)
# -- end account banking
res = {'move_line_id': line.id,
'amount_currency': amount_currency,
'bank_id': line2bank.get(line.id),
'order_id': payment.id,
'partner_id': line.partner_id and line.partner_id.id or False,
# account banking
'communication': communication,
'state': state,
# end account banking
'date': date_to_pay,
'currency': (line.invoice and line.invoice.currency_id.id
or line.journal_id.currency.id
or line.journal_id.company_id.currency_id.id)}
return res
@api.multi
def create_payment(self):
"""This method is a slightly modified version of the existing method on
this model in account_payment.
- pass the payment mode to line2bank()
- allow invoices to create influence on the payment process: not only
'Free' references are allowed, but others as well
- check date_to_pay is not in the past.
"""
if not self.entries:
return {'type': 'ir.actions.act_window_close'}
context = self.env.context
payment_line_obj = self.env['payment.line']
payment = self.env['payment.order'].browse(context['active_id'])
# Populate the current payment with new lines:
for line in self.entries:
vals = self._prepare_payment_line(payment, line)
payment_line_obj.create(vals)
# Force reload of payment order view as a workaround for lp:1155525
return {'name': _('Payment Orders'),
'context': context,
'view_type': 'form',
'view_mode': 'form,tree',
'res_model': 'payment.order',
'res_id': context['active_id'],
'type': 'ir.actions.act_window'}

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2013 Akretion (http://www.akretion.com)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
The licence is in the file __openerp__.py
-->
<openerp>
<data>
<record id="view_create_payment_order" model="ir.ui.view">
<field name="name">payment.order.create.form.export</field>
<field name="model">payment.order.create</field>
<field name="inherit_id" ref="account_payment.view_create_payment_order"/>
<field name="arch" type="xml">
<field name="duedate" position="after">
<field name="populate_results"/>
</field>
</field>
</record>
<record id="view_create_payment_order_lines" model="ir.ui.view">
<field name="name">add.context.to.display.maturity.date</field>
<field name="model">payment.order.create</field>
<field name="inherit_id" ref="account_payment.view_create_payment_order_lines"/>
<field name="arch" type="xml">
<field name="entries" position="attributes">
<attribute name="context">{'journal_type': 'sale'}</attribute>
<attribute name="nolabel">1</attribute>
</field>
</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,24 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# SEPA Credit Transfer module for OpenERP
# Copyright (C) 2010-2013 Akretion (http://www.akretion.com)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from . import wizard
from . import models

View File

@@ -26,39 +26,34 @@
'license': 'AGPL-3',
'author': 'Akretion',
'website': 'http://www.akretion.com',
'contributors': ['Pedro M. Baeza <pedro.baeza@serviciosbaeza.com>'],
'category': 'Banking addons',
'depends': ['account_banking_pain_base'],
'external_dependencies': {
'python': ['unidecode', 'lxml'],
},
'data': [
'account_banking_sepa_view.xml',
'views/account_banking_sepa_view.xml',
'wizard/export_sepa_view.xml',
'data/payment_type_sepa_sct.xml',
'security/ir.model.access.csv',
],
'demo': ['sepa_credit_transfer_demo.xml'],
'demo': [
'demo/sepa_credit_transfer_demo.xml'
],
'description': '''
Module to export payment orders in SEPA XML file format.
SEPA PAIN (PAyment INitiation) is the new european standard for
Customer-to-Bank payment instructions.
This module implements SEPA Credit Transfer (SCT), more specifically PAIN
versions 001.001.02, 001.001.03, 001.001.04 and 001.001.05.
It is part of the ISO 20022 standard, available on http://www.iso20022.org.
Customer-to-Bank payment instructions. This module implements SEPA Credit
Transfer (SCT), more specifically PAIN versions 001.001.02, 001.001.03,
001.001.04 and 001.001.05. It is part of the ISO 20022 standard, available on
http://www.iso20022.org.
The Implementation Guidelines for SEPA Credit Transfer published by the
European Payments Council (http://http://www.europeanpaymentscouncil.eu)
use PAIN version 001.001.03, so it's probably the version of PAIN that you
should try first.
This module uses the framework provided by the banking addons,
cf https://www.github.com/OCA/banking-addons
Please contact Alexis de Lattre from Akretion <alexis.delattre@akretion.com>
for any help or question about this module.
European Payments Council (http://http://www.europeanpaymentscouncil.eu) use
PAIN version 001.001.03, so it's probably the version of PAIN that you should
try first.
''',
'active': False,
'installable': False,
'installable': True,
}

View File

@@ -7,6 +7,7 @@
<record id="export_sepa_sct_001_001_05" model="payment.mode.type">
<field name="name">SEPA Credit Transfer v05</field>
<field name="code">pain.001.001.05</field>
<field name="payment_order_type">payment</field>
<field name="suitable_bank_types"
eval="[(6,0,[ref('base_iban.bank_iban')])]" />
<field name="ir_model_id" ref="model_banking_export_sepa_wizard"/>
@@ -15,6 +16,7 @@
<record id="export_sepa_sct_001_001_04" model="payment.mode.type">
<field name="name">SEPA Credit Transfer v04</field>
<field name="code">pain.001.001.04</field>
<field name="payment_order_type">payment</field>
<field name="suitable_bank_types"
eval="[(6,0,[ref('base_iban.bank_iban')])]" />
<field name="ir_model_id" ref="model_banking_export_sepa_wizard"/>
@@ -23,6 +25,7 @@
<record id="export_sepa_sct_001_001_03" model="payment.mode.type">
<field name="name">SEPA Credit Transfer v03 (recommended)</field>
<field name="code">pain.001.001.03</field>
<field name="payment_order_type">payment</field>
<field name="suitable_bank_types"
eval="[(6,0,[ref('base_iban.bank_iban')])]" />
<field name="ir_model_id" ref="model_banking_export_sepa_wizard"/>
@@ -31,6 +34,7 @@
<record id="export_sepa_sct_001_001_02" model="payment.mode.type">
<field name="name">SEPA Credit Transfer v02</field>
<field name="code">pain.001.001.02</field>
<field name="payment_order_type">payment</field>
<field name="suitable_bank_types"
eval="[(6,0,[ref('base_iban.bank_iban')])]" />
<field name="ir_model_id" ref="model_banking_export_sepa_wizard"/>

View File

@@ -1,13 +1,13 @@
# Translation of OpenERP Server.
# Translation of Odoo 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"
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-12-23 22:49+0000\n"
"PO-Revision-Date: 2013-12-23 22:49+0000\n"
"POT-Creation-Date: 2014-10-31 22:52+0000\n"
"PO-Revision-Date: 2014-10-31 22:52+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@@ -15,98 +15,18 @@ msgstr ""
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: account_banking_sepa_credit_transfer
#: selection:banking.export.sepa.wizard,state:0
msgid "Create"
msgstr ""
#. 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 ""
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,filename:0
#: field:banking.export.sepa.wizard,filename:0
msgid "Filename"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,state:0
#: field:banking.export.sepa.wizard,state:0
msgid "State"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: selection:banking.export.sepa,state:0
msgid "Draft"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: help:banking.export.sepa.wizard,charge_bearer:0
msgid "Following service level : transaction charges are to be applied following the rules agreed in the service level and/or scheme (SEPA Core messages must use this). Shared : transaction charges on the debtor side are to be borne by the debtor, transaction charges on the creditor side are to be borne by the creditor. 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."
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: selection:banking.export.sepa,charge_bearer:0
#: selection:banking.export.sepa.wizard,charge_bearer:0
msgid "Shared"
msgstr ""
#. 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 ""
#. module: account_banking_sepa_credit_transfer
#: selection:banking.export.sepa,state:0
msgid "Sent"
msgstr ""
#. 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 File"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa:0
msgid "SEPA Credit Transfer"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: selection:banking.export.sepa.wizard,state:0
msgid "Finish"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: selection:banking.export.sepa,state:0
msgid "Reconciled"
msgstr ""
#. 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 ""
#. 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 ""
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa.wizard:0
msgid "Validate"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa.wizard:0
msgid "Generate"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: selection:banking.export.sepa,charge_bearer:0
#: selection:banking.export.sepa.wizard,charge_bearer:0
@@ -114,16 +34,8 @@ msgid "Borne by Debtor"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: code:addons/account_banking_sepa_credit_transfer/wizard/export_sepa.py:128
#: code:addons/account_banking_sepa_credit_transfer/wizard/export_sepa.py:245
#, python-format
msgid "Error:"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,total_amount:0
#: field:banking.export.sepa.wizard,total_amount:0
msgid "Total Amount"
#: view:banking.export.sepa.wizard:account_banking_sepa_credit_transfer.banking_export_sepa_wizard_view
msgid "Cancel"
msgstr ""
#. module: account_banking_sepa_credit_transfer
@@ -133,25 +45,57 @@ msgid "Charge Bearer"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa.wizard:0
msgid "SEPA File Generation"
#: selection:banking.export.sepa.wizard,state:0
msgid "Create"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: model:ir.model,name:account_banking_sepa_credit_transfer.model_banking_export_sepa
msgid "SEPA export"
#: field:banking.export.sepa,create_uid:0
#: field:banking.export.sepa.wizard,create_uid:0
msgid "Created by"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: code:addons/account_banking_sepa_credit_transfer/wizard/export_sepa.py:246
#: field:banking.export.sepa.wizard,create_date:0
msgid "Created on"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: selection:banking.export.sepa,state:0
msgid "Draft"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: code:addons/account_banking_sepa_credit_transfer/wizard/export_sepa.py:124
#: code:addons/account_banking_sepa_credit_transfer/wizard/export_sepa.py:232
#, python-format
msgid "Missing Bank Account on invoice '%s' (payment order line reference '%s')."
msgid "Error:"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,file:0
#: field:banking.export.sepa.wizard,file_id:0
msgid "SEPA XML File"
#: model:ir.model,name:account_banking_sepa_credit_transfer.model_banking_export_sepa_wizard
msgid "Export SEPA Credit Transfer File"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa.wizard,file:0
msgid "File"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa.wizard,filename:0
msgid "Filename"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: selection:banking.export.sepa.wizard,state:0
msgid "Finish"
msgstr ""
#. 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 ""
#. module: account_banking_sepa_credit_transfer
@@ -160,21 +104,78 @@ msgid "Following service level : transaction charges are to be applied following
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: code:addons/account_banking_sepa_credit_transfer/wizard/export_sepa.py:129
#, python-format
msgid "Payment Type Code '%s' is not supported. The only Payment Type Codes supported for SEPA Credit Transfers are 'pain.001.001.02', 'pain.001.001.03', 'pain.001.001.04' and 'pain.001.001.05'."
#: help:banking.export.sepa.wizard,charge_bearer:0
msgid "Following service level : transaction charges are to be applied following the rules agreed in the service level and/or scheme (SEPA Core messages must use this). Shared : transaction charges on the debtor side are to be borne by the debtor, transaction charges on the creditor side are to be borne by the creditor. 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."
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa:0
#: view:banking.export.sepa:account_banking_sepa_credit_transfer.view_banking_export_sepa_form
msgid "General Information"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa.wizard:account_banking_sepa_credit_transfer.banking_export_sepa_wizard_view
msgid "Generate"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,create_date:0
msgid "Generation Date"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,id:0
#: field:banking.export.sepa.wizard,id:0
msgid "ID"
msgstr ""
#. 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 ""
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,write_uid:0
#: field:banking.export.sepa.wizard,write_uid:0
msgid "Last Updated by"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,write_date:0
#: field:banking.export.sepa.wizard,write_date:0
msgid "Last Updated on"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: code:addons/account_banking_sepa_credit_transfer/wizard/export_sepa.py:233
#, python-format
msgid "Missing Bank Account on invoice '%s' (payment order line reference '%s')."
msgstr ""
#. 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 ""
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa:account_banking_sepa_credit_transfer.view_banking_export_sepa_form
#: field:banking.export.sepa,payment_order_ids:0
#: field:banking.export.sepa.wizard,payment_order_ids:0
msgid "Payment Orders"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa:0
msgid "General Information"
#: code:addons/account_banking_sepa_credit_transfer/wizard/export_sepa.py:125
#, python-format
msgid "Payment Type Code '%s' is not supported. The only Payment Type Codes supported for SEPA Credit Transfers are 'pain.001.001.02', 'pain.001.001.03', 'pain.001.001.04' and 'pain.001.001.05'."
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa:account_banking_sepa_credit_transfer.view_banking_export_sepa_form
#: view:banking.export.sepa:account_banking_sepa_credit_transfer.view_banking_export_sepa_tree
msgid "SEPA Credit Transfer"
msgstr ""
#. module: account_banking_sepa_credit_transfer
@@ -185,23 +186,46 @@ msgid "SEPA Credit Transfer Files"
msgstr ""
#. 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."
#: view:banking.export.sepa.wizard:account_banking_sepa_credit_transfer.banking_export_sepa_wizard_view
msgid "SEPA File Generation"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa.wizard,file:0
msgid "File"
#: field:banking.export.sepa,file:0
#: field:banking.export.sepa.wizard,file_id:0
msgid "SEPA XML File"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa.wizard:0
msgid "Cancel"
#: model:ir.model,name:account_banking_sepa_credit_transfer.model_banking_export_sepa
msgid "SEPA export"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,create_date:0
msgid "Generation Date"
#: selection:banking.export.sepa,state:0
msgid "Sent"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: selection:banking.export.sepa,charge_bearer:0
#: selection:banking.export.sepa.wizard,charge_bearer:0
msgid "Shared"
msgstr ""
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,state:0
#: field:banking.export.sepa.wizard,state:0
msgid "State"
msgstr ""
#. 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 ""
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa.wizard:account_banking_sepa_credit_transfer.banking_export_sepa_wizard_view
msgid "Validate"
msgstr ""

View File

@@ -0,0 +1,231 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_banking_sepa_credit_transfer
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-10-31 22:52+0000\n"
"PO-Revision-Date: 2014-10-31 22:52+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,batch_booking:0
#: field:banking.export.sepa.wizard,batch_booking:0
msgid "Batch Booking"
msgstr "Registro en lote"
#. 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 "A cargo del acreedor"
#. 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 "A cargo del deudor"
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa.wizard:account_banking_sepa_credit_transfer.banking_export_sepa_wizard_view
msgid "Cancel"
msgstr "Cancelar"
#. 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 "A cargo del portador"
#. module: account_banking_sepa_credit_transfer
#: selection:banking.export.sepa.wizard,state:0
msgid "Create"
msgstr "Crear"
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,create_uid:0
#: field:banking.export.sepa.wizard,create_uid:0
msgid "Created by"
msgstr "Creado por"
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa.wizard,create_date:0
msgid "Created on"
msgstr "Creado en"
#. module: account_banking_sepa_credit_transfer
#: selection:banking.export.sepa,state:0
msgid "Draft"
msgstr "Borrador"
#. module: account_banking_sepa_credit_transfer
#: code:addons/account_banking_sepa_credit_transfer/wizard/export_sepa.py:124
#: code:addons/account_banking_sepa_credit_transfer/wizard/export_sepa.py:232
#, python-format
msgid "Error:"
msgstr "Error:"
#. 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 File"
msgstr "Exportar archivo de transferencia SEPA"
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa.wizard,file:0
msgid "File"
msgstr "Archivo"
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa.wizard,filename:0
msgid "Filename"
msgstr "Nombre de archivo"
#. module: account_banking_sepa_credit_transfer
#: selection:banking.export.sepa.wizard,state:0
msgid "Finish"
msgstr "Finalizar"
#. 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 "Según el acuerdo de servicio"
#. module: account_banking_sepa_credit_transfer
#: help:banking.export.sepa,charge_bearer:0
msgid "Following service level : transaction charges are to be applied following the rules agreed in the service level and/or scheme (SEPA Core messages must use this). Shared : transaction charges on the creditor side are to be borne by the creditor, transaction charges on the debtor side are to be borne by the debtor. 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."
msgstr "Según el acuerdo de servicio: los costes de la transacción se aplicarán siguiendo las reglas acordadas en el nivel de servicio y/o en el esquema (las remesas SEPA Core deben usar esta opción). Compartidos: los costes de la transacción en la parte del acreedor están a cargo del acreedor, y los costes de la transacción del lado del deudor estarán a cargo del deudor. A cargo del acreedor: todos los costes de la transacción estarán a cargo del acreedor. A cargo del deudor: Todos los costes de la transacción estarán a cargo del deudor."
#. module: account_banking_sepa_credit_transfer
#: help:banking.export.sepa.wizard,charge_bearer:0
msgid "Following service level : transaction charges are to be applied following the rules agreed in the service level and/or scheme (SEPA Core messages must use this). Shared : transaction charges on the debtor side are to be borne by the debtor, transaction charges on the creditor side are to be borne by the creditor. 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."
msgstr "Según el acuerdo de servicio: los costes de la transacción se aplicarán siguiendo las reglas acordadas en el nivel de servicio y/o en el esquema (las remesas SEPA Core deben usar esta opción). Compartidos: los costes de la transacción en la parte del acreedor están a cargo del acreedor, y los costes de la transacción del lado del deudor estarán a cargo del deudor. A cargo del acreedor: todos los costes de la transacción estarán a cargo del acreedor. A cargo del deudor: Todos los costes de la transacción estarán a cargo del deudor."
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa:account_banking_sepa_credit_transfer.view_banking_export_sepa_form
msgid "General Information"
msgstr "Información general"
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa.wizard:account_banking_sepa_credit_transfer.banking_export_sepa_wizard_view
msgid "Generate"
msgstr "Generar"
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,create_date:0
msgid "Generation Date"
msgstr "Fecha de generación"
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,id:0
#: field:banking.export.sepa.wizard,id:0
msgid "ID"
msgstr "ID"
#. 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 "Si está marcado, el extracto bancario mostrará sólo una línea del haber para todos los adeudos directos del archivo SEPA; si no está marcado, entonces el extracto bancario mostrará una línea por cada adeudo directo del archivo SEPA."
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,write_uid:0
#: field:banking.export.sepa.wizard,write_uid:0
msgid "Last Updated by"
msgstr "Última actualización por"
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,write_date:0
#: field:banking.export.sepa.wizard,write_date:0
msgid "Last Updated on"
msgstr "Última actualización en"
#. module: account_banking_sepa_credit_transfer
#: code:addons/account_banking_sepa_credit_transfer/wizard/export_sepa.py:233
#, python-format
msgid "Missing Bank Account on invoice '%s' (payment order line reference '%s')."
msgstr "Falta la cuenta bancaria en la factura '%s' (línea de pago con referencia '%s')."
#. 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 "Nº de transacciones"
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa:account_banking_sepa_credit_transfer.view_banking_export_sepa_form
#: field:banking.export.sepa,payment_order_ids:0
#: field:banking.export.sepa.wizard,payment_order_ids:0
msgid "Payment Orders"
msgstr "Órdenes de pago"
#. module: account_banking_sepa_credit_transfer
#: code:addons/account_banking_sepa_credit_transfer/wizard/export_sepa.py:125
#, python-format
msgid "Payment Type Code '%s' is not supported. The only Payment Type Codes supported for SEPA Credit Transfers are 'pain.001.001.02', 'pain.001.001.03', 'pain.001.001.04' and 'pain.001.001.05'."
msgstr "El código de tipo de pago '%s' no está soportado. Los únicos código de tipo de pago soportados por las transferencias SEPA son 'pain.001.001.02', 'pain.001.001.03', 'pain.001.001.04' y 'pain.001.001.05'."
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa:account_banking_sepa_credit_transfer.view_banking_export_sepa_form
#: view:banking.export.sepa:account_banking_sepa_credit_transfer.view_banking_export_sepa_tree
msgid "SEPA Credit Transfer"
msgstr "Transferencia SEPA"
#. module: account_banking_sepa_credit_transfer
#: model:ir.actions.act_window,name:account_banking_sepa_credit_transfer.act_banking_export_sepa_payment_order
#: 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 "SEPA Credit Transfer Files"
msgstr "Archivos de transferencias SEPA"
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa.wizard:account_banking_sepa_credit_transfer.banking_export_sepa_wizard_view
msgid "SEPA File Generation"
msgstr "Generación de archivo SEPA"
#. 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 "Archivo SEPA XML"
#. module: account_banking_sepa_credit_transfer
#: model:ir.model,name:account_banking_sepa_credit_transfer.model_banking_export_sepa
msgid "SEPA export"
msgstr "Exportación de SEPA"
#. module: account_banking_sepa_credit_transfer
#: selection:banking.export.sepa,state:0
msgid "Sent"
msgstr "Enviado"
#. module: account_banking_sepa_credit_transfer
#: selection:banking.export.sepa,charge_bearer:0
#: selection:banking.export.sepa.wizard,charge_bearer:0
msgid "Shared"
msgstr "Compartidos"
#. module: account_banking_sepa_credit_transfer
#: field:banking.export.sepa,state:0
#: field:banking.export.sepa.wizard,state:0
msgid "State"
msgstr "Estado"
#. 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 "Importe total"
#. module: account_banking_sepa_credit_transfer
#: view:banking.export.sepa.wizard:account_banking_sepa_credit_transfer.banking_export_sepa_wizard_view
msgid "Validate"
msgstr "Validar"

View File

@@ -20,5 +20,4 @@
#
##############################################################################
from . import wizard
from . import account_banking_sepa

View File

@@ -0,0 +1,76 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# SEPA Credit Transfer module for OpenERP
# Copyright (C) 2010-2013 Akretion (http://www.akretion.com)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, fields, api
from openerp.addons.decimal_precision import decimal_precision as dp
from unidecode import unidecode
class BankingExportSepa(models.Model):
"""SEPA export"""
_name = 'banking.export.sepa'
_description = __doc__
_rec_name = 'filename'
@api.one
def _generate_filename(self):
ref = self.payment_order_ids[0].reference
if ref:
label = unidecode(ref.replace('/', '-'))
else:
label = 'error'
self.filename = 'sct_%s.xml' % label
payment_order_ids = fields.Many2many(
comodel_name='payment.order', column1='banking_export_sepa_id',
column2='account_order_id', relation='account_payment_order_sepa_rel',
string='Payment Orders', readonly=True)
nb_transactions = fields.Integer(string='Number of Transactions',
readonly=True)
total_amount = fields.Float(string='Total Amount',
digits_compute=dp.get_precision('Account'),
readonly=True)
batch_booking = fields.Boolean(
'Batch Booking', readonly=True,
help="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.")
charge_bearer = fields.Selection(
[('SLEV', 'Following Service Level'),
('SHAR', 'Shared'),
('CRED', 'Borne by Creditor'),
('DEBT', 'Borne by Debtor')], string='Charge Bearer', readonly=True,
help="Following service level : transaction charges are to be applied "
"following the rules agreed in the service level and/or scheme "
"(SEPA Core messages must use this). Shared : transaction "
"charges on the creditor side are to be borne by the creditor, "
"transaction charges on the debtor side are to be borne by the "
"debtor. 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.")
create_date = fields.Datetime('Generation Date', readonly=True)
file = fields.Binary('SEPA XML File', readonly=True)
filename = fields.Char(string='Filename', size=256, readonly=True,
compute=_generate_filename)
state = fields.Selection([('draft', 'Draft'), ('sent', 'Sent')],
string='State', readonly=True, default='draft')

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -23,40 +23,39 @@
from openerp.osv import orm, fields
from openerp.tools.translate import _
from openerp import netsvc
from openerp import workflow
from lxml import etree
class banking_export_sepa_wizard(orm.TransientModel):
class BankingExportSepaWizard(orm.TransientModel):
_name = 'banking.export.sepa.wizard'
_inherit = ['banking.export.pain']
_description = 'Export SEPA Credit Transfer File'
_columns = {
'state': fields.selection([
('create', 'Create'),
('finish', 'Finish'),
], 'State', readonly=True),
'state': fields.selection([('create', 'Create'),
('finish', 'Finish')], 'State',
readonly=True),
'batch_booking': fields.boolean(
'Batch Booking',
help="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."),
'charge_bearer': fields.selection([
('SLEV', 'Following Service Level'),
('SHAR', 'Shared'),
('CRED', 'Borne by Creditor'),
('DEBT', 'Borne by Debtor'),
], 'Charge Bearer', required=True,
'charge_bearer': fields.selection(
[('SLEV', 'Following Service Level'),
('SHAR', 'Shared'),
('CRED', 'Borne by Creditor'),
('DEBT', 'Borne by Debtor')], 'Charge Bearer', required=True,
help="Following service level : transaction charges are to be "
"applied following the rules agreed in the service level and/or "
"scheme (SEPA Core messages must use this). Shared : transaction "
"charges on the debtor side are to be borne by the debtor, "
"transaction charges on the creditor side are to be borne by "
"the creditor. 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."),
"applied following the rules agreed in the service level "
"and/or scheme (SEPA Core messages must use this). Shared : "
"transaction charges on the debtor side are to be borne by "
"the debtor, transaction charges on the creditor side are to "
"be borne by the creditor. 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."),
'nb_transactions': fields.related(
'file_id', 'nb_transactions', type='integer',
string='Number of Transactions', readonly=True),
@@ -73,25 +72,23 @@ class banking_export_sepa_wizard(orm.TransientModel):
'payment_order_ids': fields.many2many(
'payment.order', 'wiz_sepa_payorders_rel', 'wizard_id',
'payment_order_id', 'Payment Orders', readonly=True),
}
}
_defaults = {
'charge_bearer': 'SLEV',
'state': 'create',
}
}
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(banking_export_sepa_wizard, self).create(
return super(BankingExportSepaWizard, self).create(
cr, uid, vals, context=context)
def create_sepa(self, cr, uid, ids, context=None):
'''
Creates the SEPA Credit Transfer file. That's the important code !
'''
"""Creates the SEPA Credit Transfer file. That's the important code!"""
if context is None:
context = {}
sepa_export = self.browse(cr, uid, ids[0], context=context)
@@ -122,16 +119,14 @@ class banking_export_sepa_wizard(orm.TransientModel):
bic_xml_tag = 'BICFI'
name_maxsize = 140
root_xml_tag = 'CstmrCdtTrfInitn'
else:
raise orm.except_orm(
_('Error:'),
_("Payment Type Code '%s' is not supported. The only "
"Payment Type Codes supported for SEPA Credit Transfers "
"are 'pain.001.001.02', 'pain.001.001.03', "
"'pain.001.001.04' and 'pain.001.001.05'.")
% pain_flavor)
"Payment Type Codes supported for SEPA Credit Transfers "
"are 'pain.001.001.02', 'pain.001.001.03', "
"'pain.001.001.04' and 'pain.001.001.05'.") %
pain_flavor)
gen_args = {
'bic_xml_tag': bic_xml_tag,
'name_maxsize': name_maxsize,
@@ -144,22 +139,18 @@ class banking_export_sepa_wizard(orm.TransientModel):
'account_banking_sepa_credit_transfer/data/%s.xsd'
% pain_flavor,
}
pain_ns = {
'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
None: 'urn:iso:std:iso:20022:tech:xsd:%s' % pain_flavor,
}
}
xml_root = etree.Element('Document', nsmap=pain_ns)
pain_root = etree.SubElement(xml_root, root_xml_tag)
pain_03_to_05 = \
['pain.001.001.03', 'pain.001.001.04', 'pain.001.001.05']
# A. Group header
group_header_1_0, nb_of_transactions_1_6, control_sum_1_7 = \
self.generate_group_header_block(
cr, uid, pain_root, gen_args, context=context)
transactions_count_1_6 = 0
total_amount = 0.0
amount_control_sum_1_7 = 0.0
@@ -187,7 +178,6 @@ class banking_export_sepa_wizard(orm.TransientModel):
self.pool['payment.line'].write(
cr, uid, line.id,
{'date': requested_date}, context=context)
for (requested_date, priority), lines in lines_per_group.items():
# B. Payment info
payment_info_2_0, nb_of_transactions_2_4, control_sum_2_5 = \
@@ -200,7 +190,6 @@ class banking_export_sepa_wizard(orm.TransientModel):
'priority': priority,
'requested_date': requested_date,
}, gen_args, context=context)
self.generate_party_block(
cr, uid, payment_info_2_0, 'Dbtr', 'B',
'sepa_export.payment_order_ids[0].mode.bank_id.partner_id.'
@@ -209,10 +198,8 @@ class banking_export_sepa_wizard(orm.TransientModel):
'sepa_export.payment_order_ids[0].mode.bank_id.bank.bic',
{'sepa_export': sepa_export},
gen_args, context=context)
charge_bearer_2_24 = etree.SubElement(payment_info_2_0, 'ChrgBr')
charge_bearer_2_24.text = sepa_export.charge_bearer
transactions_count_2_4 = 0
amount_control_sum_2_5 = 0.0
for line in lines:
@@ -240,7 +227,6 @@ class banking_export_sepa_wizard(orm.TransientModel):
instructed_amount_2_43.text = '%.2f' % line.amount_currency
amount_control_sum_1_7 += line.amount_currency
amount_control_sum_2_5 += line.amount_currency
if not line.bank_id:
raise orm.except_orm(
_('Error:'),
@@ -252,48 +238,40 @@ class banking_export_sepa_wizard(orm.TransientModel):
'C', 'line.partner_id.name', 'line.bank_id.acc_number',
'line.bank_id.bank.bic', {'line': line}, gen_args,
context=context)
self.generate_remittance_info_block(
cr, uid, credit_transfer_transaction_info_2_27,
line, gen_args, context=context)
if pain_flavor in pain_03_to_05:
nb_of_transactions_2_4.text = str(transactions_count_2_4)
control_sum_2_5.text = '%.2f' % amount_control_sum_2_5
if pain_flavor in pain_03_to_05:
nb_of_transactions_1_6.text = str(transactions_count_1_6)
control_sum_1_7.text = '%.2f' % amount_control_sum_1_7
else:
nb_of_transactions_1_6.text = str(transactions_count_1_6)
control_sum_1_7.text = '%.2f' % amount_control_sum_1_7
return self.finalize_sepa_file_creation(
cr, uid, ids, xml_root, total_amount, transactions_count_1_6,
gen_args, context=context)
def cancel_sepa(self, cr, uid, ids, context=None):
'''
Cancel the SEPA file: just drop the file
'''
"""Cancel the SEPA file: just drop the file"""
sepa_export = self.browse(cr, uid, ids[0], context=context)
self.pool.get('banking.export.sepa').unlink(
self.pool['banking.export.sepa'].unlink(
cr, uid, sepa_export.file_id.id, context=context)
return {'type': 'ir.actions.act_window_close'}
def save_sepa(self, cr, uid, ids, context=None):
'''
Save the SEPA file: send the done signal to all payment
"""Save the SEPA file: 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)
self.pool.get('banking.export.sepa').write(
self.pool['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, 'done', cr)
workflow.trg_validate(uid, 'payment.order', order.id, 'done', cr)
return {'type': 'ir.actions.act_window_close'}

View File

@@ -20,6 +20,5 @@
#
##############################################################################
from . import company
from . import models
from . import wizard
from . import account_banking_sdd

View File

@@ -26,47 +26,40 @@
'license': 'AGPL-3',
'author': 'Akretion',
'website': 'http://www.akretion.com',
'contributors': ['Pedro M. Baeza <pedro.baeza@serviciosbaeza.com>'],
'category': 'Banking addons',
'depends': ['account_direct_debit', 'account_banking_pain_base'],
'depends': [
'account_direct_debit',
'account_banking_pain_base',
'account_banking_mandate',
],
'external_dependencies': {
'python': ['unidecode', 'lxml'],
},
'data': [
'security/original_mandate_required_security.xml',
'account_banking_sdd_view.xml',
'sdd_mandate_view.xml',
'res_partner_bank_view.xml',
'account_payment_view.xml',
'company_view.xml',
'mandate_expire_cron.xml',
'account_invoice_view.xml',
'views/account_banking_sdd_view.xml',
'views/account_banking_mandate_view.xml',
'views/res_company_view.xml',
'wizard/export_sdd_view.xml',
'data/mandate_expire_cron.xml',
'data/payment_type_sdd.xml',
'data/mandate_reference_sequence.xml',
'security/original_mandate_required_security.xml',
'security/ir.model.access.csv',
],
'demo': ['sepa_direct_debit_demo.xml'],
'demo': ['demo/sepa_direct_debit_demo.xml'],
'description': '''
Module to export direct debit payment orders in SEPA XML file format.
SEPA PAIN (PAyment INitiation) is the new european standard for
Customer-to-Bank payment instructions.
This module implements SEPA Direct Debit (SDD), more specifically PAIN
versions 008.001.02, 008.001.03 and 008.001.04.
It is part of the ISO 20022 standard, available on http://www.iso20022.org.
Customer-to-Bank payment instructions. This module implements SEPA Direct
Debit (SDD), more specifically PAIN versions 008.001.02, 008.001.03 and
008.001.04. It is part of the ISO 20022 standard, available on
http://www.iso20022.org.
The Implementation Guidelines for SEPA Direct Debit published by the European
Payments Council (http://http://www.europeanpaymentscouncil.eu) use PAIN
version 008.001.02. So if you don't know which version your bank supports,
you should try version 008.001.02 first.
This module uses the framework provided by the banking addons,
cf https://www.github.com/OCA/banking-addons
Please contact Alexis de Lattre from Akretion <alexis.delattre@akretion.com>
for any help or question about this module.
version 008.001.02. So if you don't know which version your bank supports, you
should try version 008.001.02 first.
''',
'active': False,
'installable': False,
'installable': True,
}

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2013 Akretion (http://www.akretion.com/)
@author Alexis de Lattre <alexis.delattre@akretion.com>
The licence is in the file __openerp__.py
-->
<openerp>
<data noupdate="1">
<record id="sdd_mandate_expire_cron" model="ir.cron">
<field name="name">Set SEPA Direct Debit Mandates to Expired</field>
<field name="active" eval="True"/>
<field name="user_id" ref="base.user_root"/>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field name="doall" eval="False"/>
<field name="model" eval="'account.banking.mandate'"/>
<field name="function" eval="'_sdd_mandate_set_state_to_expired'" />
<field name="args" eval="'(None, )'"/>
</record>
</data>
</openerp>

Some files were not shown because too many files have changed in this diff Show More