From d55e6cca0648c78ab27e0107ab7d545e9fd4972b Mon Sep 17 00:00:00 2001 From: JF Aubert Date: Fri, 16 Sep 2022 09:03:41 +0000 Subject: [PATCH] [IMP] mrp: adapt workorder gantt view Adapt workorder gantt view to show blocked slots and summed times. closes odoo/odoo#100350 Task: 2444754 Related: odoo/enterprise#31410 Signed-off-by: Steve Van Essche --- addons/mrp/models/mrp_workorder.py | 57 +++++++++++++----------- addons/mrp/views/mrp_workorder_views.xml | 7 +++ 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/addons/mrp/models/mrp_workorder.py b/addons/mrp/models/mrp_workorder.py index a3aabdbf008..4900076f3a3 100644 --- a/addons/mrp/models/mrp_workorder.py +++ b/addons/mrp/models/mrp_workorder.py @@ -555,39 +555,46 @@ class MrpWorkorder(models.Model): @api.model def gantt_unavailability(self, start_date, end_date, scale, group_bys=None, rows=None): """Get unavailabilities data to display in the Gantt view.""" + + # recursively traverse rows and apply func to innermost rows + # (the non-grouped ones/leaves showing unavailabilities) + def traverse(rows, func): + for row in rows: + if 'groupedBy' not in row or len(row.get('groupedBy')) == 1: + func(row) + traverse(row.get('rows'), func) + workcenter_ids = set() - def traverse_inplace(func, row, **kargs): - res = func(row, **kargs) - if res: - kargs.update(res) - for row in row.get('rows'): - traverse_inplace(func, row, **kargs) + # detect_workcenters used in a row + # either by using workcenter 'resId' or by scanning records used in + def detect_workcenters(row): + row_workcenter_ids = set() + if 'groupedBy' in row and row.get('groupedBy')[0] == 'workcenter_id': + row_workcenter_ids.add(row.get('resId')) + else: + for record in row.get('records'): + row_workcenter_ids.add(record['workcenter_id'][0]) + row['workcenter_ids'] = row_workcenter_ids + workcenter_ids.update(row_workcenter_ids) - def search_workcenter_ids(row): - if row.get('groupedBy') and row.get('groupedBy')[0] == 'workcenter_id' and row.get('resId'): - workcenter_ids.add(row.get('resId')) + traverse(rows, detect_workcenters) - for row in rows: - traverse_inplace(search_workcenter_ids, row) - start_datetime = fields.Datetime.to_datetime(start_date) - end_datetime = fields.Datetime.to_datetime(end_date) workcenters = self.env['mrp.workcenter'].browse(workcenter_ids) - unavailability_mapping = workcenters._get_unavailability_intervals(start_datetime, end_datetime) + start_datetime = fields.Datetime.from_string(start_date) + end_datetime = fields.Datetime.from_string(end_date) + unavailabilities = workcenters._get_unavailability_intervals(start_datetime, end_datetime) - # Only notable interval (more than one case) is send to the front-end (avoid sending useless information) - cell_dt = (scale in ['day', 'week'] and timedelta(hours=1)) or (scale == 'month' and timedelta(days=1)) or timedelta(days=28) + # add unavailability data + # (do not remove intervals smaller than a cell anymore as we are summing workorder times by column=time) + def add_unavailabilities(row): + row_unavailabilities = set() + for workcenter_id in row['workcenter_ids']: + row_unavailabilities.update(unavailabilities[workcenter_id]) + row['unavailabilities'] = [{'start': interval[0], 'stop': interval[1]} for interval in list(sorted(row_unavailabilities))] - def add_unavailability(row, workcenter_id=None): - if row.get('groupedBy') and row.get('groupedBy')[0] == 'workcenter_id' and row.get('resId'): - workcenter_id = row.get('resId') - if workcenter_id: - notable_intervals = filter(lambda interval: interval[1] - interval[0] >= cell_dt, unavailability_mapping[workcenter_id]) - row['unavailabilities'] = [{'start': interval[0], 'stop': interval[1]} for interval in notable_intervals] - return {'workcenter_id': workcenter_id} + traverse(rows, add_unavailabilities) - for row in rows: - traverse_inplace(add_unavailability, row) return rows def button_start(self): diff --git a/addons/mrp/views/mrp_workorder_views.xml b/addons/mrp/views/mrp_workorder_views.xml index 5c44a47341b..6c0a0dc3948 100644 --- a/addons/mrp/views/mrp_workorder_views.xml +++ b/addons/mrp/views/mrp_workorder_views.xml @@ -326,6 +326,10 @@ decoration-warning="state == 'cancel' or (json_popover and 'text-warning' in json_popover)" color="workcenter_id" display_unavailability="1" + progress_bar="workcenter_id" + total_row="True" + js_class="mrp_workorder_gantt" + precision="{'day': 'hour:full', 'week': 'day:full', 'month': 'day:full', 'year': 'day:full'}" sample="1" form_view_id="%(mrp_production_workorder_form_view_inherit)d"> @@ -364,6 +368,9 @@ color="production_id" display_unavailability="1" progress_bar="workcenter_id" + total_row="True" + js_class="mrp_workorder_gantt" + precision="{'day': 'hour:full', 'week': 'day:full', 'month': 'day:full', 'year': 'day:full'}" form_view_id="mrp_production_workorder_form_view_inherit">