You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

375 lines
14 KiB

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
}