mirror of
https://github.com/OCA/bank-payment.git
synced 2025-02-02 10:37:31 +02:00
[FIX] account_payment_sale: Propagate payment_mode to invoices created from a call to sale.action_invoice_create
Into the normal process of the invoice creation from a sale order by odoo, the onchange_partner is called. In some case, this call will reset the specific payment_mode and/or partner_bank_id set on the sale_order. To fix this issue, we must override the _finalize_invoices method, take a snapshot of these values before the call to super and restore these values if these are changed. fixes #536
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user