Skip to content
Snippets Groups Projects
Commit 3645c8f6 authored by Paul Morelle's avatar Paul Morelle
Browse files

[FIX] sale: avoid crash when posting move linked to multiple SO


Because of the M2M relation, an account.move.line can be linked to
several sale.order.lines, making the cardinality of sale_line_ids
superior to 1.
Even if it is not possible to obtain this result with standard code,
a custom module could create this situation and posting the invoice
would result in a "ValueError: Expected singleton" exception.

This commit prevents this exception by checking whether the line is
linked to at least one downpayment SO line in the method action_post.
The test also checks that the methods button_draft and button_cancel
behave properly (spoiler alert: they will fail too in 16.0).

closes odoo/odoo#110560

Signed-off-by: default avatarPaul Morelle (pmo) <pmo@odoo.com>
parent b4cd54a3
Branches
Tags
No related merge requests found
......@@ -12,7 +12,7 @@ class AccountMove(models.Model):
def action_post(self):
#inherit of the function from account.move to validate a new tax and the priceunit of a downpayment
res = super(AccountMove, self).action_post()
line_ids = self.mapped('line_ids').filtered(lambda line: line.sale_line_ids.is_downpayment)
line_ids = self.mapped('line_ids').filtered(lambda line: any(line.sale_line_ids.mapped('is_downpayment')))
for line in line_ids:
try:
line.sale_line_ids.tax_id = line.tax_ids
......
......@@ -279,6 +279,37 @@ class TestSaleToInvoice(TestSaleCommon):
self.assertEqual(line.untaxed_amount_to_invoice, line.price_unit * line.qty_to_invoice, "Amount to invoice is now set as qty to invoice * unit price since no price change on invoice, for ordered products")
self.assertEqual(line.untaxed_amount_invoiced, line.price_unit * line.qty_invoiced, "Amount invoiced is now set as qty invoiced * unit price since no price change on invoice, for ordered products")
def test_multiple_sale_orders_on_same_invoice(self):
""" The model allows the association of multiple SO lines linked to the same invoice line.
Check that the operations behave well, if a custom module creates such a situation.
"""
self.sale_order.action_confirm()
payment = self.env['sale.advance.payment.inv'].with_context(self.context).create({
'advance_payment_method': 'delivered'
})
payment.create_invoices()
# create a second SO whose lines are linked to the same invoice lines
# this is a way to create a situation where sale_line_ids has multiple items
sale_order_data = self.sale_order.copy_data()[0]
sale_order_data['order_line'] = [
(0, 0, line.copy_data({
'invoice_lines': [(6, 0, line.invoice_lines.ids)],
})[0])
for line in self.sale_order.order_line
]
self.sale_order.create(sale_order_data)
# we should now have at least one move line linked to several order lines
invoice = self.sale_order.invoice_ids[0]
self.assertTrue(any(len(move_line.sale_line_ids) > 1
for move_line in invoice.line_ids))
# however these actions should not raise
invoice.action_post()
invoice.button_draft()
invoice.button_cancel()
def test_invoice_with_sections(self):
""" Test create and invoice with sections from the SO, and check qty invoice/to invoice, and the related amounts """
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment