diff --git a/sf_manufacturing/models/mrp_workcenter.py b/sf_manufacturing/models/mrp_workcenter.py index 003d1b2b..0a7e1d0e 100644 --- a/sf_manufacturing/models/mrp_workcenter.py +++ b/sf_manufacturing/models/mrp_workcenter.py @@ -1,8 +1,9 @@ import datetime -from datetime import time +from datetime import timedelta, time from collections import defaultdict from odoo import fields, models, api from odoo.addons.resource.models.resource import Intervals +from odoo.exceptions import UserError, ValidationError class ResWorkcenter(models.Model): @@ -138,7 +139,7 @@ class ResWorkcenter(models.Model): effective_working_hours_day = fields.Float(string="日有效工作时长", default=0, readonly=True, compute='_compute_effective_working_hours_day') default_capacity = fields.Float( - '生产线日产能', compute='_compute_production_line_day_capacity', readonly=True) + string='生产线日产能', compute='_compute_production_line_day_capacity', readonly=True) # 计算生产线日产能 @api.depends('production_line_hour_capacity', 'effective_working_hours_day') @@ -175,6 +176,7 @@ class ResWorkcenter(models.Model): # 判断计划开始时间是否在配置的工作中心的工作日历内 def deal_with_workcenter_calendar(self, start_date): + start_date = start_date + timedelta(hours=8) # 转换为北京时间 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( @@ -195,20 +197,34 @@ class ResWorkcenter(models.Model): 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: + # 处理排程是否超过日产能 + def deal_available_default_capacity(self, date_planned): + date_planned_start = date_planned.strftime('%Y-%m-%d') + date_planned_end = date_planned + timedelta(days=1) + date_planned_end = date_planned_end.strftime('%Y-%m-%d') + plan_ids = self.env['sf.production.plan'].sudo().search([('date_planned_start', '>=', date_planned_start), + ('date_planned_start', '<', + date_planned_end), ('state', '!=', 'draft')]) + if plan_ids: + sum_qty = sum([p.product_qty for p in plan_ids]) + if sum_qty >= self.default_capacity: return False + return True + # 处理排程是否超过小时产能 + def deal_available_single_machine_capacity(self, date_planned): + + date_planned_start = date_planned.strftime('%Y-%m-%d %H:00:00') + date_planned_end = date_planned + timedelta(hours=1) + date_planned_end = date_planned_end.strftime('%Y-%m-%d %H:00:00') + plan_ids = self.env['sf.production.plan'].sudo().search([('date_planned_start', '>=', date_planned_start), + ('date_planned_start', '<', + date_planned_end), ('state', '!=', 'draft')]) + + if plan_ids: + sum_qty = sum([p.product_qty for p in plan_ids]) + if sum_qty >= self.single_machine_capacity: + return False return True diff --git a/sf_manufacturing/views/mrp_workcenter_views.xml b/sf_manufacturing/views/mrp_workcenter_views.xml index aad35d04..37ff8af5 100644 --- a/sf_manufacturing/views/mrp_workcenter_views.xml +++ b/sf_manufacturing/views/mrp_workcenter_views.xml @@ -36,15 +36,37 @@ - 产线日产能 + 1 + + + + - - - - - - + diff --git a/sf_plan/models/custom_plan.py b/sf_plan/models/custom_plan.py index a1c57f2a..c4043d33 100644 --- a/sf_plan/models/custom_plan.py +++ b/sf_plan/models/custom_plan.py @@ -199,7 +199,7 @@ 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("排程失败") @@ -262,16 +262,17 @@ class sf_production_plan(models.Model): 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_production_lines_available(date_planned_start): # 判断生产线是否可排程 - raise UserError('当前计划开始时间不能预约排程,生产线没有可排程的资源') + 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): # 判断生产线是否可排程 + raise UserError('当前计划开始时间不能预约排程,生产线该时间段没有可排程的资源') return True - - - def calculate_plan_time_before(self, item, workorder_id_list): """ 根据CNC工单的时间去计算之前的其他工单的开始结束时间