[IMP] mrp: Remove mrp.immediate.production model

closes odoo/odoo#108446

Task: 3094741
Related: odoo/upgrade#4163
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
This commit is contained in:
JF Aubert
2023-01-11 13:20:48 +01:00
parent 74c1944ea0
commit 0cdf410a44
14 changed files with 73 additions and 223 deletions
-1
View File
@@ -21,7 +21,6 @@
'wizard/stock_warn_insufficient_qty_views.xml',
'wizard/mrp_production_backorder.xml',
'wizard/mrp_consumption_warning_views.xml',
'wizard/mrp_immediate_production_views.xml',
'wizard/stock_assign_serial_numbers.xml',
'wizard/mrp_production_split.xml',
'views/mrp_views_menus.xml',
+47 -35
View File
@@ -243,6 +243,8 @@ class MrpProduction(models.Model):
compute='_compute_show_allocation',
help='Technical Field used to decide whether the button "Allocation" should be displayed.')
allow_workorder_dependencies = fields.Boolean('Allow Work Order Dependencies')
show_produce = fields.Boolean(compute='_compute_show_produce', help='Technical field to check if produce button can be shown')
show_produce_all = fields.Boolean(compute='_compute_show_produce', help='Technical field to check if produce all button can be shown')
_sql_constraints = [
('name_uniq', 'unique(name, company_id)', 'Reference must be unique per Company!'),
@@ -734,6 +736,14 @@ class MrpProduction(models.Model):
Command.delete(move.id) for move in production.move_finished_ids if move.bom_line_id
]
@api.depends('state', 'product_qty', 'qty_producing')
def _compute_show_produce(self):
for production in self:
state_ok = production.state in ('confirmed', 'progress', 'to_close')
qty_none_or_all = production.qty_producing in (0, production.product_qty)
production.show_produce_all = state_ok and qty_none_or_all
production.show_produce = state_ok and not qty_none_or_all
@api.onchange('qty_producing', 'lot_producing_id')
def _onchange_producing(self):
self._set_qty_producing()
@@ -1217,19 +1227,6 @@ class MrpProduction(models.Model):
if self.product_id.tracking == 'serial':
self._set_qty_producing()
def _action_generate_immediate_wizard(self):
view = self.env.ref('mrp.view_immediate_production')
return {
'name': _('Immediate Production?'),
'type': 'ir.actions.act_window',
'view_mode': 'form',
'res_model': 'mrp.immediate.production',
'views': [(view.id, 'form')],
'view_id': view.id,
'target': 'new',
'context': dict(self.env.context, default_mo_ids=[(4, mo.id) for mo in self]),
}
def action_confirm(self):
self._check_company()
for production in self:
@@ -1349,7 +1346,7 @@ class MrpProduction(models.Model):
:rtype: list
"""
issues = []
if self.env.context.get('skip_consumption', False) or self.env.context.get('skip_immediate', False):
if self.env.context.get('skip_consumption', False):
return issues
for order in self:
if order.consumption == 'flexible' or not order.bom_id or not order.bom_id.bom_line_ids:
@@ -1755,8 +1752,6 @@ class MrpProduction(models.Model):
def button_mark_done(self):
self._button_mark_done_sanity_checks()
if not self.env.context.get('button_mark_done_production_ids'):
self = self.with_context(button_mark_done_production_ids=self.ids)
res = self._pre_button_mark_done()
if res is not True:
return res
@@ -1830,7 +1825,7 @@ class MrpProduction(models.Model):
action = {
'res_model': 'mrp.production',
'type': 'ir.actions.act_window',
'context': dict(context, mo_ids_to_backorder=None, button_mark_done_production_ids=None)
'context': dict(context, mo_ids_to_backorder=None)
}
if len(backorders) == 1:
action.update({
@@ -1846,19 +1841,24 @@ class MrpProduction(models.Model):
return action
def _pre_button_mark_done(self):
productions_to_immediate = self._check_immediate()
if productions_to_immediate:
return productions_to_immediate._action_generate_immediate_wizard()
immediate_productions = self.browse()
for production in self:
if not float_is_zero(production.qty_producing, precision_rounding=production.product_uom_id.rounding) or any(
not float_is_zero(ml.qty_done, precision_digits=ml.product_uom_id.rounding) for
ml in production.move_raw_ids.move_line_ids.filtered(lambda m: m.state not in ('done', 'cancel'))):
immediate_productions |= production
continue
production._set_quantities()
for production in immediate_productions:
if float_is_zero(production.qty_producing, precision_rounding=production.product_uom_id.rounding):
raise UserError(_('The quantity to produce must be positive!'))
if production.move_raw_ids and not any(production.move_raw_ids.mapped('quantity_done')):
raise UserError(_("You must indicate a non-zero amount consumed for at least one of your components"))
consumption_issues = self._get_consumption_issues()
consumption_issues = immediate_productions._get_consumption_issues()
if consumption_issues:
return self._action_generate_consumption_wizard(consumption_issues)
return immediate_productions._action_generate_consumption_wizard(consumption_issues)
quantity_issues = self._get_quantity_produced_issues()
if quantity_issues:
@@ -2178,18 +2178,6 @@ class MrpProduction(models.Model):
duplicates = co_prod_move_lines.filtered(lambda ml: ml.qty_done and ml.lot_id == lot)
return bool(duplicates)
def _check_immediate(self):
immediate_productions = self.browse()
if self.env.context.get('skip_immediate'):
return immediate_productions
pd = self.env['decimal.precision'].precision_get('Product Unit of Measure')
for production in self:
if all(float_is_zero(ml.qty_done, precision_digits=pd) for
ml in production.move_raw_ids.move_line_ids.filtered(lambda m: m.state not in ('done', 'cancel'))
) and float_is_zero(production.qty_producing, precision_digits=pd):
immediate_productions |= production
return immediate_productions
def _pre_action_split_merge_hook(self, merge=False, split=False):
if not merge and not split:
return True
@@ -2228,3 +2216,27 @@ class MrpProduction(models.Model):
continue
vals['move_orig_ids'] = [Command.set(vals['move_orig_ids'])]
return origs
def _set_quantities(self):
self.ensure_one()
missing_lot_id_products = ""
if self.product_tracking in ('lot', 'serial') and not self.lot_producing_id:
self.action_generate_serial()
if self.product_tracking == 'serial' and float_compare(self.qty_producing, 1, precision_rounding=self.product_uom_id.rounding) == 1:
self.qty_producing = 1
else:
self.qty_producing = self.product_qty - self.qty_produced
self._set_qty_producing()
for move in self.move_raw_ids.filtered(lambda m: m.state not in ['done', 'cancel']):
rounding = move.product_uom.rounding
for move_line in move.move_line_ids:
if move_line.reserved_uom_qty:
move_line.qty_done = min(move_line.reserved_uom_qty, move_line.move_id.should_consume_qty)
if float_compare(move.quantity_done, move.should_consume_qty, precision_rounding=rounding) >= 0:
break
if float_compare(move.product_uom_qty, move.quantity_done, precision_rounding=move.product_uom.rounding) == 1:
if move.has_tracking in ('serial', 'lot'):
missing_lot_id_products += "\n - %s" % move.product_id.display_name
if missing_lot_id_products:
error_msg = _('You need to supply Lot/Serial Number for products:') + missing_lot_id_products
raise UserError(error_msg)
-2
View File
@@ -54,8 +54,6 @@ access_mrp_production_backorder,access.mrp.production.backorder,model_mrp_produc
access_mrp_production_backorder_line,access.mrp.production.backorder.line,model_mrp_production_backorder_line,mrp.group_mrp_user,1,1,1,0
access_mrp_consumption_warning,access.mrp.consumption.warning,model_mrp_consumption_warning,mrp.group_mrp_user,1,1,1,0
access_mrp_consumption_warning_line,access.mrp.consumption.warning.line,model_mrp_consumption_warning_line,mrp.group_mrp_user,1,1,1,0
access_mrp_immediate_production,access.mrp.immediate.production,model_mrp_immediate_production,mrp.group_mrp_user,1,1,1,0
access_mrp_immediate_production_line,access.mrp.immediate.production.line,model_mrp_immediate_production_line,mrp.group_mrp_user,1,1,1,0
access_mrp_workcenter_tag_group_user,access.mrp.workcenter.tag,model_mrp_workcenter_tag,mrp.group_mrp_user,1,0,0,0
access_mrp_workcenter_tag_manager,access.mrp.workcenter.tag,model_mrp_workcenter_tag,mrp.group_mrp_manager,1,1,1,1
access_mrp_production_split_multi,access.mrp.production.split.multi,model_mrp_production_split_multi,mrp.group_mrp_user,1,1,1,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
54 access_mrp_production_backorder_line access.mrp.production.backorder.line model_mrp_production_backorder_line mrp.group_mrp_user 1 1 1 0
55 access_mrp_consumption_warning access.mrp.consumption.warning model_mrp_consumption_warning mrp.group_mrp_user 1 1 1 0
56 access_mrp_consumption_warning_line access.mrp.consumption.warning.line model_mrp_consumption_warning_line mrp.group_mrp_user 1 1 1 0
access_mrp_immediate_production access.mrp.immediate.production model_mrp_immediate_production mrp.group_mrp_user 1 1 1 0
access_mrp_immediate_production_line access.mrp.immediate.production.line model_mrp_immediate_production_line mrp.group_mrp_user 1 1 1 0
57 access_mrp_workcenter_tag_group_user access.mrp.workcenter.tag model_mrp_workcenter_tag mrp.group_mrp_user 1 0 0 0
58 access_mrp_workcenter_tag_manager access.mrp.workcenter.tag model_mrp_workcenter_tag mrp.group_mrp_manager 1 1 1 1
59 access_mrp_production_split_multi access.mrp.production.split.multi model_mrp_production_split_multi mrp.group_mrp_user 1 1 1 0
@@ -220,14 +220,4 @@ class TestConsumeTrackedComponentCommon(common.TransactionCase):
i += 1
if isAvailable:
mark_done_action = mrp_productions[i].button_mark_done()
immediate_production_wizard = Form(
self.env['mrp.immediate.production']
.with_context(**mark_done_action['context'])
).save()
error = False
try:
immediate_production_wizard.process()
except UserError:
error = True
self.assertFalse(error, "Immediate Production Wizard shall not raise an error.")
mrp_productions[i].button_mark_done()
+1 -7
View File
@@ -291,9 +291,6 @@ class TestMrpProductionBackorder(TestMrpCommon):
self.env['stock.quant']._update_available_quantity(p2, self.stock_location_components, 2.0)
mo.action_assign()
res_dict = mo.button_mark_done()
self.assertEqual(res_dict.get('res_model'), 'mrp.immediate.production')
immediate_wizard = Form(self.env[res_dict['res_model']].with_context(res_dict['context'])).save()
res_dict = immediate_wizard.process()
self.assertEqual(res_dict.get('res_model'), 'mrp.production.backorder')
backorder_wizard = Form(self.env[res_dict['res_model']].with_context(res_dict['context']))
@@ -302,10 +299,7 @@ class TestMrpProductionBackorder(TestMrpCommon):
self.assertEqual(action.get('res_model'), 'mrp.production')
backorder_mo_form = Form(self.env[action['res_model']].with_context(action['context']).browse(action['res_id']))
backorder_mo = backorder_mo_form.save()
res_dict = backorder_mo.button_mark_done()
self.assertEqual(res_dict.get('res_model'), 'mrp.immediate.production')
immediate_wizard = Form(self.env[res_dict['res_model']].with_context(res_dict['context'])).save()
immediate_wizard.process()
backorder_mo.button_mark_done()
self.assertEqual(self.env['stock.quant']._get_available_quantity(p_final, self.stock_location), 2, "Incorrect number of final product produced.")
self.assertEqual(len(self.env['stock.lot'].search([('product_id', '=', p_final.id)])), 2, "Serial Numbers were not correctly produced.")
+7 -37
View File
@@ -1598,9 +1598,6 @@ class TestMrpOrder(TestMrpCommon):
self.env['stock.quant']._update_available_quantity(p2, self.stock_location_components, 5.0)
mo.action_assign()
res_dict = mo.button_mark_done()
self.assertEqual(res_dict.get('res_model'), 'mrp.immediate.production')
wizard = Form(self.env[res_dict['res_model']].with_context(res_dict['context'])).save()
wizard.process()
self.assertEqual(mo.move_raw_ids.mapped('state'), ['done', 'done'])
self.assertEqual(mo.move_raw_ids.mapped('quantity_done'), [1, 1])
self.assertEqual(mo.move_finished_ids.state, 'done')
@@ -1628,9 +1625,6 @@ class TestMrpOrder(TestMrpCommon):
self.env['stock.quant']._update_available_quantity(p2, self.stock_location_components, 5.0)
mo.action_assign()
action = mo.button_mark_done()
self.assertEqual(action.get('res_model'), 'mrp.immediate.production')
wizard = Form(self.env[action['res_model']].with_context(action['context'])).save()
action = wizard.process()
self.assertEqual(action.get('res_model'), 'mrp.production.backorder')
wizard = Form(self.env[action['res_model']].with_context(action['context'])).save()
action = wizard.action_backorder()
@@ -1648,9 +1642,6 @@ class TestMrpOrder(TestMrpCommon):
self.env['stock.quant']._update_available_quantity(p1, self.stock_location_components, 5.0)
self.env['stock.quant']._update_available_quantity(p2, self.stock_location_components, 5.0)
action = mo.button_mark_done()
self.assertEqual(action.get('res_model'), 'mrp.immediate.production')
wizard = Form(self.env[action['res_model']].with_context(action['context'])).save()
action = wizard.process()
self.assertEqual(action.get('res_model'), 'mrp.production.backorder')
wizard = Form(self.env[action['res_model']].with_context(action['context'])).save()
action = wizard.action_backorder()
@@ -1682,10 +1673,7 @@ class TestMrpOrder(TestMrpCommon):
mo3.action_confirm()
mo3.action_assign()
mos = mo1 | mo2 | mo3
res_dict = mos.button_mark_done()
self.assertEqual(res_dict.get('res_model'), 'mrp.immediate.production')
wizard = Form(self.env[res_dict['res_model']].with_context(res_dict['context'])).save()
wizard.process()
mos.button_mark_done()
self.assertEqual(mos.move_raw_ids.mapped('state'), ['done'] * 6)
self.assertEqual(mos.move_raw_ids.mapped('quantity_done'), [1] * 6)
self.assertEqual(mos.move_finished_ids.mapped('state'), ['done'] * 3)
@@ -1749,10 +1737,7 @@ class TestMrpOrder(TestMrpCommon):
self.env['stock.quant']._update_available_quantity(p1, self.stock_location_components, 5.0)
self.env['stock.quant']._update_available_quantity(p2, self.stock_location_components, 5.0)
mo.action_assign()
res_dict = mo.button_mark_done()
self.assertEqual(res_dict.get('res_model'), 'mrp.immediate.production')
wizard = Form(self.env[res_dict['res_model']].with_context(res_dict['context'])).save()
wizard.process()
mo.button_mark_done()
self.assertEqual(mo.move_raw_ids.mapped('state'), ['done'] * 2)
self.assertEqual(mo.move_raw_ids.mapped('quantity_done'), [1] * 2)
self.assertEqual(mo.move_finished_ids.state, 'done')
@@ -1787,10 +1772,7 @@ class TestMrpOrder(TestMrpCommon):
mo = mo_form.save()
mo.action_confirm()
mo.action_assign()
res_dict = mo.button_mark_done()
self.assertEqual(res_dict.get('res_model'), 'mrp.immediate.production')
wizard = Form(self.env[res_dict['res_model']].with_context(res_dict['context'])).save()
wizard.process()
mo.button_mark_done()
self.assertEqual(mo.move_raw_ids.state, 'done')
self.assertEqual(mo.move_raw_ids.quantity_done, 12)
self.assertEqual(mo.move_finished_ids.state, 'done')
@@ -1848,10 +1830,7 @@ class TestMrpOrder(TestMrpCommon):
mo_form.bom_id = bom
mo = mo_form.save()
mo.action_confirm()
action = mo.button_mark_done()
self.assertEqual(action.get('res_model'), 'mrp.immediate.production')
wizard = Form(self.env[action['res_model']].with_context(action['context'])).save()
action = wizard.process()
mo.button_mark_done()
self.assertEqual(mo.move_raw_ids.product_uom_qty, 0.2)
self.assertEqual(mo.move_raw_ids.quantity_done, 0.2)
@@ -1968,10 +1947,7 @@ class TestMrpOrder(TestMrpCommon):
self.assertEqual(mo_product_final_form.reservation_state, 'assigned')
# produce
res_dict = mo_product_final_form.button_mark_done()
self.assertEqual(res_dict.get('res_model'), 'mrp.immediate.production')
wizard = Form(self.env[res_dict['res_model']].with_context(res_dict['context'])).save()
wizard.process()
mo_product_final_form.button_mark_done()
# check that in _generate_consumed_move_line,
# we do not create an extra move line because
@@ -2056,10 +2032,7 @@ class TestMrpOrder(TestMrpCommon):
self.assertEqual(mo_2.workorder_ids[0].state, 'waiting')
# produce
res_dict = (mo_1 | mo_2).button_mark_done()
self.assertEqual(res_dict.get('res_model'), 'mrp.immediate.production')
wizard = Form(self.env[res_dict['res_model']].with_context(res_dict['context'])).save()
wizard.process()
(mo_1 | mo_2).button_mark_done()
self.assertEqual(mo_1.state, 'done')
self.assertEqual(mo_2.state, 'done')
@@ -2224,10 +2197,7 @@ class TestMrpOrder(TestMrpCommon):
mo.action_assign()
self.assertEqual(list(mo.workorder_ids.mapped("state")), ["ready"])
res_dict = mo.button_mark_done()
self.assertEqual(res_dict.get('res_model'), 'mrp.immediate.production')
wizard = Form(self.env[res_dict['res_model']].with_context(res_dict['context'])).save()
wizard.process()
mo.button_mark_done()
self.assertEqual(list(mo.workorder_ids.mapped("state")), ["done"])
def test_products_with_variants(self):
+1 -3
View File
@@ -413,9 +413,7 @@ class TestTraceability(TestMrpCommon):
mo_form.product_qty = 15
mo = mo_form.save()
mo.action_confirm()
action = mo.button_mark_done()
wizard = Form(self.env[action['res_model']].with_context(action['context'])).save()
wizard.process()
mo.button_mark_done()
# Produce 15 x productB
mo_form = Form(self.env['mrp.production'])
+13 -12
View File
@@ -92,25 +92,25 @@
<header>
<field name="confirm_cancel" invisible="1"/>
<field name="show_lock" invisible="1"/>
<button name="button_mark_done" attrs="{'invisible': ['|', '|', ('state', 'in', ('draft', 'cancel', 'done', 'to_close')), ('qty_producing', '=', 0), ('move_raw_ids', '!=', [])]}" string="Validate" type="object" class="oe_highlight"
confirm="There are no components to consume. Are you still sure you want to continue?" data-hotkey="g"/>
<button name="button_mark_done" attrs="{'invisible': ['|', '|', ('state', 'in', ('draft', 'cancel', 'done', 'to_close')), ('qty_producing', '=', 0), ('move_raw_ids', '=', [])]}" string="Validate" type="object" class="oe_highlight" data-hotkey="g"/>
<field name="show_produce" invisible="1"/>
<field name="show_produce_all" invisible="1"/>
<button name="button_mark_done" attrs="{'invisible': [
'|',
('move_raw_ids', '=', []),
'&amp;',
('show_produce', '=', False)]}" string="Produce" type="object" class="oe_highlight" data-hotkey="g"/>
<button name="button_mark_done" attrs="{'invisible': [
'|',
('state', 'not in', ('confirmed', 'progress')),
('qty_producing', '!=', 0),
('state', '!=', 'to_close')]}" string="Mark as Done" type="object" class="oe_highlight" data-hotkey="g"/>
('move_raw_ids', '=', []),
('show_produce_all', '=', False)]}" string="Produce All" type="object" class="oe_highlight" data-hotkey="g"/>
<button name="button_mark_done" attrs="{'invisible': [
'|',
('move_raw_ids', '!=', []),
'&amp;',
('show_produce', '=', False)]}" string="Produce" type="object" class="oe_highlight" data-hotkey="g"
confirm="There are no components to consume. Are you still sure you want to continue?"/>
<button name="button_mark_done" attrs="{'invisible': [
'|',
('state', 'not in', ('confirmed', 'progress')),
('qty_producing', '!=', 0),
('state', '!=', 'to_close')]}" string="Mark as Done" type="object" class="oe_highlight" data-hotkey="g"
('move_raw_ids', '!=', []),
('show_produce_all', '=', False)]}" string="Produce All" type="object" class="oe_highlight" data-hotkey="g"
confirm="There are no components to consume. Are you still sure you want to continue?"/>
<button name="action_confirm" attrs="{'invisible': [('state', '!=', 'draft')]}" string="Confirm" type="object" class="oe_highlight" data-hotkey="v"/>
<button name="button_plan" attrs="{'invisible': ['|', '|', ('state', 'not in', ('confirmed', 'progress', 'to_close')), ('workorder_ids', '=', []), ('is_planned', '=', True)]}" type="object" string="Plan" class="oe_highlight" data-hotkey="x"/>
@@ -330,7 +330,8 @@
<field name="location_dest_id" domain="[('id', 'child_of', parent.location_dest_id)]" invisible="1"/>
<field name="state" invisible="1" force_save="1"/>
<field name="should_consume_qty" invisible="1"/>
<field name="product_uom_qty" widget="mrp_should_consume" force_save="1" string="To Consume" attrs="{'readonly': ['&amp;', ('parent.state', '!=', 'draft'), '|', '&amp;', ('parent.state', 'not in', ('confirmed', 'progress', 'to_close')), ('parent.is_planned', '!=', True), ('parent.is_locked', '=', True)]}"/>
<field name="product_uom_qty" force_save="1" string="To Consume" attrs="{'readonly': ['&amp;', ('parent.state', '!=', 'draft'), '|', '&amp;', ('parent.state', 'not in', ('confirmed', 'progress', 'to_close')), ('parent.is_planned', '!=', True), ('parent.is_locked', '=', True)], 'column_invisible': [('parent.show_produce_all', '=', False)]}"/>
<field name="product_uom_qty" widget="mrp_should_consume" force_save="1" string="To Consume" attrs="{'readonly': ['&amp;', ('parent.state', '!=', 'draft'), '|', '&amp;', ('parent.state', 'not in', ('confirmed', 'progress', 'to_close')), ('parent.is_planned', '!=', True), ('parent.is_locked', '=', True)], 'column_invisible': [('parent.show_produce_all', '=', True)]}"/>
<field name="product_uom" attrs="{'readonly': [('state', '!=', 'draft'), ('id', '!=', False)]}" options="{'no_open': True, 'no_create': True}" groups="uom.group_uom"/>
<field name="product_type" invisible="1"/>
<field name="product_qty" invisible="1" readonly="1"/>
-1
View File
@@ -5,6 +5,5 @@ from . import change_production_qty
from . import stock_warn_insufficient_qty
from . import mrp_production_backorder
from . import mrp_consumption_warning
from . import mrp_immediate_production
from . import stock_assign_serial_numbers
from . import mrp_production_split
@@ -1,81 +0,0 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import _, api, fields, models
from odoo.exceptions import UserError
from odoo.tools import float_compare
class MrpImmediateProductionLine(models.TransientModel):
_name = 'mrp.immediate.production.line'
_description = 'Immediate Production Line'
immediate_production_id = fields.Many2one('mrp.immediate.production', 'Immediate Production', required=True)
production_id = fields.Many2one('mrp.production', 'Production', required=True)
to_immediate = fields.Boolean('To Process')
class MrpImmediateProduction(models.TransientModel):
_name = 'mrp.immediate.production'
_description = 'Immediate Production'
@api.model
def default_get(self, fields):
res = super().default_get(fields)
if 'immediate_production_line_ids' in fields:
if self.env.context.get('default_mo_ids'):
res['mo_ids'] = self.env.context['default_mo_ids']
res['immediate_production_line_ids'] = [(0, 0, {'to_immediate': True, 'production_id': mo_id[1]}) for mo_id in res['mo_ids']]
return res
mo_ids = fields.Many2many('mrp.production', 'mrp_production_production_rel')
show_productions = fields.Boolean(compute='_compute_show_production')
immediate_production_line_ids = fields.One2many(
'mrp.immediate.production.line',
'immediate_production_id',
string="Immediate Production Lines")
@api.depends('immediate_production_line_ids')
def _compute_show_production(self):
for wizard in self:
wizard.show_productions = len(wizard.immediate_production_line_ids.production_id) > 1
def process(self):
productions_to_do = self.env['mrp.production']
productions_not_to_do = self.env['mrp.production']
for line in self.immediate_production_line_ids:
if line.to_immediate is True:
productions_to_do |= line.production_id
else:
productions_not_to_do |= line.production_id
for production in productions_to_do:
error_msg = ""
if production.product_tracking in ('lot', 'serial') and not production.lot_producing_id:
production.action_generate_serial()
if production.product_tracking == 'serial' and float_compare(production.qty_producing, 1, precision_rounding=production.product_uom_id.rounding) == 1:
production.qty_producing = 1
else:
production.qty_producing = production.product_qty - production.qty_produced
production._set_qty_producing()
for move in production.move_raw_ids.filtered(lambda m: m.state not in ['done', 'cancel']):
rounding = move.product_uom.rounding
for move_line in move.move_line_ids:
if move_line.reserved_uom_qty:
move_line.qty_done = min(move_line.reserved_uom_qty, move_line.move_id.should_consume_qty)
if float_compare(move.quantity_done, move.should_consume_qty, precision_rounding=rounding) >= 0:
break
if float_compare(move.product_uom_qty, move.quantity_done, precision_rounding=move.product_uom.rounding) == 1:
if move.has_tracking in ('serial', 'lot'):
error_msg += "\n - %s" % move.product_id.display_name
if error_msg:
error_msg = _('You need to supply Lot/Serial Number for products:') + error_msg
raise UserError(error_msg)
productions_to_validate = self.env.context.get('button_mark_done_production_ids')
if productions_to_validate:
productions_to_validate = self.env['mrp.production'].browse(productions_to_validate)
productions_to_validate = productions_to_validate - productions_not_to_do
return productions_to_validate.with_context(skip_immediate=True).button_mark_done()
return True
@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record id="view_immediate_production" model="ir.ui.view">
<field name="name">mrp.immediate.production.view.form</field>
<field name="model">mrp.immediate.production</field>
<field name="arch" type="xml">
<form string="Immediate production?">
<group>
<p colspan="2">You have not recorded <i>produced</i> quantities yet, by clicking on <i>apply</i> Odoo will produce all the finished products and consume all components.</p>
</group>
<field name="show_productions" invisible="1"/>
<field name="immediate_production_line_ids" nolabel="1" attrs="{'invisible': [('show_productions', '=', False)]}">>
<tree create="0" delete="0" editable="top">
<field name="production_id"/>
<field name="to_immediate" widget="boolean_toggle"/>
</tree>
</field>
<footer>
<button name="process" string="Apply" type="object" class="btn-primary" data-hotkey="q"/>
<button string="Cancel" class="btn-secondary" special="cancel" data-hotkey="z" />
</footer>
</form>
</field>
</record>
</odoo>
@@ -219,8 +219,7 @@ class TestAnalyticAccount(TestMrpAnalyticAccount):
self.assertEqual(len(mo.move_raw_ids.analytic_account_line_id), 0)
# Mark as done
wizard_dict = mo.button_mark_done()
Form(self.env[(wizard_dict.get('res_model'))].with_context(wizard_dict['context'])).save().process()
mo.button_mark_done()
self.assertEqual(mo.state, 'done')
self.assertEqual(len(mo.move_raw_ids.analytic_account_line_id), 1)
+1 -3
View File
@@ -90,9 +90,7 @@ class TestRepairTraceability(TestMrpCommon):
mo = mo_form.save()
mo.action_confirm()
mo.action_assign()
action = mo.button_mark_done()
wizard = Form(self.env[action['res_model']].with_context(action['context'])).save()
wizard.process()
mo.button_mark_done()
return mo
stock_location = self.env.ref('stock.stock_location_stock')
@@ -765,7 +765,7 @@ tour.stepUtils.openBuggerMenu("li.breadcrumb-item.active:contains('Manufacturing
run: "text 1",
},
...tour.stepUtils.statusbarButtonsSteps('Mark as Done', _t("Mark as Done"), ".o_statusbar_status .btn.dropdown-toggle:contains('To Close')"),
...tour.stepUtils.statusbarButtonsSteps('Produce All', _t("Produce All"), ".o_statusbar_status .btn.dropdown-toggle:contains('To Close')"),
{
edition: "enterprise",
trigger: '.o_menu_toggle',