diff --git a/sf_manufacturing/models/mrp_workcenter.py b/sf_manufacturing/models/mrp_workcenter.py index 7183b755..003d1b2b 100644 --- a/sf_manufacturing/models/mrp_workcenter.py +++ b/sf_manufacturing/models/mrp_workcenter.py @@ -1,4 +1,5 @@ import datetime +from datetime import time from collections import defaultdict from odoo import fields, models, api from odoo.addons.resource.models.resource import Intervals @@ -152,7 +153,7 @@ class ResWorkcenter(models.Model): def _compute_effective_working_hours_day(self): for record in self: attendance_ids = [p for p in record.resource_calendar_id.attendance_ids if - p.dayofweek == self.get_current_day_of_week()] + p.dayofweek == self.get_current_day_of_week(datetime.datetime.now())] if attendance_ids: for attendance_id in attendance_ids: if attendance_id.hour_from and attendance_id.hour_to: @@ -160,9 +161,9 @@ class ResWorkcenter(models.Model): else: record.effective_working_hours_day = 0 - def get_current_day_of_week(self): - - day_num = datetime.datetime.now().weekday() + # 获取传入时间是星期几 + def get_current_day_of_week(self, datetime): + day_num = datetime.weekday() return str(day_num) # 计算生产线小时产能 @@ -172,6 +173,44 @@ class ResWorkcenter(models.Model): record.production_line_hour_capacity = round( record.single_machine_capacity * record.available_machine_number, 2) + # 判断计划开始时间是否在配置的工作中心的工作日历内 + def deal_with_workcenter_calendar(self, start_date): + for record in self: + attendance_ids = [p for p in record.resource_calendar_id.attendance_ids if + p.dayofweek == record.get_current_day_of_week(start_date) and self.is_between_times( + p.hour_from, p.hour_to, start_date)] + return False if not attendance_ids else True + + # 判断传入时间是否在配置的工作中心的工作日历内 + def is_between_times(self, hour_from, hour_to, start_date): + integer_part, decimal_part = self.get_integer_and_decimal_parts(hour_from) + start_time = time(integer_part, decimal_part) + integer_part, decimal_part = self.get_integer_and_decimal_parts(hour_to) + end_time = time(integer_part, decimal_part) + return start_time <= start_date.time() <= end_time + + # 获取整数部分和小数部分 + def get_integer_and_decimal_parts(self, value): + integer_part = int(value) + decimal_part = value - integer_part + return int(integer_part), int(decimal_part) + + ## 处理生产线的是否有可排程的资源 + def deal_production_lines_available(self, date_planned_start): + for record in self: + # 自动生产线工单 + date_planned_end = date_planned_start + datetime.datetime.timedelta(hours=1) + workorder_ids = record.env['mrp.workorder'].sudo().search( + [('workcenter_id', '=', record.id), ('date_planned_start', '>=', datetime), + ('date_planned_start', '<=', date_planned_end)]) + if not workorder_ids: + return True + sum_qty = sum([p.qty_produced for p in workorder_ids]) + if sum_qty >= record.default_capacity: + return False + + return True + class ResWorkcenterProductivity(models.Model): _inherit = 'mrp.workcenter.productivity' diff --git a/sf_plan/models/custom_plan.py b/sf_plan/models/custom_plan.py index 0e56bf22..a1c57f2a 100644 --- a/sf_plan/models/custom_plan.py +++ b/sf_plan/models/custom_plan.py @@ -191,7 +191,7 @@ class sf_production_plan(models.Model): return num - def do_production_schedule(self): + def do_production_schedule(self, date_planned_start): """ 排程方法 """ @@ -199,6 +199,10 @@ class sf_production_plan(models.Model): if not record.production_line_id: raise ValidationError("未选择生产线") else: + date_planned_start = date_planned_start + timedelta(hours=8) # 转换为北京时间 + is_schedule = self.deal_processing_schedule(date_planned_start) + 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: @@ -249,6 +253,25 @@ class sf_production_plan(models.Model): 'target': 'current', # 跳转的目标窗口,可以是'current'或'new' } + # 处理是否可排程 + def deal_processing_schedule(self, date_planned_start): + 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 all(not production_line.deal_with_workcenter_calendar(date_planned_start) for production_line in + production_lines): # 判断计划开始时间是否在配置的工作中心的工作日历内 + raise UserError('当前计划开始时间不能预约排程') + if not production_lines.deal_production_lines_available(date_planned_start): # 判断生产线是否可排程 + raise UserError('当前计划开始时间不能预约排程,生产线没有可排程的资源') + return True + + + + def calculate_plan_time_before(self, item, workorder_id_list): """ 根据CNC工单的时间去计算之前的其他工单的开始结束时间 diff --git a/sf_plan/wizard/action_plan_some.py b/sf_plan/wizard/action_plan_some.py index 706714ee..9410efd5 100644 --- a/sf_plan/wizard/action_plan_some.py +++ b/sf_plan/wizard/action_plan_some.py @@ -36,7 +36,7 @@ class Action_Plan_All_Wizard(models.TransientModel): 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.do_production_schedule(self.date_planned_start) # plan_obj.state = 'done' print('处理计划:', plan.id, '完成')