[FIX] mrp: apply source location of unbuild order on SM

When unbuilding a product, the selected source location is not applied
on the SM.

To reproduce the issue:
1. In Settings, enable "Storage Locations"
2. Create two storable products P_compo, P_finished
3. Update the qty of P_compo: 1 in WH/Stock
4. Create a BoM:
    - Product: P_finished
    - Components: 1 x P_compo
5. Process a manufacturing order MO with 1 x P_finished
6. Transfer the P_finished from WH/Stock to WH/Stock/Shelf 1
7. Create an unbuild order UO:
    - Manufacturing Order: MO
    - Source Location: WH/Stock/Shelf 1
    - Destination Location: WH/Stock/Shelf 2
8. Confirm UO
9. Open the associated product moves

Error: The SML of P_finished is incorrect, its source location is
WH/Stock instead of WH/Stock/Shelf 1 (as a result, the quants are
incorrect too).

The issue only happens with P_finished. The destination of the
components is correctly defined:
https://github.com/odoo/odoo/blob/90a87d6ecd420c61ea8db8a6c571db477ee7220e/addons/mrp/models/mrp_unbuild.py#L229
(i.e., we use the destination location of the unbuild order)

OPW-2869454

closes odoo/odoo#94367

X-original-commit: 45ec5871a1ee6e3a31e790323f08df20715f4171
Signed-off-by: Tiffany Chang <tic@odoo.com>
Signed-off-by: Adrien Widart <awt@odoo.com>
This commit is contained in:
Adrien Widart
2022-06-23 10:15:12 +02:00
parent e83120936d
commit c7c96d61e9
2 changed files with 52 additions and 1 deletions
+1 -1
View File
@@ -212,7 +212,7 @@ class MrpUnbuild(models.Model):
finished_moves = unbuild.mo_id.move_finished_ids.filtered(lambda move: move.state == 'done')
factor = unbuild.product_qty / unbuild.mo_id.product_uom_id._compute_quantity(unbuild.mo_id.product_qty, unbuild.product_uom_id)
for finished_move in finished_moves:
moves += unbuild._generate_move_from_existing_move(finished_move, factor, finished_move.location_dest_id, finished_move.location_id)
moves += unbuild._generate_move_from_existing_move(finished_move, factor, unbuild.location_id, finished_move.location_id)
else:
factor = unbuild.product_uom_id._compute_quantity(unbuild.product_qty, unbuild.bom_id.product_uom_id) / unbuild.bom_id.product_qty
moves += unbuild._generate_move_from_bom_line(self.product_id, self.product_uom_id, unbuild.product_qty)
+51
View File
@@ -687,3 +687,54 @@ class TestUnbuild(TestMrpCommon):
uo.action_unbuild()
self.assertEqual(uo.produce_line_ids.filtered(lambda sm: sm.product_id == compo).lot_ids, lot01 + lot02)
def test_unbuild_and_multilocations(self):
"""
Basic flow: produce p_final, transfer it to a sub-location and then
unbuild it. The test ensures that the source/destination locations of an
unbuild order are applied on the stock moves
"""
grp_multi_loc = self.env.ref('stock.group_stock_multi_locations')
self.env.user.write({'groups_id': [(4, grp_multi_loc.id, 0)]})
warehouse = self.env['stock.warehouse'].search([('company_id', '=', self.env.user.id)], limit=1)
prod_location = self.env['stock.location'].search([('usage', '=', 'production'), ('company_id', '=', self.env.user.id)])
subloc01, subloc02, = self.stock_location.child_ids[:2]
mo, _, p_final, p1, p2 = self.generate_mo(qty_final=1, qty_base_1=1, qty_base_2=1)
self.env['stock.quant']._update_available_quantity(p1, self.stock_location, 1)
self.env['stock.quant']._update_available_quantity(p2, self.stock_location, 1)
mo.action_assign()
mo_form = Form(mo)
mo_form.qty_producing = 1.0
mo = mo_form.save()
mo.button_mark_done()
# Transfer the finished product from WH/Stock to `subloc01`
internal_form = Form(self.env['stock.picking'])
internal_form.picking_type_id = warehouse.int_type_id
internal_form.location_id = self.stock_location
internal_form.location_dest_id = subloc01
with internal_form.move_ids_without_package.new() as move:
move.product_id = p_final
move.product_uom_qty = 1.0
internal_transfer = internal_form.save()
internal_transfer.action_confirm()
internal_transfer.action_assign()
internal_transfer.move_line_ids.qty_done = 1.0
internal_transfer.button_validate()
unbuild_order_form = Form(self.env['mrp.unbuild'])
unbuild_order_form.mo_id = mo
unbuild_order_form.location_id = subloc01
unbuild_order_form.location_dest_id = subloc02
unbuild_order = unbuild_order_form.save()
unbuild_order.action_unbuild()
self.assertRecordValues(unbuild_order.produce_line_ids, [
# pylint: disable=bad-whitespace
{'product_id': p_final.id, 'location_id': subloc01.id, 'location_dest_id': prod_location.id},
{'product_id': p2.id, 'location_id': prod_location.id, 'location_dest_id': subloc02.id},
{'product_id': p1.id, 'location_id': prod_location.id, 'location_dest_id': subloc02.id},
])