|
|
- package schedule
-
- import (
- dal "LAPP_ACURA_MOM_BACKEND/dao/om"
- plnDal "LAPP_ACURA_MOM_BACKEND/dao/pln"
- "LAPP_ACURA_MOM_BACKEND/db"
- "LAPP_ACURA_MOM_BACKEND/grmi"
- common "LAPP_ACURA_MOM_BACKEND/models/base"
- model "LAPP_ACURA_MOM_BACKEND/models/om"
- plnModel "LAPP_ACURA_MOM_BACKEND/models/pln"
- "errors"
- "fmt"
- "github.com/go-xorm/xorm"
- "time"
- )
-
- // TaskSrv 调度批次任务对象
- 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 // 计划数量
- CancelQty 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 // 实际结束时间
- CustOrder plnModel.CustOrder
- CustOrderStatus plnModel.CustOrderStatus
- CustOrderQty plnModel.CustOrderQty
- SerialTaskArray []SerialTaskSrv // 批次订单的序列订单
- }
-
- // 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 model.SerialOrder
- SerialOrderStatusTab model.SerialOrderStatus
- }
-
- // Get 基于指定的批次订单号获取批次订单对象
- func (tasksrv *TaskSrv) Get() (err error) {
-
- engine := db.Eloquent.Master()
- session := engine.NewSession()
- defer session.Close()
- dao := plnDal.NewCustOrderDAO(session, tasksrv.PlantNr, "scheduler")
- var custOrder *plnModel.CustOrder
- if custOrder, err = dao.SelectOne(tasksrv.TaskId); err != nil {
- return grmi.NewBusinessError("获取工厂客户订单失败, 客户订单ID:" + tasksrv.TaskId + ", error:" + err.Error())
- }
- tasksrv.Init(*custOrder)
- return
- }
-
- // Init 基于给定的订单表和订单状态表进行结构初始化
- func (tasksrv *TaskSrv) Init(custOrder plnModel.CustOrder) {
- // 初始化批次任务的批次订单信息
- tasksrv.TaskId = custOrder.CustOrderId
- tasksrv.TaskType = custOrder.OrderType
- tasksrv.SortKey = custOrder.PlanStartTime.Restore().Unix() // 用于给MES用的排序号
- tasksrv.ArtId = custOrder.ProductFamilyId // 任务产品ID
- //tasksrv.Priority = custOrder.Priority // 优先级
- tasksrv.Status = custOrder.OrderStatus.Status // 订单状态
- //tasksrv.SchedResGrpId = wotab.PlanResourceGroupId // 调度资源组ID
- tasksrv.SchedResId = custOrder.WorkLineId // 调度资源
- tasksrv.FixResource = false // 锁定资源
- tasksrv.PlanQty = float64(custOrder.OrderQty.PlanQty) // 计划数量
- tasksrv.ReleasedQty = float64(custOrder.OrderQty.ReleasedQty) // 已下达数量 - 每个独立生成序列订单
- tasksrv.FinishedQty = float64(custOrder.OrderQty.ActQty) // 已完成数量
- tasksrv.CancelQty = float64(custOrder.OrderQty.CancelQty)
- tasksrv.EarliestStartTime = custOrder.PlanStartDate.Restore() // 最早开始时间
- tasksrv.LatestEndTime = custOrder.PlanEndTime.Restore() // 最迟结束时间
- tasksrv.SetupStartTime = custOrder.SetupStartTime.Restore() // 换型开始时间
- tasksrv.SetupEndTime = custOrder.SetupEndTime.Restore() // 换型结束时间
- if custOrder.FixStartTimeToggle { // 锁定开始时间
- tasksrv.FixStartTime = true
- } else {
- tasksrv.FixStartTime = false
- }
- tasksrv.SchedStartTime = custOrder.PlanStartTime.Restore() // 排程开始时间
- tasksrv.SchedEndTime = custOrder.PlanEndTime.Restore() // 排程结束时间
- tasksrv.ActStartTime = custOrder.ActStartTime.Restore() // 实际开始时间
- tasksrv.ActEndTime = custOrder.ActEndTime.Restore() // 实际结束时间
-
- // 获取调度任务所需要的工时
- calQty := custOrder.PlanQty - custOrder.OrderQty.CancelQty
- //if custOrder.RatePerHourToggle {
- if custOrder.QuantityPerHour <= 0 || calQty <= 0 {
- tasksrv.Duration = 0
- } else {
- tasksrv.Duration = time.Duration(float64(calQty)/float64(custOrder.QuantityPerHour)*3600) * time.Second
- }
-
- //}
- //if wotab.TimePerItemToggle {
- // perItemSeconds := float64(wotab.OpTimePerItem) * GetTimeUomSeconds(wotab.TimeUomId)
- // tasksrv.Duration = time.Duration(float64(calQty)*perItemSeconds) * time.Second
- //}
- //if wotab.TimePerBatchToggle {
- // if wotab.BatchTime <= 0 || wotab.BatchQuantity <= 0 || calQty <= 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.CustOrder = custOrder
- tasksrv.CustOrderStatus = custOrder.OrderStatus
- tasksrv.CustOrderQty = custOrder.OrderQty
- }
-
- // LoadSerialOrders 加载批次订单的序列订单
- func (tasksrv *TaskSrv) LoadSerialOrders(session *xorm.Session) (err error) {
- var (
- i int
- sordertablst []model.SerialOrder
- serialtasksrv SerialTaskSrv
- )
- // 初始化批次订单的序列订单信息
- tasksrv.SerialTaskArray = []SerialTaskSrv{}
- dao := dal.NewSerialOrderDAO(session, tasksrv.PlantNr, "scheduler")
- if sordertablst, err = dao.SelectByCustOrder(tasksrv.CustOrder.CustOrderId, common.WO_STATUS_LOCKED); err != nil {
- return grmi.NewBusinessError(fmt.Sprintf("查询客户订单的序列订单失败!, error:" + err.Error() + " ,客户订单ID: " + tasksrv.CustOrder.CustOrderId))
- }
- for i = 0; i < len(sordertablst); i++ {
- serialtasksrv = SerialTaskSrv{}
- serialtasksrv.Init(sordertablst[i])
- tasksrv.SerialTaskArray = append(tasksrv.SerialTaskArray, serialtasksrv)
- }
- return
- }
-
- // CreateStatusRecord 生成状态记录
- func (tasksrv *TaskSrv) CreateStatusRecord(prevstatus int, eventsrv EventSrv) (err error) {
- var wostatusrectab model.WorkOrderStatusRecLst
-
- // 初始化
- wostatusrectab = model.WorkOrderStatusRecLst{}
- 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 = common.OUTPUT_TRIGGER_UNHANDLED // 未处理
- wostatusrectab.OutputEvent = eventsrv.OutputEvent
- wostatusrectab.OutputEventMessageId = eventsrv.OutputEventMsgId
- wostatusrectab.OutputObjectId = eventsrv.OutputObjectId
- wostatusrectab.OutputSubObjectId = eventsrv.OutputSubObjectId
- SetTableLastModify(&wostatusrectab, wostatusrectab, common.MODIFY_MODE_CREATE, eventsrv.TriggerService)
-
- engine := db.Eloquent.Master()
- session := engine.NewSession()
- defer session.Close()
- dao := dal.NewWorkOrderStatusRecLstDAO(session, tasksrv.PlantNr, "scheduler")
- if err := dao.InsertOne(&wostatusrectab); err != nil {
- err = errors.New(fmt.Sprintf("无法为工单%s插入状态变更记录%v!", tasksrv.TaskId, err))
- return err
- }
-
- return
- }
-
- // ReleaseSerialOrder 下达批次订单,同步生成对应的序列订单
- func (tasksrv *TaskSrv) ReleaseSerialOrder(relQty int, releaseId string) (err error) {
- //engine := db.Eloquent.Master()
- //session := engine.NewSession()
- //defer session.Close()
- //if err = session.Begin(); err != nil {
- // return grmi.NewBusinessError("开启事务失败, error:" + err.Error())
- //}
- //var user = "scheduler"
- //workLineDao := baseDal.NewWorkLineDAO(session, tasksrv.PlantNr, user)
- //innerLog, _ := logger.NewLogger("scheduler", "scheduler")
- //innerLog.Debug("开始派工, 派工任务ID:"+releaseId, ", 客户订单ID:"+tasksrv.CustOrder.CustOrderId+", 通过数量进行派工,派工数量:"+strconv.Itoa(relQty))
- //// 判断批次订单状态是否满足下达条件 >= 24 && < 80
- //if tasksrv.CustOrderStatus.Status < common.WO_STATUS_LOCKED || tasksrv.CustOrderStatus.Status >= common.WO_STATUS_FINISHED {
- // _ = session.Rollback()
- // return grmi.NewBusinessError("客户订单状态不满足派工条件, 无法下达, 客户订单ID:" + tasksrv.CustOrder.CustOrderId + ", 订单状态:" + strconv.Itoa(tasksrv.CustOrderStatus.Status))
- //}
- //innerLog.Debug("开始派工, 派工任务ID:"+releaseId, ", 客户订单ID:"+tasksrv.CustOrder.CustOrderId+", 加载客户订单下的序列订单完成")
- //// 计算实际可下达的序列订单数量
- //actRelQty := len(tasksrv.SerialTaskArray)
- //if actRelQty <= 0 {
- // _ = session.Rollback()
- // innerLog.Error("开始派工, 派工任务ID:" + releaseId + ", 客户订单ID:" + tasksrv.CustOrder.CustOrderId + ", 该客户订单下可派工的订单数量为0")
- // return grmi.NewBusinessError("客户订单可下达数量为0, 客户订单ID:" + tasksrv.CustOrder.CustOrderId)
- //}
- //if relQty > actRelQty {
- // _ = session.Rollback()
- // innerLog.Error("开始派工, 派工任务ID:" + releaseId + ", 客户订单ID:" + tasksrv.CustOrder.CustOrderId + ", 需要派工数量大于客户订单可派工数量, 需要派工数量:" + strconv.Itoa(relQty) + ", 可派工数量:" + strconv.Itoa(actRelQty))
- // return grmi.NewBusinessError("客户订单需要派工数量大于可派工数量, 客户订单ID:" + tasksrv.CustOrder.CustOrderId)
- //}
- //workLine, err := workLineDao.SelectOne(tasksrv.CustOrder.WorkLineId)
- //if err != nil {
- // _ = session.Rollback()
- // innerLog.Error("开始派工, 派工任务ID:" + releaseId + ", 客户订单ID:" + tasksrv.CustOrder.CustOrderId + ", 获取产线数据失败, error:" + err.Error())
- // return grmi.NewBusinessError("获取产线数据失败, 客户订单ID:" + tasksrv.CustOrder.CustOrderId + ", error:" + err.Error())
- //}
- //if workLine == nil {
- // _ = session.Rollback()
- // innerLog.Error("开始派工, 派工任务ID:" + releaseId + ", 客户订单ID:" + tasksrv.CustOrder.CustOrderId + ", 产线不存在, 产线ID:" + tasksrv.CustOrder.WorkLineId)
- // return grmi.NewBusinessError("获取产线不存在, 产线ID:" + tasksrv.CustOrder.WorkLineId + ", 客户订单ID:" + tasksrv.CustOrder.CustOrderId)
- //}
- //custOrderSvr := plnSvr.NewCustOrderService()
- //resCustOrder, err := custOrderSvr.ReleaseCustOrder(session, relQty, &tasksrv.CustOrder)
- //if err != nil {
- // _ = session.Rollback()
- // innerLog.Error("开始派工, 派工任务ID:" + releaseId + ", 客户订单ID:" + tasksrv.CustOrder.CustOrderId + ", 客户订单派工阶段失败, error:" + err.Error())
- //}
- //_ = session.Commit()
- //innerLog.Debug("派工完成, 派工任务ID:"+releaseId, ", 客户订单ID:"+tasksrv.CustOrder.CustOrderId+", 派工数量:"+strconv.Itoa(relQty))
- //tasksrv.Init(*resCustOrder)
- return
- }
-
- // Get 基于指定的序列订单号获取序列订单对象
- func (stasksrv *SerialTaskSrv) Get() (err error) {
- var serordtab model.SerialOrder
-
- engine := db.Eloquent.Master()
- session := engine.NewSession()
- defer session.Close()
- dao := dal.NewSerialOrderDAO(session, stasksrv.PlantNr, "scheduler")
- if serordtab, err = dao.SelectInfo(stasksrv.TaskId); err != nil {
- err = errors.New(fmt.Sprintf("获取工厂%d序列订单%s失败!", stasksrv.PlantNr, stasksrv.TaskId))
- return
- }
- stasksrv.Init(serordtab)
- return
- }
-
- // Init 初始化序列订单
- func (stasksrv *SerialTaskSrv) Init(serialordertab model.SerialOrder) {
-
- stasksrv.SerialOrderTab = serialordertab
- stasksrv.SerialOrderStatusTab = serialordertab.SerialOrderStatus
- }
-
- // Create 创建序列订单
- func (stasksrv *SerialTaskSrv) Create() (err error) {
-
- // 插入序列订单
- stasksrv.SerialOrderTab = model.SerialOrder{}
- 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 = float64(stasksrv.PlanQty)
- stasksrv.SerialOrderTab.PlanStartTime = grmi.DateTime(stasksrv.SchedStartTime)
- stasksrv.SerialOrderTab.PlanEndTime = grmi.DateTime(stasksrv.SchedEndTime)
- SetTableLastModify(&stasksrv.SerialOrderTab, stasksrv.SerialOrderTab, common.MODIFY_MODE_CREATE, "rel_service")
-
- engine := db.Eloquent.Master()
- session := engine.NewSession()
- defer session.Close()
- dao := dal.NewSerialOrderDAO(session, stasksrv.PlantNr, "rel_service")
- if err = dao.InsertOne(&stasksrv.SerialOrderTab); err != nil {
- err = errors.New(fmt.Sprintf("工单%s的序列订单%s头创建失败%v!", stasksrv.ParentTaskId, stasksrv.TaskId, err))
- return
- }
-
- // 插入序列订单状态行
- stasksrv.SerialOrderStatusTab = model.SerialOrderStatus{}
- stasksrv.SerialOrderStatusTab.PlantNr = stasksrv.PlantNr
- stasksrv.SerialOrderStatusTab.SerialOrderId = stasksrv.TaskId
- stasksrv.SerialOrderStatusTab.Status = common.WO_STATUS_PLANNED
- stasksrv.SerialOrderStatusTab.TriggerObjectId = stasksrv.ParentTaskId
- stasksrv.SerialOrderStatusTab.TriggerEvent = common.BATORD_EVENT_LOCK
- SetTableLastModify(&stasksrv.SerialOrderStatusTab, stasksrv.SerialOrderStatusTab, common.MODIFY_MODE_CREATE, "rel_service")
- serial := dal.NewSerialOrderStatusDAO(session, stasksrv.PlantNr, "rel_service")
- if err = serial.InsertOne(&stasksrv.SerialOrderStatusTab); err != nil {
- err = errors.New(fmt.Sprintf("工单%s的序列订单%s状态头创建失败%v!", stasksrv.ParentTaskId, stasksrv.TaskId, err))
- return
- }
-
- // 插入序列订单状态记录行
- // 如果需要触发动作可在此处添加
- serordstatrectab := model.SerialOrderStatusRecLst{}
- serordstatrectab.PlantNr = stasksrv.PlantNr
- serordstatrectab.SerialOrderId = stasksrv.TaskId
- serordstatrectab.PrevStatus = 0
- serordstatrectab.Status = common.WO_STATUS_PLANNED
- serordstatrectab.OutputEvent = common.OUTPUT_EVENT_SER_NEW
- serordstatrectab.OutputObjectId = serordstatrectab.SerialOrderId
- serordstatrectab.OutputStatus = common.OUTPUT_TRIGGER_UNHANDLED
- SetTableLastModify(&serordstatrectab, serordstatrectab, common.MODIFY_MODE_CREATE, "rel_service")
- serord := dal.NewSerialOrderStatusRecLstDAO(session, stasksrv.PlantNr, "rel_service")
- if err = serord.InsertOne(&serordstatrectab); err != nil {
- err = errors.New(fmt.Sprintf("工单%s的序列订单%s状态记录行创建失败%v!", stasksrv.ParentTaskId, stasksrv.TaskId, err))
- return
- }
-
- return
- }
-
- // Release 下达序列订单
- func (stasksrv *SerialTaskSrv) Release() (err error) {
- var prevstatus int
-
- // 判断序列订单是否可以被下达
- if stasksrv.SerialOrderStatusTab.Status >= common.WO_STATUS_RELEASED {
- return
- }
-
- // 获取序列订单当前状态
- prevstatus = stasksrv.SerialOrderStatusTab.Status
-
- // 更新序列订单状态行
- stasksrv.SerialOrderStatusTab.Status = common.WO_STATUS_RELEASED
- stasksrv.SerialOrderStatusTab.TriggerObjectId = stasksrv.ParentTaskId
- stasksrv.SerialOrderStatusTab.TriggerEvent = common.BATORD_EVENT_RELEASE
- SetTableLastModify(&stasksrv.SerialOrderStatusTab, stasksrv.SerialOrderStatusTab, common.MODIFY_MODE_UPDATE, "rel_service")
- engine := db.Eloquent.Master()
- session := engine.NewSession()
- defer session.Close()
- serial := dal.NewSerialOrderStatusDAO(session, stasksrv.PlantNr, "rel_service")
- if err = serial.UpdateOne(&stasksrv.SerialOrderStatusTab); err != nil {
- err = errors.New(fmt.Sprintf("工单%s的序列订单%s状态头更新失败%v!", stasksrv.ParentTaskId, stasksrv.TaskId, err))
- return
- }
-
- // 插入序列订单状态记录行
- // 如果需要触发动作可在此处添加
- serordstatrectab := model.SerialOrderStatusRecLst{}
- serordstatrectab.PlantNr = stasksrv.PlantNr
- serordstatrectab.SerialOrderId = stasksrv.TaskId
- serordstatrectab.PrevStatus = prevstatus
- serordstatrectab.Status = common.WO_STATUS_RELEASED
- serordstatrectab.OutputEvent = common.OUTPUT_EVENT_SER_REL
- serordstatrectab.OutputObjectId = serordstatrectab.SerialOrderId
- serordstatrectab.OutputStatus = common.OUTPUT_TRIGGER_UNHANDLED
- SetTableLastModify(&serordstatrectab, serordstatrectab, common.MODIFY_MODE_UPDATE, "rel_service")
- serord := dal.NewSerialOrderStatusRecLstDAO(session, stasksrv.PlantNr, "rel_service")
- if err = serord.UpdateOne(&serordstatrectab); err != nil {
- err = errors.New(fmt.Sprintf("工单%s的序列订单%s状态记录行创建失败%v!", stasksrv.ParentTaskId, stasksrv.TaskId, err))
- return
- }
- return
- }
|