sf计划排程计算排程时间日排程的制造订单总数量不能超过产线日产能数量,计算排程时间制造订单每小时排程不能超过产线小时产能
This commit is contained in:
@@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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>-->
|
||||||
|
|||||||
@@ -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工单的时间去计算之前的其他工单的开始结束时间
|
||||||
|
|||||||
Reference in New Issue
Block a user