From ba0375a615bff5912c26449c7036a9b8bfb56e72 Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Wed, 8 Oct 2014 03:34:21 +0200 Subject: [PATCH] [ADD] account_banking_mandate, spliting functionality in two modules --- .../__init__.py | 52 ++-- account_banking_mandate/__openerp__.py | 57 ++++ .../data/mandate_reference_sequence.xml | 20 ++ account_banking_mandate/models/__init__.py | 26 ++ .../models/account_banking_mandate.py | 154 +++++++++ .../models/account_invoice.py | 65 ++-- .../models/payment_line.py | 76 +++++ .../models/res_partner_bank.py | 34 ++ .../security/ir.model.access.csv | 3 + .../test/banking_mandate.yml | 36 +++ .../views/account_banking_mandate_view.xml | 122 ++++++++ .../views/account_invoice_view.xml | 4 +- .../views/account_payment_view.xml | 8 +- .../views/res_partner_bank_view.xml | 20 +- .../__openerp__.py | 6 +- .../data/mandate_expire_cron.xml | 30 +- .../data/mandate_reference_sequence.xml | 21 -- .../demo/sepa_direct_debit_demo.xml | 2 +- .../models/__init__.py | 5 +- .../models/account_banking_mandate.py | 145 +++++++++ .../models/payment_line.py | 74 ----- .../models/sdd_mandate.py | 291 ------------------ .../security/ir.model.access.csv | 2 - .../views/account_banking_mandate_view.xml | 117 +++++++ .../views/sdd_mandate_view.xml | 153 --------- account_payment_partner/i18n/fr.po | 57 ++++ 26 files changed, 935 insertions(+), 645 deletions(-) rename account_banking_sepa_direct_debit/models/res_partner_bank.py => account_banking_mandate/__init__.py (69%) create mode 100644 account_banking_mandate/__openerp__.py create mode 100644 account_banking_mandate/data/mandate_reference_sequence.xml create mode 100644 account_banking_mandate/models/__init__.py create mode 100644 account_banking_mandate/models/account_banking_mandate.py rename {account_banking_sepa_direct_debit => account_banking_mandate}/models/account_invoice.py (75%) create mode 100644 account_banking_mandate/models/payment_line.py create mode 100644 account_banking_mandate/models/res_partner_bank.py create mode 100644 account_banking_mandate/security/ir.model.access.csv create mode 100644 account_banking_mandate/test/banking_mandate.yml create mode 100644 account_banking_mandate/views/account_banking_mandate_view.xml rename {account_banking_sepa_direct_debit => account_banking_mandate}/views/account_invoice_view.xml (69%) rename {account_banking_sepa_direct_debit => account_banking_mandate}/views/account_payment_view.xml (59%) rename {account_banking_sepa_direct_debit => account_banking_mandate}/views/res_partner_bank_view.xml (60%) delete mode 100644 account_banking_sepa_direct_debit/data/mandate_reference_sequence.xml create mode 100644 account_banking_sepa_direct_debit/models/account_banking_mandate.py delete mode 100644 account_banking_sepa_direct_debit/models/payment_line.py delete mode 100644 account_banking_sepa_direct_debit/models/sdd_mandate.py create mode 100644 account_banking_sepa_direct_debit/views/account_banking_mandate_view.xml delete mode 100644 account_banking_sepa_direct_debit/views/sdd_mandate_view.xml create mode 100644 account_payment_partner/i18n/fr.po diff --git a/account_banking_sepa_direct_debit/models/res_partner_bank.py b/account_banking_mandate/__init__.py similarity index 69% rename from account_banking_sepa_direct_debit/models/res_partner_bank.py rename to account_banking_mandate/__init__.py index 132a4fa42..1feaa8f2d 100644 --- a/account_banking_sepa_direct_debit/models/res_partner_bank.py +++ b/account_banking_mandate/__init__.py @@ -1,30 +1,22 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# SEPA Direct Debit module for OpenERP -# Copyright (C) 2013 Akretion (http://www.akretion.com) -# @author: Alexis de Lattre -# -# 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 . -# -############################################################################## - -from openerp import models, fields - - -class ResPartnerBank(models.Model): - _inherit = 'res.partner.bank' - - sdd_mandate_ids = fields.One2many( - 'sdd.mandate', 'partner_bank_id', string='SEPA Direct Debit Mandates') +# -*- encoding: utf-8 -*- +############################################################################## +# +# Mandate module for openERP +# Copyright (C) 2014 Compassion CH (http://www.compassion.ch) +# @author: Cyril Sester +# +# 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 . +# +############################################################################## +from . import models diff --git a/account_banking_mandate/__openerp__.py b/account_banking_mandate/__openerp__.py new file mode 100644 index 000000000..5f825eaa9 --- /dev/null +++ b/account_banking_mandate/__openerp__.py @@ -0,0 +1,57 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# Mandate module for openERP +# Copyright (C) 2014 Compassion CH (http://www.compassion.ch) +# @author: Cyril Sester , +# Alexis de Lattre +# +# 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 . +# +############################################################################## +{ + '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 '], + '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, +} diff --git a/account_banking_mandate/data/mandate_reference_sequence.xml b/account_banking_mandate/data/mandate_reference_sequence.xml new file mode 100644 index 000000000..9a51db944 --- /dev/null +++ b/account_banking_mandate/data/mandate_reference_sequence.xml @@ -0,0 +1,20 @@ + + + + + + + DD Mandate Reference + account.banking.mandate + + + + DD Mandate Reference + account.banking.mandate + BM + + + + + + diff --git a/account_banking_mandate/models/__init__.py b/account_banking_mandate/models/__init__.py new file mode 100644 index 000000000..480270819 --- /dev/null +++ b/account_banking_mandate/models/__init__.py @@ -0,0 +1,26 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# Mandate module for openERP +# Copyright (C) 2014 Compassion CH (http://www.compassion.ch) +# @author: Cyril Sester , +# Alexis de Lattre +# +# 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 . +# +############################################################################## +from . import account_banking_mandate +from . import account_invoice +from . import res_partner_bank +from . import payment_line diff --git a/account_banking_mandate/models/account_banking_mandate.py b/account_banking_mandate/models/account_banking_mandate.py new file mode 100644 index 000000000..f372f1192 --- /dev/null +++ b/account_banking_mandate/models/account_banking_mandate.py @@ -0,0 +1,154 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# Mandate module for openERP +# Copyright (C) 2014 Compassion CH (http://www.compassion.ch) +# @author: Cyril Sester , +# Alexis de Lattre +# +# 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 . +# +############################################################################## + +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', relation='partner_bank_id.partner_id', + string='Partner', readonly=True, 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 diff --git a/account_banking_sepa_direct_debit/models/account_invoice.py b/account_banking_mandate/models/account_invoice.py similarity index 75% rename from account_banking_sepa_direct_debit/models/account_invoice.py rename to account_banking_mandate/models/account_invoice.py index eee2b7757..a4e43eba6 100644 --- a/account_banking_sepa_direct_debit/models/account_invoice.py +++ b/account_banking_mandate/models/account_invoice.py @@ -1,32 +1,33 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# SEPA Direct Debit module for OpenERP -# Copyright (C) 2013 Akretion (http://www.akretion.com) -# @author: Alexis de Lattre -# -# 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 . -# -############################################################################## - -from openerp import models, fields - - -class AccountInvoice(models.Model): - _inherit = 'account.invoice' - - sdd_mandate_id = fields.Many2one( - 'sdd.mandate', string='SEPA Direct Debit Mandate', - domain=[('state', '=', 'valid')], readonly=True, - states={'draft': [('readonly', False)]}) +# -*- encoding: utf-8 -*- +############################################################################## +# +# Mandate module for openERP +# Copyright (C) 2014 Compassion CH (http://www.compassion.ch) +# @author: Cyril Sester , +# Alexis de Lattre +# +# 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 . +# +############################################################################## + +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)]}) diff --git a/account_banking_mandate/models/payment_line.py b/account_banking_mandate/models/payment_line.py new file mode 100644 index 000000000..9c6c00dce --- /dev/null +++ b/account_banking_mandate/models/payment_line.py @@ -0,0 +1,76 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# Mandate module for openERP +# Copyright (C) 2014 Compassion CH (http://www.compassion.ch) +# @author: Cyril Sester , +# Alexis de Lattre +# +# 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 . +# +############################################################################## + +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.id + return super(PaymentLine, self).create(vals) + + @api.one + @api.constrains('mandate_id', 'bank_id') + def _check_mandate_bank_link(self, cr, uid, ids): + 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])) diff --git a/account_banking_mandate/models/res_partner_bank.py b/account_banking_mandate/models/res_partner_bank.py new file mode 100644 index 000000000..ecb1e944c --- /dev/null +++ b/account_banking_mandate/models/res_partner_bank.py @@ -0,0 +1,34 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# Mandate module for openERP +# Copyright (C) 2014 Compassion CH (http://www.compassion.ch) +# @author: Cyril Sester , +# Alexis de Lattre +# +# 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 . +# +############################################################################## + +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') diff --git a/account_banking_mandate/security/ir.model.access.csv b/account_banking_mandate/security/ir.model.access.csv new file mode 100644 index 000000000..f89130b3f --- /dev/null +++ b/account_banking_mandate/security/ir.model.access.csv @@ -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 \ No newline at end of file diff --git a/account_banking_mandate/test/banking_mandate.yml b/account_banking_mandate/test/banking_mandate.yml new file mode 100644 index 000000000..d7291cc99 --- /dev/null +++ b/account_banking_mandate/test/banking_mandate.yml @@ -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')]) diff --git a/account_banking_mandate/views/account_banking_mandate_view.xml b/account_banking_mandate/views/account_banking_mandate_view.xml new file mode 100644 index 000000000..fbb942b10 --- /dev/null +++ b/account_banking_mandate/views/account_banking_mandate_view.xml @@ -0,0 +1,122 @@ + + + + + + view.mandate.form + account.banking.mandate + +
+
+
+ +
+

+ +

+
+ + + + + + + + + + + +
+
+ + +
+
+
+
+ + + view.mandate.tree + account.banking.mandate + + + + + + + + + + + + + + view.mandate.search + account.banking.mandate + + + + + + + + + + + + + Banking Mandates + account.banking.mandate + form + tree,form + +

+ Click to create a new Banking Mandate. +

+ 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. +

+
+
+ + + + + + Mandate Validated + account.banking.mandate + + Banking Mandate Validated + + + + Mandate Expired + account.banking.mandate + + Banking Mandate has Expired + + + + Mandate Cancelled + account.banking.mandate + + Banking Mandate Cancelled + +
+
diff --git a/account_banking_sepa_direct_debit/views/account_invoice_view.xml b/account_banking_mandate/views/account_invoice_view.xml similarity index 69% rename from account_banking_sepa_direct_debit/views/account_invoice_view.xml rename to account_banking_mandate/views/account_invoice_view.xml index 2ca480e54..a21e83857 100644 --- a/account_banking_sepa_direct_debit/views/account_invoice_view.xml +++ b/account_banking_mandate/views/account_invoice_view.xml @@ -8,12 +8,12 @@ - add.sdd.mandate.on.customer.invoice.form + add.mandate.on.customer.invoice.form account.invoice - + diff --git a/account_banking_sepa_direct_debit/views/account_payment_view.xml b/account_banking_mandate/views/account_payment_view.xml similarity index 59% rename from account_banking_sepa_direct_debit/views/account_payment_view.xml rename to account_banking_mandate/views/account_payment_view.xml index 74098c44e..39ec86953 100644 --- a/account_banking_sepa_direct_debit/views/account_payment_view.xml +++ b/account_banking_mandate/views/account_payment_view.xml @@ -7,17 +7,17 @@ - - sdd.payment.order.form + + mandate.payment.order.form payment.order - + - + diff --git a/account_banking_sepa_direct_debit/views/res_partner_bank_view.xml b/account_banking_mandate/views/res_partner_bank_view.xml similarity index 60% rename from account_banking_sepa_direct_debit/views/res_partner_bank_view.xml rename to account_banking_mandate/views/res_partner_bank_view.xml index 0b32e9f1c..572fa766e 100644 --- a/account_banking_sepa_direct_debit/views/res_partner_bank_view.xml +++ b/account_banking_mandate/views/res_partner_bank_view.xml @@ -7,39 +7,39 @@ - - sdd.mandate.res.partner.bank.form + + mandate.res.partner.bank.form res.partner.bank - - + + - - sdd.mandate.res.partner.bank.tree + + mandate.res.partner.bank.tree res.partner.bank - + - - sdd.mandate.partner.form + + mandate.partner.form res.partner - + diff --git a/account_banking_sepa_direct_debit/__openerp__.py b/account_banking_sepa_direct_debit/__openerp__.py index 5f222df80..c5fc42fb4 100644 --- a/account_banking_sepa_direct_debit/__openerp__.py +++ b/account_banking_sepa_direct_debit/__openerp__.py @@ -34,15 +34,11 @@ }, 'data': [ 'views/account_banking_sdd_view.xml', - 'views/sdd_mandate_view.xml', - 'views/res_partner_bank_view.xml', - 'views/account_payment_view.xml', + 'views/account_banking_mandate_view.xml', 'views/res_company_view.xml', - 'views/account_invoice_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', ], diff --git a/account_banking_sepa_direct_debit/data/mandate_expire_cron.xml b/account_banking_sepa_direct_debit/data/mandate_expire_cron.xml index 4cb0693d2..79aa05689 100644 --- a/account_banking_sepa_direct_debit/data/mandate_expire_cron.xml +++ b/account_banking_sepa_direct_debit/data/mandate_expire_cron.xml @@ -7,20 +7,18 @@ --> - - - - Set SEPA Direct Debit Mandates to Expired - - - 1 - days - -1 - - - - - - - + + + Set SEPA Direct Debit Mandates to Expired + + + 1 + days + -1 + + + + + + diff --git a/account_banking_sepa_direct_debit/data/mandate_reference_sequence.xml b/account_banking_sepa_direct_debit/data/mandate_reference_sequence.xml deleted file mode 100644 index 68075d526..000000000 --- a/account_banking_sepa_direct_debit/data/mandate_reference_sequence.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - SDD Mandate Reference - sdd.mandate.reference - - - - SDD Mandate Reference - sdd.mandate.reference - RUM - - - - - - - diff --git a/account_banking_sepa_direct_debit/demo/sepa_direct_debit_demo.xml b/account_banking_sepa_direct_debit/demo/sepa_direct_debit_demo.xml index 220261088..041082d76 100644 --- a/account_banking_sepa_direct_debit/demo/sepa_direct_debit_demo.xml +++ b/account_banking_sepa_direct_debit/demo/sepa_direct_debit_demo.xml @@ -15,7 +15,7 @@ FR78ZZZ424242 - + recurrent first diff --git a/account_banking_sepa_direct_debit/models/__init__.py b/account_banking_sepa_direct_debit/models/__init__.py index 36b8b4b56..274855e14 100644 --- a/account_banking_sepa_direct_debit/models/__init__.py +++ b/account_banking_sepa_direct_debit/models/__init__.py @@ -20,9 +20,6 @@ # ############################################################################## -from . import account_invoice from . import banking_export_sdd -from . import payment_line from . import res_company -from . import res_partner_bank -from . import sdd_mandate +from . import account_banking_mandate diff --git a/account_banking_sepa_direct_debit/models/account_banking_mandate.py b/account_banking_sepa_direct_debit/models/account_banking_mandate.py new file mode 100644 index 000000000..4df706378 --- /dev/null +++ b/account_banking_sepa_direct_debit/models/account_banking_mandate.py @@ -0,0 +1,145 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# SEPA Direct Debit module for OpenERP +# Copyright (C) 2013 Akretion (http://www.akretion.com) +# @author: Alexis de Lattre +# +# 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 . +# +############################################################################## + +from openerp import models, fields, api, exceptions, _ +from datetime import datetime +from dateutil.relativedelta import relativedelta +import logging + +NUMBER_OF_UNUSED_MONTHS_BEFORE_EXPIRY = 36 + +logger = logging.getLogger(__name__) + + +class AccountBankingMandate(models.Model): + """SEPA Direct Debit Mandate""" + _inherit = 'account.banking.mandate' + _track = { + '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', + } + } + + type = fields.Selection([('recurrent', 'Recurrent'), + ('oneoff', 'One-Off')], + string='Type of Mandate', required=True, + track_visibility='always') + recurrent_sequence_type = fields.Selection( + [('first', 'First'), + ('recurring', 'Recurring'), + ('final', 'Final')], + string='Sequence Type for Next Debit', track_visibility='onchange', + help="This field is only used for Recurrent mandates, not for " + "One-Off mandates.", default="first") + sepa_migrated = fields.Boolean( + string='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.", default=True) + original_mandate_identification = fields.Char( + string='Original Mandate Identification', 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.") + scheme = fields.Selection([('CORE', 'Basic (CORE)'), + ('B2B', 'Enterprise (B2B)')], + string='Scheme', required=True, default="CORE") + + @api.one + @api.constrains('type', 'recurrent_sequence_type') + def _check_recurring_type(self): + if (self.type == 'recurrent' + and not self.recurrent_sequence_type): + raise exceptions.Warning( + _("The recurrent mandate '%s' must have a sequence type.") + % self.unique_mandate_reference) + + @api.one + @api.constrains('type', 'recurrent_sequence_type', 'sepa_migrated') + def _check_migrated_to_sepa(self): + if (self.type == 'recurrent' and not self.sepa_migrated + and self.recurrent_sequence_type != 'first'): + raise exceptions.Warning( + _("The recurrent mandate '%s' which is not marked as " + "'Migrated to SEPA' must have its recurrent sequence type " + "set to 'First'.") % self.unique_mandate_reference) + + @api.one + @api.constrains('type', 'original_mandate_identification', 'sepa_migrated') + def _check_original_mandate_identification(self): + if (self.type == 'recurrent' and not self.sepa_migrated + and not self.original_mandate_identification): + raise exceptions.Warning( + _("You must set the 'Original Mandate Identification' on the " + "recurrent mandate '%s' which is not marked as 'Migrated to " + "SEPA'.") % self.unique_mandate_reference) + + @api.one + @api.onchange('partner_bank_id') + def mandate_partner_bank_change(self): + super(AccountBankingMandate, self).mandate_partner_bank_change() + res = {} + if (self.state == 'valid' and self.partner_bank_id + and self.type == 'recurrent' + and self.recurrent_sequence_type != 'first'): + self.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 + + @api.multi + def _sdd_mandate_set_state_to_expired(self): + 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_mandates = self.search( + ['|', + ('last_debit_date', '=', False), + ('last_debit_date', '<=', expire_limit_date_str), + ('state', '=', 'valid'), + ('signature_date', '<=', expire_limit_date_str)]) + if expired_mandates: + expired_mandates.write({'state': 'expired'}) + logger.info( + 'The following SDD Mandate IDs has been set to expired: %s' + % expired_mandates.ids) + else: + logger.info('0 SDD Mandates must be set to Expired') + return True diff --git a/account_banking_sepa_direct_debit/models/payment_line.py b/account_banking_sepa_direct_debit/models/payment_line.py deleted file mode 100644 index 31c47bd89..000000000 --- a/account_banking_sepa_direct_debit/models/payment_line.py +++ /dev/null @@ -1,74 +0,0 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# SEPA Direct Debit module for OpenERP -# Copyright (C) 2013 Akretion (http://www.akretion.com) -# @author: Alexis de Lattre -# -# 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 . -# -############################################################################## - -from openerp import models, fields, api, exceptions, _ - - -class PaymentLine(models.Model): - _inherit = 'payment.line' - - sdd_mandate_id = fields.Many2one( - 'sdd.mandate', string='SEPA Direct Debit Mandate', - domain=[('state', '=', 'valid')]) - - 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 not vals: - vals = {} - partner_bank_id = vals.get('bank_id') - if (self.env.context.get('search_payment_order_type') == 'debit' - and 'sdd_mandate_id' not in vals): - if vals.get('move_line_id'): - line = self.env['account.move.line'].browse( - vals['move_line_id']) - 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: - mandates = self.env['sdd.mandate'].search( - [('partner_bank_id', '=', partner_bank_id), - ('state', '=', 'valid')]) - if mandates: - vals['sdd_mandate_id'] = mandates.ids[0] - return super(PaymentLine, self).create(vals) - - @api.one - @api.constrains('sdd_mandate_id', 'bank_id') - def _check_mandate_bank_link(self): - if (self.sdd_mandate_id and self.bank_id - and self.sdd_mandate_id.partner_bank_id.id != - self.bank_id.id): - raise exceptions.Warning( - _('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').") % - (self.name, - self.bank_id.name_get()[0][1], - self.sdd_mandate_id.unique_mandate_reference, - self.sdd_mandate_id.partner_bank_id.name_get()[0][1])) diff --git a/account_banking_sepa_direct_debit/models/sdd_mandate.py b/account_banking_sepa_direct_debit/models/sdd_mandate.py deleted file mode 100644 index ebee316d2..000000000 --- a/account_banking_sepa_direct_debit/models/sdd_mandate.py +++ /dev/null @@ -1,291 +0,0 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# SEPA Direct Debit module for OpenERP -# Copyright (C) 2013 Akretion (http://www.akretion.com) -# @author: Alexis de Lattre -# -# 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 . -# -############################################################################## - -from openerp.osv import orm, fields -from openerp.tools.translate import _ -from datetime import datetime -from dateutil.relativedelta import relativedelta -import logging - -NUMBER_OF_UNUSED_MONTHS_BEFORE_EXPIRY = 36 - -logger = logging.getLogger(__name__) - - -class SddMandate(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."), - 'scheme': fields.selection([('CORE', 'Basic (CORE)'), - ('B2B', 'Enterprise (B2B)')], - 'Scheme', required=True), - } - - _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, - 'scheme': 'CORE', - } - - _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(SddMandate, 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 diff --git a/account_banking_sepa_direct_debit/security/ir.model.access.csv b/account_banking_sepa_direct_debit/security/ir.model.access.csv index cf78ffb59..0cd579511 100644 --- a/account_banking_sepa_direct_debit/security/ir.model.access.csv +++ b/account_banking_sepa_direct_debit/security/ir.model.access.csv @@ -1,4 +1,2 @@ "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" "access_banking_export_sdd","Full access on banking.export.sdd","model_banking_export_sdd","account_payment.group_account_payment",1,1,1,1 -"access_sdd_mandate","Full access on sdd.mandate","model_sdd_mandate","account_payment.group_account_payment",1,1,1,1 -"access_sdd_mandate_read","Read access on sdd.mandate","model_sdd_mandate","base.group_user",1,0,0,0 diff --git a/account_banking_sepa_direct_debit/views/account_banking_mandate_view.xml b/account_banking_sepa_direct_debit/views/account_banking_mandate_view.xml new file mode 100644 index 000000000..eba8ae28b --- /dev/null +++ b/account_banking_sepa_direct_debit/views/account_banking_mandate_view.xml @@ -0,0 +1,117 @@ + + + + + + + sdd.mandate.form + account.banking.mandate + + + + + + + + + + + + + + + + + sdd.mandate.tree + account.banking.mandate + + + + + + + + + + sdd.mandate.search + account.banking.mandate + + + + + + + + + + + SEPA Direct Debit Mandates + account.banking.mandate + form + tree,form + +

+ Click to create a new SEPA Direct Debit Mandate. +

+ 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. +

+
+
+ + + + + sdd.mandate.res.partner.bank.tree + res.partner.bank + + + + SDD Mandates + + + + + + sdd.mandate.partner.form + res.partner + + + + SDD Mandates + + + + + + Sequence Type set to First + account.banking.mandate + + Sequence Type set to First + + + + Sequence Type set to Recurring + account.banking.mandate + + Sequence Type set to Recurring + + + + Sequence Type set to Final + account.banking.mandate + + Sequence Type set to Final + + +
+
diff --git a/account_banking_sepa_direct_debit/views/sdd_mandate_view.xml b/account_banking_sepa_direct_debit/views/sdd_mandate_view.xml deleted file mode 100644 index 4388bd314..000000000 --- a/account_banking_sepa_direct_debit/views/sdd_mandate_view.xml +++ /dev/null @@ -1,153 +0,0 @@ - - - - - - - sdd.mandate.form - sdd.mandate - -
-
-
- -
-

- -

-
- - - - - - - - - - - - - - - - -
-
- - -
-
-
-
- - - sdd.mandate.tree - sdd.mandate - - - - - - - - - - - - - - - sdd.mandate.search - sdd.mandate - - - - - - - - - - - - - - - SEPA Direct Debit Mandates - sdd.mandate - form - tree,form - -

- Click to create a new SEPA Direct Debit Mandate. -

- 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. -

-
-
- - - - - - Mandate Validated - sdd.mandate - - SEPA Direct Debit Mandate Validated - - - - Mandate Expired - sdd.mandate - - SEPA Direct Debit Mandate has Expired - - - - Mandate Cancelled - sdd.mandate - - SEPA Direct Debit Mandate Cancelled - - - - Sequence Type set to First - sdd.mandate - - Sequence Type set to First - - - - Sequence Type set to Recurring - sdd.mandate - - Sequence Type set to Recurring - - - - Sequence Type set to Final - sdd.mandate - - Sequence Type set to Final - - -
-
diff --git a/account_payment_partner/i18n/fr.po b/account_payment_partner/i18n/fr.po new file mode 100644 index 000000000..ca26e532d --- /dev/null +++ b/account_payment_partner/i18n/fr.po @@ -0,0 +1,57 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * account_payment_partner +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 7.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-06-09 23:22+0000\n" +"PO-Revision-Date: 2014-06-09 23:22+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_payment_partner +#: field:res.partner,customer_payment_mode:0 +msgid "Customer Payment Mode" +msgstr "" + +#. module: account_payment_partner +#: model:ir.model,name:account_payment_partner.model_account_invoice +msgid "Invoice" +msgstr "" + +#. module: account_payment_partner +#: model:ir.model,name:account_payment_partner.model_res_partner +msgid "Partner" +msgstr "" + +#. module: account_payment_partner +#: field:account.invoice,payment_mode_id:0 +msgid "Payment Mode" +msgstr "" + +#. module: account_payment_partner +#: help:res.partner,customer_payment_mode:0 +msgid "Select the default payment mode for this customer." +msgstr "" + +#. module: account_payment_partner +#: help:res.partner,supplier_payment_mode:0 +msgid "Select the default payment mode for this supplier." +msgstr "" + +#. module: account_payment_partner +#: field:res.partner,supplier_payment_mode:0 +msgid "Supplier Payment Mode" +msgstr "" + +#. module: account_payment_partner +#: model:ir.model,name:account_payment_partner.model_payment_order_create +msgid "payment.order.create" +msgstr "" +