From ad9f376b292abd32b045ffe855503cfc4efae7cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=A7al=20Isern?= Date: Tue, 14 Dec 2021 18:53:42 +0100 Subject: [PATCH] [MIG] account_payment_order: Migration to 15.0 --- account_payment_order/__manifest__.py | 3 +- .../models/account_journal.py | 12 +- account_payment_order/models/account_move.py | 15 ++- .../models/account_payment.py | 50 ++++---- .../models/account_payment_order.py | 59 +++++---- .../models/bank_payment_line.py | 33 ++--- account_payment_order/models/res_bank.py | 7 +- account_payment_order/readme/CONTRIBUTORS.rst | 1 + .../tests/test_account_payment.py | 121 ++++++++++++------ .../tests/test_payment_mode.py | 35 ++++- .../views/account_payment_line.xml | 2 +- .../views/account_payment_order.xml | 2 +- .../views/bank_payment_line.xml | 2 +- .../wizard/account_payment_line_create.py | 5 +- 14 files changed, 223 insertions(+), 124 deletions(-) diff --git a/account_payment_order/__manifest__.py b/account_payment_order/__manifest__.py index 70d83a02b..c84b84c85 100644 --- a/account_payment_order/__manifest__.py +++ b/account_payment_order/__manifest__.py @@ -6,9 +6,10 @@ # © 2016 Aselcis (). # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + { "name": "Account Payment Order", - "version": "14.0.1.4.0", + "version": "15.0.1.0.0", "license": "AGPL-3", "author": "ACSONE SA/NV, " "Therp BV, " diff --git a/account_payment_order/models/account_journal.py b/account_payment_order/models/account_journal.py index 3dd82efac..e8a298ca1 100644 --- a/account_payment_order/models/account_journal.py +++ b/account_payment_order/models/account_journal.py @@ -14,16 +14,20 @@ class AccountJournal(models.Model): compute="_compute_outbound_payment_order_only", readonly=True, store=True ) - @api.depends("inbound_payment_method_ids.payment_order_only") + @api.depends("inbound_payment_method_line_ids.payment_method_id.payment_order_only") def _compute_inbound_payment_order_only(self): for rec in self: rec.inbound_payment_order_only = all( - p.payment_order_only for p in rec.inbound_payment_method_ids + p.payment_order_only + for p in rec.inbound_payment_method_line_ids.payment_method_id ) - @api.depends("outbound_payment_method_ids.payment_order_only") + @api.depends( + "outbound_payment_method_line_ids.payment_method_id.payment_order_only" + ) def _compute_outbound_payment_order_only(self): for rec in self: rec.outbound_payment_order_only = all( - p.payment_order_only for p in rec.outbound_payment_method_ids + p.payment_order_only + for p in rec.outbound_payment_method_line_ids.payment_method_id ) diff --git a/account_payment_order/models/account_move.py b/account_payment_order/models/account_move.py index 7a7fe65bd..cac14564d 100644 --- a/account_payment_order/models/account_move.py +++ b/account_payment_order/models/account_move.py @@ -23,7 +23,6 @@ class AccountMove(models.Model): # payment mode or company level reference_type = fields.Selection( selection=[("none", "Free Reference"), ("structured", "Structured Reference")], - string="Reference Type", readonly=True, states={"draft": [("readonly", False)]}, default="none", @@ -102,18 +101,20 @@ class AccountMove(models.Model): if new_payorder: move.message_post( body=_( - "%d payment lines added to the new draft payment " - "order %s which has been automatically created." + "%(count)d payment lines added to the new draft payment " + "order %(name)s which has been automatically created.", + count=count, + name=payorder.name, ) - % (count, payorder.name) ) else: move.message_post( body=_( - "%d payment lines added to the existing draft " - "payment order %s." + "%(count)d payment lines added to the existing draft " + "payment order %(name)s.", + count=count, + name=payorder.name, ) - % (count, payorder.name) ) action = self.env["ir.actions.act_window"]._for_xml_id( "account_payment_order.account_payment_order_%s_action" diff --git a/account_payment_order/models/account_payment.py b/account_payment_order/models/account_payment.py index 6decc5e98..22f71b2d5 100644 --- a/account_payment_order/models/account_payment.py +++ b/account_payment_order/models/account_payment.py @@ -11,29 +11,33 @@ class AccountPayment(models.Model): res = super()._get_default_journal() return res.filtered(lambda journal: not journal.inbound_payment_order_only) - @api.depends( - "payment_type", - "journal_id.inbound_payment_method_ids", - "journal_id.outbound_payment_method_ids", - ) - def _compute_payment_method_fields(self): - res = super()._compute_payment_method_fields() + @api.depends("payment_type", "journal_id") + def _compute_payment_method_line_fields(self): + res = super()._compute_payment_method_line_fields() for pay in self: - if pay.payment_type == "inbound": - pay.available_payment_method_ids = ( - pay.journal_id.inbound_payment_method_ids.filtered( - lambda m: not m.payment_order_only - ) - ) - else: - pay.available_payment_method_ids = ( - pay.journal_id.outbound_payment_method_ids.filtered( - lambda m: not m.payment_order_only - ) - ) - - pay.hide_payment_method = ( - len(pay.available_payment_method_ids) == 1 - and pay.available_payment_method_ids.code == "manual" + pay.available_payment_method_line_ids = ( + pay.journal_id._get_available_payment_method_lines( + pay.payment_type + ).filtered(lambda x: not x.payment_method_id.payment_order_only) ) + to_exclude = self._get_payment_method_codes_to_exclude() + if to_exclude: + pay.available_payment_method_line_ids = ( + pay.available_payment_method_line_ids.filtered( + lambda x: x.code not in to_exclude + ) + ) + if ( + pay.payment_method_line_id.id + not in pay.available_payment_method_line_ids.ids + ): + # In some cases, we could be linked to a payment method + # line that has been unlinked from the journal. + # In such cases, we want to show it on the payment. + pay.hide_payment_method_line = False + else: + pay.hide_payment_method_line = ( + len(pay.available_payment_method_line_ids) == 1 + and pay.available_payment_method_line_ids.code == "manual" + ) return res diff --git a/account_payment_order/models/account_payment_order.py b/account_payment_order/models/account_payment_order.py index 00d0ed03b..a5661bfab 100644 --- a/account_payment_order/models/account_payment_order.py +++ b/account_payment_order/models/account_payment_order.py @@ -29,7 +29,6 @@ class AccountPaymentOrder(models.Model): ) payment_type = fields.Selection( selection=[("inbound", "Inbound"), ("outbound", "Outbound")], - string="Payment Type", readonly=True, required=True, ) @@ -180,10 +179,11 @@ class AccountPaymentOrder(models.Model): ): raise ValidationError( _( - "The payment type (%s) is not the same as the payment " - "type of the payment mode (%s)" + "The payment type (%(ptype)s) is not the same as the payment " + "type of the payment mode (%(pmode)s)", + ptype=order.payment_type, + pmode=order.payment_mode_id.payment_type, ) - % (order.payment_type, order.payment_mode_id.payment_type) ) @api.constrains("date_scheduled") @@ -194,10 +194,11 @@ class AccountPaymentOrder(models.Model): if order.date_scheduled < today: raise ValidationError( _( - "On payment order %s, the Payment Execution Date " - "is in the past (%s)." + "On payment order %(porder)s, the Payment Execution Date " + "is in the past (%(exedate)s).", + porder=order.name, + exedate=order.date_scheduled, ) - % (order.name, order.date_scheduled) ) @api.depends("payment_line_ids", "payment_line_ids.amount_company_currency") @@ -327,16 +328,14 @@ class AccountPaymentOrder(models.Model): ): raise UserError( _( - "The payment mode '%s' has the option " + "The payment mode '%(pmode)s' has the option " "'Disallow Debit Before Maturity Date'. The " - "payment line %s has a maturity date %s " - "which is after the computed payment date %s." - ) - % ( - order.payment_mode_id.name, - payline.name, - payline.ml_maturity_date, - requested_date, + "payment line %(pline)s has a maturity date %(mdate)s " + "which is after the computed payment date %(pdate)s.", + pmode=order.payment_mode_id.name, + pline=payline.name, + mdate=payline.ml_maturity_date, + pdate=requested_date, ) ) # Write requested_date on 'date' field of payment line @@ -366,8 +365,12 @@ class AccountPaymentOrder(models.Model): # Block if a bank payment line is <= 0 if paydict["total"] <= 0: raise UserError( - _("The amount for Partner '%s' is negative " "or null (%.2f) !") - % (paydict["paylines"][0].partner_id.name, paydict["total"]) + _( + "The amount for Partner '%(partner)s' is negative " + "or null (%(amount).2f) !", + partner=paydict["paylines"][0].partner_id.name, + amount=paydict["total"], + ) ) vals = self._prepare_bank_payment_line(paydict["paylines"]) bplo.create(vals) @@ -460,10 +463,22 @@ class AccountPaymentOrder(models.Model): self, amount_company_currency, amount_payment_currency, bank_lines ): vals = {} - if self.payment_type == "outbound": - account_id = self.journal_id.payment_credit_account_id.id - else: - account_id = self.journal_id.payment_debit_account_id.id + payment_method = self.payment_mode_id.payment_method_id + account_id = False + if self.payment_type == "inbound": + account_id = ( + self.journal_id.inbound_payment_method_line_ids.filtered( + lambda x: x.payment_method_id == payment_method + ).payment_account_id.id + or self.journal_id.company_id.account_journal_payment_debit_account_id.id + ) + elif self.payment_type == "outbound": + account_id = ( + self.journal_id.outbound_payment_method_line_ids.filtered( + lambda x: x.payment_method_id == payment_method + ).payment_account_id.id + or self.journal_id.company_id.account_journal_payment_credit_account_id.id + ) partner_id = False for index, bank_line in enumerate(bank_lines): diff --git a/account_payment_order/models/bank_payment_line.py b/account_payment_order/models/bank_payment_line.py index 27e0ae324..ed7e04622 100644 --- a/account_payment_order/models/bank_payment_line.py +++ b/account_payment_order/models/bank_payment_line.py @@ -70,7 +70,7 @@ class BankPaymentLine(models.Model): communication_type = fields.Selection( related="payment_line_ids.communication_type", readonly=True ) - communication = fields.Char(string="Communication", required=True, readonly=True) + communication = fields.Char(required=True, readonly=True) company_id = fields.Many2one( comodel_name="res.company", related="order_id.payment_mode_id.company_id", @@ -160,26 +160,29 @@ class BankPaymentLine(models.Model): raise UserError( _( "Can not reconcile: no move line for " - "payment line %s of partner '%s'." + "payment line %(line)s of partner '%(partner)s'.", + line=payment_line.name, + partner=payment_line.partner_id.name, ) - % (payment_line.name, payment_line.partner_id.name) ) if payment_line.move_line_id.reconciled: raise UserError( - _("Move line '%s' of partner '%s' has already " "been reconciled") - % (payment_line.move_line_id.name, payment_line.partner_id.name) + _( + "Move line '%(line)s' of partner '%(partner)s' has already " + "been reconciled", + line=payment_line.move_line_id.name, + partner=payment_line.partner_id.name, + ) ) if payment_line.move_line_id.account_id != transit_mline.account_id: raise UserError( _( - "For partner '%s', the account of the account " - "move line to pay (%s) is different from the " - "account of of the transit move line (%s)." - ) - % ( - payment_line.move_line_id.partner_id.name, - payment_line.move_line_id.account_id.code, - transit_mline.account_id.code, + "For partner '%(partner)s', the account of the account " + "move line to pay (%(line1)s) is different from the " + "account of of the transit move line (%(line2)s).", + partner=payment_line.move_line_id.partner_id.name, + line1=payment_line.move_line_id.account_id.code, + line2=transit_mline.account_id.code, ) ) @@ -194,8 +197,8 @@ class BankPaymentLine(models.Model): raise UserError( _( "Cannot delete a payment order line whose payment order is" - " in state '%s'. You need to cancel it first." + " in state '%(state)s'. You need to cancel it first.", + state=order_state, ) - % order_state ) return super(BankPaymentLine, self).unlink() diff --git a/account_payment_order/models/res_bank.py b/account_payment_order/models/res_bank.py index bea633992..59a2d4dc1 100644 --- a/account_payment_order/models/res_bank.py +++ b/account_payment_order/models/res_bank.py @@ -14,10 +14,11 @@ class ResBank(models.Model): if bank.bic and len(bank.bic) not in (8, 11): raise ValidationError( _( - "A valid BIC contains 8 or 11 characters. The BIC '%s' " - "contains %d characters, so it is not valid." + "A valid BIC contains 8 or 11 characters. The BIC '%(bic)s' " + "contains %(num)d characters, so it is not valid.", + bic=bank.bic, + num=len(bank.bic), ) - % (bank.bic, len(bank.bic)) ) diff --git a/account_payment_order/readme/CONTRIBUTORS.rst b/account_payment_order/readme/CONTRIBUTORS.rst index acf4c751b..317e603ce 100644 --- a/account_payment_order/readme/CONTRIBUTORS.rst +++ b/account_payment_order/readme/CONTRIBUTORS.rst @@ -27,3 +27,4 @@ * `Open Source Integrators `_: * Ammar Officewala +* Marçal Isern diff --git a/account_payment_order/tests/test_account_payment.py b/account_payment_order/tests/test_account_payment.py index 6120563bb..e7853ffa4 100644 --- a/account_payment_order/tests/test_account_payment.py +++ b/account_payment_order/tests/test_account_payment.py @@ -1,7 +1,9 @@ # Copyright 2019 ACSONE SA/NV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from unittest.mock import patch +from odoo.addons.account.models.account_payment_method import AccountPaymentMethod from odoo.addons.account.tests.common import AccountTestInvoicingCommon @@ -9,6 +11,18 @@ class TestAccountPayment(AccountTestInvoicingCommon): @classmethod def setUpClass(cls, chart_template_ref=None): super().setUpClass(chart_template_ref=chart_template_ref) + + Method_get_payment_method_information = ( + AccountPaymentMethod._get_payment_method_information + ) + + def _get_payment_method_information(self): + res = Method_get_payment_method_information(self) + res["IN"] = {"mode": "multi", "domain": [("type", "=", "bank")]} + res["IN2"] = {"mode": "multi", "domain": [("type", "=", "bank")]} + res["OUT"] = {"mode": "multi", "domain": [("type", "=", "bank")]} + return res + cls.company = cls.company_data["company"] cls.env.user.company_ids += cls.company @@ -19,38 +33,38 @@ class TestAccountPayment(AccountTestInvoicingCommon): # INSTANCES # Payment methods - cls.inbound_payment_method_01 = cls.payment_method_model.create( - { - "name": "inbound", - "code": "IN", - "payment_type": "inbound", - } - ) - cls.inbound_payment_method_02 = cls.inbound_payment_method_01.copy( - { - "name": "inbound 2", - "code": "IN2", - } - ) - cls.outbound_payment_method_01 = cls.payment_method_model.create( - { - "name": "outbound", - "code": "OUT", - "payment_type": "outbound", - } - ) - # Journals - cls.bank_journal = cls.company_data["default_journal_bank"] - cls.bank_journal.inbound_payment_method_ids = [ - ( - 6, - 0, - [cls.inbound_payment_method_01.id, cls.inbound_payment_method_02.id], + with patch.object( + AccountPaymentMethod, + "_get_payment_method_information", + _get_payment_method_information, + ): + + cls.inbound_payment_method_01 = cls.payment_method_model.create( + { + "name": "inbound", + "code": "IN", + "payment_type": "inbound", + } ) - ] - cls.bank_journal.outbound_payment_method_ids = [ - (6, 0, [cls.outbound_payment_method_01.id]) - ] + cls.inbound_payment_method_02 = cls.inbound_payment_method_01.copy( + { + "name": "inbound 2", + "code": "IN2", + "payment_type": "inbound", + } + ) + cls.outbound_payment_method_01 = cls.payment_method_model.create( + { + "name": "outbound", + "code": "OUT", + "payment_type": "outbound", + } + ) + # Journals + cls.manual_in = cls.env.ref("account.account_payment_method_manual_in") + cls.manual_out = cls.env.ref("account.account_payment_method_manual_out") + + cls.bank_journal = cls.company_data["default_journal_bank"] def test_account_payment_01(self): self.assertFalse(self.inbound_payment_method_01.payment_order_only) @@ -63,6 +77,7 @@ class TestAccountPayment(AccountTestInvoicingCommon): self.inbound_payment_method_02.payment_order_only = True self.assertTrue(self.inbound_payment_method_01.payment_order_only) self.assertTrue(self.inbound_payment_method_02.payment_order_only) + self.manual_in.payment_order_only = True self.assertTrue(self.bank_journal.inbound_payment_order_only) def test_account_payment_02(self): @@ -70,6 +85,11 @@ class TestAccountPayment(AccountTestInvoicingCommon): self.assertFalse(self.bank_journal.outbound_payment_order_only) self.outbound_payment_method_01.payment_order_only = True self.assertTrue(self.outbound_payment_method_01.payment_order_only) + + payment_method_id = ( + self.bank_journal.outbound_payment_method_line_ids.payment_method_id + ) + payment_method_id.payment_order_only = True self.assertTrue(self.bank_journal.outbound_payment_order_only) def test_account_payment_03(self): @@ -90,7 +110,13 @@ class TestAccountPayment(AccountTestInvoicingCommon): journals = new_account_payment._get_default_journal() self.assertIn(self.bank_journal, journals) # check payment methods - payment_methods = new_account_payment.available_payment_method_ids.ids + payment_methods = ( + new_account_payment.available_payment_method_line_ids.filtered( + lambda x: x.payment_type == "inbound" + ) + .mapped("payment_method_id") + .ids + ) self.assertIn(self.inbound_payment_method_01.id, payment_methods) self.assertIn(self.inbound_payment_method_02.id, payment_methods) # Set one payment method of the bank journal 'payment order only' @@ -99,20 +125,43 @@ class TestAccountPayment(AccountTestInvoicingCommon): journals = new_account_payment._get_default_journal() self.assertIn(self.bank_journal, journals) # check payment methods - new_account_payment._compute_payment_method_fields() - payment_methods = new_account_payment.available_payment_method_ids.ids + new_account_payment2 = self.account_payment_model.with_context( + default_company_id=self.company.id + ).new( + { + "journal_id": self.bank_journal.id, + "payment_type": "inbound", + "amount": 1, + "company_id": self.company.id, + } + ) + payment_methods = new_account_payment2.available_payment_method_line_ids.mapped( + "payment_method_id" + ).ids self.assertNotIn(self.inbound_payment_method_01.id, payment_methods) self.assertIn(self.inbound_payment_method_02.id, payment_methods) # Set all payment methods of the bank journal 'payment order only' self.inbound_payment_method_02.payment_order_only = True self.assertTrue(self.inbound_payment_method_01.payment_order_only) self.assertTrue(self.inbound_payment_method_02.payment_order_only) + self.manual_in.payment_order_only = True self.assertTrue(self.bank_journal.inbound_payment_order_only) # check journals journals = new_account_payment._get_default_journal() self.assertNotIn(self.bank_journal, journals) # check payment methods - new_account_payment._compute_payment_method_fields() - payment_methods = new_account_payment.available_payment_method_ids.ids + new_account_payment3 = self.account_payment_model.with_context( + default_company_id=self.company.id + ).new( + { + "journal_id": self.bank_journal.id, + "payment_type": "inbound", + "amount": 1, + "company_id": self.company.id, + } + ) + payment_methods = new_account_payment3.available_payment_method_line_ids.mapped( + "payment_method_id" + ).ids self.assertNotIn(self.inbound_payment_method_01.id, payment_methods) self.assertNotIn(self.inbound_payment_method_02.id, payment_methods) diff --git a/account_payment_order/tests/test_payment_mode.py b/account_payment_order/tests/test_payment_mode.py index 0141fd510..5a101b044 100644 --- a/account_payment_order/tests/test_payment_mode.py +++ b/account_payment_order/tests/test_payment_mode.py @@ -1,13 +1,28 @@ # © 2017 Creu Blanca # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from unittest.mock import patch + from odoo.tests.common import TransactionCase +from odoo.addons.account.models.account_payment_method import AccountPaymentMethod + class TestPaymentMode(TransactionCase): def setUp(self): super(TestPaymentMode, self).setUp() + Method_get_payment_method_information = ( + AccountPaymentMethod._get_payment_method_information + ) + + def _get_payment_method_information(self): + res = Method_get_payment_method_information(self) + res["IN"] = {"mode": "multi", "domain": [("type", "=", "bank")]} + res["IN2"] = {"mode": "multi", "domain": [("type", "=", "bank")]} + res["electronic_out"] = {"mode": "multi", "domain": [("type", "=", "bank")]} + return res + # Company self.company = self.env.ref("base.main_company") @@ -28,13 +43,19 @@ class TestPaymentMode(TransactionCase): self.manual_in = self.env.ref("account.account_payment_method_manual_in") - self.electronic_out = self.env["account.payment.method"].create( - { - "name": "Electronic Out", - "code": "electronic_out", - "payment_type": "outbound", - } - ) + with patch.object( + AccountPaymentMethod, + "_get_payment_method_information", + _get_payment_method_information, + ): + + self.electronic_out = self.env["account.payment.method"].create( + { + "name": "Electronic Out", + "code": "electronic_out", + "payment_type": "outbound", + } + ) self.payment_mode_c1 = self.env["account.payment.mode"].create( { diff --git a/account_payment_order/views/account_payment_line.xml b/account_payment_order/views/account_payment_line.xml index 6f774cd38..85b0d1964 100644 --- a/account_payment_order/views/account_payment_line.xml +++ b/account_payment_order/views/account_payment_line.xml @@ -51,7 +51,7 @@ account.payment.line.tree account.payment.line - + account.payment.order.tree account.payment.order - + diff --git a/account_payment_order/views/bank_payment_line.xml b/account_payment_order/views/bank_payment_line.xml index 52d57e8bf..624742fc9 100644 --- a/account_payment_order/views/bank_payment_line.xml +++ b/account_payment_order/views/bank_payment_line.xml @@ -39,7 +39,7 @@ bank.payment.line.tree bank.payment.line - +