// Copyright (c) Shenyang Leading Edge Intelligent Technology Co., Ltd. All rights reserved.

package implments

import (
	baseDal "LAPP_LF_MOM_BACKEND/dao/base"
	meDal "LAPP_LF_MOM_BACKEND/dao/me"
	baseMeta "LAPP_LF_MOM_BACKEND/meta/base"
	meModel "LAPP_LF_MOM_BACKEND/models/me"
	"fmt"
	"github.com/go-xorm/xorm"
	"strings"

	//logDal "LAPP_LF_MOM_BACKEND/dao/log"
	dal "LAPP_LF_MOM_BACKEND/dao/om"
	"LAPP_LF_MOM_BACKEND/db"
	"LAPP_LF_MOM_BACKEND/grmi"
	"LAPP_LF_MOM_BACKEND/infra/logger"
	meMeta "LAPP_LF_MOM_BACKEND/meta/me"
	//logMeta "LAPP_LF_MOM_BACKEND/meta/log"
	meta "LAPP_LF_MOM_BACKEND/meta/om"
	baseModel "LAPP_LF_MOM_BACKEND/models/base"
	//logModel "LAPP_LF_MOM_BACKEND/models/log"
	model "LAPP_LF_MOM_BACKEND/models/om"
	"LAPP_LF_MOM_BACKEND/utils"
	"LAPP_LF_MOM_BACKEND/web/models"
	"strconv"
	"time"
)

/******************************************************************************
 *
 * @Description              : WorkOrder的默认查询条件
 *
 * @Author                   : 代码生成器创建
 *
 * @Date                     : 2021-04-22 16:45:05
 *
 ******************************************************************************/
var DefaultConditionOfWorkOrder = grmi.NewCondition(
	map[string]grmi.ConditionItem{
		meta.WorkOrder_WorkOrderId.UrlParameterName:          grmi.NewConditionItem(meta.WorkOrder_WorkOrderId, grmi.Equal, true),
		meta.WorkOrder_ArtId.UrlParameterName:                grmi.NewConditionItem(meta.WorkOrder_ArtId, grmi.Equal, false),
		meta.WorkOrder_CustArtId.UrlParameterName:            grmi.NewConditionItem(meta.WorkOrder_CustArtId, grmi.Equal, false),
		meta.WorkOrder_RouteTemplateId.UrlParameterName:      grmi.NewConditionItem(meta.WorkOrder_RouteTemplateId, grmi.Equal, false),
		meta.WorkOrder_OrderType.UrlParameterName:            grmi.NewConditionItem(meta.WorkOrder_OrderType, grmi.Equal, false),
		meta.WorkOrder_OrderType1.UrlParameterName:           grmi.NewConditionItem(meta.WorkOrder_OrderType1, grmi.Equal, false),
		meta.WorkOrder_OrderType2.UrlParameterName:           grmi.NewConditionItem(meta.WorkOrder_OrderType2, grmi.Equal, false),
		meta.WorkOrder_OrderInfo.UrlParameterName:            grmi.NewConditionItem(meta.WorkOrder_OrderInfo, grmi.Equal, false),
		meta.WorkOrder_CustOrderId.UrlParameterName:          grmi.NewConditionItem(meta.WorkOrder_CustOrderId, grmi.Equal, false),
		meta.WorkOrder_ErpOrderId.UrlParameterName:           grmi.NewConditionItem(meta.WorkOrder_ErpOrderId, grmi.Equal, false),
		meta.WorkOrder_ParentOrderId.UrlParameterName:        grmi.NewConditionItem(meta.WorkOrder_ParentOrderId, grmi.Equal, false),
		meta.WorkOrder_Priority.UrlParameterName:             grmi.NewConditionItem(meta.WorkOrder_Priority, grmi.Equal, false),
		meta.WorkOrder_PlanResourceGroupId.UrlParameterName:  grmi.NewConditionItem(meta.WorkOrder_PlanResourceGroupId, grmi.Equal, false),
		meta.WorkOrder_PlanResourceId.UrlParameterName:       grmi.NewConditionItem(meta.WorkOrder_PlanResourceId, grmi.Equal, false),
		meta.WorkOrder_UsedResourceId.UrlParameterName:       grmi.NewConditionItem(meta.WorkOrder_UsedResourceId, grmi.Equal, false),
		meta.WorkOrder_PlanQty.UrlParameterName:              grmi.NewConditionItem(meta.WorkOrder_PlanQty, grmi.Equal, false),
		meta.WorkOrder_QtyUomId.UrlParameterName:             grmi.NewConditionItem(meta.WorkOrder_QtyUomId, grmi.Equal, false),
		meta.WorkOrder_RatePerHourToggle.UrlParameterName:    grmi.NewConditionItem(meta.WorkOrder_RatePerHourToggle, grmi.Equal, false),
		meta.WorkOrder_TimePerItemToggle.UrlParameterName:    grmi.NewConditionItem(meta.WorkOrder_TimePerItemToggle, grmi.Equal, false),
		meta.WorkOrder_TimePerBatchToggle.UrlParameterName:   grmi.NewConditionItem(meta.WorkOrder_TimePerBatchToggle, grmi.Equal, false),
		meta.WorkOrder_BatchTimeFieldToggle.UrlParameterName: grmi.NewConditionItem(meta.WorkOrder_BatchTimeFieldToggle, grmi.Equal, false),
		meta.WorkOrder_OpTimePerItem.UrlParameterName:        grmi.NewConditionItem(meta.WorkOrder_OpTimePerItem, grmi.Equal, false),
		meta.WorkOrder_BatchTime.UrlParameterName:            grmi.NewConditionItem(meta.WorkOrder_BatchTime, grmi.Equal, false),
		meta.WorkOrder_QuantityPerHour.UrlParameterName:      grmi.NewConditionItem(meta.WorkOrder_QuantityPerHour, grmi.Equal, false),
		meta.WorkOrder_BatchQuantity.UrlParameterName:        grmi.NewConditionItem(meta.WorkOrder_BatchQuantity, grmi.Equal, false),
		meta.WorkOrder_TimeUomId.UrlParameterName:            grmi.NewConditionItem(meta.WorkOrder_TimeUomId, grmi.Equal, false),
		meta.WorkOrder_BatchingMethod.UrlParameterName:       grmi.NewConditionItem(meta.WorkOrder_BatchingMethod, grmi.Equal, false),
		meta.WorkOrder_PlanStartDate.UrlParameterName:        grmi.NewConditionItem(meta.WorkOrder_PlanStartDate, grmi.Approximate, false),
		meta.WorkOrder_PlanEndDate.UrlParameterName:          grmi.NewConditionItem(meta.WorkOrder_PlanEndDate, grmi.Approximate, false),
		meta.WorkOrder_SetupStartTime.UrlParameterName:       grmi.NewConditionItem(meta.WorkOrder_SetupStartTime, grmi.Approximate, false),
		meta.WorkOrder_SetupEndTime.UrlParameterName:         grmi.NewConditionItem(meta.WorkOrder_SetupEndTime, grmi.Approximate, false),
		meta.WorkOrder_PlanStartTime.UrlParameterName:        grmi.NewConditionItem(meta.WorkOrder_PlanStartTime, grmi.Approximate, false),
		meta.WorkOrder_PlanEndTime.UrlParameterName:          grmi.NewConditionItem(meta.WorkOrder_PlanEndTime, grmi.Approximate, false),
		meta.WorkOrder_ActStartTime.UrlParameterName:         grmi.NewConditionItem(meta.WorkOrder_ActStartTime, grmi.Approximate, false),
		meta.WorkOrder_ActEndTime.UrlParameterName:           grmi.NewConditionItem(meta.WorkOrder_ActEndTime, grmi.Approximate, false),
		meta.WorkOrder_ProjectId.UrlParameterName:            grmi.NewConditionItem(meta.WorkOrder_ProjectId, grmi.Equal, false),
		meta.WorkOrder_CustomerId.UrlParameterName:           grmi.NewConditionItem(meta.WorkOrder_CustomerId, grmi.Equal, false),
		meta.WorkOrder_CustomerName.UrlParameterName:         grmi.NewConditionItem(meta.WorkOrder_CustomerName, grmi.Equal, false),
		meta.WorkOrder_FixStartTimeToggle.UrlParameterName:   grmi.NewConditionItem(meta.WorkOrder_FixStartTimeToggle, grmi.Equal, false),
		meta.WorkOrder_LastModify.UrlParameterName:           grmi.NewConditionItem(meta.WorkOrder_LastModify, grmi.Approximate, false),
		meta.WorkOrder_LastUser.UrlParameterName:             grmi.NewConditionItem(meta.WorkOrder_LastUser, grmi.Equal, false),
		meta.WorkOrder_CreateTime.UrlParameterName:           grmi.NewConditionItem(meta.WorkOrder_CreateTime, grmi.Approximate, false),
	},
	nil,
)

/******************************************************************************
 *
 * @Description              : WorkOrder的默认分页查询条件
 *
 * @Author                   : 代码生成器创建
 *
 * @Date                     : 2021-04-19 14:04:47
 *
 ******************************************************************************/
var DefaultConditionOfWorkOrderAndPaging = grmi.NewCondition(
	DefaultConditionOfWorkOrder.Items,
	grmi.NewPaging(),
)

/******************************************************************************
 *
 * @Struct Name              : WorkOrderServiceImplement
 *-----------------------------------------------------------------------------
 *
 * @Description              : WorkOrder的服务实现
 *
 * @Author                   : 代码生成器创建
 *
 * @Date                     : 2021-04-19 14:04:47
 *
 ******************************************************************************/
type WorkOrderServiceImplement struct {
}

/******************************************************************************
 *
 * @Function Name            : NewWorkOrderDAOImplement
 *-----------------------------------------------------------------------------
 *
 * @Description              : 创建一个WorkOrderDAOImplement实例
 *
 * @Return Value             : WorkOrderDAOImplement实例
 *
 * @Author                   : 代码生成器创建
 *
 * @Date                     : 2021-04-19 14:04:47
 *
 ******************************************************************************/
func NewWorkOrderServiceImplement() *WorkOrderServiceImplement {
	return &WorkOrderServiceImplement{}
}

/******************************************************************************
 *
 * @Reference LAPP_LF_MOM_BACKEND/services/om/WorkOrderService.InsertOne
 *
 ******************************************************************************/
func (impl *WorkOrderServiceImplement) InsertOne(user *models.Usertab, entity *model.WorkOrderJoin) error {
	log, _ := logger.NewLogger(user.Userid, "OM")
	grmi.Log(user, "/services/om/implments/WorkOrder.service.impl.go", "InsertOneWorkOrder", "插入一个WorkOrder")

	engine := db.Eloquent.Master()
	session := engine.NewSession()
	err := session.Begin()
	if err != nil {
		return err
	}
	defer session.Close()

	dao := dal.NewWorkOrderDAO(session, user.Pid, user.Userid)
	statusDao := dal.NewWorkOrderStatusDAO(session, user.Pid, user.Userid)
	qtyDao := dal.NewWorkOrderQtyDAO(session, user.Pid, user.Userid)
	//artDemandHeadDao := logDal.NewArtDemandHeadDAO(session, user.Pid, user.Userid)
	//artDemandLstDao := logDal.NewArtDemandLstDAO(session, user.Pid, user.Userid)
	workOrder := entity.WorkOrder
	workQty := entity.WorkOrderQty
	workStatus := entity.WorkOrderStatus
	if workStatus.Status != baseModel.WO_STATUS_UNPLANNED {
		return grmi.NewBusinessError("创建的订单状态不合规,status:" + strconv.Itoa(entity.Status))
	}
	endTime := workOrder.PlanEndTime.Restore()
	startTime := workOrder.PlanStartTime.Restore()
	if endTime.Before(startTime) || endTime.Equal(startTime) {
		return grmi.NewBusinessError("创建的订单状态计划时间不合规")
	}
	startDate := workOrder.PlanStartDate.Restore()
	endDate := workOrder.PlanEndDate.Restore()
	if endDate.Before(startDate) {
		return grmi.NewBusinessError("创建的订单状态计划时间不合规")
	}
	if workOrder.WorkOrderId == "" {
		snr := new(models.Snrtab)
		snr.Finr = user.Pid
		workOrderId, err := snr.GetNextSnrWithSession(session, "WorkOrder")
		if err != nil {
			_ = session.Rollback()
			log.Error("workOrder InsertOne get work order id failed, error: " + err.Error())

			return err
		}
		workOrder.WorkOrderId = workOrderId
	}

	workQty.WorkOrderId = workOrder.WorkOrderId
	workStatus.WorkOrderId = workOrder.WorkOrderId
	err = dao.InsertOne(workOrder)
	if err != nil {
		log.Error("workOrder InsertOne insert workOrder failed, error: " + err.Error())
		session.Rollback()
		return err
	}
	err = statusDao.InsertOne(workStatus)
	if err != nil {
		log.Error("workOrder InsertOne insert workOrder status failed, error: " + err.Error())
		session.Rollback()
		return err
	}
	err = qtyDao.InsertOne(workQty)
	if err != nil {
		log.Error("workOrder InsertOne insert workOrder qty failed, error: " + err.Error())
		session.Rollback()
		return err
	}
	// 联动处理供应商门户
	//artDemandHeadLi, err := artDemandHeadDao.SelectByEndDate(workOrder.ArtId, workOrder.PlanEndDate.Restore().Format("2006-01-02"))
	//if err != nil {
	//	session.Rollback()
	//	log.Error("WorkOrder InsertOne get art demand head, error: " + err.Error())
	//
	//	return err
	//}
	//var demandId string
	//demandTime := workOrder.PlanEndTime.Restore()
	//weekIndex := utils.ParseWeekIndex(demandTime)
	//if len(artDemandHeadLi) == 0 {
	//	snr := new(models.Snrtab)
	//	snr.Finr = user.Pid
	//	demandId, err = snr.GetNextSnr("ArtDemand")
	//	if err != nil {
	//		session.Rollback()
	//		log.Error("WorkOrder InsertOne generate art demand id failed, error: " + err.Error())
	//
	//		return err
	//	}
	//	artDemandHead := logModel.ArtDemandHead{
	//		Source: logModel.DemandSourceInterval,
	//		UnproducedQty: workQty.PlanQty,
	//		DemandId:    demandId,
	//		ArtId:       workOrder.ArtId,
	//		DemandType:  "byDay",
	//		DemandYear:  demandTime.Year(),
	//		DemandMonth: int(demandTime.Month()),
	//		DemandWeek:  weekIndex,
	//		DemandTime:  workOrder.PlanEndTime,
	//		DemandDate:  grmi.Date(demandTime),
	//		DemandQty:   workQty.PlanQty,
	//		Status:      logModel.WaitReceivingStatus,
	//		OrderStatus: workStatus.Status,
	//		QtyUomId:    "",
	//	}
	//	err = artDemandHeadDao.InsertOne(&artDemandHead)
	//	if err != nil {
	//		session.Rollback()
	//		log.Error("WorkOrder InsertOne art demand failed, error: " + err.Error())
	//		return err
	//	}
	//
	//} else {
	//	artDemandHead := artDemandHeadLi[0]
	//	demandId = artDemandHead.DemandId
	//	artDemandHead.OrderStatus = workStatus.Status
	//	artDemandHead.DemandQty = workQty.PlanQty
	//	artDemandHead.UnproducedQty = workQty.PlanQty
	//	err = artDemandHeadDao.UpdateOne(&artDemandHead)
	//	if err != nil {
	//		session.Rollback()
	//		log.Error("WorkOrder InsertOne art demand failed, error: " + err.Error())
	//		return err
	//	}
	//	err = artDemandLstDao.DeleteWhere([]grmi.Predicate{logMeta.ArtDemandLst_DemandId.NewPredicate(grmi.Equal, demandId)})
	//	if err != nil {
	//		session.Rollback()
	//		log.Error("WorkOrder InsertOne art demandLst failed, error: " + err.Error())
	//
	//		return err
	//	}
	//}

	//artDemandLstLi := make([]logModel.ArtDemandLst, 0, workQty.PlanQty)
	//for i := 0; i < int(workQty.ActQty); i++ {
	//	artDemandLst := logModel.ArtDemandLst{
	//		DemandId:    demandId,
	//		ArtId:       workOrder.ArtId,
	//		DemandType:  "byDay",
	//		DemandYear:  demandTime.Year(),
	//		DemandMonth: int(demandTime.Month()),
	//		DemandWeek:  weekIndex,
	//		DemandTime:  workOrder.PlanEndTime,
	//		DemandDate:  grmi.Date(demandTime),
	//		DemandQty:   1,
	//		Status:     logModel.WaitReceivingStatus,
	//		OrderStatus:  workStatus.Status,
	//		QtyUomId:    "",
	//	}
	//	artDemandLstLi = append(artDemandLstLi, artDemandLst)
	//}
	//// 批量插入时 一次最多插入50条
	//demandLstTempLi := make([]logModel.ArtDemandLst, 0, 50)
	//for index, demandLst := range artDemandLstLi {
	//	if index%50 == 0 {
	//		err = artDemandLstDao.Insert(&demandLstTempLi)
	//		if err != nil {
	//			session.Rollback()
	//			log.Error("WorkOrder InsertOne art demandLst failed, error: " + err.Error())
	//			return err
	//		}
	//		demandLstTempLi = make([]logModel.ArtDemandLst, 0, 50)
	//	}
	//	demandLstTempLi = append(demandLstTempLi, demandLst)
	//}
	//if len(demandLstTempLi) != 0 {
	//	err = artDemandLstDao.Insert(&demandLstTempLi)
	//	if err != nil {
	//		session.Rollback()
	//		log.Error("WorkOrder InsertOne art demandLst failed, error: " + err.Error())
	//		return err
	//	}
	//}

	session.Commit()
	return nil
}

/******************************************************************************
 *
 * @Reference LAPP_LF_MOM_BACKEND/services/om/WorkOrderService.DeleteOne
 *
 ******************************************************************************/
func (impl *WorkOrderServiceImplement) DeleteOne(user *models.Usertab, workOrderId string) error {
	grmi.Log(user, "/services/om/implments/WorkOrder.service.impl.go", "DeleteOneWorkOrder", "删除一个WorkOrder")
	log, _ := logger.NewLogger(user.Userid, "OM")
	engine := db.Eloquent.Master()
	session := engine.NewSession()
	err := session.Begin()
	if err != nil {
		return err
	}
	defer session.Close()
	dao := dal.NewWorkOrderDAO(session, user.Pid, user.Userid)
	statusDao := dal.NewWorkOrderStatusDAO(session, user.Pid, user.Userid)
	qtyDao := dal.NewWorkOrderQtyDAO(session, user.Pid, user.Userid)
	statusRecDao := dal.NewWorkOrderStatusRecLstDAO(session, user.Pid, user.Userid)
	//artDemandHeadDao := logDal.NewArtDemandHeadDAO(session, user.Pid, user.Userid)
	//artDemandLstDao := logDal.NewArtDemandLstDAO(session, user.Pid, user.Userid)
	record, err := dao.SelectOne(workOrderId)
	if err != nil {
		log.Error("WorkOrder DeleteOne select workOrder failed, error: " + err.Error())
		return err
	}
	if record == nil {
		return grmi.NewBusinessError("不存在指定workOrder记录!")
	}
	statusRecord, err := statusDao.SelectOne(workOrderId)
	if err != nil {
		log.Error("WorkOrder DeleteOne select workOrder status failed, error: " + err.Error())
		return err
	}
	if statusRecord == nil {
		return grmi.NewBusinessError("不存在指定workOrderStatus记录!")
	}
	qtyRecord, err := qtyDao.SelectOne(workOrderId)
	if err != nil {
		log.Error("WorkOrder DeleteOne select workOrder qty failed, error: " + err.Error())
		return err
	}
	if qtyRecord == nil {
		return grmi.NewBusinessError("不存在指定workOrderQty记录!")
	}
	if statusRecord.Status != baseModel.WO_STATUS_UNPLANNED {
		return grmi.NewBusinessError("该workOrder不可以删除, status:" + strconv.Itoa(statusRecord.Status))
	}
	//maxPos, err := statusRecDao.GetMaxPos(record.WorkOrderId)
	//if err != nil {
	//	log.Error("WorkOrder DeleteOne get status rec max pos failed, error: " + err.Error())
	//	session.Rollback()
	//	return err
	//}
	var workOrderStatusRec model.WorkOrderStatusRecLst
	workOrderStatusRec.WorkOrderId = record.WorkOrderId
	workOrderStatusRec.PrevStatus = statusRecord.Status
	workOrderStatusRec.Status = baseModel.WO_STATUS_CANCELED
	//workOrderStatusRec.Pos = maxPos + 1
	err = statusRecDao.InsertOne(&workOrderStatusRec)
	if err != nil {
		log.Error("WorkOrder DeleteOne insert status rec failed, error: " + err.Error())
		session.Rollback()
		return err
	}
	statusRecord.Status = baseModel.WO_STATUS_CANCELED
	err = statusDao.UpdateOne(statusRecord)
	if err != nil {
		log.Error("WorkOrder DeleteOne update work order status failed, error: " + err.Error())
		session.Rollback()
		return err
	}
	// 从供应商门户处处理对应的需求数据
	//artDemandHeadLi, err := artDemandHeadDao.SelectByEndDate(record.ArtId, record.PlanEndDate.Restore().Format("2006-01-02"))
	//if err != nil {
	//	log.Error("WorkOrder DeleteOne get art demand head failed, error: " + err.Error())
	//	session.Rollback()
	//	return err
	//}
	//if len(artDemandHeadLi) != 0 {
	//	artDemandHead := artDemandHeadLi[0]
	//	artDemandHead.OrderStatus = statusRecord.Status
	//	err = artDemandHeadDao.UpdateOne(&artDemandHead)
	//	if err != nil {
	//		log.Error("WorkOrder DeleteOne update art demand head failed, error: " + err.Error())
	//		session.Rollback()
	//		return err
	//	}
	//	//err = artDemandLstDao.DeleteWhere([]grmi.Predicate{logMeta.ArtDemandLst_DemandId.NewPredicate(grmi.Equal, artDemandHead.DemandId)})
	//	//if err != nil {
	//	//	log.Error("WorkOrder DeleteOne delete art demand lst failed, error: " + err.Error())
	//	//	session.Rollback()
	//	//	return err
	//	//}
	//}
	session.Commit()
	return nil
}

/******************************************************************************
 *
 * @Reference LAPP_LF_MOM_BACKEND/services/om/WorkOrderService.SelectOne
 *
 ******************************************************************************/
func (impl *WorkOrderServiceImplement) SelectOne(user *models.Usertab, workOrderId string) (*model.WorkOrderJoin, error) {

	grmi.Log(user, "/services/om/implments/WorkOrder.service.impl.go", "SelectOneWorkOrder", "查询一个WorkOrder")

	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	dao := dal.NewWorkOrderDAO(session, user.Pid, user.Userid)
	statusDao := dal.NewWorkOrderStatusDAO(session, user.Pid, user.Userid)
	qtyDao := dal.NewWorkOrderQtyDAO(session, user.Pid, user.Userid)
	workOrder, err := dao.SelectOne(workOrderId)
	if err != nil {
		return nil, err
	}
	if workOrder == nil {
		return nil, grmi.NewBusinessError("workOrder不存在")
	}
	workOrderStatus, err := statusDao.SelectOne(workOrderId)
	if err != nil {
		return nil, err
	}
	workOrderQty, err := qtyDao.SelectOne(workOrderId)
	if err != nil {
		return nil, err
	}
	data := &model.WorkOrderJoin{
		WorkOrder:       workOrder,
		WorkOrderQty:    workOrderQty,
		WorkOrderStatus: workOrderStatus,
	}

	return data, nil
}

/******************************************************************************
 *
 * @Reference LAPP_LF_MOM_BACKEND/services/om/WorkOrderService.UpdateOne
 *
 ******************************************************************************/
func (impl *WorkOrderServiceImplement) UpdateOne(user *models.Usertab, entity *model.WorkOrderJoin) error {

	grmi.Log(user, "/services/om/implments/WorkOrder.service.impl.go", "UpdateOneWorkOrder", "修改一个WorkOrder")
	//log, _ := logger.NewLogger(user.Userid, "OM")

	engine := db.Eloquent.Master()
	session := engine.NewSession()
	if err := session.Begin(); err != nil {
		return err
	}
	defer session.Close()
	workOrder := entity.WorkOrder
	workOrderStatus := entity.WorkOrderStatus
	workOrderQty := entity.WorkOrderQty
	dao := dal.NewWorkOrderDAO(session, user.Pid, user.Userid)
	statusDao := dal.NewWorkOrderStatusDAO(session, user.Pid, user.Userid)
	qtyDao := dal.NewWorkOrderQtyDAO(session, user.Pid, user.Userid)
	//artDemandHeadDao := logDal.NewArtDemandHeadDAO(session, user.Pid, user.Userid)
	workOrderRecord, err := dao.SelectOne(workOrder.WorkOrderId)
	if err != nil {
		return err
	}
	if workOrderRecord == nil {
		return grmi.NewBusinessError("不存在指定记录!")
	}
	statusRecord, err := statusDao.SelectOne(workOrder.WorkOrderId)
	if err != nil {
		return err
	}
	if statusRecord == nil {
		return grmi.NewBusinessError("不存在指定的WorkOrderStatus")
	}
	qtyRecord, err := qtyDao.SelectOne(workOrder.WorkOrderId)
	if err != nil {
		return err
	}
	if qtyRecord == nil {
		return grmi.NewBusinessError("不存在指定的WorkOrderQty")
	}
	if workOrderStatus.Status != statusRecord.Status {
		return grmi.NewBusinessError("workOrderStatus不允许修改")
	}
	err = dao.UpdateOne(workOrder)
	if err != nil {
		session.Rollback()
		return err
	}
	workOrderQty.WorkOrderId = qtyRecord.WorkOrderId
	err = qtyDao.UpdateOne(workOrderQty)
	if err != nil {
		session.Rollback()
		return err
	}
	// 从供应商门户处处理对应的需求数据
	//artDemandHeadLi, err := artDemandHeadDao.SelectByEndDate(workOrderRecord.ArtId, workOrderRecord.PlanEndDate.Restore().Format("2006-01-02"))
	//if err != nil {
	//	log.Error("WorkOrder UpdateOne get art demand head failed, error: " + err.Error())
	//	session.Rollback()
	//	return err
	//}
	//if len(artDemandHeadLi) != 0 {
	//	artDemandHead := artDemandHeadLi[0]
	//	artDemandHead.OrderStatus = statusRecord.Status
	//	artDemandHead.DemandQty = qtyRecord.PlanQty
	//	artDemandHead.UnproducedQty = qtyRecord.PlanQty
	//	err = artDemandHeadDao.UpdateOne(&artDemandHead)
	//	if err != nil {
	//		log.Error("WorkOrder UpdateOne update art demand head failed, error: " + err.Error())
	//		session.Rollback()
	//		return err
	//	}
	//	//err = artDemandLstDao.DeleteWhere([]grmi.Predicate{logMeta.ArtDemandLst_DemandId.NewPredicate(grmi.Equal, artDemandHead.DemandId)})
	//	//if err != nil {
	//	//	log.Error("WorkOrder DeleteOne delete art demand lst failed, error: " + err.Error())
	//	//	session.Rollback()
	//	//	return err
	//	//}
	//}
	session.Commit()
	return nil
}

/******************************************************************************
 *
 * @Reference LAPP_LF_MOM_BACKEND/services/om/WorkOrderService.Insert
 *
 ******************************************************************************/
func (impl *WorkOrderServiceImplement) Insert(user *models.Usertab, entities *[]model.WorkOrder) error {

	grmi.Log(user, "/services/om/implments/WorkOrder.service.impl.go", "InsertWorkOrder", "插入多个WorkOrder")

	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	dao := dal.NewWorkOrderDAO(session, user.Pid, user.Userid)

	for _, entity := range *entities {
		record, err := dao.SelectOne(entity.WorkOrderId)
		if err != nil {
			return err
		}
		if record != nil {
			return grmi.NewBusinessError("已经存在相同主键的记录!")
		}
	}

	err := dao.Insert(entities)
	if err != nil {
		return err
	}
	return nil
}

/******************************************************************************
 *
 * @Reference LAPP_LF_MOM_BACKEND/services/om/WorkOrderService.Delete
 *
 ******************************************************************************/
func (impl *WorkOrderServiceImplement) Delete(user *models.Usertab, entities *[]model.WorkOrder) error {

	grmi.Log(user, "/services/om/implments/WorkOrder.service.impl.go", "DeleteWorkOrder", "删除多个WorkOrder")

	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	dao := dal.NewWorkOrderDAO(session, user.Pid, user.Userid)

	for _, entity := range *entities {
		record, err := dao.SelectOne(entity.WorkOrderId)
		if err != nil {
			return err
		}
		if record == nil {
			return grmi.NewBusinessError("不存在指定记录!")
		}
	}

	err := dao.Delete(entities)
	if err != nil {
		return err
	}
	return nil
}

/******************************************************************************
 *
 * @Reference LAPP_LF_MOM_BACKEND/services/om/WorkOrderService.Select
 *
 ******************************************************************************/
func (impl *WorkOrderServiceImplement) Select(user *models.Usertab, urlParameters map[string]string) (interface{}, error) {

	grmi.Log(user, "/services/om/implments/WorkOrder.service.impl.go", "SelectWorkOrder", "查询WorkOrder")
	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	var projectId string
	var artId string
	var timeStart string
	var timeEnd string
	var workOrderId string
	var orderType string
	var statusStr string
	var pageNumberStr string
	var pageSizeStr string
	projectId, _ = urlParameters["ProjectId"]
	artId, _ = urlParameters["ArtId"]
	workOrderId, _ = urlParameters["WorkOrderId"]
	timeStart, _ = urlParameters["start"]
	timeEnd, _ = urlParameters["end"]
	orderType, _ = urlParameters["OrderType"]
	statusStr, _ = urlParameters["status"]
	pageNumberStr, _ = urlParameters["pageNumber"]
	pageSizeStr, _ = urlParameters["pageSize"]
	status, err := strconv.Atoi(statusStr)
	if err != nil {
		status = 0
	}
	if timeStart != "" {
		_, err = time.ParseInLocation("2006-01-02 15:04:05", timeStart, utils.TimezoneLocation)
		if err != nil {
			return nil, err
		}
	}
	if timeEnd != "" {
		_, err = time.ParseInLocation("2006-01-02 15:04:05", timeEnd, utils.TimezoneLocation)
		if err != nil {
			return nil, err
		}
	}
	pageNumber, err := strconv.Atoi(pageNumberStr)
	if err != nil {
		pageNumber = 1
	}
	pageSize, err := strconv.Atoi(pageSizeStr)
	if err != nil {
		pageSize = 10
	}
	dao := dal.NewWorkOrderDAO(session, user.Pid, user.Userid)
	roleRelDao := baseDal.NewRoleRelDAO(session, user.Pid, user.Userid)
	roleRelLi, err := roleRelDao.Select([]grmi.Predicate{baseMeta.RoleRel_RoleId.NewPredicate(grmi.Equal, user.RoleId)}, nil)
	if err != nil {
		return nil, err
	}
	workLineIdLi := make([]string, 0, len(roleRelLi))
	for _, roleRel := range roleRelLi {
		workLineIdLi = append(workLineIdLi, roleRel.WorkLineid)
	}
	result, err := dao.SelectByPage(projectId, artId, timeStart, timeEnd, workOrderId, orderType, status, pageNumber, pageSize, workLineIdLi)
	if err != nil {
		return nil, err
	}
	return result, nil
}

/******************************************************************************
 *
 * @Reference LAPP_LF_MOM_BACKEND/services/om/WorkOrderService.Update
 *
 ******************************************************************************/
func (impl *WorkOrderServiceImplement) Update(user *models.Usertab, entities *[]model.WorkOrder) error {

	grmi.Log(user, "/services/om/implments/WorkOrder.service.impl.go", "UpdateWorkOrder", "修改多个WorkOrder")

	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	dao := dal.NewWorkOrderDAO(session, user.Pid, user.Userid)

	for _, entity := range *entities {
		record, err := dao.SelectOne(entity.WorkOrderId)
		if err != nil {
			return err
		}
		if record == nil {
			return grmi.NewBusinessError("不存在指定记录!")
		}
	}

	err := dao.Update(entities)
	if err != nil {
		return err
	}
	return nil
}

/******************************************************************************
 *
 * @Reference LAPP_LF_MOM_BACKEND/services/om/WorkOrderService.Revocation
 *
 ******************************************************************************/
func (impl *WorkOrderServiceImplement) Revocation(user *models.Usertab, entities []string) error {

	grmi.Log(user, "/services/om/implments/WorkOrder.service.impl.go", "UpdateOneWorkOrder", "修改一个WorkOrder")

	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	err := session.Begin()
	if err != nil {
		return err
	}
	dao := dal.NewWorkOrderDAO(session, user.Pid, user.Userid)
	statusDao := dal.NewWorkOrderStatusDAO(session, user.Pid, user.Userid)
	qtyDao := dal.NewWorkOrderQtyDAO(session, user.Pid, user.Userid)
	for _, workOrderId := range entities {
		workOrderRecord, err := dao.SelectOne(workOrderId)
		if err != nil {
			return err
		}
		if workOrderRecord == nil {
			return grmi.NewBusinessError("不存在指定记录!")
		}
		statusRecord, err := statusDao.SelectOne(workOrderId)
		if err != nil {
			return err
		}
		if statusRecord == nil {
			return grmi.NewBusinessError("不存在指定的WorkOrderStatus")
		}
		qtyRecord, err := qtyDao.SelectOne(workOrderId)
		if err != nil {
			return err
		}
		if qtyRecord == nil {
			return grmi.NewBusinessError("不存在指定的WorkOrderQty")
		}
		if statusRecord.Status > baseModel.WO_STATUS_PLANNED {
			return grmi.NewBusinessError("该订单状态不支持撤销,status:" + strconv.Itoa(statusRecord.Status))
		}
		statusRecord.Status = baseModel.WO_STATUS_UNPLANNED
		err = statusDao.UpdateOne(statusRecord)
		if err != nil {
			session.Rollback()
			return err
		}
	}
	session.Commit()
	return nil
}

/******************************************************************************
 *
 * @Reference LAPP_LF_MOM_BACKEND/services/om/WorkOrderService.CancelWorkOrder
 *
 ******************************************************************************/
func (impl WorkOrderServiceImplement) CancelWorkOrder(user *models.Usertab, workOrderId string, qty float64) (err error) {
	grmi.Log(user, "/services/om/implments/WorkOrder.service.impl.go", "CancelWorkOrder", "取消workOrder中指定数量的serialOrder")

	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	if err = session.Begin(); err != nil {
		return err
	}
	dao := dal.NewWorkOrderDAO(session, user.Pid, user.Userid)
	workOrderQtyDao := dal.NewWorkOrderQtyDAO(session, user.Pid, user.Userid)
	workOrderStatusDao := dal.NewWorkOrderStatusDAO(session, user.Pid, user.Userid)
	workOrderStatusRecDao := dal.NewWorkOrderStatusRecLstDAO(session, user.Pid, user.Userid)
	serialOrderDao := dal.NewSerialOrderDAO(session, user.Pid, user.Userid)
	serialOrderStatusDao := dal.NewSerialOrderStatusDAO(session, user.Pid, user.Userid)
	serialOrderStatusRecDao := dal.NewSerialOrderStatusRecLstDAO(session, user.Pid, user.Userid)
	workOrder, err := dao.SelectOneJoin(workOrderId)
	if err != nil {
		_ = session.Rollback()
		return err
	}
	if workOrder == nil {
		_ = session.Rollback()
		return grmi.NewBusinessError("workOrder不存在")
	}
	if workOrder.WorkOrderStatus.Status != baseModel.WO_STATUS_LOCKED && workOrder.WorkOrderStatus.Status != baseModel.WO_STATUS_RELEASED && workOrder.WorkOrderStatus.Status != baseModel.WO_STATUS_RUNNING {
		_ = session.Rollback()
		return grmi.NewBusinessError("workOrder目前的状态不支持该操作")
	}
	if qty > (workOrder.WorkOrderQty.PlanQty - workOrder.WorkOrderQty.ReleasedQty) {
		_ = session.Rollback()
		return grmi.NewBusinessError("workOrder未派工数量不足")
	}
	workOrder.WorkOrderQty.ReleasedQty += qty
	workOrder.WorkOrderQty.ActQty3 += qty
	workOrder.WorkOrderQty.ActQty += qty
	err = workOrderQtyDao.UpdateOne(&workOrder.WorkOrderQty)
	if err != nil {
		_ = session.Rollback()
		return err
	}
	if workOrder.WorkOrderQty.PlanQty == workOrder.WorkOrderQty.ReleasedQty && workOrder.WorkOrderQty.ReleasedQty == workOrder.WorkOrderQty.ActQty {
		var status int
		if workOrder.WorkOrderQty.PlanQty == workOrder.WorkOrderQty.ActQty3 {
			status = baseModel.WO_STATUS_CANCELED
		} else {
			status = baseModel.WO_STATUS_FINISHED
		}
		workOrderStatusRec := model.WorkOrderStatusRecLst{
			WorkOrderId: workOrderId,
			PrevStatus:  workOrder.WorkOrderStatus.Status,
			Status:      status,
		}
		err = workOrderStatusRecDao.InsertOne(&workOrderStatusRec)
		if err != nil {
			_ = session.Rollback()
			return err
		}
		workOrder.WorkOrderStatus.Status = status
		err = workOrderStatusDao.UpdateOne(&workOrder.WorkOrderStatus)
		if err != nil {
			_ = session.Rollback()
			return err
		}
	}
	serialOrderLi, err := serialOrderDao.SelectByWorkOrderId(workOrderId, baseModel.WO_STATUS_LOCKED)
	if err != nil {
		_ = session.Rollback()
		return err
	}
	if len(serialOrderLi) < int(qty) {
		_ = session.Rollback()
		return grmi.NewBusinessError("未派工的序列工单不足")
	}
	for i := 0; i < int(qty); i++ {
		serialOrder := serialOrderLi[i]
		serialOrderStatusRec := model.SerialOrderStatusRecLst{
			SerialOrderId: serialOrder.SerialOrderId,
			PrevStatus:    serialOrder.SerialOrderStatus.Status,
			Status:        baseModel.WO_STATUS_CANCELED,
		}
		err = serialOrderStatusRecDao.InsertOne(&serialOrderStatusRec)
		if err != nil {
			_ = session.Rollback()
			return err
		}
		serialOrder.SerialOrderStatus.Status = baseModel.WO_STATUS_CANCELED
		err = serialOrderStatusDao.UpdateForStatus(&serialOrder.SerialOrderStatus, baseModel.WO_STATUS_LOCKED)
		if err != nil {
			_ = session.Rollback()
			return err
		}
	}
	_ = session.Commit()
	return nil

}

/******************************************************************************
*
* @Reference LAPP_LF_MOM_BACKEND/services/om/WorkOrderService.LockWorkOrder
*
******************************************************************************/
func (impl *WorkOrderServiceImplement) LockWorkOrder(user *models.Usertab, workOrderIds []string) ([]model.LockedResponseWorkOrder, error) {
	grmi.Log(user, "/services/om/implments/WorkOrder.service.impl.go", "LockWorkOrder", "锁定workOrder")
	result := make([]model.LockedResponseWorkOrder, 0, len(workOrderIds))
	//engine := db.Eloquent.Master()
	//session := engine.NewSession()
	//defer session.Close()
	//err := session.Begin()
	//if err != nil {
	//	return nil, err
	//}
	//dao := dal.NewSerialOrderDAO(session, user.Pid, user.Userid)
	//workOrderDao := dal.NewWorkOrderDAO(session, user.Pid, user.Userid)
	//workOrderStatusDao := dal.NewWorkOrderStatusDAO(session, user.Pid, user.Userid)
	//workOrderStatusRecDao := dal.NewWorkOrderStatusRecLstDAO(session, user.Pid, user.Userid)
	//serialOrderStatusDao := dal.NewSerialOrderStatusDAO(session, user.Pid, user.Userid)
	//projectDao := meDal.NewProjectDAO(session, user.Pid, user.Userid)
	//operationDao := baseDal.NewOperationDAO(session, user.Pid, user.Userid)
	//PODao := dal.NewSerialOrderPOLstDAO(session, user.Pid, user.Userid)
	//stepDao := dal.NewSerialOrderStepLstDAO(session, user.Pid, user.Userid)
	//artRelDao := baseDal.NewArticleRelLstDAO(session, user.Pid, user.Userid)
	//articleWithAttrDao := baseDal.NewArticleAtcodLstDAO(session, user.Pid, user.Userid)
	//scanRuleDao := baseDal.NewScanRuleInfoDAO(session, user.Pid, user.Userid)
	//guideDao := baseDal.NewGuideRuleInfoDAO(session, user.Pid, user.Userid)
	//// 获取项目数据 用于获取流水号
	//project, err := projectDao.SelectOne(baseModel.ProjectId)
	//if err != nil {
	//	_ = session.Rollback()
	//	return nil, grmi.NewBusinessError("获取项目数据失败, error:" + err.Error())
	//}
	//if project == nil {
	//	_ = session.Rollback()
	//	return nil, grmi.NewBusinessError("不存在该项目数据")
	//}
	//attributeLi, err := articleWithAttrDao.SelectAllWithAttrValue()
	//if err != nil {
	//	_ = session.Rollback()
	//	return nil, grmi.NewBusinessError("查询零件属性失败,error:" + err.Error())
	//}
	//attributeMap := make(map[int][]baseModel.ArticleWithAttrValue)
	//for _, data := range attributeLi {
	//	_, exist := attributeMap[data.ArticleAtcodLst.AttrCode]
	//	if !exist {
	//		attributeMap[data.ArticleAtcodLst.AttrCode] = make([]baseModel.ArticleWithAttrValue, 0)
	//	}
	//	attributeMap[data.ArticleAtcodLst.AttrCode] = append(attributeMap[data.ArticleAtcodLst.AttrCode], data)
	//}
	//scanRuleLi, err := scanRuleDao.Select(nil, nil)
	//if err != nil {
	//	_ = session.Rollback()
	//	return nil, grmi.NewBusinessError("查询扫码校验条码失败, error:" + err.Error())
	//}
	//scanRuleMap := make(map[int]baseModel.ScanRuleInfo)
	//for _, scanRule := range scanRuleLi {
	//	scanRuleMap[scanRule.OperationId] = scanRule
	//}
	//guideRuleLi, err := guideDao.Select(nil, nil)
	//if err != nil {
	//	_ = session.Rollback()
	//	return nil, grmi.NewBusinessError("查询指导操作规则失败, error:" + err.Error())
	//}
	//guideRuleMap := make(map[int]baseModel.GuideRuleInfo, len(guideRuleLi))
	//for _, guideRule := range guideRuleLi {
	//	guideRuleMap[guideRule.OperationId] = guideRule
	//}
	//// 进入业务处理逻辑
	//for _, workOrderId := range workOrderIds {
	//	// 进行对应的批次工单数据校验
	//	vomWorkOrder, err := workOrderDao.SelectOneJoin(workOrderId)
	//	if err != nil {
	//		_ = session.Rollback()
	//		return nil, grmi.NewBusinessError("获取批次工单数据失败,error:" + err.Error())
	//	}
	//	if vomWorkOrder == nil {
	//		_ = session.Rollback()
	//		return nil, grmi.NewBusinessError("不存在对应的workOrder, workOrderId:" + workOrderId)
	//	}
	//
	//	if vomWorkOrder.WorkOrderStatus.Status != baseModel.WO_STATUS_PLANNED {
	//		_ = session.Rollback()
	//		return nil, grmi.NewBusinessError("对应的workOrderStatus 不是 WO_STATUS_PLANNED，workOrderId:" + workOrderId)
	//	}
	//	// 检测在系统中对用的批次工单是否存在对应的序列工单
	//	serialOrderLi, err := dao.Select([]grmi.Predicate{meta.SerialOrder_WorkOrderId.NewPredicate(grmi.Equal, workOrderId)}, nil)
	//	if err != nil {
	//		_ = session.Rollback()
	//		return nil, grmi.NewBusinessError("查询原有序列工单数据失败, error:" + err.Error())
	//	}
	//	if len(serialOrderLi) > 0 {
	//		_ = session.Rollback()
	//		return nil, grmi.NewBusinessError("已存在对应的SerialOrder, workOrderId:" + workOrderId)
	//	}
	//	serialOrderLi = make([]model.SerialOrder, 0, int(vomWorkOrder.WorkOrder.PlanQty))
	//	serialOrderStatusLi := make([]model.SerialOrderStatus, 0, int(vomWorkOrder.WorkOrder.PlanQty))
	//	if vomWorkOrder.WorkOrder.PlanQty == 0 {
	//		_ = session.Rollback()
	//		return nil, grmi.NewBusinessError("订单的计划数量为0,workOrderID:" + workOrderId)
	//	}
	//	// 进行批次工单的时间拆解到序列工单的计划时间上
	//	endTime := vomWorkOrder.WorkOrder.PlanEndTime.Restore()
	//	now := time.Now()
	//	var perDuration float64
	//	if !now.Before(endTime) {
	//		perDuration = 0
	//	} else {
	//		perDuration = endTime.Sub(now).Seconds() / vomWorkOrder.WorkOrder.PlanQty
	//	}
	//	// 生成序列工单
	//	for i := 0; i < int(vomWorkOrder.WorkOrder.PlanQty); i++ {
	//		snr := new(models.Snrtab)
	//		snr.Finr = user.Pid
	//		serialNum, err := snr.GetNextSnrWithSession(session, project.SerialOrderSnr)
	//		if err != nil {
	//			_ = session.Rollback()
	//			return nil, grmi.NewBusinessError("获取序列工单流水号失败, error:" + err.Error())
	//		}
	//		planStartDate := vomWorkOrder.WorkOrder.PlanStartDate.Restore().Format("20060102")
	//		prefix := vomWorkOrder.WorkOrder.ArtId + baseModel.PlantName + planStartDate
	//		serialOrderId := strings.Replace(serialNum, "SO-", prefix, 1)
	//		var planEndTime time.Time
	//		if perDuration != 0 {
	//			planEndTime = now.Add(time.Duration(perDuration*float64(i+1)) * time.Second)
	//		} else {
	//			planEndTime = vomWorkOrder.WorkOrder.PlanEndTime.Restore()
	//		}
	//		serialOrder := model.SerialOrder{
	//			WorkOrderId:    workOrderId,
	//			SerialOrderId:  serialOrderId,
	//			ArtId:          vomWorkOrder.WorkOrder.ArtId,
	//			OrderType1:     vomWorkOrder.WorkOrder.OrderType1,
	//			OrderType2:     vomWorkOrder.WorkOrder.OrderType2,
	//			PlanResourceId: vomWorkOrder.WorkOrder.PlanResourceId,
	//			UsedResourceId: vomWorkOrder.WorkOrder.UsedResourceId,
	//			PlanQty:        1,
	//			QtyUomId:       vomWorkOrder.WorkOrder.QtyUomId,
	//			OpTimePerItem:  vomWorkOrder.WorkOrder.OpTimePerItem,
	//			TimeUomId:      vomWorkOrder.WorkOrder.TimeUomId,
	//			PlanStartDate:  vomWorkOrder.WorkOrder.PlanStartDate,
	//			PlanEndDate:    vomWorkOrder.WorkOrder.PlanEndDate,
	//			SetupStartTime: vomWorkOrder.WorkOrder.SetupStartTime,
	//			SetupEndTime:   vomWorkOrder.WorkOrder.SetupEndTime,
	//			PlanStartTime:  vomWorkOrder.WorkOrder.PlanStartTime,
	//			PlanEndTime:    grmi.DateTime(planEndTime),
	//			ActStartTime:   vomWorkOrder.WorkOrder.ActStartTime,
	//			ActEndTime:     vomWorkOrder.WorkOrder.ActEndTime,
	//			ProjectId:      vomWorkOrder.WorkOrder.ProjectId,
	//		}
	//		serialOrderLi = append(serialOrderLi, serialOrder)
	//		serialStatus := model.SerialOrderStatus{
	//			Status:        baseModel.WO_STATUS_LOCKED,
	//			SerialOrderId: serialOrderId,
	//		}
	//		serialOrderStatusLi = append(serialOrderStatusLi, serialStatus)
	//	}
	//	for _, serialOrder := range serialOrderLi {
	//		err = dao.InsertOne(&serialOrder)
	//		if err != nil {
	//			_ = session.Rollback()
	//			return nil, grmi.NewBusinessError("插入序列工单数据失败,error:" + err.Error())
	//		}
	//	}
	//	for _, serialOrderStatus := range serialOrderStatusLi {
	//		err = serialOrderStatusDao.InsertOne(&serialOrderStatus)
	//		if err != nil {
	//			_ = session.Rollback()
	//			return nil, grmi.NewBusinessError("插入序列工单状态失败,error:" + err.Error())
	//		}
	//	}
	//	// 修改批次工单状态 并记录状态变化
	//	workOrderStatusRec := model.WorkOrderStatusRecLst{
	//		WorkOrderId:        workOrderId,
	//		PrevStatus:         vomWorkOrder.WorkOrderStatus.Status,
	//		Status:             baseModel.WO_STATUS_LOCKED,
	//		StartTime:          vomWorkOrder.WorkOrder.PlanStartTime,
	//		EndTime:            vomWorkOrder.WorkOrder.PlanEndTime,
	//		OutputEvent:        baseModel.BATORD_EVENT_LOCK,
	//		OutputStatus:       baseModel.OUTPUT_TRIGGER_UNHANDLED,
	//		TriggerObjectId:    vomWorkOrder.WorkOrderStatus.TriggerObjectId,
	//		TriggerSubObjectId: vomWorkOrder.WorkOrderStatus.TriggerSubObjectId,
	//	}
	//	err = workOrderStatusRecDao.InsertOne(&workOrderStatusRec)
	//	if err != nil {
	//		_ = session.Rollback()
	//		return nil, grmi.NewBusinessError("插入批次工单状态数据失败,error:" + err.Error())
	//	}
	//	vomWorkOrder.WorkOrderStatus.Status = baseModel.WO_STATUS_LOCKED
	//	err = workOrderStatusDao.UpdateOne(&vomWorkOrder.WorkOrderStatus)
	//	if err != nil {
	//		_ = session.Rollback()
	//		return nil, grmi.NewBusinessError("更新批次工单状态失败,error:" + err.Error())
	//	}
	//	artId := vomWorkOrder.WorkOrder.ArtId
	//	// 生成序列工单对应的工艺数据
	//	articleLi, err := artRelDao.Select([]grmi.Predicate{baseMeta.ArticleRelLst_PID.NewPredicate(grmi.Equal, artId)}, nil)
	//	if err != nil {
	//		_ = session.Rollback()
	//		return nil, grmi.NewBusinessError("获取物料关联关系失败, error:" + err.Error())
	//	}
	//	if len(articleLi) == 0 {
	//		_ = session.Rollback()
	//		return nil, grmi.NewBusinessError("未获取到零件关联关系")
	//	}
	//	artIdLi := make([]string, 0, len(articleLi))
	//	artRelMap := make(map[string]baseModel.ArticleRelLst)
	//	for _, article := range articleLi {
	//		artIdLi = append(artIdLi, article.ArtId)
	//		artRelMap[article.ArtId] = article
	//	}
	//	subArtMap := make(map[string]interface{})
	//	for _, artId := range artIdLi {
	//		subArtMap[artId] = nil
	//	}
	//	opLi, err := operationDao.GetOperationRelData(artIdLi, vomWorkOrder.WorkOrder.PlanResourceId)
	//	if err != nil {
	//		_ = session.Rollback()
	//		return nil, grmi.NewBusinessError("获取工艺操作失败,error:" + err.Error())
	//	}
	//	allocateMap := make(map[string][]baseModel.ArtQtyAllocate)
	//	checkRuleMap := make(map[string]baseModel.ArtCheckRule)
	//	opcBasicMap := make(map[int][]baseModel.OPCBasicComInfo)
	//	twMap := make(map[int][]baseModel.TightenWrenchInfo)
	//	for _, serialOrderStatus := range serialOrderStatusLi {
	//		var PO int
	//		processPos := 1
	//		opPos := 1
	//		for _, op := range opLi {
	//
	//			if PO != op.Process.PO {
	//				PO = op.Process.PO
	//				serialOrderWorkPlace := model.SerialOrderPOLst{
	//					SerialOrderId: serialOrderStatus.SerialOrderId,
	//					PO:            PO,
	//					Status:        baseModel.WO_STATUS_LOCKED,
	//					HasDependOn:   op.Process.HasDependOn,
	//				}
	//				err = PODao.InsertOne(&serialOrderWorkPlace)
	//				if err != nil {
	//					_ = session.Rollback()
	//					return nil, grmi.NewBusinessError("插入serialOrder工序数据失败,error:" + err.Error())
	//				}
	//				processPos++
	//
	//			}
	//			serialOrderStep := model.SerialOrderStepLst{
	//				PO:            op.Process.PO,
	//				OperationId:   op.OperationId,
	//				SerialOrderId: serialOrderStatus.SerialOrderId,
	//				StepNo:        op.Operation.StepNo,
	//				Pos:           opPos,
	//				SubArtId:      op.ArticleAtcodLst.ArtId,
	//				StepDesc:      op.Operation.StepDesc,
	//				AttrCode:      op.ArticleAtcodLst.AttrCode,
	//				AttrValue:     op.ArticleAtcodLst.AttrValue,
	//				StepType:      op.Operation.StepType,
	//				Status:        baseModel.WO_STATUS_LOCKED,
	//			}
	//			opPos++
	//			err = stepDao.InsertOne(&serialOrderStep)
	//			if err != nil {
	//				_ = session.Rollback()
	//
	//				return nil, grmi.NewBusinessError("插入序列工单工艺数据失败, error:" + err.Error())
	//			}
	//			if serialOrderStep.StepType == baseModel.STEP_CHECK_RULE { // 生成扫码校验的工艺数据
	//				scanRule, exist := scanRuleMap[serialOrderStep.OperationId]
	//				if !exist {
	//					return nil, grmi.NewBusinessError("未获取到扫描校验详细规则")
	//				}
	//
	//				checkRuleMapPointer, allocateMapPointer, err := impl.ScanCodeCheck(user, session, checkRuleMap, allocateMap, artRelMap, &scanRule, &op, &serialOrderStep)
	//				if err != nil {
	//					_ = session.Rollback()
	//					return nil, err
	//				}
	//				checkRuleMap = *checkRuleMapPointer
	//				allocateMap = *allocateMapPointer
	//			} else if serialOrderStep.StepType == baseModel.STEP_OPC_RULE { // 生成OPC通讯的工艺数据
	//				opcBasicMapPointer, err := impl.OPCCommunication(user, session, opcBasicMap, &serialOrderStep, attributeMap, workOrderId, subArtMap)
	//				if err != nil {
	//					_ = session.Rollback()
	//					return nil, err
	//				}
	//				opcBasicMap = *opcBasicMapPointer
	//			} else if serialOrderStep.StepType == baseModel.STEP_TW_RULE { // 生成开发协议的工艺数据
	//				twMapPointer, err := impl.TightenWrenchInfo(user, session, twMap, &serialOrderStep)
	//				if err != nil {
	//					_ = session.Rollback()
	//					return nil, err
	//				}
	//				twMap = *twMapPointer
	//			} else if serialOrderStep.StepType == baseModel.STEP_GUIDE_RULE {
	//				guideRule, exist := guideRuleMap[serialOrderStep.OperationId]
	//				if !exist {
	//					_ = session.Rollback()
	//					return nil, grmi.NewBusinessError("未获取到指导操作的详细规则")
	//				}
	//				err = impl.GuideRuleInfo(user, session, &guideRule, &serialOrderStep)
	//				if err != nil {
	//					_ = session.Rollback()
	//					return nil, err
	//				}
	//			} else {
	//				_ = session.Rollback()
	//				return nil, grmi.NewBusinessError("获取到的工艺数据系统暂不支持该操作类型:" + serialOrderStep.StepType)
	//			}
	//		}
	//	}
	//
	//	lockedWorkOrder := model.LockedResponseWorkOrder{WorkOrderId: workOrderId, Status: baseModel.WO_STATUS_LOCKED}
	//	result = append(result, lockedWorkOrder)
	//}
	//_ = session.Commit()
	return result, nil
}

/******************************************************************************
*
* @Reference LAPP_LF_MOM_BACKEND/services/om/WorkOrderService.ScanCodeCheck   生成扫码校验的工艺数据
*
******************************************************************************/
func (impl *WorkOrderServiceImplement) ScanCodeCheck(user *models.Usertab, session *xorm.Session, checkRuleMap map[string]baseModel.ArtCheckRule, allocateMap map[string][]baseModel.ArtQtyAllocate, artRelMap map[string]int, scanRule *baseModel.ScanRuleInfo, op *baseModel.OperationRelData, serialOrderStep *model.SerialOrderStepLst) (resCheckRuleMap *map[string]baseModel.ArtCheckRule, resAllocateMap *map[string][]baseModel.ArtQtyAllocate, err error) {
	ruleDao := baseDal.NewArtCheckRuleDAO(session, user.Pid, user.Userid)
	allocateDao := baseDal.NewArtQtyAllocateDAO(session, user.Pid, user.Userid)
	serialOrderDetailDao := dal.NewSerialOrderOPDetailDAO(session, user.Pid, user.Userid)
	if scanRule.RuleType == baseModel.SCAN_RULE_TYPE_ARTICLE {
		if scanRule.SRCtrlPara1 == baseModel.SCAN_RULE_CHECK {
			// 获取零件校验规则
			rule, exist := checkRuleMap[op.ArticleAtcodLst.ArtId]
			if !exist {
				ruleLi, err := ruleDao.Select([]grmi.Predicate{baseMeta.ArtCheckRule_AttriCode.NewPredicate(grmi.Equal, op.ArticleAtcodLst.AttrCode), baseMeta.ArtCheckRule_SubObject.NewPredicate(grmi.Equal, serialOrderStep.SubArtId)}, nil)
				if err != nil {
					return nil, nil, grmi.NewBusinessError("获取零件检验规则失败, error:" + err.Error())
				}
				if len(ruleLi) == 0 {
					ruleLi, err = ruleDao.Select([]grmi.Predicate{baseMeta.ArtCheckRule_AttriCode.NewPredicate(grmi.Equal, op.ArticleAtcodLst.AttrCode), baseMeta.ArtCheckRule_SubObject.NewPredicate(grmi.Equal, baseModel.MES_MATCH_ALL)}, nil)
					if err != nil {
						return nil, nil, grmi.NewBusinessError("获取零件检验规则失败, error:" + err.Error())
					}
					if len(ruleLi) == 0 {
						return nil, nil, grmi.NewBusinessError("未获取到零件检验规则, artId:" + serialOrderStep.SubArtId)
					}
				}
				rule = ruleLi[0]
				checkRuleMap[op.ArticleAtcodLst.ArtId] = rule
			}
			// 获取零件分配数量
			var num int
			// 零件BOM中两件组成父级零件的数量
			composeQty := artRelMap[serialOrderStep.SubArtId]
			allocateLi, exist := allocateMap[op.ArticleAtcodLst.ArtId]
			if !exist {
				allocateLi, err = allocateDao.Select([]grmi.Predicate{baseMeta.ArtQtyAllocate_AttriCode.NewPredicate(grmi.Equal, op.ArticleAtcodLst.AttrCode), baseMeta.ArtQtyAllocate_TotalPlanty.NewPredicate(grmi.Equal, composeQty)}, nil)
				if err != nil {
					return nil, nil, grmi.NewBusinessError("获取特殊工位数量分配数据失败，错误:" + err.Error())
				}
				allocateMap[op.ArticleAtcodLst.ArtId] = allocateLi
			}
			// 获取特殊工位零件分配数量
			if len(allocateLi) == 0 {
				num = composeQty
			} else {
				var allNum int
				for _, allocate := range allocateLi {
					if allocate.PO == serialOrderStep.PO {
						if allocate.SubObject == baseModel.MES_MATCH_ALL {
							allNum = allocate.AssignPlanty
						} else if allocate.SubObject == serialOrderStep.SubArtId {
							num = allocate.AssignPlanty
						}
					}
				}
				if num == 0 {
					if allNum != 0 {
						num = allNum
					} else {
						num = composeQty
					}
				}
			}
			// 生成零件校验规则的工艺数据
			pos := 1
			for i := 0; i < num; i++ {
				op := model.SerialOrderOPDetail{
					SerialOrderId: serialOrderStep.SerialOrderId,
					OperationId:   serialOrderStep.OperationId,
					PO:            serialOrderStep.PO,
					SubArtId:      serialOrderStep.SubArtId,
					Pos:           pos,
					StepNo:        serialOrderStep.StepNo,
					StepType:      baseModel.STEP_CHECK_RULE,
					Status:        baseModel.WO_STATUS_LOCKED,
					// 扫码校验 AttriCodeDesc
					CharPara1: rule.AttriCodeDesc,
					// 扫码校验 SubObject
					CharPara2: rule.SubObject,
					// 扫码校验 CodeLength
					CharPara3: rule.CodeLength,
					// 扫码校验 CheckObject
					CharPara4: rule.CheckObject,
					// 扫码校验 CheckStartPos
					IntPara1: rule.CheckStartPos,
					// 扫码校验 CheckLength
					IntPara2: rule.CheckLength,
					// 扫码校验 OnlyBarCodeFlag
					FlagPara1: rule.OnlyBarCodeFlag,
				}
				pos++
				err = serialOrderDetailDao.InsertOne(&op)
				if err != nil {
					return nil, nil, grmi.NewBusinessError("插入操作明细记录失败，error:" + err.Error())
				}
			}
			return &checkRuleMap, &allocateMap, nil
		} else if scanRule.SRCtrlPara1 == baseModel.SCAN_RULE_CRWAL {
			op := model.SerialOrderOPDetail{
				SerialOrderId: serialOrderStep.SerialOrderId,
				OperationId:   serialOrderStep.OperationId,
				PO:            serialOrderStep.PO,
				SubArtId:      serialOrderStep.SubArtId,
				Pos:           1,
				StepNo:        serialOrderStep.StepNo,
				StepType:      baseModel.STEP_CHECK_RULE,
				Status:        baseModel.WO_STATUS_LOCKED,
				IntPara5:      -1,
			}
			err = serialOrderDetailDao.InsertOne(&op)
			if err != nil {
				return nil, nil, grmi.NewBusinessError("插入扫码校验操作明细记录失败，error:" + err.Error())
			} else {
				return &checkRuleMap, &allocateMap, nil
			}
		} else {
			return nil, nil, grmi.NewBusinessError("不支持的条码校验类型")
		}

	} else if scanRule.RuleType == baseModel.SCAN_RULE_TYPE_OTHER {
		if scanRule.SRCtrlPara1 == baseModel.SCAN_RULE_SERIALORDER {
			op := model.SerialOrderOPDetail{
				SerialOrderId: serialOrderStep.SerialOrderId,
				OperationId:   serialOrderStep.OperationId,
				PO:            serialOrderStep.PO,
				SubArtId:      serialOrderStep.SubArtId,
				Pos:           1,
				StepNo:        serialOrderStep.StepNo,
				StepType:      baseModel.STEP_CHECK_RULE,
				Status:        baseModel.WO_STATUS_LOCKED,
				// 扫码校验 AttriCodeDesc
				CharPara1: serialOrderStep.SerialOrderId,
			}
			err = serialOrderDetailDao.InsertOne(&op)
			if err != nil {
				return nil, nil, grmi.NewBusinessError("插入扫码校验操作明细记录失败，error:" + err.Error())
			} else {
				return &checkRuleMap, &allocateMap, nil
			}
		} else {
			return nil, nil, grmi.NewBusinessError("不支持的条码校验规则")
		}
	} else {
		return nil, nil, grmi.NewBusinessError("不支持的条码校验类型")
	}
}

/******************************************************************************
*
* @Reference LAPP_LF_MOM_BACKEND/services/om/WorkOrderService.ScanCodeCheck 生成OPC通信的工艺数据
*
******************************************************************************/
func (impl *WorkOrderServiceImplement) OPCCommunication(user *models.Usertab, session *xorm.Session, opcBasicMap map[int][]baseModel.OPCBasicComInfo, serialOrderStep *model.SerialOrderStepLst, attributeMap map[int][]baseModel.ArticleWithAttrValue, workOrderId string, subArtMap map[string]int) (*map[int][]baseModel.OPCBasicComInfo, error) {
	var err error
	opcBasicDao := baseDal.NewOPCBasicComInfoDAO(session, user.Pid, user.Userid)
	opcComRuleDao := baseDal.NewOPCComRuleDAO(session, user.Pid, user.Userid)
	opcComDetailDao := baseDal.NewOPCComDetailRuleDAO(session, user.Pid, user.Userid)
	serialOrderDetailDao := dal.NewSerialOrderOPDetailDAO(session, user.Pid, user.Userid)
	opcBasicLi, exist := opcBasicMap[serialOrderStep.OperationId]
	if !exist {
		opcBasicLi, err = opcBasicDao.Select([]grmi.Predicate{baseMeta.OPCBasicComInfo_OperationId.NewPredicate(grmi.Equal, serialOrderStep.OperationId)}, nil)
		if err != nil {
			return nil, grmi.NewBusinessError("查询OPC基础通信规则失败，error:" + err.Error())
		}
		if len(opcBasicLi) == 0 {
			return nil, grmi.NewBusinessError("未获取到OPC基础通信规则")
		}
		for index, opcBasic := range opcBasicLi {
			opcComLi, err := opcComRuleDao.Select([]grmi.Predicate{baseMeta.OPCComRule_OperationId.NewPredicate(grmi.Equal, opcBasic.OperationId), baseMeta.OPCComRule_WorkPlaceNr.NewPredicate(grmi.Equal, opcBasic.WorkPlaceNr)}, nil)
			if err != nil {
				return nil, grmi.NewBusinessError("查询OPC通信规则失败, error:" + err.Error())
			}
			if len(opcComLi) == 0 {
				return nil, grmi.NewBusinessError("未获取到OPC通信规则")
			}
			opcDetailLi, err := opcComDetailDao.Select([]grmi.Predicate{baseMeta.OPCComDetailRule_OperationId.NewPredicate(grmi.Equal, opcBasic.OperationId), baseMeta.OPCComDetailRule_WorkPlaceNr.NewPredicate(grmi.Equal, opcBasic.WorkPlaceNr)}, nil)
			if err != nil {
				return nil, grmi.NewBusinessError("查询OPC通信详细规则失败, error:" + err.Error())
			}
			for index, opcCom := range opcComLi {
				opcCom.OPCComDetailRuleLi = make([]baseModel.OPCComDetailRule, 0)
				for _, detail := range opcDetailLi {
					if detail.OperationId == opcCom.OperationId && detail.RuleId == opcCom.RuleId {
						opcCom.OPCComDetailRuleLi = append(opcCom.OPCComDetailRuleLi, detail)
					}
				}
				opcComLi[index] = opcCom
			}
			opcBasic.OPCComRuleLi = opcComLi
			opcBasicLi[index] = opcBasic
		}
		opcBasicMap[serialOrderStep.OperationId] = make([]baseModel.OPCBasicComInfo, 0)
		opcBasicMap[serialOrderStep.OperationId] = opcBasicLi
	}
	pos := 1
	for _, opcBasic := range opcBasicLi {
		for _, opc := range opcBasic.OPCComRuleLi {
			var value string
			if opc.DBlockValueType == baseModel.OPC_DBBLOCK_VALUE_TYPE_MAP {
				for _, detail := range opc.OPCComDetailRuleLi {
					if detail.BaseOnType == baseModel.BASE_ON_TYPE_ATTRNAME {
						attrCode, err := strconv.Atoi(detail.BaseOnValue)
						if err != nil {
							return nil, grmi.NewBusinessError("OPC通讯规则映射值转换ATTRCODE失败, error:" + err.Error())
						}
						attrLi, exist := attributeMap[attrCode]
						if !exist {
							return nil, grmi.NewBusinessError("未获取到OPC通信细则中的零件属性描述对应的shortCode, 属性描述:" + detail.BaseOnValue)
						}
						if detail.DataType == baseModel.DATA_TYPE_ATTRCODE {

							value += strconv.Itoa(attrLi[0].AttributeValst.AttrCode)
						} else if detail.DataType == baseModel.DATA_TYPE_SHORTCODE {
							var sign bool
							for _, data := range attrLi {
								_, exist := subArtMap[data.ArticleAtcodLst.ArtId]
								if !exist {
									continue
								} else {
									if sign {
										return nil, grmi.NewBusinessError("OPC通讯规则映射值获取ATTRCODE下的零件多于一个")
									}
									sign = true
									value += data.AttributeValst.ShortCode
								}
							}
							if !sign {
								return nil, grmi.NewBusinessError("未获取到OPC通信细则中的零件属性描述对应的shortCode, 属性描述:" + detail.BaseOnValue)
							}
						} else if detail.DataType == baseModel.DATA_TYPE_ATTRVALUE {
							var sign bool
							for _, data := range attrLi {
								_, exist := subArtMap[data.ArticleAtcodLst.ArtId]
								if !exist {
									continue
								} else {
									if sign {
										return nil, grmi.NewBusinessError("OPC通讯规则映射值获取ATTRCODE下的零件多于一个")
									}
									sign = true
									value += data.AttributeValst.AttrValue
								}
							}
						} else {
							return nil, grmi.NewBusinessError("不支持的OPC通信细则中的DATA TYPE, DATA TYPE:" + detail.DataType)
						}
					} else if detail.BaseOnType == baseModel.BASE_ON_TYPE_ORDERINFO {
						if detail.DataType == baseModel.DATA_TYPE_WONO {
							value += workOrderId
						} else if detail.DataType == baseModel.DATA_TYPE_PARTNO {
							value += serialOrderStep.SubArtId
						} else {
							return nil, grmi.NewBusinessError("不支持的OPC通信细则中的DATA TYPE, DATA TYPE:" + detail.DataType)
						}
					} else if detail.BaseOnType == baseModel.BASE_ON_TYPE_MAINBARCODE {
						if detail.BaseOnValue == baseModel.BASE_ON_VALUE_UNITSN {
							value += serialOrderStep.SerialOrderId
						} else {
							return nil, grmi.NewBusinessError("不支持的OPC通信细则中的BASE ON VALUE, BASE ON VALUE:" + detail.BaseOnValue)
						}
					}
				}
			} else {
				value = opc.DBlockValue
			}
			op := model.SerialOrderOPDetail{
				SerialOrderId: serialOrderStep.SerialOrderId,
				OperationId:   serialOrderStep.OperationId,
				PO:            serialOrderStep.PO,
				SubArtId:      serialOrderStep.SubArtId,
				Pos:           pos,
				StepType:      baseModel.STEP_OPC_RULE,
				Status:        baseModel.WO_STATUS_LOCKED,
				StepNo:        serialOrderStep.StepNo,
				// OPC BRAND NAME
				CharPara1: opcBasic.BrandName,
				// OPC MACHINE TYPE
				CharPara2: opcBasic.MachineType,
				// OPC IP ADDRESS
				CharPara3: opcBasic.IpAddress,
				// OPC ACTION TYPE
				CharPara4: opc.ActionType,
				// OPC DBLOCK ADDRESS
				CharPara5: opc.DBlockAddress,
				// OPC DBLOCK VALUE TYPE
				CharPara6: opc.DBlockValueType,
				CharPara7: opc.Formula,
				CharPara8: opc.OperatorSimbol,
				CharPara9: value,
				// OPC WorkPlaceNr
				IntPara1: opcBasic.WorkPlaceNr,
				IntPara5: opc.RuleId,
			}
			pos++
			err = serialOrderDetailDao.InsertOne(&op)
			if err != nil {
				return nil, grmi.NewBusinessError("插入OPC通讯操作明细记录失败，error:" + err.Error())
			}
		}
	}
	return &opcBasicMap, nil
}

/******************************************************************************
*
* @Reference LAPP_LF_MOM_BACKEND/services/om/WorkOrderService.ScanCodeCheck 生成开放协议的工艺数据
*
******************************************************************************/
func (impl *WorkOrderServiceImplement) TightenWrenchInfo(user *models.Usertab, session *xorm.Session, twMap map[int][]baseModel.TightenWrenchInfo, serialOrderStep *model.SerialOrderStepLst) (*map[int][]baseModel.TightenWrenchInfo, error) {
	var err error
	twDao := baseDal.NewTightenWrenchInfoDAO(session, user.Pid, user.Userid)
	twrDao := baseDal.NewTightenWrenchRuleInfoDAO(session, user.Pid, user.Userid)
	serialOrderDetailDao := dal.NewSerialOrderOPDetailDAO(session, user.Pid, user.Userid)
	twLi, exist := twMap[serialOrderStep.OperationId]
	if !exist {
		twLi, err = twDao.Select([]grmi.Predicate{baseMeta.TightenWrenchRuleInfo_OperationId.NewPredicate(grmi.Equal, serialOrderStep.OperationId)}, nil)
		if err != nil {
			return nil, grmi.NewBusinessError("查询开放协议通信规则失败，error:" + err.Error())
		}
		if len(twLi) == 0 {
			return nil, grmi.NewBusinessError("未获取到开放协议通信规则")
		}
		for index, tw := range twLi {
			twrLi, err := twrDao.Select([]grmi.Predicate{baseMeta.TightenWrenchRuleInfo_OperationId.NewPredicate(grmi.Equal, tw.OperationId), baseMeta.TightenWrenchRuleInfo_WorkPlaceNr.NewPredicate(grmi.Equal, tw.WorkPlaceNr)}, nil)
			if err != nil {
				return nil, grmi.NewBusinessError("查询开放协议通信细则失败, error:" + err.Error())
			}
			if len(twrLi) == 0 {
				return nil, grmi.NewBusinessError("未获取到开放协议通信细则")
			}
			tw.TightenWrenchRuleInfoLi = twrLi
			twLi[index] = tw
		}
		twMap[serialOrderStep.OperationId] = twLi
	}
	pos := 1
	for _, tw := range twLi {
		for _, twr := range tw.TightenWrenchRuleInfoLi {

			for i := 0; i < twr.ControlTime; i++ {
				op := model.SerialOrderOPDetail{
					SerialOrderId: serialOrderStep.SerialOrderId,
					OperationId:   serialOrderStep.OperationId,
					PO:            serialOrderStep.PO,
					SubArtId:      serialOrderStep.SubArtId,
					Pos:           pos,
					StepType:      baseModel.STEP_TW_RULE,
					Status:        baseModel.WO_STATUS_LOCKED,
					StepNo:        serialOrderStep.StepNo,
					// TightenWrenchInfo BRAND NAME
					CharPara1: tw.BrandName,
					// TightenWrenchInfo 	MACHINE TYPE
					CharPara2: tw.MachineType,
					// TightenWrenchInfo IP ADDRESS
					CharPara3: tw.IpAddress,
					// TightenWrenchInfo MainControlAction
					CharPara4: twr.MainControlAction,
					// TightenWrenchInfo ControlTime
					IntPara1: twr.ControlId,
					// TightenWrenchInfo WorkPlaceNr
					IntPara2: tw.WorkPlaceNr,
					IntPara5: twr.RuleId,
				}
				pos++
				err = serialOrderDetailDao.InsertOne(&op)
				if err != nil {
					return nil, grmi.NewBusinessError("插入开放协议操作明细记录失败，error:" + err.Error())
				}
			}
		}
	}
	return &twMap, nil
}

/******************************************************************************
*
* @Reference LAPP_LF_MOM_BACKEND/services/om/WorkOrderService.GuideRuleInfo 生成指导数据
*
******************************************************************************/
func (impl *WorkOrderServiceImplement) GuideRuleInfo(user *models.Usertab, session *xorm.Session, guideRule *baseModel.GuideRuleInfo, serialOrderStep *model.SerialOrderStepLst) error {
	var err error
	serialOrderDetailDao := dal.NewSerialOrderOPDetailDAO(session, user.Pid, user.Userid)

	op := model.SerialOrderOPDetail{
		SerialOrderId: serialOrderStep.SerialOrderId,
		OperationId:   serialOrderStep.OperationId,
		PO:            serialOrderStep.PO,
		SubArtId:      serialOrderStep.SubArtId,
		Pos:           1,
		StepType:      baseModel.STEP_GUIDE_RULE,
		Status:        baseModel.WO_STATUS_LOCKED,
		StepNo:        serialOrderStep.StepNo,
		IntPara1:      guideRule.DisplayTime,
	}
	err = serialOrderDetailDao.InsertOne(&op)
	if err != nil {
		return grmi.NewBusinessError("插入指导操作操作明细记录失败，error:" + err.Error())
	}
	return nil
}

/******************************************************************************
*
* @Reference LAPP_LF_MOM_BACKEND/services/om/WorkOrderService.PrintRuleInfo 生成单据打印数据
*
******************************************************************************/
func (impl *WorkOrderServiceImplement) PrintRuleInfo(user *models.Usertab, session *xorm.Session, printRule *baseModel.PrintRuleInfo, serialOrderStep *model.SerialOrderStepLst) error {
	var err error
	serialOrderDetailDao := dal.NewSerialOrderOPDetailDAO(session, user.Pid, user.Userid)

	op := model.SerialOrderOPDetail{
		SerialOrderId: serialOrderStep.SerialOrderId,
		OperationId:   serialOrderStep.OperationId,
		PO:            serialOrderStep.PO,
		SubArtId:      serialOrderStep.SubArtId,
		Pos:           1,
		StepType:      baseModel.STEP_PRINT_RULE,
		Status:        baseModel.WO_STATUS_LOCKED,
		StepNo:        serialOrderStep.StepNo,
		IntPara1:      printRule.DisplayTime,
	}
	err = serialOrderDetailDao.InsertOne(&op)
	if err != nil {
		return grmi.NewBusinessError("插入单据打印操作明细记录失败，error:" + err.Error())
	}
	return nil
}

func (impl *WorkOrderServiceImplement) CreateLockWorkOrder(user *models.Usertab, entity *model.CreateLockWorkOrder) error {
	grmi.Log(user, "/services/om/implments/WorkOrder.service.impl.go", "CreateLockWorkOrder", "创建锁定的workOrder")
	engine := db.Eloquent.Master()
	session := engine.NewSession()
	defer session.Close()
	err := session.Begin()
	if err != nil {
		return err
	}
	dao := dal.NewSerialOrderDAO(session, user.Pid, user.Userid)
	articleDao := baseDal.NewArticleDAO(session, user.Pid, user.Userid)
	workOrderDao := dal.NewWorkOrderDAO(session, user.Pid, user.Userid)
	statusDao := dal.NewWorkOrderStatusDAO(session, user.Pid, user.Userid)
	qtyDao := dal.NewWorkOrderQtyDAO(session, user.Pid, user.Userid)
	serialOrderStatusDao := dal.NewSerialOrderStatusDAO(session, user.Pid, user.Userid)
	projectDao := meDal.NewProjectDAO(session, user.Pid, user.Userid)
	operationDao := baseDal.NewOperationDAO(session, user.Pid, user.Userid)
	PODao := dal.NewSerialOrderPOLstDAO(session, user.Pid, user.Userid)
	stepDao := dal.NewSerialOrderStepLstDAO(session, user.Pid, user.Userid)
	articleWithAttrDao := baseDal.NewArticleAtcodLstDAO(session, user.Pid, user.Userid)
	scanRuleDao := baseDal.NewScanRuleInfoDAO(session, user.Pid, user.Userid)
	guideDao := baseDal.NewGuideRuleInfoDAO(session, user.Pid, user.Userid)
	printDao := baseDal.NewPrintRuleInfoDAO(session, user.Pid, user.Userid)
	bomHeadDao := meDal.NewBomHeadDAO(session, user.Pid, user.Userid)
	bomLstDao := meDal.NewBomLstDAO(session, user.Pid, user.Userid)
	artWorkLineDao := baseDal.NewArtWorkLineLstDAO(session, user.Pid, user.Userid)
	// 校验物料属性
	article, err := articleDao.SelectOne(entity.ArtId)
	if err != nil {
		_ = session.Rollback()
		return grmi.NewBusinessError("查询物料数据失败, error:" + err.Error())
	}
	if article == nil {
		_ = session.Rollback()
		return grmi.NewBusinessError("不存在对应的物料数据")
	}
	if article.ArtSpec1 != baseModel.ART_TYPE_FINISHED && article.ArtSpec1 != baseModel.ART_TYPE_VIRTUAL {
		_ = session.Rollback()
		return grmi.NewBusinessError("传递的物料不是成品或虚拟物料ID")
	}
	workLineLi, err := artWorkLineDao.Select([]grmi.Predicate{baseMeta.ArtWorkLineLst_ArtId.NewPredicate(grmi.Equal, article.ArtId)}, nil)
	if err != nil {
		_ = session.Rollback()
		return grmi.NewBusinessError("查询物料关联产线失败, error:" + err.Error())
	}
	var workLineExist bool
	for _, workLineData := range workLineLi {
		if workLineData.WorkLineId == entity.WorkLineId {
			workLineExist = true
		}
	}
	if !workLineExist {
		_ = session.Rollback()
		return grmi.NewBusinessError("该总成不支持在该产线上生产")
	}
	fmt.Println("--------------------------------------")
	// 虚拟件获取实际物料BOM及比例关系
	var virtualArtMap map[string]int
	var countMap map[string]int
	if article.ArtSpec1 == baseModel.ART_TYPE_VIRTUAL {
		virtualArtMap = make(map[string]int)
		countMap = make(map[string]int)

		var count int
		if article.ArtSpec1 == baseModel.ART_TYPE_VIRTUAL {
			bomHead, err := bomHeadDao.SelectOne(article.ArtId)
			if err != nil {
				_ = session.Rollback()
				return grmi.NewBusinessError("获取物料BOM失败, error:" + err.Error())
			}
			if bomHead == nil {
				_ = session.Rollback()
				return grmi.NewBusinessError("不存在对应的物料BOM，artId:" + article.ArtId)
			}
			bomLstLi, err := bomLstDao.Select([]grmi.Predicate{meMeta.BomLst_BomId.NewPredicate(grmi.Equal, bomHead.BomId)}, nil)
			if err != nil {
				_ = session.Rollback()
				return grmi.NewBusinessError("获取BOM细则失败, error:" + err.Error())
			}
			if len(bomLstLi) == 0 {
				_ = session.Rollback()
				return grmi.NewBusinessError("未获取到BOM细则, artId:" + bomHead.BomId)
			}
			for _, bomLst := range bomLstLi {
				if int(bomLst.FmatQty) != 1 || bomLst.FmatNr != bomLst.BomId {
					_ = session.Rollback()
					return grmi.NewBusinessError("虚拟件BOM配置错误")
				}
				virtualArtMap[bomLst.CmatNr] = int(bomLst.CmatQty)
				count += int(bomLst.CmatQty)
			}
		}
		if entity.Qty%count != 0 {
			_ = session.Rollback()
			return grmi.NewBusinessError("创建工单的生产数量不能匹配BOM分配关系")
		}
		for artId := range virtualArtMap {
			countMap[artId] = 0
		}
	}
	// 组装BOM切片
	bomHeadMap := make(map[string]meModel.BomHead, 0)
	if article.ArtSpec1 == baseModel.ART_TYPE_VIRTUAL {
		for artId := range virtualArtMap {
			bomHead, err := bomHeadDao.SelectOne(artId)
			if err != nil {
				_ = session.Rollback()
				return grmi.NewBusinessError("查询物料BOM失败, error:" + err.Error())
			}
			if bomHead == nil {
				_ = session.Rollback()
				return grmi.NewBusinessError("不存在对应的物料BOM, artId:" + artId)
			}
			var Me meModel.BomLst
			Me.PlantNr = user.Pid
			Me.BomId = bomHead.BomId
			bomList, err := Me.SetMenu(bomHead.MatNr)
			if err != nil {
				_ = session.Rollback()
				return grmi.NewBusinessError("获取BOM细则失败, error:" + err.Error())
			}
			if len(bomList) == 0 {
				_ = session.Rollback()
				return grmi.NewBusinessError("未获取到BOM细则, artId:" + bomHead.BomId)
			}
			bomHead.BomLstLi = bomList
			bomHeadMap[bomHead.MatNr] = *bomHead
		}
	} else {
		bomHead, err := bomHeadDao.SelectOne(article.ArtId)
		if err != nil {
			_ = session.Rollback()
			return grmi.NewBusinessError("查询物料BOM失败, error:" + err.Error())
		}
		if bomHead == nil {
			_ = session.Rollback()
			return grmi.NewBusinessError("不存在对应的物料BOM, artId:" + article.ArtId)
		}
		var Me meModel.BomLst
		Me.PlantNr = user.Pid
		Me.BomId = bomHead.BomId
		bomList, err := Me.SetMenu(bomHead.MatNr)
		if err != nil {
			_ = session.Rollback()
			return grmi.NewBusinessError("获取BOM细则失败, error:" + err.Error())
		}
		if len(bomList) == 0 {
			_ = session.Rollback()
			return grmi.NewBusinessError("未获取到BOM细则, artId:" + bomHead.BomId)
		}
		bomHead.BomLstLi = bomList
		bomHeadMap[bomHead.MatNr] = *bomHead
	}
	// 获取项目数据 用于获取流水号
	project, err := projectDao.SelectOne(baseModel.ProjectId)
	if err != nil {
		_ = session.Rollback()
		return grmi.NewBusinessError("获取项目数据失败, error:" + err.Error())
	}
	if project == nil {
		_ = session.Rollback()
		return grmi.NewBusinessError("不存在该项目数据")
	}
	scanRuleLi, err := scanRuleDao.Select(nil, nil)
	if err != nil {
		_ = session.Rollback()
		return grmi.NewBusinessError("查询扫码校验条码失败, error:" + err.Error())
	}
	scanRuleMap := make(map[int]baseModel.ScanRuleInfo)
	for _, scanRule := range scanRuleLi {
		scanRuleMap[scanRule.OperationId] = scanRule
	}
	guideRuleLi, err := guideDao.Select(nil, nil)
	if err != nil {
		_ = session.Rollback()
		return grmi.NewBusinessError("查询指导操作规则失败, error:" + err.Error())
	}
	guideRuleMap := make(map[int]baseModel.GuideRuleInfo, len(guideRuleLi))
	for _, guideRule := range guideRuleLi {
		guideRuleMap[guideRule.OperationId] = guideRule
	}
	printLi, err := printDao.Select(nil, nil)
	if err != nil {
		_ = session.Rollback()
		return grmi.NewBusinessError("查询单据打印规则失败, error:" + err.Error())
	}
	printMap := make(map[int]baseModel.PrintRuleInfo, len(printLi))
	for _, printData := range printLi {
		printMap[printData.OperationId] = printData
	}
	snr := new(models.Snrtab)
	snr.Finr = user.Pid
	workOrderId, err := snr.GetNextSnrWithSession(session, project.WorkOrderSnr)
	if err != nil {
		_ = session.Rollback()
		return grmi.NewBusinessError("生成工单流水号失败")
	}
	workOrder := model.WorkOrder{
		WorkOrderId:          workOrderId,
		ArtId:                article.ArtId,
		CustArtId:            article.CustArtId,
		OrderType:            baseModel.ODER_TYPE_INTERVAL,
		OrderInfo:            article.Descr1,
		PlanResourceGroupId:  article.PlanResourceGroupId,
		PlanResourceId:       entity.WorkLineId,
		UsedResourceId:       entity.WorkLineId,
		PlanQty:              float64(entity.Qty),
		QtyUomId:             article.UomId,
		RatePerHourToggle:    article.RatePerHourToggle,
		TimePerItemToggle:    article.TimePerItemToggle,
		TimePerBatchToggle:   article.TimePerBatchToggle,
		BatchTimeFieldToggle: article.BatchTimeFieldToggle,
		OpTimePerItem:        article.OpTimePerItem,
		BatchTime:            article.BatchTime,
		QuantityPerHour:      article.QuantityPerHour,
		BatchingMethod:       article.BatchingMethod,
		PlanStartDate:        grmi.Date(time.Now()),
		PlanEndDate:          grmi.Date(time.Now()),
		PlanStartTime:        grmi.DateTime(time.Now()),
		PlanEndTime:          grmi.DateTime(time.Now()),
		ProjectId:            project.ProjectId,
	}
	workOrderStatus := model.WorkOrderStatus{
		WorkOrderId: workOrderId,
		Status:      baseModel.WO_STATUS_LOCKED,
	}
	workOrderQty := model.WorkOrderQty{
		WorkOrderId: workOrderId,
		PlanQty:     float64(entity.Qty),
	}
	err = workOrderDao.InsertOne(&workOrder)
	if err != nil {
		_ = session.Rollback()
		return grmi.NewBusinessError("插入批次工单失败, error:" + err.Error())
	}
	err = statusDao.InsertOne(&workOrderStatus)
	if err != nil {
		_ = session.Rollback()
		return grmi.NewBusinessError("插入批次工单状态失败, error:" + err.Error())
	}
	err = qtyDao.InsertOne(&workOrderQty)
	if err != nil {
		_ = session.Rollback()
		return grmi.NewBusinessError("插入批次工单数量失败, error:" + err.Error())
	}
	attributeLi, err := articleWithAttrDao.SelectAllWithAttrValue()
	if err != nil {
		_ = session.Rollback()
		return grmi.NewBusinessError("查询零件属性失败,error:" + err.Error())
	}
	attributeMap := make(map[int][]baseModel.ArticleWithAttrValue)
	for _, data := range attributeLi {
		_, exist := attributeMap[data.ArticleAtcodLst.AttrCode]
		if !exist {
			attributeMap[data.ArticleAtcodLst.AttrCode] = make([]baseModel.ArticleWithAttrValue, 0)
		}
		attributeMap[data.ArticleAtcodLst.AttrCode] = append(attributeMap[data.ArticleAtcodLst.AttrCode], data)
	}

	serialOrderLi := make([]model.SerialOrder, 0, entity.Qty)
	serialOrderStatusLi := make([]model.SerialOrderStatus, 0, entity.Qty)

	// 进行批次工单的时间拆解到序列工单的计划时间上
	// 生成序列工单
	for i := 0; i < entity.Qty; i++ {
		snr := new(models.Snrtab)
		snr.Finr = user.Pid
		serialNum, err := snr.GetNextSnrWithSession(session, project.SerialOrderSnr)
		if err != nil {
			_ = session.Rollback()
			return grmi.NewBusinessError("获取序列工单流水号失败, error:" + err.Error())
		}
		planStartDate := workOrder.PlanStartDate.Restore().Format("20060102")
		prefix := workOrder.ArtId + baseModel.PlantName + planStartDate
		serialOrderId := strings.Replace(serialNum, "SO-", prefix, 1)
		// 根据虚拟件还是总成件 来获取ArtId
		var artId string
		if article.ArtSpec1 == baseModel.ART_TYPE_VIRTUAL {
			accomplish := true
			for innerArtId, qty := range virtualArtMap {
				if countMap[innerArtId] < qty {
					accomplish = false
				}
			}
			if accomplish {
				for artId := range countMap {
					countMap[artId] = 0
				}
			}
			for innerArtId, qty := range virtualArtMap {
				if countMap[innerArtId] < qty {
					artId = innerArtId
					countMap[innerArtId] += 1
					break
				}
			}
		} else {
			artId = article.ArtId
		}
		serialOrder := model.SerialOrder{
			WorkOrderId:    workOrderId,
			SerialOrderId:  serialOrderId,
			ArtId:          artId,
			OrderType1:     workOrder.OrderType1,
			OrderType2:     workOrder.OrderType2,
			PlanResourceId: workOrder.PlanResourceId,
			UsedResourceId: workOrder.UsedResourceId,
			PlanQty:        1,
			QtyUomId:       workOrder.QtyUomId,
			OpTimePerItem:  workOrder.OpTimePerItem,
			TimeUomId:      workOrder.TimeUomId,
			PlanStartDate:  workOrder.PlanStartDate,
			PlanEndDate:    workOrder.PlanEndDate,
			SetupStartTime: workOrder.SetupStartTime,
			SetupEndTime:   workOrder.SetupEndTime,
			PlanStartTime:  workOrder.PlanStartTime,
			PlanEndTime:    workOrder.PlanEndTime,
			ProjectId:      workOrder.ProjectId,
		}
		serialOrderLi = append(serialOrderLi, serialOrder)
		serialStatus := model.SerialOrderStatus{
			Status:        baseModel.WO_STATUS_LOCKED,
			SerialOrderId: serialOrderId,
		}
		serialOrderStatusLi = append(serialOrderStatusLi, serialStatus)
	}
	for _, serialOrder := range serialOrderLi {
		err = dao.InsertOne(&serialOrder)
		if err != nil {
			_ = session.Rollback()
			return grmi.NewBusinessError("插入序列工单数据失败,error:" + err.Error())
		}
	}
	for _, serialOrderStatus := range serialOrderStatusLi {
		err = serialOrderStatusDao.InsertOne(&serialOrderStatus)
		if err != nil {
			_ = session.Rollback()
			return grmi.NewBusinessError("插入序列工单状态失败,error:" + err.Error())
		}
	}
	// 生成序列工单对应的工艺数据
	opMap := make(map[string][]baseModel.OperationRelData)
	totalArtMap := make(map[string]map[string]int)
	for artId, bomHead := range bomHeadMap {
		artMap := impl.ExtractArtId(&bomHead)
		artIdLi := make([]string, 0, len(artMap))
		for innerArtId := range artMap {
			artIdLi = append(artIdLi, innerArtId)
		}
		opLi, err := operationDao.GetOperationRelData(artIdLi, workOrder.PlanResourceId, article.ProjectId)
		if err != nil {
			_ = session.Rollback()
			return grmi.NewBusinessError("获取工艺操作失败,error:" + err.Error())
		}
		if len(opLi) == 0 {
			_ = session.Rollback()
			return grmi.NewBusinessError("未获取到工艺数据")
		}
		opMap[artId] = opLi
		totalArtMap[artId] = artMap
	}

	allocateMap := make(map[string][]baseModel.ArtQtyAllocate)
	checkRuleMap := make(map[string]baseModel.ArtCheckRule)
	opcBasicMap := make(map[int][]baseModel.OPCBasicComInfo)
	twMap := make(map[int][]baseModel.TightenWrenchInfo)
	for _, serialOrder := range serialOrderLi {
		opLi := opMap[serialOrder.ArtId]
		artRelMap := totalArtMap[serialOrder.ArtId]
		var PO int
		processPos := 1
		opPos := 1
		for _, op := range opLi {
			if PO != op.Process.PO {
				PO = op.Process.PO
				serialOrderWorkPlace := model.SerialOrderPOLst{
					SerialOrderId: serialOrder.SerialOrderId,
					PO:            PO,
					Status:        baseModel.WO_STATUS_LOCKED,
					HasDependOn:   op.Process.HasDependOn,
				}
				err = PODao.InsertOne(&serialOrderWorkPlace)
				if err != nil {
					_ = session.Rollback()
					return grmi.NewBusinessError("插入serialOrder工序数据失败,error:" + err.Error())
				}
				processPos++

			}
			serialOrderStep := model.SerialOrderStepLst{
				PO:            op.Process.PO,
				OperationId:   op.OperationId,
				SerialOrderId: serialOrder.SerialOrderId,
				StepNo:        op.Operation.StepNo,
				Pos:           opPos,
				SubArtId:      op.ArticleAtcodLst.ArtId,
				StepDesc:      op.Operation.StepDesc,
				AttrCode:      op.ArticleAtcodLst.AttrCode,
				AttrValue:     op.ArticleAtcodLst.AttrValue,
				StepType:      op.Operation.StepType,
				Status:        baseModel.WO_STATUS_LOCKED,
			}
			opPos++
			err = stepDao.InsertOne(&serialOrderStep)
			if err != nil {
				_ = session.Rollback()
				return grmi.NewBusinessError("插入序列工单工艺数据失败, error:" + err.Error())
			}
			if serialOrderStep.StepType == baseModel.STEP_CHECK_RULE { // 生成扫码校验的工艺数据
				scanRule, exist := scanRuleMap[serialOrderStep.OperationId]
				if !exist {
					return grmi.NewBusinessError("未获取到扫描校验详细规则")
				}

				checkRuleMapPointer, allocateMapPointer, err := impl.ScanCodeCheck(user, session, checkRuleMap, allocateMap, artRelMap, &scanRule, &op, &serialOrderStep)
				if err != nil {
					_ = session.Rollback()
					return err
				}
				checkRuleMap = *checkRuleMapPointer
				allocateMap = *allocateMapPointer
			} else if serialOrderStep.StepType == baseModel.STEP_OPC_RULE { // 生成OPC通讯的工艺数据

				opcBasicMapPointer, err := impl.OPCCommunication(user, session, opcBasicMap, &serialOrderStep, attributeMap, workOrderId, artRelMap)
				if err != nil {
					_ = session.Rollback()
					return err
				}
				opcBasicMap = *opcBasicMapPointer
			} else if serialOrderStep.StepType == baseModel.STEP_TW_RULE { // 生成开发协议的工艺数据
				twMapPointer, err := impl.TightenWrenchInfo(user, session, twMap, &serialOrderStep)
				if err != nil {
					_ = session.Rollback()
					return err
				}
				twMap = *twMapPointer
			} else if serialOrderStep.StepType == baseModel.STEP_GUIDE_RULE {
				guideRule, exist := guideRuleMap[serialOrderStep.OperationId]
				if !exist {
					_ = session.Rollback()
					return grmi.NewBusinessError("未获取到指导操作的详细规则")
				}
				err = impl.GuideRuleInfo(user, session, &guideRule, &serialOrderStep)
				if err != nil {
					_ = session.Rollback()
					return err
				}
			} else if serialOrderStep.StepType == baseModel.STEP_PRINT_RULE {
				printRule, exist := printMap[serialOrderStep.OperationId]
				if !exist {
					_ = session.Rollback()
					return grmi.NewBusinessError("未获取到单据打印的详细规则")
				}
				err = impl.PrintRuleInfo(user, session, &printRule, &serialOrderStep)
				if err != nil {
					_ = session.Rollback()
					return err
				}
			} else {
				_ = session.Rollback()
				return grmi.NewBusinessError("获取到的工艺数据系统暂不支持该操作类型:" + serialOrderStep.StepType)
			}
		}
	}
	_ = session.Commit()
	return nil
}

func (impl *WorkOrderServiceImplement) ExtractArtId(bomHead *meModel.BomHead) map[string]int {
	artMap := make(map[string]int)
	bomLstLi := bomHead.BomLstLi
	for _, bomLst := range bomLstLi {
		_, exist := artMap[bomLst.CmatNr]
		if exist {
			artMap[bomLst.CmatNr] += int(bomLst.CmatQty / bomLst.FmatQty)
		} else {
			artMap[bomLst.CmatNr] = int(bomLst.CmatQty / bomLst.FmatQty)
		}
	}
	return artMap
}
