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 @@