using Admin.NET.Application; using Admin.NET.Core.TaskModule.Enum; using iWareCC.Common.Helper; using iWareCommon; using iWareCommon.Common.Globle; using iWareCommon.Utils; using iWareModel.Entity.WCS; using iWareSql.DataAccess; using iWareSql.MyDbContext; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data.Entity; using System.Linq; using System.Threading; using static System.Windows.Forms.VisualStyles.VisualStyleElement; using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel; namespace iWareCC { /// /// WCS任务完成线程(平库) /// public static class TaskFinishHandler { public static void Handler() { while (true) { Thread.Sleep(2000);//休眠2秒 try { if (SystemValue.isAllowRuning_PingKuTaskFinish && SystemValue.isStartedModel) { using (MyDbContext dbContext = new MyDbContext()) { //只查询平库 var models = dbContext.wms_task .Where(x => x.TaskStatus == (int)TaskStatusEnum.已下发) .Where(x => (x.IsDelete == false) // && (x.AreaType == (int)AreaTypeEnum.平库) ).ToList(); if (models != null && models.Count > 0) { FinishTask(dbContext,models); } SystemWarningMsg._lbl_Alert_PingKuTaskFinish = ""; } } } catch (Exception ex) { SystemWarningMsg._lbl_Alert_PingKuTaskFinish = "WCS任务完成线程(平库) 出现异常:" + ex.Message; Log4NetHelper.WriteErrorLog(LogType.PingKuTaskFinish, "WCS任务完成线程(平库) 出现异常:" + ex.Message, ex); } } } /// /// 模拟完成任务调度 /// /// /// public static void FinishTask(MyDbContext dbContext, List taskList) { string errMsg = string.Empty; try { //处理调度任务 foreach (var singleTask in taskList) { OrderMovementFinishTask(dbContext, singleTask, ref errMsg); if (!string.IsNullOrEmpty(errMsg)) { SystemWarningMsg._lbl_Alert_OutPlanTaskHandler += "任务号" + singleTask.TaskNo + "模拟完成任务失败," + errMsg; } } } catch (Exception ex) { SystemWarningMsg._lbl_Alert_OutPlanTaskHandler = "错误信息:" + ex; } } /// /// 模拟完成 上、下架 /// /// /// /// /// private static int OrderMovementFinishTask(MyDbContext mycontext, wms_task singleTask, ref string errMsg) { try { //获取移动单 var moveOrder = BaseInfoHelper.GetOrderMovement(mycontext, singleTask, ref errMsg); var moveOrderDetails = BaseInfoHelper.GetMoveOrderDetails(mycontext, singleTask, moveOrder, ref errMsg); //获取业务类型 var wmsBusinessType = BusinessTypeHelper.GetBusinessTypeInfoFromDB(moveOrder.BusinessType, mycontext); //查询库位 //目标库位校验 var toPlace =BaseInfoHelper.GetPlace(mycontext, singleTask.ToPlaceCode, "目标库位", ref errMsg); //目标库区 var toArea = BaseInfoHelper.GetArea(mycontext, singleTask.ToAreaCode, "目标库区", ref errMsg); ////源库位校验 var sourcePlace = BaseInfoHelper.GetPlace(mycontext, singleTask.SourcePlaceCode, "源库位", ref errMsg); //解锁起始、目标库位 sourcePlace.PlaceStatus = (int)PlaceStatusEnum.正常; toPlace.PlaceStatus = (int)PlaceStatusEnum.正常; //查询容器 var container = BaseInfoHelper.GetContainer(mycontext, singleTask.ContainerCode, ref errMsg); //更新库位容器绑定关系 UpdaeContainerPlace(mycontext, singleTask, container, toPlace, ref errMsg); //更新库存 //上架更新库存状态=》已上架 //下架更新冻结状态=》未冻结 //创建事务记录 //非下架、上架仅创建事务记录(因为变更了库位) UpdateStockQuan(mycontext, wmsBusinessType, singleTask, moveOrder, container, toPlace, toArea, ref errMsg); #region 处理移动单 //处理移动单(上架单、下架单) //上架单或下架单业务类型设置了 自动完成 就 自动完成单据 bool isFinish = false; if (wmsBusinessType.UpDownShelvesType == (int)UpDownShelvesTypeEnum.上架 || wmsBusinessType.BusinessTypeValue==(int)BusinessTypeEnum.盘点下架|| wmsBusinessType.DownShelvesIsAutoFinish == true) { isFinish = true; } if (isFinish) { if (moveOrderDetails.Any(a => string.IsNullOrWhiteSpace(a.ContainerCode))) { errMsg = $"{moveOrder.OrderTypeName}类型移动单{moveOrder.OrderNo}存在容器为空的移动单明细"; return 3; } //上架调度任务自动完成上架单 var updateMoveOrderDetails = moveOrderDetails.Where(w => w.ContainerCode.Equals(container.ContainerCode)).ToList(); if (updateMoveOrderDetails?.Count <= 0) { errMsg = $"{moveOrder.OrderTypeName}类型移动单{moveOrder.OrderNo}不存在容器为{container.ContainerCode}的移动单明细"; return 3; } foreach (var item in updateMoveOrderDetails) { item.OrderStatus = (int)OrderStatusEnum.已完成; item.OrderStatusName = OrderStatusEnum.已完成.ToString(); item.UpdateTime = DateTime.Now; item.UpdateUserId = 0; item.UpdateUserName =FormCC.WcsSysUserName; } //更新移动单时间信息 UpdatOrderMovementStatus(moveOrderDetails, moveOrder, ref errMsg); } //盘点下架以外的下架不处理下架单,PDA分拣或自动完成分拣后完成下架单 #endregion singleTask.TaskStatus = (int)TaskStatusEnum.已完成;//更新任务状态为 已完成 singleTask.TaskStatusName = TaskStatusEnum.已完成.ToString(); singleTask.UpdateTime = DateTime.Now; singleTask.TaskMsg = "任务完成"; singleTask.FinishedTime = DateTime.Now; mycontext.SaveChanges(); return 3; } catch (Exception ex) { SystemWarningMsg._lbl_Alert_OutPlanTaskHandler = "错误信息:" + ex; return 2; } } // /// 公共更新 移动单的 状态 /// /// /// public static void UpdatOrderMovementStatus(List wmsOrderMovementDetails, wms_order_movement wmsOrderMovement, ref string errMsg) { var wmsOrderMovementDetailsAll = wmsOrderMovementDetails.Where(x => x.MovementId == wmsOrderMovement.Id && x.IsDelete == false).ToList(); if (wmsOrderMovementDetailsAll?.Count <= 0) { errMsg = $"{wmsOrderMovement.OrderTypeName}类型移动单{wmsOrderMovement.OrderNo}更新状态,未获取到明细!"; } else { int sttaus = (int)OrderStatusEnum.已完成; //汇总已完成的明细 var totalOffShelvesCount = wmsOrderMovementDetailsAll.Count(o => o.OrderStatus == sttaus); //单据有所明细数量 var totalTount = wmsOrderMovementDetailsAll.Count(); if (totalOffShelvesCount == totalTount) //单据完结 { wmsOrderMovement.OrderStatus = (int)OrderStatusEnum.已完成; wmsOrderMovement.OrderStatusName = OrderStatusEnum.已完成.ToString(); //更新时间信息 wmsOrderMovement.UpdateTime = DateTime.Now; wmsOrderMovement.UpdateUserId = 0; wmsOrderMovement.UpdateUserName =FormCC.WcsSysUserName; } } } /// /// 更新库存 /// /// /// /// /// /// /// /// /// /// /// private static void UpdateStockQuan(MyDbContext mycontext, wms_base_business_type wmsBusinessType, wms_task singleTask, wms_order_movement moveOrder, wms_base_container container, wms_base_place toPlace, wms_base_area toArea, ref string errMsg) { //不是 上架,不是下架 不处理库存,仅操作库位转移 string remark = singleTask.BusinessTypeName + "-完成调度任务"; var updateStockList = GetWmsStockQuanList(mycontext, container, ref errMsg); var updateStockViewList = GetWmsStockQuanViewList(mycontext, updateStockList, ref errMsg); foreach (var currentStock in updateStockList) { //再次之前库存的库位已经发生了变更 //上架 if (wmsBusinessType.UpDownShelvesType== (int)UpDownShelvesTypeEnum.上架) { // 待上架的库存,上架操作完成后变成 已上架 if (currentStock.StockStatus == (int)StockStatusEnum.待上架) { currentStock.StockStatus = (int)StockStatusEnum.已上架; currentStock.StockStatusName = StockStatusEnum.已上架.ToString(); } } //下架 else if (wmsBusinessType.UpDownShelvesType == (int)UpDownShelvesTypeEnum.下架) { //盘点上架或 盘点下架 不解冻库存 调差解冻 //下架任务完成不解冻库存,分拣完成后操作解冻 //没有分拣环节的 业务类型需要配置 自动完成单据,这里就解冻 if (wmsBusinessType.DownShelvesIsAutoFinish == true && moveOrder.BusinessType != (int)BusinessTypeEnum.盘点下架) { LockInfo freezeInfo = new LockInfo() { LockReason = "调度任务完成", LockTime = DateTime.Now, LockUser =FormCC.WcsSysUserName, LockStatus = LockStatusEnum.未锁定,// }; StockQuanHelper.UpdateStockLockStatus(currentStock, freezeInfo); } } //在此之前库存的库位已经发生了变更 //更新时间信息 currentStock.UpdateTime = DateTime.Now; currentStock.UpdateUserId = 0; currentStock.UpdateUserName =FormCC.WcsSysUserName; #region 添加调度任务 var currentStockQuanView = updateStockViewList.FirstOrDefault(f => f.SNCode.Equals(currentStock.SNCode)); if (currentStockQuanView == null) { errMsg = $"跟踪码{currentStock.SNCode}没有获取到库存信息"; throw new Exception(errMsg); } wms_record_trans addWmsRecordTrans = CreateRecordTransInfo(moveOrder, currentStockQuanView, singleTask, currentStock, toPlace, toArea, remark); mycontext.wms_record_trans.Add(addWmsRecordTrans); #endregion } } /// /// /// /// /// /// /// /// /// private static wms_record_trans CreateRecordTransInfo(wms_order_movement order, v_wms_stock_quan currentStockQuanView, wms_task task , wms_stock_quan StockModel, wms_base_place toPlace, wms_base_area toArea, string recordTransRemarks) { try { TransferOtherDetail transferOtherDetail = new TransferOtherDetail() { RelationNo = order.OrderNo,//上架单号 RelationNoLineNumber = string.Empty,//上架 关联单行号 无法精准获取 Remarks = recordTransRemarks, }; //源信息 //新增的库存源信息都 TransferDetail sourceDetail = new TransferDetail() { SNCode = currentStockQuanView.SNCode,//源跟踪码 Quantity = currentStockQuanView.Quantity,//源库存数 StockStatus = currentStockQuanView.StockStatus,//源库存状态 StockStatusName = currentStockQuanView.StockStatusName,//源库存状态名称 StockQcStatus = currentStockQuanView.QCStatus,//源质量状态 StockQcStatusName = currentStockQuanView.QCStatusName,//源质量状态名称 ContainerCode = currentStockQuanView.ContainerCode,//源容器编号 ContainerName = currentStockQuanView.ContainerCode,//源容器名称 AreaCode = currentStockQuanView.AreaCode,//源库区编号 AreaName = currentStockQuanView.AreaName,//源库区名称 PlaceCode = currentStockQuanView.PlaceCode,//源库位编号 PlaceName = currentStockQuanView.PlaceName//源库位名称 }; //目标信息 确认质检产生的心得库存 库区、库位 容器跟源库存一样 TransferDetail targetDetail = new TransferDetail() { SNCode = StockModel.SNCode,//目标跟踪码 Quantity = StockModel.Quantity,//目标库存数 StockStatus = StockModel.StockStatus,//目标库存状态 StockStatusName = StockModel.StockStatusName,//目标库存状态名称 StockQcStatus = StockModel.QCStatus,//目标质量状态 StockQcStatusName = StockModel.QCStatusName,//目标质量状态名称 ContainerCode = StockModel.ContainerCode,//目标容器编号 ContainerName = StockModel.ContainerCode,//目标容器名称 AreaCode = toArea.AreaCode,//目标库区编号 AreaName = toArea.AreaName,//目标库区名称 PlaceCode = toPlace.PlaceCode,//目标库位编号 PlaceName = toPlace.PlaceName//目标库位名称 }; wms_record_trans addWmsRecordTrans = LogRecordHelper.CreateWmsRecordTrans(task, currentStockQuanView, sourceDetail, targetDetail, transferOtherDetail); return addWmsRecordTrans; } catch (Exception ex) { throw ex; } } /// /// 更新容器库位关系 /// /// /// /// /// /// private static void UpdaeContainerPlace(MyDbContext mycontext, wms_task singleTask, wms_base_container container, wms_base_place toPlace, ref string errMsg) { var containerPlaceList = mycontext.wms_container_place.Where(f => f.ContainerCode == singleTask.ContainerCode).ToList(); if (containerPlaceList?.Count <= 0) { //新增库位关系绑定到目标容器 wms_container_place addContainerPlace = new wms_container_place() { Id = Yitter.IdGenerator.YitIdHelper.NextId(), PlaceCode = toPlace.PlaceCode, PlaceName = toPlace.PlaceName, PlaceId = toPlace.Id, ContainerName = container.ContainerName, ContainerId = container.Id, ContainerCode = singleTask.ContainerCode }; addContainerPlace.PlaceCode = singleTask.ToPlaceCode; addContainerPlace.PlaceName = toPlace.PlaceName; addContainerPlace.PlaceId = toPlace.Id; addContainerPlace.CreateTime = DateTime.Now; addContainerPlace.CreateUserId = 0; addContainerPlace.CreateUserName =FormCC.WcsSysUserName; //addContainerPlace.UpdateTime = DateTime.Now; //addContainerPlace.UpdateUserId = 0; //addContainerPlace.UpdateUserName =FormCC.WcsSysUserName; mycontext.wms_container_place.Add(addContainerPlace); } else { if (containerPlaceList.Count > 1) { errMsg = $"库位号{singleTask.ToPlaceCode},容器{singleTask.ContainerCode}有{containerPlaceList.Count}条绑定关系"; throw new Exception(errMsg); } else { containerPlaceList.First().PlaceId = toPlace.Id; containerPlaceList.First().PlaceCode = toPlace.PlaceCode; containerPlaceList.First().PlaceName = toPlace.PlaceName; containerPlaceList.First().UpdateTime = DateTime.Now; containerPlaceList.First().UpdateUserId = 0; containerPlaceList.First().UpdateUserName =FormCC.WcsSysUserName; } } } /// /// 获取库存详情信息-查询wms_stock_quan(表) /// /// /// /// /// private static List GetWmsStockQuanList(MyDbContext mycontext,wms_base_container container, ref string errMsg) { var updateStockList = mycontext.wms_stock_quan.Where(f => container.ContainerCode.Equals(f.ContainerCode)).ToList(); if (updateStockList?.Count <= 0) { errMsg = $"容器{container.ContainerCode}库存不存在"; throw new Exception(errMsg); } return updateStockList; } /// /// 获取库存详情信息-查询v_wms_stock_quan(视图) /// /// /// /// /// private static List GetWmsStockQuanViewList(MyDbContext mycontext, List updateStockList, ref string errMsg) { var snCodeList = updateStockList.Select(s => s.SNCode).ToList(); var updateStockViewList = mycontext.v_wms_stock_quan.Where(f => snCodeList.Contains(f.SNCode)).ToList(); if (updateStockViewList?.Count <= 0) { errMsg = $"根据库存跟踪码没有获取到库存详情"; throw new Exception(errMsg); } return updateStockViewList; } } }