sf计划排程计算排程时间日排程的制造订单总数量不能超过产线日产能数量,计算排程时间制造订单每小时排程不能超过产线小时产能

This commit is contained in:
hujiaying
2024-09-09 14:08:39 +08:00
parent 4560bbc0ed
commit 37493a4688
3 changed files with 67 additions and 28 deletions

View File

@@ -1,8 +1,9 @@
import datetime import datetime
from datetime import time from datetime import timedelta, time
from collections import defaultdict from collections import defaultdict
from odoo import fields, models, api from odoo import fields, models, api
from odoo.addons.resource.models.resource import Intervals from odoo.addons.resource.models.resource import Intervals
from odoo.exceptions import UserError, ValidationError
class ResWorkcenter(models.Model): class ResWorkcenter(models.Model):
@@ -138,7 +139,7 @@ class ResWorkcenter(models.Model):
effective_working_hours_day = fields.Float(string="日有效工作时长", default=0, readonly=True, effective_working_hours_day = fields.Float(string="日有效工作时长", default=0, readonly=True,
compute='_compute_effective_working_hours_day') compute='_compute_effective_working_hours_day')
default_capacity = fields.Float( 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') @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): def deal_with_workcenter_calendar(self, start_date):
start_date = start_date + timedelta(hours=8) # 转换为北京时间
for record in self: for record in self:
attendance_ids = [p for p in record.resource_calendar_id.attendance_ids if 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.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 decimal_part = value - integer_part
return int(integer_part), int(decimal_part) return int(integer_part), int(decimal_part)
## 处理生产线的是否有可排程的资源 # 处理排程是否超过日产能
def deal_production_lines_available(self, date_planned_start): def deal_available_default_capacity(self, date_planned):
for record in self: date_planned_start = date_planned.strftime('%Y-%m-%d')
# 自动生产线工单 date_planned_end = date_planned + timedelta(days=1)
date_planned_end = date_planned_start + datetime.datetime.timedelta(hours=1) date_planned_end = date_planned_end.strftime('%Y-%m-%d')
workorder_ids = record.env['mrp.workorder'].sudo().search( plan_ids = self.env['sf.production.plan'].sudo().search([('date_planned_start', '>=', date_planned_start),
[('workcenter_id', '=', record.id), ('date_planned_start', '>=', datetime), ('date_planned_start', '<',
('date_planned_start', '<=', date_planned_end)]) date_planned_end), ('state', '!=', 'draft')])
if not workorder_ids: if plan_ids:
return True sum_qty = sum([p.product_qty for p in plan_ids])
sum_qty = sum([p.qty_produced for p in workorder_ids]) if sum_qty >= self.default_capacity:
if sum_qty >= record.default_capacity:
return False 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 return True

View File

@@ -36,15 +36,37 @@
</div> </div>
</xpath> </xpath>
<xpath expr="//field[@name='default_capacity'][last()]" position="attributes"> <xpath expr="//field[@name='default_capacity'][last()]" position="attributes">
<attribute name="string">产线日产能</attribute> <attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='default_capacity'][last()]" position="after">
<label for="default_capacity"/>
<div class="o_row">
<field name="default_capacity" string="产线日产能"/>
</div>
</xpath> </xpath>
<xpath expr="//field[@name='default_capacity'][last()]" position="before"> <xpath expr="//field[@name='default_capacity'][last()]" position="before">
<label for="available_machine_number"/>
<field name="available_machine_number"/> <div class="o_row">
<field name="single_machine_capacity"/> <field name="available_machine_number"/>
<field name="production_line_hour_capacity"/>
<field name="effective_working_hours_day"/> </div>
<label for="single_machine_capacity"/>
<div class="o_row">
<field name="single_machine_capacity"/>
件/小时
</div>
<label for="production_line_hour_capacity"/>
<div class="o_row">
<field name="production_line_hour_capacity"/>
件/小时
</div>
<label for="effective_working_hours_day"/>
<div class="o_row">
<field name="effective_working_hours_day"/>
小时
</div>
</xpath> </xpath>
<!-- <xpath expr='//group[@name="capacity"]//field[@name="default_capacity"])' position="after">--> <!-- <xpath expr='//group[@name="capacity"]//field[@name="default_capacity"])' position="after">-->
<!-- <group>--> <!-- <group>-->

View File

@@ -199,7 +199,7 @@ class sf_production_plan(models.Model):
if not record.production_line_id: if not record.production_line_id:
raise ValidationError("未选择生产线") raise ValidationError("未选择生产线")
else: else:
date_planned_start = date_planned_start + timedelta(hours=8) # 转换为北京时间
is_schedule = self.deal_processing_schedule(date_planned_start) is_schedule = self.deal_processing_schedule(date_planned_start)
if not is_schedule: if not is_schedule:
raise ValidationError("排程失败") raise ValidationError("排程失败")
@@ -262,16 +262,17 @@ class sf_production_plan(models.Model):
production_lines = workcenter_ids.filtered(lambda b: "自动生产线" in b.name) production_lines = workcenter_ids.filtered(lambda b: "自动生产线" in b.name)
if not production_lines: # 判断是否配置了自动生产线 if not production_lines: # 判断是否配置了自动生产线
raise UserError('生产线没有配置自动生产线') 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 if all(not production_line.deal_with_workcenter_calendar(date_planned_start) for production_line in
production_lines): # 判断计划开始时间是否在配置的工作中心的工作日历内 production_lines): # 判断计划开始时间是否在配置的工作中心的工作日历内
raise UserError('当前计划开始时间不能预约排程') raise UserError('当前计划开始时间不能预约排程,请在工作时间内排程')
if not production_lines.deal_production_lines_available(date_planned_start): # 判断生产线是否可排程 if not production_lines.deal_available_default_capacity(date_planned_start): # 判断生产线是否可排程
raise UserError('当前计划开始时间不能预约排程,生产线没有可排程的资源') raise UserError('当前计划开始时间不能预约排程,生产线今日没有可排程的资源')
if not production_lines.deal_available_single_machine_capacity(date_planned_start): # 判断生产线是否可排程
raise UserError('当前计划开始时间不能预约排程,生产线该时间段没有可排程的资源')
return True return True
def calculate_plan_time_before(self, item, workorder_id_list): def calculate_plan_time_before(self, item, workorder_id_list):
""" """
根据CNC工单的时间去计算之前的其他工单的开始结束时间 根据CNC工单的时间去计算之前的其他工单的开始结束时间