[FIX] mrp_subcontracting: fix origin moves on backorder
This commit adapts commits d4abaafa4757ace22010be49bb1f7ce1c4fbfc0d and 7a78839ca6cf45ddec7adb59051da132e0ebceb4 The commits above try to split the origin moves during a split (backorder). The issues was the split move lost its correct origin move and the backorder move had all the origin moves linked to it. HOW TO REPRODUCE: - Create product FNS (storable) - Create subcontracted BoM for FNS - On Operation type 'Receipt', set Show Detailed Operations = True and Pre-fill Detailed Operations = True - Create PO for 10 units of FNS -> Confirm - Go to Receipt > Detailed operation > Set quantity = 1 > Validate (with backorder) - Repeat step above on the created backorder OR - Create storable product FNS tracked by serial number - Create subcontracting BoM, with strict consumption - Create PO for 10 units of FNS -> Confirm - Open detailed operation, add 2 lines with SN, confirm, Validate & create backorder - Redo the same step with backorder receipt OPW-3838250 OPW-3812937 closes odoo/odoo#163553 X-original-commit: db78c0bdd4a50e094f8867b58b651e06a8822a8a Signed-off-by: William Henrotin (whe) <whe@odoo.com> Signed-off-by: David Fesquet (dafr) <dafr@odoo.com>
This commit is contained in:
@@ -276,19 +276,9 @@ class StockMove(models.Model):
|
||||
|
||||
def _prepare_move_split_vals(self, qty):
|
||||
vals = super(StockMove, self)._prepare_move_split_vals(qty)
|
||||
if self.is_subcontract:
|
||||
vals['move_orig_ids'] = [] if not self.move_orig_ids else [(4, self.move_orig_ids[-1].id)]
|
||||
vals['location_id'] = self.location_id.id
|
||||
return vals
|
||||
|
||||
def _split(self, qty, restrict_partner_id=False):
|
||||
self.ensure_one()
|
||||
new_move_vals = super()._split(qty=qty, restrict_partner_id=restrict_partner_id)
|
||||
# Update the origin moves to remove the split one
|
||||
if self.move_orig_ids and self.is_subcontract:
|
||||
self.move_orig_ids = (self.move_orig_ids - self.move_orig_ids[-1]).ids
|
||||
return new_move_vals
|
||||
|
||||
def _should_bypass_reservation(self, forced_location=False):
|
||||
""" If the move is subcontracted then ignore the reservation. """
|
||||
should_bypass_reservation = super()._should_bypass_reservation(forced_location=forced_location)
|
||||
|
||||
@@ -709,6 +709,66 @@ class TestSubcontractingFlows(TestMrpSubcontractingCommon):
|
||||
|
||||
self.assertEqual(self.env['mrp.production'].search_count([('bom_id', '=', bom.id)]), 3)
|
||||
|
||||
def test_several_backorders_2(self):
|
||||
# This test ensure that the backorders finished moves are correctly made (Production -> Subcontracting -> Stock)
|
||||
# When the receipt is done, the Subcontracting location should have 0 quantity of the finished product.
|
||||
# In more detail, this test checks that everything is done correctly
|
||||
# when the quantity of the backorder is set on the stock.move.line instead of the stock.move,
|
||||
# it can for example happens if the finished product is tracked by Serial Number.
|
||||
|
||||
def process_picking_with_backorder(picking, qty):
|
||||
# Process the picking by putting the given quantity on the stock.move.line
|
||||
picking.move_line_ids.ensure_one().qty_done = qty
|
||||
action = picking.button_validate()
|
||||
if isinstance(action, dict):
|
||||
wizard = Form(self.env[action['res_model']].with_context(action['context'])).save()
|
||||
wizard.process()
|
||||
return picking.backorder_ids
|
||||
|
||||
def check_quants(product, stock_qty, sub_qty, prod_qty):
|
||||
# Check the quantities of the Stock, Subcontracting and Production locations for the given product
|
||||
subcontracting_location = self.env.company.subcontracting_location_id
|
||||
production_location = product.property_stock_production
|
||||
stock_location = self.env.ref('stock.stock_location_stock')
|
||||
|
||||
self.assertEqual(sub_qty, self.env['stock.quant']._gather(product, subcontracting_location).quantity)
|
||||
self.assertEqual(stock_qty, self.env['stock.quant']._gather(product, stock_location).quantity)
|
||||
self.assertEqual(prod_qty, self.env['stock.quant']._gather(product, production_location).quantity)
|
||||
|
||||
in_pck_type = self.env.ref('stock.picking_type_in')
|
||||
in_pck_type.write({'show_operations': True, 'show_reserved': True})
|
||||
|
||||
finished = self.env['product.product'].create({'name': 'Finished Product', 'type': 'product'})
|
||||
component = self.env['product.product'].create([{'name': 'Component', 'type': 'product'}])
|
||||
self.env['mrp.bom'].create({
|
||||
'product_tmpl_id': finished.product_tmpl_id.id,
|
||||
'product_qty': 1.0,
|
||||
'type': 'subcontract',
|
||||
'subcontractor_ids': [(4, self.subcontractor_partner1.id)],
|
||||
'bom_line_ids': [(0, 0, {'product_id': component.id, 'product_qty': 1.0})],
|
||||
})
|
||||
|
||||
picking_form = Form(self.env['stock.picking'])
|
||||
picking_form.picking_type_id = in_pck_type
|
||||
picking_form.partner_id = self.subcontractor_partner1
|
||||
with picking_form.move_ids_without_package.new() as move:
|
||||
move.product_id = finished
|
||||
move.product_uom_qty = 6
|
||||
picking = picking_form.save()
|
||||
picking.action_confirm()
|
||||
|
||||
backorder01 = process_picking_with_backorder(picking, 1)
|
||||
check_quants(product=finished, stock_qty=1, sub_qty=0, prod_qty=-1)
|
||||
check_quants(product=component, stock_qty=0, sub_qty=-1, prod_qty=1)
|
||||
|
||||
backorder02 = process_picking_with_backorder(backorder01, 2)
|
||||
check_quants(product=finished, stock_qty=3, sub_qty=0, prod_qty=-3)
|
||||
check_quants(product=component, stock_qty=0, sub_qty=-3, prod_qty=3)
|
||||
|
||||
process_picking_with_backorder(backorder02, 3)
|
||||
check_quants(product=finished, stock_qty=6, sub_qty=0, prod_qty=-6)
|
||||
check_quants(product=component, stock_qty=0, sub_qty=-6, prod_qty=6)
|
||||
|
||||
def test_subcontracting_rules_replication(self):
|
||||
""" Test activate/archive subcontracting location rules."""
|
||||
reference_location_rules = self.env['stock.rule'].search(['|', ('location_src_id', '=', self.env.company.subcontracting_location_id.id), ('location_dest_id', '=', self.env.company.subcontracting_location_id.id)])
|
||||
|
||||
Reference in New Issue
Block a user