diff --git a/addons/mrp/models/mrp_bom.py b/addons/mrp/models/mrp_bom.py index 1d1a580330d..50688201799 100644 --- a/addons/mrp/models/mrp_bom.py +++ b/addons/mrp/models/mrp_bom.py @@ -141,6 +141,15 @@ class MrpBom(models.Model): self.operation_ids.bom_product_template_attribute_value_ids = False self.byproduct_ids.bom_product_template_attribute_value_ids = False + domain = [('product_tmpl_id', '=', self.product_tmpl_id.id)] + if self.id.origin: + domain.append(('id', '!=', self.id.origin)) + number_of_bom_of_this_product = self.env['mrp.bom'].search_count(domain) + if number_of_bom_of_this_product: # add a reference to the bom if there is already a bom for this product + self.code = _("%s (new) %s", self.product_tmpl_id.name, number_of_bom_of_this_product) + else: + self.code = False + def copy(self, default=None): res = super().copy(default) for bom_line in res.bom_line_ids: @@ -446,6 +455,7 @@ class MrpByProduct(models.Model): _description = 'Byproduct' _rec_name = "product_id" _check_company_auto = True + _order = 'sequence, id' product_id = fields.Many2one('product.product', 'By-product', required=True, check_company=True) company_id = fields.Many2one(related='bom_id.company_id', store=True, index=True, readonly=True) @@ -465,6 +475,7 @@ class MrpByProduct(models.Model): 'product.template.attribute.value', string="Apply on Variants", ondelete='restrict', domain="[('id', 'in', possible_bom_product_template_attribute_value_ids)]", help="BOM Product Variants needed to apply this line.") + sequence = fields.Integer("Sequence") @api.onchange('product_id') def _onchange_product_id(self): diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py index a70db0196c5..1f105236eab 100644 --- a/addons/mrp/models/mrp_production.py +++ b/addons/mrp/models/mrp_production.py @@ -65,7 +65,7 @@ class MrpProduction(models.Model): def _get_default_date_planned_start(self): if self.env.context.get('default_date_deadline'): return fields.Datetime.to_datetime(self.env.context.get('default_date_deadline')) - return datetime.datetime.now() + return fields.Datetime.now().replace(minute=0, second=0, microsecond=0) + datetime.timedelta(hours=1) @api.model def _get_default_is_locked(self): @@ -143,6 +143,10 @@ class MrpProduction(models.Model): help="Informative date allowing to define when the manufacturing order should be processed at the latest to fulfill delivery on time.") date_start = fields.Datetime('Start Date', copy=False, readonly=True, help="Date of the WO") date_finished = fields.Datetime('End Date', copy=False, readonly=True, help="Date when the MO has been close") + + production_duration_expected = fields.Float("Expected Duration", help="Total expected duration (in minutes)", compute='_compute_production_duration_expected') + production_real_duration = fields.Float("Real Duration", help="Total real duration (in minutes)", compute='_compute_production_real_duration') + bom_id = fields.Many2one( 'mrp.bom', 'Bill of Material', readonly=True, states={'draft': [('readonly', False)]}, @@ -308,6 +312,16 @@ class MrpProduction(models.Model): for production in self: production.move_finished_ids.date_deadline = production.date_deadline + @api.depends('workorder_ids.duration_expected') + def _compute_production_duration_expected(self): + for production in self: + production.production_duration_expected = sum(production.workorder_ids.mapped('duration_expected')) + + @api.depends('workorder_ids.duration') + def _compute_production_real_duration(self): + for production in self: + production.production_real_duration = sum(production.workorder_ids.mapped('duration')) + @api.depends("workorder_ids.date_planned_start", "workorder_ids.date_planned_finished") def _compute_is_planned(self): for production in self: diff --git a/addons/mrp/models/mrp_workcenter.py b/addons/mrp/models/mrp_workcenter.py index 5c65f0f45ab..94d220072b7 100644 --- a/addons/mrp/models/mrp_workcenter.py +++ b/addons/mrp/models/mrp_workcenter.py @@ -6,6 +6,7 @@ from datetime import timedelta from functools import partial import datetime from pytz import timezone +from random import randint from odoo import api, exceptions, fields, models, _ from odoo.exceptions import ValidationError @@ -71,6 +72,7 @@ class MrpWorkcenter(models.Model): string="Alternative Workcenters", check_company=True, help="Alternative workcenters that can be substituted to this one in order to dispatch production" ) + tag_ids = fields.Many2many('mrp.workcenter.tag') @api.constrains('alternative_workcenter_ids') def _check_alternative_workcenter(self): @@ -264,6 +266,23 @@ class MrpWorkcenter(models.Model): return False, 'Not available slot 700 days after the planned start' +class WorkcenterTag(models.Model): + _name = 'mrp.workcenter.tag' + _description = 'Add tag for the workcenter' + _order = 'name' + + def _get_default_color(self): + return randint(1, 11) + + name = fields.Char("Tag Name", required=True) + color = fields.Integer("Color Index", default=_get_default_color) + + _sql_constraints = [ + ('tag_name_unique', 'unique(name)', + 'The tag name must be unique.'), + ] + + class MrpWorkcenterProductivityLossType(models.Model): _name = "mrp.workcenter.productivity.loss.type" _description = 'MRP Workorder productivity losses' diff --git a/addons/mrp/security/ir.model.access.csv b/addons/mrp/security/ir.model.access.csv index a7bfdbff69d..829a386dce9 100644 --- a/addons/mrp/security/ir.model.access.csv +++ b/addons/mrp/security/ir.model.access.csv @@ -63,3 +63,5 @@ access_mrp_consumption_warning,access.mrp.consumption.warning,model_mrp_consumpt 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 diff --git a/addons/mrp/views/mrp_bom_views.xml b/addons/mrp/views/mrp_bom_views.xml index 5e1b0c71629..0ef5aaf07bf 100644 --- a/addons/mrp/views/mrp_bom_views.xml +++ b/addons/mrp/views/mrp_bom_views.xml @@ -116,6 +116,7 @@ + diff --git a/addons/mrp/views/mrp_production_views.xml b/addons/mrp/views/mrp_production_views.xml index 8333091096e..3d00f154dbb 100644 --- a/addons/mrp/views/mrp_production_views.xml +++ b/addons/mrp/views/mrp_production_views.xml @@ -17,13 +17,15 @@ - + + - + + @@ -154,7 +156,7 @@ - + @@ -276,17 +278,20 @@ + - + +