|
package schedule
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"leit.com/LAPP_GAAS_GFrame/models"
|
|
"time"
|
|
)
|
|
|
|
// 调度批次任务对象
|
|
type TaskSrv struct {
|
|
TaskId string
|
|
TaskType string
|
|
PlantNr int
|
|
ProjectId string
|
|
SortKey int64 // 用于给MES用的排序号
|
|
ArtId string // 任务产品ID
|
|
Priority int
|
|
Status int
|
|
SchedResGrpId string // 调度资源组ID
|
|
SchedResId string // 调度资源
|
|
FixResource bool // 锁定资源
|
|
PlanQty float64 // 计划数量
|
|
ReleasedQty float64 // 已下达数量 - 每个独立生成序列订单
|
|
FinishedQty float64 // 已完成数量
|
|
Duration time.Duration // 任务所需工时
|
|
EarliestStartTime time.Time // 最早开始时间
|
|
LatestEndTime time.Time // 最迟结束时间
|
|
SetupStartTime time.Time // 换型开始时间
|
|
SetupEndTime time.Time // 换型结束时间
|
|
FixStartTime bool // 锁定派车给开始时间
|
|
SchedStartTime time.Time // 排程开始时间
|
|
SchedEndTime time.Time // 排程结束时间
|
|
ActStartTime time.Time // 实际开始时间
|
|
ActEndTime time.Time // 实际结束时间
|
|
Wotab models.OmWorkorder
|
|
WoStatusTab models.OmWorkorderstatus
|
|
WoQtyTab models.OmWorkorderqty
|
|
SerialTaskArray []SerialTaskSrv // 批次订单的序列订单
|
|
}
|
|
|
|
// 序列任务对象
|
|
type SerialTaskSrv struct {
|
|
TaskId string
|
|
TaskType string
|
|
ParentTaskId string
|
|
PlantNr int
|
|
ProjectId string
|
|
Barcode string // 序列订单条码
|
|
ArtId string // 任务产品ID
|
|
Status int
|
|
SchedResId string // 调度资源
|
|
PlanQty float64 // 计划数量
|
|
Duration time.Duration // 任务所需工时
|
|
EarliestStartTime time.Time // 最早开始时间
|
|
LatestEndTime time.Time // 最迟结束时间
|
|
SetupStartTime time.Time // 换型开始时间
|
|
SetupEndTime time.Time // 换型结束时间
|
|
SchedStartTime time.Time // 排程开始时间
|
|
SchedEndTime time.Time // 排程结束时间
|
|
ActStartTime time.Time // 实际开始时间
|
|
ActEndTime time.Time // 实际结束时间
|
|
SerialOrderTab models.OmSerialorder
|
|
SerialOrderStatusTab models.OmSerialorderstatus
|
|
}
|
|
|
|
// 基于指定的批次订单号获取批次订单对象
|
|
func(tasksrv *TaskSrv)Get()(err error){
|
|
var wotab models.OmWorkorder
|
|
|
|
wotab = models.OmWorkorder{Plantnr: tasksrv.PlantNr, Workorderid: tasksrv.TaskId}
|
|
if wotab, err = wotab.SelectOne(); err != nil{
|
|
err = errors.New(fmt.Sprintf("获取工厂%d批次订单%s失败!",tasksrv.PlantNr,tasksrv.TaskId))
|
|
return
|
|
}
|
|
tasksrv.Init(wotab)
|
|
return
|
|
}
|
|
|
|
// 基于给定的订单表和订单状态表进行结构初始化
|
|
func(tasksrv *TaskSrv)Init(wotab models.OmWorkorder){
|
|
// 初始化批次任务的批次订单信息
|
|
tasksrv.TaskId = wotab.Workorderid
|
|
tasksrv.TaskType = wotab.Ordertype
|
|
tasksrv.SortKey = wotab.Planstarttime.Unix() // 用于给MES用的排序号
|
|
tasksrv.ArtId = wotab.Artid // 任务产品ID
|
|
tasksrv.Priority = wotab.Priority // 优先级
|
|
tasksrv.Status = wotab.Wostatustab.Status // 订单状态
|
|
tasksrv.SchedResGrpId = wotab.Planresourcegroupid // 调度资源组ID
|
|
tasksrv.SchedResId = wotab.Planresourceid // 调度资源
|
|
tasksrv.FixResource = false // 锁定资源
|
|
tasksrv.PlanQty = float64(wotab.Planqty ) // 计划数量
|
|
tasksrv.ReleasedQty = float64(wotab.Woqtytab.Releasedqty) // 已下达数量 - 每个独立生成序列订单
|
|
tasksrv.FinishedQty = float64(wotab.Woqtytab.Actqty) // 已完成数量
|
|
tasksrv.EarliestStartTime = wotab.Planstartdate // 最早开始时间
|
|
tasksrv.LatestEndTime = wotab.Planendtime // 最迟结束时间
|
|
tasksrv.SetupStartTime = wotab.Setupstarttime // 换型开始时间
|
|
tasksrv.SetupEndTime = wotab.Setupendtime // 换型结束时间
|
|
if wotab.Fixstarttime > 0 { // 锁定开始时间
|
|
tasksrv.FixStartTime = true
|
|
}else{
|
|
tasksrv.FixStartTime = false
|
|
}
|
|
tasksrv.SchedStartTime = wotab.Planstarttime // 排程开始时间
|
|
tasksrv.SchedEndTime = wotab.Planendtime // 排程结束时间
|
|
tasksrv.ActStartTime = wotab.Actstarttime // 实际开始时间
|
|
tasksrv.ActEndTime = wotab.Actendtime // 实际结束时间
|
|
|
|
// 获取调度任务所需要的工时
|
|
calQty := wotab.Planqty - wotab.Woqtytab.Actqty
|
|
if wotab.Rateperhourtoggle > 0 {
|
|
if wotab.Quantityperhour <= 0 {
|
|
tasksrv.Duration = 0
|
|
}else{
|
|
tasksrv.Duration = time.Duration(calQty / wotab.Quantityperhour) * time.Hour
|
|
}
|
|
}
|
|
if wotab.Timeperitemtoggle > 0 {
|
|
perItemSeconds := float64(wotab.Optimeperitem) * GetTimeUomSeconds(wotab.Timeuomid)
|
|
tasksrv.Duration = time.Duration(float64(calQty) * perItemSeconds ) * time.Second
|
|
}
|
|
if wotab.Timeperbatchtoggle > 0 {
|
|
if wotab.Batchtime <= 0 || wotab.Batchquantity <= 0{
|
|
tasksrv.Duration = 0
|
|
}else{
|
|
perBatchSeconds := float64(wotab.Batchtime) * GetTimeUomSeconds(wotab.Timeuomid)
|
|
tasksrv.Duration = time.Duration(perBatchSeconds * float64(calQty) / float64(wotab.Batchquantity)) * time.Hour
|
|
}
|
|
}
|
|
|
|
tasksrv.Wotab = wotab
|
|
tasksrv.WoStatusTab = wotab.Wostatustab
|
|
tasksrv.WoQtyTab = wotab.Woqtytab
|
|
}
|
|
|
|
// 加载批次订单的序列订单
|
|
func(tasksrv *TaskSrv)LoadSerialOrders()(err error){
|
|
var(
|
|
i int
|
|
sordertab models.OmSerialorder
|
|
sordertablst []models.OmSerialorder
|
|
serialtasksrv SerialTaskSrv
|
|
)
|
|
// 初始化批次订单的序列订单信息
|
|
tasksrv.SerialTaskArray = []SerialTaskSrv{}
|
|
sordertab = models.OmSerialorder{Plantnr: tasksrv.Wotab.Plantnr, Workorderid: tasksrv.Wotab.Workorderid}
|
|
if sordertablst, err = sordertab.SelectByBatchOrder(); err != nil{
|
|
err = errors.New(fmt.Sprintf("查询批次订单%s的序列订单失败!",sordertab.Workorderid))
|
|
return
|
|
}
|
|
for i = 0; i < len(sordertablst); i++ {
|
|
serialtasksrv = SerialTaskSrv{}
|
|
serialtasksrv.Init(sordertablst[i])
|
|
tasksrv.SerialTaskArray = append(tasksrv.SerialTaskArray, serialtasksrv)
|
|
}
|
|
return
|
|
}
|
|
|
|
// 生成状态记录
|
|
func(tasksrv *TaskSrv)CreateStatusRecord(prevstatus int, eventsrv EventSrv)(err error){
|
|
var wostatusrectab models.OMWorkorderstatusrecLst
|
|
|
|
// 初始化
|
|
wostatusrectab = models.OMWorkorderstatusrecLst{}
|
|
wostatusrectab.Plantnr = tasksrv.PlantNr
|
|
wostatusrectab.Workorderid = tasksrv.TaskId
|
|
wostatusrectab.Prevstatus = prevstatus
|
|
wostatusrectab.Status = tasksrv.Status
|
|
wostatusrectab.Triggerevent = eventsrv.TriggerEvent
|
|
wostatusrectab.Triggerobjectid = eventsrv.TriggerObjectId
|
|
wostatusrectab.Triggersubobjectid = eventsrv.TriggerSubObjectId
|
|
wostatusrectab.Outputstatus = OUTPUT_TRIGGER_UNHANDLED // 未处理
|
|
wostatusrectab.Outputevent = eventsrv.OutputEvent
|
|
wostatusrectab.OutputeventmessageId = eventsrv.OutputEventMsgId
|
|
wostatusrectab.OutputobjectId = eventsrv.OutputObjectId
|
|
wostatusrectab.OutputsubobjectId = eventsrv.OutputSubObjectId
|
|
SetTableLastModify(&wostatusrectab, wostatusrectab, MODIFY_MODE_CREATE, eventsrv.TriggerService)
|
|
if err = wostatusrectab.Add(); err != nil {
|
|
err = errors.New(fmt.Sprintf("无法为工单%s插入状态变更记录%v!",tasksrv.TaskId, err))
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// 下达批次订单
|
|
func(tasksrv *TaskSrv)Release()(err error){
|
|
var(
|
|
wostatrectab models.OMWorkorderstatusrecLst
|
|
)
|
|
|
|
if tasksrv.WoStatusTab.Status != WO_STATUS_LOCKED {
|
|
err = errors.New(fmt.Sprintf("批次订单%s状态%d不满足下达条件,无法下达!", tasksrv.WoStatusTab.Workorderid, tasksrv.WoStatusTab.Status))
|
|
return
|
|
}
|
|
// 变更状态
|
|
tasksrv.Status = WO_STATUS_RELEASED
|
|
tasksrv.WoStatusTab.Status = WO_STATUS_RELEASED
|
|
SetTableLastModify(&tasksrv.WoStatusTab, tasksrv.WoStatusTab,MODIFY_MODE_UPDATE,"rel_service")
|
|
if err = tasksrv.WoStatusTab.Update(); err != nil{
|
|
err = errors.New(fmt.Sprintf("批次订单%s更新状态出错%v!", tasksrv.WoStatusTab.Workorderid, err))
|
|
return
|
|
}
|
|
// 新增批次订单状态变更记录
|
|
wostatrectab = models.OMWorkorderstatusrecLst{}
|
|
wostatrectab.Plantnr = tasksrv.WoStatusTab.Plantnr
|
|
wostatrectab.Workorderid = tasksrv.WoStatusTab.Workorderid
|
|
wostatrectab.Prevstatus = WO_STATUS_LOCKED
|
|
wostatrectab.Status = WO_STATUS_RELEASED
|
|
wostatrectab.Triggerevent = BATORD_EVENT_RELEASE
|
|
wostatrectab.Triggerobjectid = tasksrv.WoStatusTab.Workorderid
|
|
wostatrectab.Outputstatus = OUTPUT_TRIGGER_UNHANDLED
|
|
wostatrectab.Outputevent = BATORD_EVENT_RELEASE
|
|
wostatrectab.OutputobjectId = tasksrv.WoStatusTab.Workorderid
|
|
SetTableLastModify(&wostatrectab, wostatrectab, MODIFY_MODE_CREATE,"rel_service")
|
|
if err = wostatrectab.Add(); err != nil{
|
|
err = errors.New(fmt.Sprintf("批次订单%s无法插入状态变更记录%v!", tasksrv.WoStatusTab.Workorderid, err))
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
// 下达批次订单,同步生成对应的序列订单
|
|
func(tasksrv *TaskSrv)ReleaseSerialOrder(relqty int)(err error){
|
|
var(
|
|
i,actrelqty int
|
|
)
|
|
|
|
// 获取批次订单对象
|
|
if err = tasksrv.Get(); err != nil{
|
|
return
|
|
}
|
|
// 判断批次订单状态是否满足下达条件 >= 24 && < 80
|
|
if tasksrv.WoStatusTab.Status < WO_STATUS_LOCKED || tasksrv.WoStatusTab.Status >= WO_STATUS_FINISHED {
|
|
err = errors.New(fmt.Sprintf("批次订单%s状态%d不满足下达条件,无法下达!", tasksrv.WoStatusTab.Workorderid, tasksrv.WoStatusTab.Status))
|
|
return
|
|
}
|
|
// 获取批次订单已下达序列订单
|
|
if err = tasksrv.LoadSerialOrders(); err != nil {
|
|
return
|
|
}
|
|
// 计算实际可下达的序列订单数量
|
|
actrelqty = int(tasksrv.PlanQty) - len(tasksrv.SerialTaskArray)
|
|
if actrelqty <= 0 {
|
|
err = errors.New(fmt.Sprintf("批次订单%s可下达数量小于0!", tasksrv.WoStatusTab.Workorderid))
|
|
return
|
|
}
|
|
// 置位批次订单状态
|
|
if tasksrv.WoStatusTab.Status == WO_STATUS_LOCKED {
|
|
if err = tasksrv.Release(); err != nil{
|
|
err = errors.New(fmt.Sprintf("下达批次订单%s失败!",tasksrv.TaskId))
|
|
return
|
|
}
|
|
}
|
|
// 下达指定数量的序列订单,置位序列订单为26
|
|
for i = 0; i < actrelqty; i++ {
|
|
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// 基于指定的序列订单号获取序列订单对象
|
|
func(stasksrv *SerialTaskSrv)Get()(err error){
|
|
var serordtab models.OmSerialorder
|
|
|
|
serordtab = models.OmSerialorder{Plantnr: stasksrv.PlantNr, Workorderid: stasksrv.TaskId}
|
|
if serordtab, err = serordtab.SelectOne(); err != nil{
|
|
err = errors.New(fmt.Sprintf("获取工厂%d序列订单%s失败!",stasksrv.PlantNr,stasksrv.TaskId))
|
|
return
|
|
}
|
|
stasksrv.Init(serordtab)
|
|
return
|
|
}
|
|
|
|
// 初始化序列订单
|
|
func(stasksrv *SerialTaskSrv)Init(serialordertab models.OmSerialorder){
|
|
|
|
|
|
stasksrv.SerialOrderTab = serialordertab
|
|
stasksrv.SerialOrderStatusTab = serialordertab.Serstatustab
|
|
}
|
|
|
|
// 创建序列订单
|
|
func(stasksrv *SerialTaskSrv)Create()(err error){
|
|
|
|
// 插入序列订单
|
|
stasksrv.SerialOrderTab = models.OmSerialorder{}
|
|
stasksrv.SerialOrderTab.Plantnr = stasksrv.PlantNr
|
|
stasksrv.SerialOrderTab.Projectid = stasksrv.ProjectId
|
|
stasksrv.SerialOrderTab.Artid = stasksrv.ArtId
|
|
stasksrv.SerialOrderTab.Workorderid = stasksrv.ParentTaskId
|
|
stasksrv.SerialOrderTab.Planresourceid = stasksrv.SchedResId
|
|
stasksrv.SerialOrderTab.Ordertype = stasksrv.TaskType
|
|
stasksrv.SerialOrderTab.Serialorderid = stasksrv.TaskId
|
|
stasksrv.SerialOrderTab.Planqty = float32(stasksrv.PlanQty)
|
|
stasksrv.SerialOrderTab.Planstarttime = stasksrv.SchedStartTime
|
|
stasksrv.SerialOrderTab.Planendtime = stasksrv.SchedEndTime
|
|
SetTableLastModify(&stasksrv.SerialOrderTab, stasksrv.SerialOrderTab, MODIFY_MODE_CREATE, "rel_service")
|
|
if err = stasksrv.SerialOrderTab.Add(); err != nil{
|
|
err = errors.New(fmt.Sprintf("工单%s的序列订单%s头创建失败%v!",stasksrv.ParentTaskId, stasksrv.TaskId, err))
|
|
return
|
|
}
|
|
|
|
// 插入序列订单状态行
|
|
stasksrv.SerialOrderStatusTab = models.OmSerialorderstatus{}
|
|
stasksrv.SerialOrderStatusTab.Plantnr = stasksrv.PlantNr
|
|
stasksrv.SerialOrderStatusTab.Serialorderid = stasksrv.TaskId
|
|
stasksrv.SerialOrderStatusTab.Status = WO_STATUS_PLANNED
|
|
stasksrv.SerialOrderStatusTab.Triggerobjectid = stasksrv.ParentTaskId
|
|
stasksrv.SerialOrderStatusTab.Triggerevent = BATORD_EVENT_LOCK
|
|
SetTableLastModify(&stasksrv.SerialOrderStatusTab, stasksrv.SerialOrderStatusTab, MODIFY_MODE_CREATE, "rel_service")
|
|
if err = stasksrv.SerialOrderStatusTab.Add(); err != nil{
|
|
err = errors.New(fmt.Sprintf("工单%s的序列订单%s状态头创建失败%v!",stasksrv.ParentTaskId, stasksrv.TaskId, err))
|
|
return
|
|
}
|
|
|
|
// 插入序列订单状态记录行
|
|
// 如果需要触发动作可在此处添加
|
|
serordstatrectab := models.OmSerialorderstatusrecLst{}
|
|
serordstatrectab.Plantnr = stasksrv.PlantNr
|
|
serordstatrectab.Serialorderid = stasksrv.TaskId
|
|
serordstatrectab.Prevstatus = 0
|
|
serordstatrectab.Status = WO_STATUS_PLANNED
|
|
serordstatrectab.Outputevent = OUTPUT_EVENT_SER_NEW
|
|
serordstatrectab.OutputobjectId = serordstatrectab.Serialorderid
|
|
serordstatrectab.Outputstatus = OUTPUT_TRIGGER_UNHANDLED
|
|
SetTableLastModify(&serordstatrectab, serordstatrectab, MODIFY_MODE_CREATE, "rel_service")
|
|
if err = serordstatrectab.Add(); err != nil{
|
|
err = errors.New(fmt.Sprintf("工单%s的序列订单%s状态记录行创建失败%v!",stasksrv.ParentTaskId, stasksrv.TaskId, err))
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// 下达序列订单
|
|
func(stasksrv *SerialTaskSrv)Release()(err error){
|
|
var prevstatus int
|
|
|
|
// 判断序列订单是否可以被下达
|
|
if stasksrv.SerialOrderStatusTab.Status >= WO_STATUS_RELEASED {
|
|
return
|
|
}
|
|
|
|
// 获取序列订单当前状态
|
|
prevstatus = stasksrv.SerialOrderStatusTab.Status
|
|
|
|
// 更新序列订单状态行
|
|
stasksrv.SerialOrderStatusTab.Status = WO_STATUS_RELEASED
|
|
stasksrv.SerialOrderStatusTab.Triggerobjectid = stasksrv.ParentTaskId
|
|
stasksrv.SerialOrderStatusTab.Triggerevent = BATORD_EVENT_RELEASE
|
|
SetTableLastModify(&stasksrv.SerialOrderStatusTab, stasksrv.SerialOrderStatusTab, MODIFY_MODE_UPDATE, "rel_service")
|
|
if err = stasksrv.SerialOrderStatusTab.Update(); err != nil{
|
|
err = errors.New(fmt.Sprintf("工单%s的序列订单%s状态头更新失败%v!",stasksrv.ParentTaskId, stasksrv.TaskId, err))
|
|
return
|
|
}
|
|
|
|
// 插入序列订单状态记录行
|
|
// 如果需要触发动作可在此处添加
|
|
serordstatrectab := models.OmSerialorderstatusrecLst{}
|
|
serordstatrectab.Plantnr = stasksrv.PlantNr
|
|
serordstatrectab.Serialorderid = stasksrv.TaskId
|
|
serordstatrectab.Prevstatus = prevstatus
|
|
serordstatrectab.Status = WO_STATUS_RELEASED
|
|
serordstatrectab.Outputevent = OUTPUT_EVENT_SER_REL
|
|
serordstatrectab.OutputobjectId = serordstatrectab.Serialorderid
|
|
serordstatrectab.Outputstatus = OUTPUT_TRIGGER_UNHANDLED
|
|
SetTableLastModify(&serordstatrectab, serordstatrectab, MODIFY_MODE_UPDATE, "rel_service")
|
|
if err = serordstatrectab.Add(); err != nil{
|
|
err = errors.New(fmt.Sprintf("工单%s的序列订单%s状态记录行创建失败%v!",stasksrv.ParentTaskId, stasksrv.TaskId, err))
|
|
return
|
|
}
|
|
return
|
|
}
|