diff --git a/services/om/implments/SerialOrder.Logic.impl.go b/services/om/implments/SerialOrder.Logic.impl.go index 092ce9a..2d43049 100644 --- a/services/om/implments/SerialOrder.Logic.impl.go +++ b/services/om/implments/SerialOrder.Logic.impl.go @@ -462,7 +462,8 @@ func (impl *SerialOrderServiceImplement) ReplaceData(serialOrder *model.SerialOr } } -func (impl *SerialOrderServiceImplement) SingleProductTask(user *global.User, session *xorm.Session, task *baseModel.CrossPlanTask, productId string) (*model.SerialOrder ,error) { +// SingleProductTask 聚合单个总成的工艺数据 +func (impl *SerialOrderServiceImplement) SingleProductTask(user *global.User, session *xorm.Session, task *baseModel.CrossPlanTask, productId string) (*model.SerialOrder, error) { writeSerialOrderLi := make([]model.SerialOrder, 0) workLinePoDao := baseDal.NewWorkLineProcessLstDAO(session, user.PlantNr, user.UserId) productDao := meDal.NewProductDAO(session, user.PlantNr, user.UserId) @@ -514,13 +515,14 @@ func (impl *SerialOrderServiceImplement) SingleProductTask(user *global.User, se } +// ExecuteCrossPlantTask 执行跨工厂任务 func (impl *SerialOrderServiceImplement) ExecuteCrossPlantTask(task baseModel.CrossPlanTask) { engine := db.Eloquent.Master() session := engine.NewSession() defer session.Close() user := &global.User{ PlantNr: task.ToPlantNr, - UserId: "MultiPlantTask", + UserId: "MultiPlantTask", } releaseId, err := uuid.NewV4() if err != nil { @@ -528,6 +530,26 @@ func (impl *SerialOrderServiceImplement) ExecuteCrossPlantTask(task baseModel.Cr } log, _ := logger.NewLogger("跨工厂生成计划,id:"+releaseId.String(), "CrossPlant") taskDao := baseDal.NewCrossPlanTaskDAO(session, user.UserId) + projectDao := meDal.NewProjectDAO(session, user.PlantNr, user.UserId) + project, err := projectDao.SelectOne(task.ProjectId) + if err != nil { + task.Status = baseModel.CROSS_TASK_STATUS_ERROR + task.ErrorMsg = "查询任务项目失败,错误:" + err.Error() + err = taskDao.UpdateOne(&task) + if err != nil { + log.Error("更新任务状态失败, 错误:" + err.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) + } + return + } + if project == nil { + task.Status = baseModel.CROSS_TASK_STATUS_ERROR + task.ErrorMsg = "任务项目不存在, 项目ID:" + task.ProjectId + err = taskDao.UpdateOne(&task) + if err != nil { + log.Error("更新任务状态失败, 错误:" + err.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) + } + return + } // 获取生产的物料 productIdLi := strings.Split(task.ArtId, ";") if len(productIdLi) == 0 { @@ -548,6 +570,38 @@ func (impl *SerialOrderServiceImplement) ExecuteCrossPlantTask(task baseModel.Cr } return } + // 获取每个总成当前派工数量 + releaseQtyStrLi := strings.Split(task.ReleaseQty, ";") + releaseQtyLi := make([]int, 0, len(productIdLi)) + if len(releaseQtyStrLi) == 0 { + for range productIdLi { + releaseQtyStrLi = append(releaseQtyStrLi, "0") + } + } else if len(releaseQtyStrLi) != len(productIdLi) { + task.Status = baseModel.CROSS_TASK_STATUS_ERROR + task.ErrorMsg = "派工数量格式错误" + err = taskDao.UpdateOne(&task) + if err != nil { + log.Error("更新任务状态失败, 错误:" + err.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) + } + return + } + // 获取当前一共派工的数量 + var currentQty int + for _, releaseQtyStr := range releaseQtyStrLi { + qty, err := strconv.Atoi(releaseQtyStr) + if err != nil { + task.Status = baseModel.CROSS_TASK_STATUS_ERROR + task.ErrorMsg = "派工数量格式错误" + err = taskDao.UpdateOne(&task) + if err != nil { + log.Error("更新任务状态失败, 错误:" + err.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) + } + return + } + releaseQtyLi = append(releaseQtyLi, qty) + currentQty += qty + } subTime := task.PlanEndTime.Restore().Sub(task.PlanStartTime.Restore()) totalQty := len(productIdLi) * task.PlanQty perDuration := int(subTime.Seconds()) / totalQty @@ -564,14 +618,14 @@ func (impl *SerialOrderServiceImplement) ExecuteCrossPlantTask(task baseModel.Cr } // 记录生成计划中间的数量 type ProductQty struct { - ArtId string // 物料id - CurrentQty int // 当前数量 + ProductId string // 物料id + CurrentQty int // 当前数量 } productQtyCacheLi := make([]ProductQty, 0, len(productIdLi)) for _, productId := range productIdLi { productQtyData := ProductQty{ - ArtId: productId, + ProductId: productId, } productQtyCacheLi = append(productQtyCacheLi, productQtyData) } @@ -589,12 +643,246 @@ func (impl *SerialOrderServiceImplement) ExecuteCrossPlantTask(task baseModel.Cr } productCraftMap[productId] = serialOrderCraft } - for index, productQtyCache := range productQtyCacheLi { - if productQtyCache.CurrentQty == schedQty { - productQtyCache.CurrentQty = 0 - productQtyCacheLi[index] = productQtyCache - continue + for { + if task.Status == baseModel.CROSS_TASK_STATUS_ACCOMPLISHED { + break + } + for index, productQtyCache := range productQtyCacheLi { + if productQtyCache.CurrentQty == schedQty { + productQtyCache.CurrentQty = 0 + productQtyCacheLi[index] = productQtyCache + continue + } + if err = session.Begin(); err != nil { + task.Status = baseModel.CROSS_TASK_STATUS_ERROR + task.ErrorMsg = "开启事务失败, 错误:" + err.Error() + err = taskDao.UpdateOne(&task) + if err != nil { + log.Error("更新任务状态失败, 错误:" + err.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) + } + return + } + orderCraft := productCraftMap[productQtyCache.ProductId] + planStartTime := task.PlanStartTime.Restore().Add(time.Duration(currentQty*perDuration) * time.Second) + err = impl.SaveBatchOrderData(user, session, orderCraft, planStartTime, perDuration, schedQty, project.SerialOrderSnr) + if err != nil { + _ = session.Rollback() + task.Status = baseModel.CROSS_TASK_STATUS_ERROR + task.ErrorMsg = "保存工单工艺失败, 错误:" + err.Error() + err = taskDao.UpdateOne(&task) + if err != nil { + log.Error("更新任务状态失败, 错误:" + err.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) + } + return + } + releaseQtyLi[index] += schedQty + var totalReleaseQty string + for index, releaseQty := range releaseQtyLi { + if index != 0 { + totalReleaseQty += ";" + } + totalReleaseQty += strconv.Itoa(releaseQty) + } + task.ReleaseQty = totalReleaseQty + currentQty += schedQty + if currentQty == totalQty { + if task.Status == baseModel.CROSS_TASK_STATUS_PLAN { + task.StartTime = grmi.DateTime(time.Now()) + } + task.Status = baseModel.CROSS_TASK_STATUS_ACCOMPLISHED + task.ActQty = task.PlanQty + task.AccomplishTime = grmi.DateTime(time.Now()) + } else { + if task.Status == baseModel.CROSS_TASK_STATUS_PLAN { + task.StartTime = grmi.DateTime(time.Now()) + } + task.Status = baseModel.CHECK_STATUS_RUNNING + } + err = taskDao.UpdateOne(&task) + if err != nil { + _ = session.Rollback() + log.Error("更新任务状态失败, 错误:" + err.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr)) + return + } + _ = session.Commit() + } + } + return +} + +// SaveBatchOrderData 保存总成的工艺数据 +func (impl *SerialOrderServiceImplement) SaveBatchOrderData(user *global.User, session *xorm.Session, orderCraft *model.SerialOrder, planStartTime time.Time, perDuration, qty int, snrRule string) (err error) { + serialOrderDao := dal.NewSerialOrderDAO(session, user.PlantNr, user.UserId) + serialOrderStatusDao := dal.NewSerialOrderStatusDAO(session, user.PlantNr, user.UserId) + serialOrderPoDao := dal.NewSerialOrderPOLstDAO(session, user.PlantNr, user.UserId) + serialOrderStepDao := dal.NewSerialOrderStepLstDAO(session, user.PlantNr, user.UserId) + serialOrderOpDetailDao := dal.NewSerialOrderOPDetailDAO(session, user.PlantNr, user.UserId) + labelHeadDao := baseDal.NewLabelHeadDAO(session, user.PlantNr, user.UserId) + labelDetailDao := baseDal.NewLabelDetailDAO(session, user.PlantNr, user.UserId) + snrDao := baseDal.NewSnrDAO(session, user.PlantNr, user.UserId) + writeSerialOrderLi := make([]model.SerialOrder, 0) + writeSerialOrderStatusLi := make([]model.SerialOrderStatus, 0) + writeSerialOrderStepLi := make([]model.SerialOrderStepLst, 0) + writeSerialOrderPoLi := make([]model.SerialOrderPOLst, 0) + writeSerialOrderOpLi := make([]model.SerialOrderOPDetail, 0) + writeLabelHeadLi := make([]baseModel.LabelHead, 0) + writeLabelDetailLi := make([]baseModel.LabelDetail, 0) + for i := 0; i < qty; i++ { + var serialOrder model.SerialOrder + serialOrder = *orderCraft + serialOrder.PlanStartTime = grmi.DateTime(planStartTime.Add(time.Duration(perDuration*i) * time.Second)) + serialOrder.PlanEndTime = grmi.DateTime(planStartTime.Add(time.Duration(perDuration*(i+1)) * time.Second)) + serialOrder.PlanStartDate = grmi.Date(serialOrder.PlanStartTime) + serialOrder.PlanEndDate = grmi.Date(serialOrder.PlanEndTime) + timeInt, err := strconv.Atoi(planStartTime.Format("060102150405")) + if err != nil { + return grmi.NewBusinessError("通过时间获取工单调度Key失败, error:" + err.Error()) + } + var dealedSchedKey = int64(timeInt * 100) + serialOrder.SchedKey = dealedSchedKey + serialNum, err := snrDao.GetNextSnrWithTime(snrRule, serialOrder.PlanStartTime.Restore()) + if err != nil { + return grmi.NewBusinessError("生成工单流水号失败, error:" + err.Error()) + } + serialOrder.SerialOrderPOLstLi = make([]model.SerialOrderPOLst, len(orderCraft.SerialOrderPOLstLi), len(orderCraft.SerialOrderPOLstLi)) + serialOrder.SerialOrderStepLstLi = make([]model.SerialOrderStepLst, len(orderCraft.SerialOrderStepLstLi), len(orderCraft.SerialOrderStepLstLi)) + serialOrder.SerialOrderOPDetailLi = make([]model.SerialOrderOPDetail, len(orderCraft.SerialOrderOPDetailLi), len(orderCraft.SerialOrderOPDetailLi)) + serialOrder.LabelHeadLi = make([]baseModel.LabelHead, len(orderCraft.LabelHeadLi), len(orderCraft.LabelHeadLi)) + serialOrder.LabelDetailLi = make([]baseModel.LabelDetail, len(orderCraft.LabelDetailLi), len(orderCraft.LabelDetailLi)) + copy(serialOrder.SerialOrderPOLstLi, orderCraft.SerialOrderPOLstLi) + copy(serialOrder.SerialOrderStepLstLi, orderCraft.SerialOrderStepLstLi) + copy(serialOrder.SerialOrderOPDetailLi, orderCraft.SerialOrderOPDetailLi) + copy(serialOrder.LabelHeadLi, orderCraft.LabelHeadLi) + copy(serialOrder.LabelDetailLi, orderCraft.LabelDetailLi) + impl.ReplaceData(&serialOrder, serialNum, true) + writeSerialOrderLi = append(writeSerialOrderLi, serialOrder) + writeSerialOrderStatusLi = append(writeSerialOrderStatusLi, serialOrder.SerialOrderStatus) + writeSerialOrderPoLi = append(writeSerialOrderPoLi, serialOrder.SerialOrderPOLstLi...) + writeSerialOrderStepLi = append(writeSerialOrderStepLi, serialOrder.SerialOrderStepLstLi...) + writeSerialOrderOpLi = append(writeSerialOrderOpLi, serialOrder.SerialOrderOPDetailLi...) + writeLabelHeadLi = append(writeLabelHeadLi, serialOrder.LabelHeadLi...) + writeLabelDetailLi = append(writeLabelDetailLi, serialOrder.LabelDetailLi...) + } + // 插入工单 + num := len(writeSerialOrderLi) / 50 + remainder := len(writeSerialOrderLi) % 50 + for i := 0; i < num; i++ { + insertLi := writeSerialOrderLi[50*i : (i+1)*50] + err = serialOrderDao.Insert(&insertLi) + if err != nil { + return grmi.NewBusinessError("保存工单失败, 错误:" + err.Error()) + } + } + if remainder != 0 { + insertLi := writeSerialOrderLi[num*50:] + err = serialOrderDao.Insert(&insertLi) + if err != nil { + return grmi.NewBusinessError("保存工单失败, 错误:" + err.Error()) + } + } + // 插入工单状态 + num = len(writeSerialOrderStatusLi) / 50 + remainder = len(writeSerialOrderStatusLi) % 50 + for i := 0; i < num; i++ { + insertLi := writeSerialOrderStatusLi[50*i : (i+1)*50] + err = serialOrderStatusDao.Insert(&insertLi) + if err != nil { + return grmi.NewBusinessError("保存工单状态失败, 错误:" + err.Error()) + } + } + if remainder != 0 { + insertLi := writeSerialOrderStatusLi[num*50:] + err = serialOrderStatusDao.Insert(&insertLi) + if err != nil { + _ = session.Rollback() + return grmi.NewBusinessError("保存工单状态失败, 错误:" + err.Error()) + } + } + // 插入工单工序数据 + num = len(writeSerialOrderPoLi) / 50 + remainder = len(writeSerialOrderPoLi) % 50 + for i := 0; i < num; i++ { + insertLi := writeSerialOrderPoLi[50*i : (i+1)*50] + err = serialOrderPoDao.Insert(&insertLi) + if err != nil { + return grmi.NewBusinessError("保存工单工序失败, 错误:" + err.Error()) + } + } + if remainder != 0 { + insertLi := writeSerialOrderPoLi[num*50:] + err = serialOrderPoDao.Insert(&insertLi) + if err != nil { + return grmi.NewBusinessError("保存工单工序失败, 错误:" + err.Error()) + } + } + // 插入工单工步数据 + num = len(writeSerialOrderStepLi) / 50 + remainder = len(writeSerialOrderStepLi) % 50 + for i := 0; i < num; i++ { + insertLi := writeSerialOrderStepLi[50*i : (i+1)*50] + err = serialOrderStepDao.Insert(&insertLi) + if err != nil { + return grmi.NewBusinessError("保存工单工步失败, 错误:" + err.Error()) + } + } + if remainder != 0 { + insertLi := writeSerialOrderStepLi[num*50:] + err = serialOrderStepDao.Insert(&insertLi) + if err != nil { + return grmi.NewBusinessError("保存工单工步失败, 错误:" + err.Error()) + } + } + // 插入工单工艺数据 + num = len(writeSerialOrderOpLi) / 50 + remainder = len(writeSerialOrderOpLi) % 50 + for i := 0; i < num; i++ { + insertLi := writeSerialOrderOpLi[50*i : (i+1)*50] + err = serialOrderOpDetailDao.Insert(&insertLi) + if err != nil { + return grmi.NewBusinessError("保存工单工艺失败, 错误:" + err.Error()) + } + } + if remainder != 0 { + insertLi := writeSerialOrderOpLi[num*50:] + err = serialOrderOpDetailDao.Insert(&insertLi) + if err != nil { + return grmi.NewBusinessError("保存工单工艺失败, 错误:" + err.Error()) + } + } + // 写入打印标签数据 + num = len(writeLabelHeadLi) / 50 + remainder = len(writeLabelHeadLi) % 50 + for i := 0; i < num; i++ { + insertLi := writeLabelHeadLi[50*i : (i+1)*50] + err = labelHeadDao.Insert(&insertLi) + if err != nil { + return grmi.NewBusinessError("保存标签头部失败, 错误:" + err.Error()) + } + } + if remainder != 0 { + insertLi := writeLabelHeadLi[num*50:] + err = labelHeadDao.Insert(&insertLi) + if err != nil { + return grmi.NewBusinessError("保存标签头部失败, 错误:" + err.Error()) + } + } + num = len(writeLabelDetailLi) / 50 + remainder = len(writeLabelDetailLi) % 50 + for i := 0; i < num; i++ { + insertLi := writeLabelDetailLi[50*i : (i+1)*50] + err = labelDetailDao.Insert(&insertLi) + if err != nil { + return grmi.NewBusinessError("保存标签详情失败, 错误:" + err.Error()) } - startNum := } -} \ No newline at end of file + if remainder != 0 { + insertLi := writeLabelDetailLi[num*50:] + err = labelDetailDao.Insert(&insertLi) + if err != nil { + return grmi.NewBusinessError("保存标签详情失败, 错误:" + err.Error()) + } + } + return nil +} + +