diff --git a/account_payment_sale/models/sale_order.py b/account_payment_sale/models/sale_order.py index 900c3f302..6267d2215 100644 --- a/account_payment_sale/models/sale_order.py +++ b/account_payment_sale/models/sale_order.py @@ -33,3 +33,31 @@ class SaleOrder(models.Model): """Copy bank partner from sale order to invoice""" vals = super()._prepare_invoice() return self._get_payment_mode_vals(vals) + + def _finalize_invoices(self, invoices, references): + """ + Invoked after creating invoices at the end of action_invoice_create. + + We must override this method since the onchange on partner is called by + the base method and therefore will change the specific payment_mode set + on the SO if one is defined on the partner.. + + :param invoices: {group_key: invoice} + :param references: {invoice: order} + """ + payment_vals_by_invoice = {} + for invoice in invoices.values(): + payment_vals_by_invoice[invoice] = { + 'payment_mode_id': invoice.payment_mode_id.id, + 'partner_bank_id': invoice.partner_bank_id.id + } + res = super()._finalize_invoices(invoices, references) + for invoice in invoices.values(): + payment_vals = payment_vals_by_invoice[invoice] + if invoice.payment_mode_id.id == payment_vals['payment_mode_id']: + payment_vals.pop("payment_mode_id") + if invoice.partner_bank_id.id == payment_vals["partner_bank_id"]: + payment_vals.pop("partner_bank_id") + if payment_vals: + invoice.write(payment_vals) + return res diff --git a/account_payment_sale/tests/common.py b/account_payment_sale/tests/common.py index ca53295de..369c8a8f4 100644 --- a/account_payment_sale/tests/common.py +++ b/account_payment_sale/tests/common.py @@ -30,6 +30,15 @@ class CommonTestCase(SavepointCase): 'bank_account_link': 'fixed', 'fixed_journal_id': cls.journal.id, }) + cls.payment_mode_2 = cls.env["account.payment.mode"].create({ + 'name': 'test_mode_2', + 'active': True, + 'payment_method_id': cls.env.ref( + "account.account_payment_method_manual_in" + ).id, + 'bank_account_link': 'fixed', + 'fixed_journal_id': cls.journal.id, + }) cls.base_partner = cls.env["res.partner"].create({ 'name': 'Dummy', 'email': 'dummy@example.com', diff --git a/account_payment_sale/tests/test_sale_order.py b/account_payment_sale/tests/test_sale_order.py index 4e35f911c..7180b7ff8 100644 --- a/account_payment_sale/tests/test_sale_order.py +++ b/account_payment_sale/tests/test_sale_order.py @@ -5,57 +5,102 @@ from .common import CommonTestCase class TestSaleOrder(CommonTestCase): - - def create_sale_order(self): - so_lines = [(0, 0, { - 'name': p.name, - 'product_id': p.id, - 'product_uom_qty': 2, - 'product_uom': p.uom_id.id, - 'price_unit': p.list_price, - }) for (_, p) in self.products.items()] - so = self.env['sale.order'].create({ - 'partner_id': self.base_partner.id, - 'partner_invoice_id': self.base_partner.id, - 'partner_shipping_id': self.base_partner.id, - 'order_line': so_lines, - 'pricelist_id': self.env.ref('product.list0').id, - }) + def create_sale_order(self, payment_mode=None): + so_lines = [ + ( + 0, + 0, + { + "name": p.name, + "product_id": p.id, + "product_uom_qty": 2, + "product_uom": p.uom_id.id, + "price_unit": p.list_price, + }, + ) + for (_, p) in self.products.items() + ] + so = self.env["sale.order"].create( + { + "partner_id": self.base_partner.id, + "partner_invoice_id": self.base_partner.id, + "partner_shipping_id": self.base_partner.id, + "order_line": so_lines, + "pricelist_id": self.env.ref("product.list0").id, + } + ) self.assertFalse(so.payment_mode_id) so.onchange_partner_id() self.assertEqual( - so.payment_mode_id, - self.base_partner.customer_payment_mode_id + so.payment_mode_id, self.base_partner.customer_payment_mode_id ) + # force payment mode + if payment_mode: + so.payment_mode_id = payment_mode.id return so + def create_invoice_and_check( + self, order, expected_payment_mode, expected_partner_bank + ): + order.action_confirm() + order.action_invoice_create() + invoice = order.invoice_ids + self.assertEqual(len(invoice), 1) + self.assertEqual(invoice.payment_mode_id, expected_payment_mode) + self.assertEqual(invoice.partner_bank_id, expected_partner_bank) + def test_sale_to_invoice_payment_mode(self): + """ + Data: + A partner with a specific payment_mode + A sale order created with the payment_mode of the partner + Test case: + Create the invoice from the sale order + Expected result: + The invoice must be created with the payment_mode of the partner + """ order = self.create_sale_order() + self.create_invoice_and_check(order, self.payment_mode, self.bank) + + def test_sale_to_invoice_payment_mode_2(self): + """ + Data: + A partner with a specific payment_mode + A sale order created with an other payment_mode + Test case: + Create the invoice from the sale order + Expected result: + The invoice must be created with the specific payment_mode + """ + order = self.create_sale_order(payment_mode=self.payment_mode_2) + self.create_invoice_and_check(order, self.payment_mode_2, self.bank) + + def test_sale_to_invoice_payment_mode_via_payment(self): + """ + Data: + A partner with a specific payment_mode + A sale order created with an other payment_mode + Test case: + Create the invoice from sale.advance.payment.inv + Expected result: + The invoice must be created with the specific payment_mode + """ + order = self.create_sale_order(payment_mode=self.payment_mode_2) context = { - "active_model": 'sale.order', + "active_model": "sale.order", "active_ids": [order.id], "active_id": order.id, } - order.with_context(context).action_confirm() - payment = self.env['sale.advance.payment.inv'].create({ - 'advance_payment_method': 'fixed', - 'amount': 5, - 'product_id': self.env.ref('sale.advance_product_0').id, - }) - vals = order._get_payment_mode_vals({}) - expected_vals = { - 'payment_mode_id': self.payment_mode.id, - 'partner_bank_id': self.bank.id, - } - self.assertEqual(vals, expected_vals) + order.action_confirm() + payment = self.env["sale.advance.payment.inv"].create( + { + "advance_payment_method": "fixed", + "amount": 5, + "product_id": self.env.ref("sale.advance_product_0").id, + } + ) payment.with_context(context).create_invoices() invoice = order.invoice_ids self.assertEqual(len(invoice), 1) - self.assertEqual( - invoice.payment_mode_id.id, - expected_vals["payment_mode_id"] - ) - self.assertEqual( - invoice.partner_bank_id.id, - expected_vals["partner_bank_id"] - ) + self.assertEqual(invoice.payment_mode_id, self.payment_mode_2) + self.assertEqual(invoice.partner_bank_id, self.bank)