[FIX] mrp: lock MOs by default

Previous specification of making MOs unlocked by default was confusing
for users and made it too easy to accidentally change the qty to consume
rather than the consumed amount. This fix makes it so MOs are now locked
by default and will be unlocked/locked (including existing draft /
confirmed / in progress MOs) automatically when setting is changed.
Previous setting (Lock Quantities To Consume) has been repurposed for
this. When setting is active, no lock/unlock button will be visible to
match the updated setting description (i.e. non-done MOs can
never be locked).

Task: 2518523
ENT PR (only fixes test): odoo/enterprise#19732
Upgrade PR: odoo/upgrade#2655
This commit is contained in:
Tiffany Chang (tic)
2021-07-26 11:57:50 +00:00
parent d5ba4e032b
commit 1e2c03a47d
7 changed files with 24 additions and 9 deletions
+6 -2
View File
@@ -69,7 +69,7 @@ class MrpProduction(models.Model):
@api.model
def _get_default_is_locked(self):
return self.user_has_groups('mrp.group_locked_by_default')
return not self.user_has_groups('mrp.group_unlocked_by_default')
name = fields.Char(
'Reference', copy=False, readonly=True, default=lambda x: _('New'))
@@ -501,7 +501,11 @@ class MrpProduction(models.Model):
@api.depends('state')
def _compute_show_lock(self):
for order in self:
order.show_lock = self.env.user.has_group('mrp.group_locked_by_default') and order.id is not False and order.state not in {'cancel', 'draft'}
order.show_lock = order.state == 'done' or (
not self.env.user.has_group('mrp.group_unlocked_by_default')
and order.id is not False
and order.state not in {'cancel', 'draft'}
)
@api.depends('state','move_raw_ids')
def _compute_show_lot_ids(self):
+9 -1
View File
@@ -19,7 +19,7 @@ class ResConfigSettings(models.TransientModel):
module_mrp_subcontracting = fields.Boolean("Subcontracting")
group_mrp_routings = fields.Boolean("MRP Work Orders",
implied_group='mrp.group_mrp_routings')
group_locked_by_default = fields.Boolean("Lock Quantities To Consume", implied_group='mrp.group_locked_by_default')
group_unlocked_by_default = fields.Boolean("Unlock Manufacturing Orders", implied_group='mrp.group_unlocked_by_default')
@api.onchange('use_manufacturing_lead')
def _onchange_use_manufacturing_lead(self):
@@ -38,3 +38,11 @@ class ResConfigSettings(models.TransientModel):
self.module_mrp_workorder = True
else:
self.module_mrp_workorder = False
@api.onchange('group_unlocked_by_default')
def _onchange_group_unlocked_by_default(self):
""" When changing this setting, we want existing MOs to automatically update to match setting. """
if self.group_unlocked_by_default:
self.env['mrp.production'].search([('state', 'not in', ('cancel', 'done')), ('is_locked', '=', True)]).is_locked = False
else:
self.env['mrp.production'].search([('state', 'not in', ('cancel', 'done')), ('is_locked', '=', False)]).is_locked = True
+2 -2
View File
@@ -30,8 +30,8 @@
<field name="category_id" ref="base.module_category_hidden"/>
</record>
<record id="group_locked_by_default" model="res.groups">
<field name="name">Locked by default</field>
<record id="group_unlocked_by_default" model="res.groups">
<field name="name">Unlocked by default</field>
<field name="category_id" ref="base.module_category_hidden"/>
</record>
+2
View File
@@ -396,6 +396,7 @@ class TestMrpOrder(TestMrpCommon):
production = production_form.save()
production.action_confirm()
production.action_assign()
production.is_locked = False
production_form = Form(production)
# change the quantity producing and the initial demand
# in the same transaction
@@ -1027,6 +1028,7 @@ class TestMrpOrder(TestMrpCommon):
mo.bom_id.consumption = 'flexible' # Because we'll over-consume with a product not defined in the BOM
mo.action_assign()
mo.is_locked = False
mo_form = Form(mo)
mo_form.qty_producing = 3
+1
View File
@@ -467,6 +467,7 @@ class TestProcurement(TestMrpCommon):
self.assertEqual(len(mo), 1, "Manufacture order was not automatically created")
mo.action_assign()
mo.is_locked = False
self.assertEqual(mo.move_raw_ids.reserved_availability, 0, "No components should be reserved yet")
self.assertEqual(mo.product_qty, 15, "Quantity to produce should be picking demand + reordering rule max qty")
@@ -297,7 +297,7 @@ class TestMultistepManufacturingWarehouse(TestMrpCommon):
production = production_form.save()
production.action_confirm()
production.is_locked = False
production_form = Form(production)
with production_form.move_raw_ids.new() as move:
move.product_id = new_product
@@ -65,12 +65,12 @@
</div>
<div class="col-lg-6 col-12 o_setting_box" id="mrp_lock" title="Makes confirmed manufacturing orders locked rather than unlocked by default. This only applies to new manufacturing orders, not previously created ones.">
<div class="o_setting_left_pane">
<field name="group_locked_by_default"/>
<field name="group_unlocked_by_default"/>
</div>
<div class="o_setting_right_pane">
<label for="group_locked_by_default"/>
<label for="group_unlocked_by_default"/>
<div class="text-muted">
Prevent manufacturing users from modifying quantities to consume, unless a manager has unlocked the document
Allow manufacturing users to modify quantities to consume, without the need for prior approval
</div>
</div>
</div>