diff --git a/addons/mrp_subcontracting/models/stock_move.py b/addons/mrp_subcontracting/models/stock_move.py index dd4afc6eb1b..4dddcd35f19 100644 --- a/addons/mrp_subcontracting/models/stock_move.py +++ b/addons/mrp_subcontracting/models/stock_move.py @@ -16,6 +16,11 @@ class StockMove(models.Model): compute='_compute_show_subcontracting_details_visible' ) + @api.depends('is_subcontract', 'move_orig_ids.production_id') + def _compute_is_quantity_done_editable(self): + super()._compute_is_quantity_done_editable() + self.filtered(lambda m: m.is_subcontract).is_quantity_done_editable = False + def _compute_display_assign_serial(self): super(StockMove, self)._compute_display_assign_serial() for move in self: diff --git a/addons/mrp_subcontracting/tests/test_subcontracting.py b/addons/mrp_subcontracting/tests/test_subcontracting.py index 3056e11a5e7..a81edcc467c 100644 --- a/addons/mrp_subcontracting/tests/test_subcontracting.py +++ b/addons/mrp_subcontracting/tests/test_subcontracting.py @@ -651,6 +651,61 @@ class TestSubcontractingFlows(TestMrpSubcontractingCommon): self.assertEqual(self.env['mrp.production'].search_count([('bom_id', '=', bom.id)]), 3) + def test_several_backorders02(self): + """ + Receipt for 5 subcontracted products + Process three of them with backorder, then the remaining qty. The user + should never be able to define the produced qty directly on the + picking's SM. + """ + finished, component = self.env['product.product'].create([{ + 'name': 'Finished Product', + 'type': 'product', + }, { + '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 = self.env.ref('stock.picking_type_in') + 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 = 5 + picking = picking_form.save() + picking.action_confirm() + + for done_qty in [2, 3]: + with self.assertRaises(AssertionError): + with Form(picking) as picking_form: + with picking_form.move_ids_without_package.edit(0) as line: + line.quantity_done = done_qty + + action = picking.action_record_components() + mo = self.env['mrp.production'].browse(action['res_id']) + mo_form = Form(mo.with_context(**action['context']), view=action['view_id']) + mo_form.qty_producing = done_qty + mo = mo_form.save() + mo.subcontracting_record_component() + res = picking.button_validate() + + if res is not True: + wizard = Form(self.env[res['res_model']].with_context(res['context'])).save() + wizard.process() + picking = picking.backorder_ids + + productions = self.env['mrp.production'].search([('product_id', '=', finished.id)], order='id') + self.assertEqual(productions.mapped('state'), ['done', 'done']) + self.assertEqual(productions.move_raw_ids.mapped('quantity_done'), [2.0, 3.0]) + 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)]) diff --git a/addons/stock/models/stock_move.py b/addons/stock/models/stock_move.py index 21d26f774a1..a671011d366 100644 --- a/addons/stock/models/stock_move.py +++ b/addons/stock/models/stock_move.py @@ -270,14 +270,6 @@ class StockMove(models.Model): for move in self: if not move.product_id: move.is_quantity_done_editable = False - elif not move.picking_id.immediate_transfer and move.picking_id.state == 'draft': - move.is_quantity_done_editable = False - elif move.picking_id.is_locked and move.state in ('done', 'cancel'): - move.is_quantity_done_editable = False - elif move.show_details_visible: - move.is_quantity_done_editable = False - elif move.show_operations: - move.is_quantity_done_editable = False else: move.is_quantity_done_editable = True diff --git a/addons/stock/views/stock_picking_views.xml b/addons/stock/views/stock_picking_views.xml index f3b2da958f6..e3923fe7d42 100644 --- a/addons/stock/views/stock_picking_views.xml +++ b/addons/stock/views/stock_picking_views.xml @@ -307,7 +307,7 @@ -