Skip to content
Snippets Groups Projects
Commit 206c9c8d authored by Nathan Marotte (nama)'s avatar Nathan Marotte (nama) Committed by Touati Djamel (otd)
Browse files

[FIX] sale_mrp : wrong delivered quantities on kit return


Issue: When returning a product sold that is only made of kits and
validating the return, the delivered quantities of the sales order was
set back to the full amount delivered

Steps to reproduce :
  1) Install MRP and Sales
  2) Create a BoM Kit for a new product [Nested Kit] that has one or
    more consumable or storable product as component
  3) Create a BoM Kit for a new product [Main Kit] that has
    [Nested Kit] as component
  4) Create a SO for [Main Kit], confirm, validate delivery
  5) Check SO, 1 product is delivered (correct)
  6) Go back to the Delivery, create a return for the delivery
    (don't validate)
  7) Check SO, 0 product is delivered (correct)
  8) Now validate the return for the delivery
  -> Check SO, 1 product is delivered (bug)

Why is that a bug:
 Since the Main Kit was returned, the delivered should be 0 and not
 the full amount initially delivered. It was set back to 1 because we
 didn't look at the type of picking, when computing the quantity
 delivered, the fall back considered that if all the moves were done,
 everything was delivered, but it is the opposite when returning

opw-2542337

closes odoo/odoo#78838

X-original-commit: e90452bf
Signed-off-by: default avatarArnold Moyaux <arm@odoo.com>
Signed-off-by: default avatarRémy Voet <ryv@odoo.com>
parent 0b0a359e
No related branches found
No related tags found
No related merge requests found
......@@ -109,7 +109,8 @@ class SaleOrderLine(models.Model):
# when the product sold is made only of kits. In this case, the BOM of the stock moves
# do not correspond to the product sold => no relevant BOM.
elif boms:
if all(m.state == 'done' for m in order_line.move_ids):
# if the move is ingoing, the product **sold** has delivered qty 0
if all(m.state == 'done' and m.location_dest_id.usage == 'customer' for m in order_line.move_ids):
order_line.qty_delivered = order_line.product_uom_qty
else:
order_line.qty_delivered = 0.0
......
......@@ -1769,3 +1769,91 @@ class TestSaleMrpFlow(ValuationReconciliationTestCommon):
# Check that the cost of Good Sold entries for variant 2 are equal to 2 * 10 = 20
check_cogs_entry_values(self.invoice_2, 20)
def test_13_so_return_kit(self):
"""
Test that when returning a SO containing only a kit that contains another kit, the
SO delivered quantities is set to 0 (with the all-or-nothing policy).
Products :
Main Kit
Nested Kit
Screw
BoMs :
Main Kit BoM (kit), recipe :
Nested Kit Bom (kit), recipe :
Screw
Business flow :
Create those
Create a Sales order selling one Main Kit BoM
Confirm the sales order
Validate the delivery (outgoing) (qty_delivered = 1)
Create a return for the delivery
Validate return for delivery (ingoing) (qty_delivered = 0)
"""
main_kit_product = self.env['product.product'].create({
'name': 'Main Kit',
'type': 'product',
})
nested_kit_product = self.env['product.product'].create({
'name': 'Nested Kit',
'type': 'product',
})
product = self.env['product.product'].create({
'name': 'Screw',
'type': 'product',
})
nested_kit_bom = self.env['mrp.bom'].create({
'product_id': nested_kit_product.id,
'product_tmpl_id': nested_kit_product.product_tmpl_id.id,
'product_qty': 1.0,
'type': 'phantom',
'bom_line_ids': [(5, 0), (0, 0, {'product_id': product.id})]
})
main_bom = self.env['mrp.bom'].create({
'product_id': main_kit_product.id,
'product_tmpl_id': main_kit_product.product_tmpl_id.id,
'product_qty': 1.0,
'type': 'phantom',
'bom_line_ids': [(5, 0), (0, 0, {'product_id': nested_kit_product.id})]
})
# Create a SO for product Main Kit Product
order_form = Form(self.env['sale.order'])
order_form.partner_id = self.env.ref('base.res_partner_2')
with order_form.order_line.new() as line:
line.product_id = main_kit_product
line.product_uom_qty = 1
order = order_form.save()
order.action_confirm()
qty_del_not_yet_validated = sum(sol.qty_delivered for sol in order.order_line)
self.assertEqual(qty_del_not_yet_validated, 0.0, 'No delivery validated yet')
# Validate delivery
pick = order.picking_ids
pick.move_lines.write({'quantity_done': 1})
pick.button_validate()
qty_del_validated = sum(sol.qty_delivered for sol in order.order_line)
self.assertEqual(qty_del_validated, 1.0, 'The order went from warehouse to client, so it has been delivered')
# 1 was delivered, now create a return
stock_return_picking_form = Form(self.env['stock.return.picking'].with_context(
active_ids=pick.ids, active_id=pick.ids[0], active_model='stock.picking'))
return_wiz = stock_return_picking_form.save()
for return_move in return_wiz.product_return_moves:
return_move.write({
'quantity': 1,
'to_refund': True
})
res = return_wiz.create_returns()
return_pick = self.env['stock.picking'].browse(res['res_id'])
return_pick.move_line_ids.qty_done = 1
wiz_act = return_pick.button_validate() # validate return
# Delivered quantities to the client should be 0
qty_del_return_validated = sum(sol.qty_delivered for sol in order.order_line)
self.assertNotEqual(qty_del_return_validated, 1.0, "The return was validated, therefore the delivery from client to"
" company was successful, and the client is left without his 1 product.")
self.assertEqual(qty_del_return_validated, 0.0, "The return has processed, client doesn't have any quantity anymore")
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment