From 5ac8471eab76a95b858bbc4c81fd43c200ee485a Mon Sep 17 00:00:00 2001 From: Nicolas Lempereur Date: Fri, 9 Jun 2017 14:13:42 +0200 Subject: [PATCH] [FIX] mrp: multi production inconsistencies When several user run a production on a workorder, things go awry. For example the end of the "productive" production is computed based on ProductiveStartTime + DurationExpected - Duration so if the duration was bigger than the time expected, we easily get a productive end before the start, and start of the "reduced speed" before the production actually happened. eg: productive time is 30 minutes user A: start production at 10:00 user B: start production at 10:10 production is set to done at 10:50 => result before the patch: user A has been productive from 10:00 to 10:30 user A has not been productive from 10:30 to 10:50 user B has been productive from 10:10 to 10:00 user B has not been productive from 10:00 to 10:50 this is totally erroneous. => result after the patch: user A has been productive from 10:00 to 10:30 user A has not been productive from 10:30 to 10:50 user B has not been productive from 10:10 to 10:50 this is a measure of right, we could argue about wether one or the other should be productive or not but this is anyway an edge case. In master we are considering only allowing one user to run a production at a time but we prefer not to change such a behavior in stable version. opw-709223 closes #17528 --- addons/mrp/models/mrp_workorder.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/addons/mrp/models/mrp_workorder.py b/addons/mrp/models/mrp_workorder.py index 86107856873..8b5f45d3b24 100644 --- a/addons/mrp/models/mrp_workorder.py +++ b/addons/mrp/models/mrp_workorder.py @@ -391,9 +391,12 @@ class MrpWorkorder(models.Model): domain = [('workorder_id', 'in', self.ids), ('date_end', '=', False)] if not doall: domain.append(('user_id', '=', self.env.user.id)) + not_productive_timelines = timeline_obj.browse() for timeline in timeline_obj.search(domain, limit=None if doall else 1): wo = timeline.workorder_id - if timeline.loss_type != 'productive': + if wo.duration_expected <= wo.duration: + if timeline.loss_type == 'productive': + not_productive_timelines += timeline timeline.write({'date_end': fields.Datetime.now()}) else: maxdate = fields.Datetime.from_string(timeline.date_start) + relativedelta(minutes=wo.duration_expected - wo.duration) @@ -402,10 +405,12 @@ class MrpWorkorder(models.Model): timeline.write({'date_end': enddate}) else: timeline.write({'date_end': maxdate}) - loss_id = self.env['mrp.workcenter.productivity.loss'].search([('loss_type', '=', 'performance')], limit=1) - if not len(loss_id): - raise UserError(_("You need to define at least one unactive productivity loss in the category 'Performance'. Create one from the Manufacturing app, menu: Configuration / Productivity Losses.")) - timeline.copy({'date_start': maxdate, 'date_end': enddate, 'loss_id': loss_id.id}) + not_productive_timelines += timeline.copy({'date_start': maxdate, 'date_end': enddate}) + if not_productive_timelines: + loss_id = self.env['mrp.workcenter.productivity.loss'].search([('loss_type', '=', 'performance')], limit=1) + if not len(loss_id): + raise UserError(_("You need to define at least one unactive productivity loss in the category 'Performance'. Create one from the Manufacturing app, menu: Configuration / Productivity Losses.")) + not_productive_timelines.write({'loss_id': loss_id.id}) return True @api.multi