diff --git a/sf_plan/models/custom_plan.py b/sf_plan/models/custom_plan.py index 60587dec..492ef525 100644 --- a/sf_plan/models/custom_plan.py +++ b/sf_plan/models/custom_plan.py @@ -219,7 +219,7 @@ class sf_production_plan(models.Model): return num - def do_production_schedule(self, count=1): + def do_production_schedule(self): """ 排程方法 """ @@ -227,29 +227,26 @@ class sf_production_plan(models.Model): if not record.production_line_id: raise ValidationError("未选择生产线") else: - is_schedule = self.deal_processing_schedule(record.date_planned_start, count) - if not is_schedule: - raise ValidationError("排程失败") - workorder_id_list = record.production_id.workorder_ids.ids - if record.production_id: - if record.production_id.workorder_ids: - for item in record.production_id.workorder_ids: - if item.name == 'CNC加工': - item.date_planned_finished = datetime.now() + timedelta(days=100) - item.date_planned_start = self.date_planned_start if self.date_planned_start else datetime.now() - record.sudo().production_id.plan_start_processing_time = item.date_planned_start - item.date_planned_finished = item.date_planned_start + timedelta( - minutes=record.env['mrp.routing.workcenter'].sudo().search( - [('name', '=', 'CNC加工')]).time_cycle) - item.duration_expected = record.env['mrp.routing.workcenter'].sudo().search( - [('name', '=', 'CNC加工')]).time_cycle - record.calculate_plan_time_before(item, workorder_id_list) - record.calculate_plan_time_after(item, workorder_id_list) - record.date_planned_start, record.date_planned_finished = \ - item.date_planned_start, item.date_planned_finished + if record.production_id.workorder_ids: + last_cnc_start = record.date_planned_start if record.date_planned_start else datetime.now() + for item in record.production_id.workorder_ids: + if item.name == 'CNC加工': + # 将同一个面的所有工单筛选出来 + workorder_list = record.production_id.workorder_ids.filtered(lambda x: x.processing_panel == item.processing_panel) + routing_workcenter = record.env['mrp.routing.workcenter'].sudo().search( + [('name', '=', 'CNC加工')], limit=1) + # 设置一个小的开始时间 + item.date_planned_start = datetime.now() - timedelta(days=100) + item.date_planned_finished = last_cnc_start + timedelta( + minutes=routing_workcenter.time_cycle) + item.date_planned_start = last_cnc_start + record.sudo().production_id.plan_start_processing_time = item.date_planned_start + item.duration_expected = routing_workcenter.time_cycle + pre_duration , next_duration = record.calculate_plan_time(item, workorder_list) + record.date_planned_finished = item.date_planned_finished + # 计算下一个cnc工单的开始时间 + last_cnc_start = workorder_list[-1].date_planned_finished + timedelta(minutes=pre_duration) record.state = 'done' - record.date_planned_finished = record.date_planned_start + timedelta( - minutes=60) if not record.date_planned_finished else record.date_planned_finished # record.production_id.schedule_state = '已排' record.sudo().production_id.schedule_state = '已排' record.sudo().production_id.process_state = '待装夹' @@ -282,54 +279,66 @@ class sf_production_plan(models.Model): } # 处理是否可排程 - def deal_processing_schedule(self, date_planned_start, count): - for record in self: - workcenter_ids = record.production_line_id.mrp_workcenter_ids - if not workcenter_ids: - raise UserError('生产线没有配置工作中心') - production_lines = workcenter_ids.filtered(lambda b: "自动生产线" in b.name) - if not production_lines: # 判断是否配置了自动生产线 - raise UserError('生产线没有配置自动生产线') - if date_planned_start < datetime.now(): # 判断计划开始时间是否小于当前时间 - raise UserError('计划开始时间不能小于当前时间') - if all(not production_line.deal_with_workcenter_calendar(date_planned_start) for production_line in - production_lines): # 判断计划开始时间是否在配置的工作中心的工作日历内 - raise UserError('当前计划开始时间不能预约排程,请在工作时间内排程') - if not production_lines.deal_available_default_capacity(date_planned_start): # 判断生产线是否可排程 - raise UserError('当前计划开始时间不能预约排程,生产线今日没有可排程的资源') - if not production_lines.deal_available_single_machine_capacity(date_planned_start, count): # 判断生产线是否可排程 - raise UserError('当前计划开始时间不能预约排程,生产线该时间段没有可排程的资源') + def deal_processing_schedule(self, date_planned_start,): + count = len(self) + workcenter_ids = self.production_line_id.mrp_workcenter_ids + if not workcenter_ids: + raise UserError('生产线没有配置工作中心') + production_lines = workcenter_ids.filtered(lambda b: "自动生产线" in b.name) + if not production_lines: # 判断是否配置了自动生产线 + raise UserError('生产线没有配置自动生产线') + if date_planned_start < datetime.now(): # 判断计划开始时间是否小于当前时间 + raise UserError('计划开始时间不能小于当前时间') + if all(not production_line.deal_with_workcenter_calendar(date_planned_start) for production_line in + production_lines): # 判断计划开始时间是否在配置的工作中心的工作日历内 + raise UserError('当前计划开始时间不能预约排程,请在工作时间内排程') + if not production_lines.deal_available_default_capacity(date_planned_start): # 判断生产线是否可排程 + raise UserError('当前计划开始时间不能预约排程,生产线今日没有可排程的资源') + if not production_lines.deal_available_single_machine_capacity(date_planned_start, count): # 判断生产线是否可排程 + raise UserError('当前计划开始时间不能预约排程,生产线该时间段没有可排程的资源') return True - def calculate_plan_time_before(self, item, workorder_id_list): + def calculate_plan_time(self, item, workorder_list): """ 根据CNC工单的时间去计算之前的其他工单的开始结束时间 """ - sequence = workorder_id_list.index(item.id) - 1 - # 计算CNC加工之前工单的开始结束时间 - for i in range(1 if sequence == 0 else sequence): - current_workorder_id = (item.id - (i + 1)) - current_workorder_obj = self.env['mrp.workorder'].sudo().search( - [('id', '=', current_workorder_id)]) - old_workorder_obj = self.env['mrp.workorder'].sudo().search( - [('id', '=', (current_workorder_id + 1))]) - work_order = self.env['mrp.workorder'].sudo().search( - [('production_id', '=', self.production_id.id), ('id', '=', current_workorder_id)]) - work_order.date_planned_finished = datetime.now() + timedelta(days=100) - work_order.date_planned_start = old_workorder_obj.date_planned_start - timedelta( - minutes=self.env['mrp.routing.workcenter'].sudo().search( - [('name', '=', current_workorder_obj.name)]).time_cycle) - work_order.date_planned_finished = old_workorder_obj.date_planned_start - work_order.duration_expected = self.env['mrp.routing.workcenter'].sudo().search( - [('name', '=', current_workorder_obj.name)]).time_cycle - first_workorder = self.env['mrp.workorder'].sudo().search([('id', '=', workorder_id_list[0])]) - second_workorder = self.env['mrp.workorder'].sudo().search([('id', '=', workorder_id_list[1])]) - if second_workorder.date_planned_start < first_workorder.date_planned_finished: - item.date_planned_start += timedelta(minutes=60) - item.date_planned_finished += timedelta(minutes=60) - item.duration_expected = self.env['mrp.routing.workcenter'].sudo().search( - [('name', '=', 'CNC加工')]).time_cycle - self.calculate_plan_time_before(item, workorder_id_list) + item_position = 0 + for index, workorder in enumerate(workorder_list): + if workorder.id == item.id: + item_position = index + break + routing_workcenters = self.env['mrp.routing.workcenter'].sudo().search([]) + # 记录所有前序工序时长 + previous_workorder_duration = 0 + for i in range(item_position, -1, -1): + if i < 1: + break + current_workorder = workorder_list[i] + next_workorder = workorder_list[i - 1] + routing_workcenter = routing_workcenters.filtered(lambda x: x.name == next_workorder.name)[0] + # 设置一个小的开始时间 + next_workorder.date_planned_start = datetime.now() - timedelta(days=100) + next_workorder.date_planned_finished = current_workorder.date_planned_start + next_workorder.date_planned_start = next_workorder.date_planned_finished - timedelta( + minutes=routing_workcenter.time_cycle) + next_workorder.duration_expected = routing_workcenter.time_cycle + previous_workorder_duration += routing_workcenter.time_cycle + # 记录所有后续工序时长 + next_workorder_duration = 0 + for i in range(item_position, len(workorder_list) - 1): + if i > len(workorder_list) - 1: + break + current_workorder = workorder_list[i] + next_workorder = workorder_list[i + 1] + routing_workcenter = routing_workcenters.filtered(lambda x: x.name == next_workorder.name)[0] + # 设置一个小的开始时间 + next_workorder.date_planned_start = datetime.now() - timedelta(days=100) + next_workorder.date_planned_finished = current_workorder.date_planned_finished + timedelta( + minutes=routing_workcenter.time_cycle) + next_workorder.date_planned_start = current_workorder.date_planned_finished + next_workorder.duration_expected = routing_workcenter.time_cycle + next_workorder_duration += routing_workcenter.time_cycle + return previous_workorder_duration, next_workorder_duration def calculate_plan_time_after(self, item, workorder_id_list): """ diff --git a/sf_plan/wizard/action_plan_some.py b/sf_plan/wizard/action_plan_some.py index 23545516..4b56547e 100644 --- a/sf_plan/wizard/action_plan_some.py +++ b/sf_plan/wizard/action_plan_some.py @@ -31,22 +31,24 @@ class Action_Plan_All_Wizard(models.TransientModel): # 确认排程按钮 def action_plan_all(self): # 使用传递过来的计划ID - temp_plan_ids = self.plan_ids + self.plan_ids.production_line_id = self.production_line_id.id + self.plan_ids.date_planned_start = self.date_planned_start # 在这里添加您的逻辑来处理这些ID - count = len(temp_plan_ids) + 1 - for plan in temp_plan_ids: - count = count - 1 - # 处理每个计划 - # 比如更新计划状态、分配资源等 - # 示例:plan.state = 'scheduled' - print('处理计划:', plan.id) - # 拿到计划对象 - plan_obj = self.env['sf.production.plan'].browse(plan.id) - plan_obj.production_line_id = self.production_line_id.id - plan.date_planned_start = self.date_planned_start - plan_obj.do_production_schedule(count) + # 判断能否排成 + self.plan_ids.deal_processing_schedule(self.date_planned_start) + self.plan_ids.do_production_schedule() + # for plan in temp_plan_ids: + # # 处理每个计划 + # # 比如更新计划状态、分配资源等 + # # 示例:plan.state = 'scheduled' + # print('处理计划:', plan.id) + # # 拿到计划对象 + # plan_obj = self.env['sf.production.plan'].browse(plan.id) + # plan_obj.production_line_id = self.production_line_id.id + # plan.date_planned_start = self.date_planned_start + # plan_obj.do_production_schedule() # plan_obj.state = 'done' - print('处理计划:', plan.id, '完成') + print('处理计划:', self.plan_ids.id, '完成') # # 获取当前生产线 # production_line_id = self.production_line_id