diff --git a/addons/sale_stock/models/sale_order.py b/addons/sale_stock/models/sale_order.py index 8cccb84719e..605433e8e91 100644 --- a/addons/sale_stock/models/sale_order.py +++ b/addons/sale_stock/models/sale_order.py @@ -434,6 +434,14 @@ class SaleOrderLine(models.Model): @api.depends('order_id.state') def _compute_invoice_status(self): + def check_moves_state(moves): + # All moves states are either 'done' or 'cancel', and there is at least one 'done' + at_least_one_done = False + for move in moves: + if move.state not in ['done', 'cancel']: + return False + at_least_one_done = at_least_one_done or move.state == 'done' + return at_least_one_done super(SaleOrderLine, self)._compute_invoice_status() for line in self: # We handle the following specific situation: a physical product is partially delivered, @@ -445,7 +453,7 @@ class SaleOrderLine(models.Model): and line.product_id.type in ['consu', 'product']\ and line.product_id.invoice_policy == 'delivery'\ and line.move_ids \ - and all(move.state in ['done', 'cancel'] for move in line.move_ids): + and check_moves_state(line.move_ids): line.invoice_status = 'invoiced' @api.depends('move_ids') diff --git a/addons/sale_stock/tests/test_sale_stock.py b/addons/sale_stock/tests/test_sale_stock.py index 9f31482fbf7..963327ef27b 100644 --- a/addons/sale_stock/tests/test_sale_stock.py +++ b/addons/sale_stock/tests/test_sale_stock.py @@ -1060,3 +1060,32 @@ class TestSaleStock(TestSaleCommon, ValuationReconciliationTestCommon): }) so.action_confirm() self.assertEqual(so.order_line.move_ids.product_packaging_id, packaging) + + def test_15_cancel_delivery(self): + """ Suppose the option "Lock Confirmed Sales" enabled and a product with the invoicing + policy set to "Delivered quantities". When cancelling the delivery of such a product, the + invoice status of the associated SO should be 'Nothing to Invoice' + """ + group_auto_done = self.env['ir.model.data'].xmlid_to_object('sale.group_auto_done_setting') + self.env.user.groups_id = [(4, group_auto_done.id)] + + product = self.product_a + product.invoice_policy = 'delivery' + partner = self.partner_a + so = self.env['sale.order'].create({ + 'partner_id': partner.id, + 'partner_invoice_id': partner.id, + 'partner_shipping_id': partner.id, + 'order_line': [(0, 0, { + 'name': product.name, + 'product_id': product.id, + 'product_uom_qty': 2, + 'product_uom': product.uom_id.id, + 'price_unit': product.list_price + })], + 'pricelist_id': self.env.ref('product.list0').id, + }) + so.action_confirm() + so.picking_ids.action_cancel() + + self.assertEqual(so.invoice_status, 'no')