From b1b805959aaa3e0d1f95f13e2df9678296b9aaae Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Sun, 28 Jul 2024 15:20:12 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=A4=9A=E6=AC=A1=E8=BF=94?= =?UTF-8?q?=E5=B7=A5=E6=8A=A5=E4=BE=9D=E8=B5=96=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_workorder.py | 61 +++++++++++++++++++++++- sf_manufacturing/wizard/rework_wizard.py | 17 ++++--- 2 files changed, 71 insertions(+), 7 deletions(-) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index ded46f93..7693755a 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -256,7 +256,66 @@ class ResMrpWorkOrder(models.Model): detailed_reason = fields.Text('详细原因') is_rework = fields.Boolean(string='是否返工', default=False) - # is_send_program_again = fields.Boolean(string='是否重新下发NC程序', default=False) + @api.constrains('blocked_by_workorder_ids') + def _check_no_cyclic_dependencies(self): + if self.production_id.state not in ['rework'] and self.state not in ['rework']: + if not self._check_m2m_recursion('blocked_by_workorder_ids'): + raise ValidationError(_("您不能创建周期性的依赖关系.")) + + def _plan_workorder(self, replan=False): + self.ensure_one() + # Plan workorder after its predecessors + start_date = max(self.production_id.date_planned_start, datetime.now()) + for workorder in self.blocked_by_workorder_ids: + if workorder.state in ['done', 'cancel', 'rework']: + continue + workorder._plan_workorder(replan) + start_date = max(start_date, workorder.date_planned_finished) + # Plan only suitable workorders + if self.state not in ['pending', 'waiting', 'ready']: + return + if self.leave_id: + if replan: + self.leave_id.unlink() + else: + return + # Consider workcenter and alternatives + workcenters = self.workcenter_id | self.workcenter_id.alternative_workcenter_ids + best_finished_date = datetime.max + vals = {} + for workcenter in workcenters: + # Compute theoretical duration + if self.workcenter_id == workcenter: + duration_expected = self.duration_expected + else: + duration_expected = self._get_duration_expected(alternative_workcenter=workcenter) + from_date, to_date = workcenter._get_first_available_slot(start_date, duration_expected) + # If the workcenter is unavailable, try planning on the next one + if not from_date: + continue + # Check if this workcenter is better than the previous ones + if to_date and to_date < best_finished_date: + best_start_date = from_date + best_finished_date = to_date + best_workcenter = workcenter + vals = { + 'workcenter_id': workcenter.id, + 'duration_expected': duration_expected, + } + # If none of the workcenter are available, raise + if best_finished_date == datetime.max: + raise UserError(_('Impossible to plan the workorder. Please check the workcenter availabilities.')) + # Create leave on chosen workcenter calendar + leave = self.env['resource.calendar.leaves'].create({ + 'name': self.display_name, + 'calendar_id': best_workcenter.resource_calendar_id.id, + 'date_from': best_start_date, + 'date_to': best_finished_date, + 'resource_id': best_workcenter.resource_id.id, + 'time_type': 'other' + }) + vals['leave_id'] = leave.id + self.write(vals) @api.onchange('rfid_code') def _onchange(self): diff --git a/sf_manufacturing/wizard/rework_wizard.py b/sf_manufacturing/wizard/rework_wizard.py index a52c5093..91b5b970 100644 --- a/sf_manufacturing/wizard/rework_wizard.py +++ b/sf_manufacturing/wizard/rework_wizard.py @@ -99,9 +99,12 @@ class ReworkWizard(models.TransientModel): self.production_id.get_new_program(panel.name) if self.reprogramming_num >= 0 and self.programming_state == '已下发': ret = {'programming_list': []} - cnc_rework = self.production_id.workorder_ids.filtered( - lambda crw: crw.processing_panel == panel.name and crw.state in ( - 'rework') and crw.routing_type == 'CNC加工') + cnc_rework = max( + self.production_id.workorder_ids.filtered( + lambda + crw: crw.processing_panel == panel.name and crw.state == 'rework' and crw.routing_type == 'CNC加工'), + key=lambda w: w.create_date + ) if cnc_rework.cnc_ids: for item_line in cnc_rework.cnc_ids: vals = { @@ -150,9 +153,10 @@ class ReworkWizard(models.TransientModel): p: p.routing_type == '装夹预调' and p.processing_panel == panel.name and p.state not in ( 'rework', 'done')) if new_pre_workorder: - pre_rework = self.production_id.workorder_ids.filtered( + pre_rework = max(self.production_id.workorder_ids.filtered( lambda pr: pr.processing_panel == panel.name and pr.state in ( - 'rework') and pr.routing_type == '装夹预调') + 'rework') and pr.routing_type == '装夹预调'), + key=lambda w1: w1.create_date) new_pre_workorder.write( {'processing_drawing': pre_rework.processing_drawing}) self.production_id.write({'state': 'progress', 'is_rework': False}) @@ -171,7 +175,8 @@ class ReworkWizard(models.TransientModel): ('programming_state', '=', '已编程未下发')]) if productions_not_delivered: productions_not_delivered.write( - {'programming_state': '已编程', 'work_state': '已编程', 'is_rework': False}) + {'state': 'progress', 'programming_state': '已编程', 'work_state': '已编程', + 'is_rework': False}) @api.onchange('production_id') def onchange_processing_panel_id(self):