From dddc7684714bdbcea4717b2d912a9f92048d4def Mon Sep 17 00:00:00 2001 From: Carlos Dauden Date: Tue, 24 Oct 2017 23:38:17 +0200 Subject: [PATCH 1/3] [IMP] account_banking_mandate: Fill payment line with first valid mandate --- account_banking_mandate/README.rst | 3 +- account_banking_mandate/__manifest__.py | 9 +++--- .../models/account_move_line.py | 30 ++++++++++++------- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/account_banking_mandate/README.rst b/account_banking_mandate/README.rst index 3b5d39c9a..e6d6d6ae8 100644 --- a/account_banking_mandate/README.rst +++ b/account_banking_mandate/README.rst @@ -30,7 +30,7 @@ TODO Usage ===== -To use this module, see menu "Accounting > payment > SEPA direct debit mandates" +To use this module, see menu "Accounting > payment > SEPA direct debit mandates" .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas :alt: Try me on Runbot @@ -61,6 +61,7 @@ Contributors * Stéphane Bidoul * Sergio Teruel (Incaser) * Cédric Pigeon +* Carlos Dauden Maintainer ---------- diff --git a/account_banking_mandate/__manifest__.py b/account_banking_mandate/__manifest__.py index 42969b563..7a9004db6 100644 --- a/account_banking_mandate/__manifest__.py +++ b/account_banking_mandate/__manifest__.py @@ -1,13 +1,14 @@ # -*- coding: utf-8 -*- -# © 2014 Compassion CH - Cyril Sester -# © 2014 Tecnativa - Pedro M. Baeza -# © 2015-2016 Akretion - Alexis de Lattre +# Copyright 2014 Compassion CH - Cyril Sester +# Copyright 2014 Tecnativa - Pedro M. Baeza +# Copyright 2015-16 Akretion - Alexis de Lattre +# Copyright 2017 Tecnativa - Carlos Dauden # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { 'name': 'Account Banking Mandate', 'summary': 'Banking mandates', - 'version': '10.0.1.1.2', + 'version': '10.0.1.1.3', 'license': 'AGPL-3', 'author': "Compassion CH, " "Tecnativa, " diff --git a/account_banking_mandate/models/account_move_line.py b/account_banking_mandate/models/account_move_line.py index 8306ca1e4..927ed2fee 100644 --- a/account_banking_mandate/models/account_move_line.py +++ b/account_banking_mandate/models/account_move_line.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- -# © 2016 Akretion (http://www.akretion.com/) +# Copyright Akretion (http://www.akretion.com/) +# Copyright 2017 Carlos Dauden # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import models, fields, api @@ -16,14 +17,21 @@ class AccountMoveLine(models.Model): def _prepare_payment_line_vals(self, payment_order): vals = super(AccountMoveLine, self)._prepare_payment_line_vals( payment_order) - if payment_order.payment_type == 'inbound' and self.mandate_id: - vals['mandate_id'] = self.mandate_id.id - vals['partner_bank_id'] = self.mandate_id.partner_bank_id.id - partner_bank_id = vals.get('partner_bank_id', False) - if partner_bank_id and 'mandate_id' not in vals: - mandate = self.env['account.banking.mandate'].search( - [('partner_bank_id', '=', partner_bank_id), - ('state', '=', 'valid')], limit=1) - if mandate: - vals['mandate_id'] = mandate.id + if payment_order.payment_type != 'inbound': + return vals + mandate = self.mandate_id + if not mandate and vals.get('mandate_id', False): + mandate = mandate.browse(vals['mandate_id']) + if not mandate: + partner_bank_id = vals.get('partner_bank_id', False) + if partner_bank_id: + domain = [('partner_bank_id', '=', partner_bank_id)] + else: + domain = [('partner_id', '=', self.partner_id.id)] + domain.append(('state', '=', 'valid')) + mandate = mandate.search(domain, limit=1) + vals.update({ + 'mandate_id': mandate.id, + 'partner_bank_id': mandate.partner_bank_id.id or partner_bank_id, + }) return vals From 19eac27736b3fb146d347f07f953b975838ac595 Mon Sep 17 00:00:00 2001 From: Carlos Dauden Date: Wed, 2 Aug 2017 11:33:21 +0200 Subject: [PATCH 2/3] [IMP] account_banking_mandate: Add valid_mandate field and fix onchange (cherry picked from commit 25d2e4d) --- account_banking_mandate/README.rst | 4 +- .../models/account_invoice.py | 43 +++++++------------ account_banking_mandate/models/res_partner.py | 21 ++++++++- 3 files changed, 37 insertions(+), 31 deletions(-) diff --git a/account_banking_mandate/README.rst b/account_banking_mandate/README.rst index e6d6d6ae8..9cd42ef57 100644 --- a/account_banking_mandate/README.rst +++ b/account_banking_mandate/README.rst @@ -56,10 +56,10 @@ Contributors ------------ * Alexis de Lattre -* Pedro M. Baeza +* Pedro M. Baeza * Alexandre Fayolle * Stéphane Bidoul -* Sergio Teruel (Incaser) +* Sergio Teruel * Cédric Pigeon * Carlos Dauden diff --git a/account_banking_mandate/models/account_invoice.py b/account_banking_mandate/models/account_invoice.py index 7adb49f10..755859be5 100644 --- a/account_banking_mandate/models/account_invoice.py +++ b/account_banking_mandate/models/account_invoice.py @@ -1,7 +1,8 @@ # -*- coding: utf-8 -*- -# © 2014 Compassion CH - Cyril Sester -# © 2014 Serv. Tecnol. Avanzados - Pedro M. Baeza -# © 2016 Akretion (Alexis de Lattre ) +# Copyright 2014 Compassion CH - Cyril Sester +# Copyright 2014 Serv. Tecnol. Avanzados - Pedro M. Baeza +# Copyright 2016 Akretion (Alexis de Lattre ) +# Copyright 2017 Carlos Dauden # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). @@ -35,6 +36,7 @@ class AccountInvoice(models.Model): creation, using same method as upstream.""" onchanges = { '_onchange_partner_id': ['mandate_id'], + 'payment_mode_id_change': ['mandate_id'], } for onchange_method, changed_fields in onchanges.items(): if any(f not in vals for f in changed_fields): @@ -43,7 +45,7 @@ class AccountInvoice(models.Model): for field in changed_fields: if field not in vals and invoice[field]: vals[field] = invoice._fields[field].convert_to_write( - invoice[field], invoice, + invoice[field], ) return super(AccountInvoice, self).create(vals) @@ -62,34 +64,19 @@ class AccountInvoice(models.Model): vals['mandate_id'] = invoice.mandate_id.id return vals + def set_mandate(self): + if self.payment_mode_id.payment_method_id.mandate_required: + self.mandate_id = self.partner_id.valid_mandate_id + else: + self.mandate_id = False + @api.onchange('partner_id', 'company_id') def _onchange_partner_id(self): """Select by default the first valid mandate of the partner""" - res = super(AccountInvoice, self)._onchange_partner_id() - if ( - self.type == 'out_invoice' and - self.partner_id.customer_payment_mode_id. - payment_type == 'inbound' and - self.partner_id.customer_payment_mode_id.payment_method_id. - mandate_required and - self.commercial_partner_id): - mandates = self.env['account.banking.mandate'].search([ - ('state', '=', 'valid'), - ('partner_id', '=', self.commercial_partner_id.id), - ]) - if mandates: - self.mandate_id = mandates[0] - else: - self.mandate_id = False - return res + super(AccountInvoice, self)._onchange_partner_id() + self.set_mandate() @api.onchange('payment_mode_id') def payment_mode_id_change(self): super(AccountInvoice, self).payment_mode_id_change() - if ( - self.payment_mode_id and - self.payment_mode_id.payment_type == 'inbound' and - not self.payment_mode_id.payment_method_id.mandate_required): - self.mandate_id = False - elif not self.payment_mode_id: - self.mandate_id = False + self.set_mandate() diff --git a/account_banking_mandate/models/res_partner.py b/account_banking_mandate/models/res_partner.py index bcc7b3dd7..af4d6927f 100644 --- a/account_banking_mandate/models/res_partner.py +++ b/account_banking_mandate/models/res_partner.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- -# © 2016 Akretion (Alexis de Lattre ) +# Copyright 2016 Akretion (Alexis de Lattre ) +# Copyright 2017 Carlos Dauden # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import models, fields, api @@ -11,6 +12,10 @@ class ResPartner(models.Model): mandate_count = fields.Integer( compute='_compute_mandate_count', string="Number of Mandates", readonly=True) + valid_mandate_id = fields.Many2one( + comodel_name='account.banking.mandate', + compute='compute_valid_mandate_id', + string='Valid Mandate') @api.multi def _compute_mandate_count(self): @@ -21,3 +26,17 @@ class ResPartner(models.Model): for mandate in mandate_data]) for partner in self: partner.mandate_count = mapped_data.get(partner.id, 0) + + @api.multi + def compute_valid_mandate_id(self): + # Dict to reduce impact with "bug" that process all partners related + mandates_dic = {} + for partner in self: + commercial_partner_id = partner.commercial_partner_id + if commercial_partner_id in mandates_dic: + partner.valid_mandate_id = mandates_dic[commercial_partner_id] + else: + mandate_id = partner.commercial_partner_id.bank_ids.mapped( + 'mandate_ids').filtered(lambda x: x.state == 'valid').id + partner.valid_mandate_id = mandate_id + mandates_dic[commercial_partner_id] = mandate_id From 355b7acc1c4ebe8d53bc9b593f01b5795edee24d Mon Sep 17 00:00:00 2001 From: Carlos Dauden Date: Wed, 2 Aug 2017 18:46:26 +0200 Subject: [PATCH 3/3] [IMP] account_banking_mandate: Changes suggested (cherry picked from commit 45c1cc2) --- account_banking_mandate/models/res_partner.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/account_banking_mandate/models/res_partner.py b/account_banking_mandate/models/res_partner.py index af4d6927f..f59a7ea73 100644 --- a/account_banking_mandate/models/res_partner.py +++ b/account_banking_mandate/models/res_partner.py @@ -15,7 +15,7 @@ class ResPartner(models.Model): valid_mandate_id = fields.Many2one( comodel_name='account.banking.mandate', compute='compute_valid_mandate_id', - string='Valid Mandate') + string='First Valid Mandate') @api.multi def _compute_mandate_count(self): @@ -29,14 +29,15 @@ class ResPartner(models.Model): @api.multi def compute_valid_mandate_id(self): - # Dict to reduce impact with "bug" that process all partners related + # Dict for reducing the duplicated searches on parent/child partners mandates_dic = {} for partner in self: - commercial_partner_id = partner.commercial_partner_id + commercial_partner_id = partner.commercial_partner_id.id if commercial_partner_id in mandates_dic: partner.valid_mandate_id = mandates_dic[commercial_partner_id] else: - mandate_id = partner.commercial_partner_id.bank_ids.mapped( - 'mandate_ids').filtered(lambda x: x.state == 'valid').id - partner.valid_mandate_id = mandate_id - mandates_dic[commercial_partner_id] = mandate_id + mandates = partner.commercial_partner_id.bank_ids.mapped( + 'mandate_ids').filtered(lambda x: x.state == 'valid') + first_valid_mandate_id = mandates[:1].id + partner.valid_mandate_id = first_valid_mandate_id + mandates_dic[commercial_partner_id] = first_valid_mandate_id