[FIX] sale_stock: set invoice_status value when delivery is canceled

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'

To reproduce the error:
1. In Settings, enable "Lock Confirmed Sales"
2. Create a product P:
    - Type: Consumable
    - Invoicing policy: Delivered quantities
3. Create a SO with one P
4. Confirm the SO
5. Cancel the SO's delivery
6. Check the invoice status (`invoice_status`)
    - 12.0: Either by modifying the view, or by adding the field with
studio or directly via PSQL
    - 13.0+: The field can be enabled thanks to the options of the tree
view

Error: The invoice status is "Fully Invoiced" but the product hasn't be
delivered and no invoice has been created

OPW-2464343

closes odoo/odoo#73558

X-original-commit: b87d06da379abff8fc40352192699f6b44727797
Signed-off-by: William Henrotin <Whenrow@users.noreply.github.com>
Signed-off-by: Adrien Widart <adwid@users.noreply.github.com>
This commit is contained in:
Adrien Widart
2021-07-12 10:56:37 +00:00
parent 56d8c387ba
commit cc5ff7ac8c
2 changed files with 38 additions and 1 deletions
+9 -1
View File
@@ -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')
@@ -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')