using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using iWareSql; using System.Data.Entity.Migrations; using iWareSql.Orm; using iWareCommon; using iWareCommon.Utils; using iWareSql.Entity.ViewMode; using iWareSql.DBModel; using XiGang.Core.Model; using XiGang.Core.Model.PostParamModels.Task; using iWareModel; using iWareCommon.Common.Globle; using iWareModel.EnumType.XiGangPublicCommon; using iWareModel.Entity; namespace iWareSql.DataAccess { public class MainTaskHandler { /// /// 给任务主表赋值物料信息 /// /// /// public static void SetMaterialForMainTask(ref Task_Main mainTask, Base_Material newMaterial) { //物料信息 mainTask.MaterialModel_CodeItemId = newMaterial.MaterialModel_CodeItemId; mainTask.MaterialModel = newMaterial.MaterialModel; mainTask.Supplier = newMaterial.Supplier; mainTask.MaterialType = newMaterial.MaterialType; mainTask.MaterialTypeName = newMaterial.MaterialTypeName; mainTask.Series_CodeItemId = newMaterial.Series_CodeItemId; mainTask.SeriesName = newMaterial.SeriesName; mainTask.CargoType_CodeItemId = newMaterial.CargoType_CodeItemId; mainTask.CargoTypeName = newMaterial.CargoTypeName; mainTask.Qty = newMaterial.Qty; } /// /// 获取目标站点和中间站点,空托盘转运专用 /// /// /// /// /// /// /// /// public static FunRetEntity GetMidToPlaceForAddTransferTask(Base_Station sourcePlace, AddTransferTaskEnum flag, DbModel edm, ref string errMsg, ref Base_Station toPlace, ref Base_Station midPlace, ref Task_Main mainTask) { if (flag == AddTransferTaskEnum.位置1011转移到1014位置) {//空托转移到1014位置 toPlace = StationHandler.GetRgvPlace(edm, ((int)EDevice.拆盘机入口1014).ToString()); } else if (flag == AddTransferTaskEnum.位置1011转移到立体库中) {//空托转移到立体库中 //目标点 寻找空库位 toPlace = StationHandler.FindBestEmptyPlaceForOrdinaryMaterial(edm, mainTask.OrderNo, MaterialTypeEnum.托盘); if (toPlace == null) { return FunRetEntity.Fail("没有找到目标空闲库位"); } //中间点 midPlace = StationHandler.GetRgvPlaceBySrmPlaceForInStore(edm, toPlace); if (midPlace == null) { return FunRetEntity.Fail("没有找到RGV入库位置"); } } else if (flag == AddTransferTaskEnum.位置1009到位置1011) {// 3:1009到1011 var getToPlaceResult = StationHandler.GetTargtStationForAddTransferTask(edm, EDevice.空托缓存1011, ref errMsg, ref toPlace); if (getToPlaceResult.result == false) return getToPlaceResult; } else if (flag == AddTransferTaskEnum.立体库到1014位置) {//4:4:立体库到1014位置 var getToPlaceResult = StationHandler.GetTargtStationForAddTransferTask(edm, EDevice.拆盘机入口1014, ref errMsg, ref toPlace); if (getToPlaceResult.result == false) return getToPlaceResult; //中间点 midPlace = StationHandler.GetRgvPlaceBySrmPlaceForOutStore(edm, sourcePlace); if (midPlace == null) { return FunRetEntity.Fail("没有找到RGV出库位置"); } } else if (flag == AddTransferTaskEnum.位置1014到1020) {// 5:1014到1020 var getToPlaceResult = StationHandler.GetTargtStationForAddTransferTask(edm, EDevice.拆盘机1020, ref errMsg, ref toPlace); if (getToPlaceResult.result == false) return getToPlaceResult; } //统一设置目标站点 //判断站点是否有任务被占用 if (StationHandler.IsAllowUsePlace(edm, toPlace, ref errMsg) == false) { return FunRetEntity.Fail(errMsg); } //判断目标库位是否有库存 var toPlaceStore = StoreHandler.GetV_AllStoreByPlaceId(edm, toPlace.Id); if (toPlaceStore != null) return FunRetEntity.Fail("目标库位" + toPlace.SrmStationCode + toPlace.RgvStationCode + "有库存!"); mainTask.ToPlace = toPlace.Id; if (flag == AddTransferTaskEnum.位置1011转移到立体库中) { mainTask.RealToPlace = toPlace.SrmStationCode; //记录区域 [EditBy shaocx,2022-05-02] var device = BusinessHelper.GetSrmDeviceByPlaceNo(toPlace.SrmStationCode); mainTask.Area = ((int)device).ToString(); } else { mainTask.RealToPlace = toPlace.RgvStationCode; } return FunRetEntity.Success("成功"); } /* /// /// 新增入库任务 /// /// /// /// /// public static FunRetEntity AddInStoreTask(SysUser user, AddMainTaskPostParam param) { FunRetEntity fr = new FunRetEntity(); var errMsg = ""; var remark = "新增入库任务"; try { //数据验证 if (string.IsNullOrEmpty(param.CargoNo)) { return FunRetEntity.Fail("件号不能为空"); } if (string.IsNullOrEmpty(param.SalverCode)) { return FunRetEntity.Fail("托盘号不能为空"); } #region 事务 #endregion using (DbModel edm = new DbModel()) { using (var trans = edm.Database.BeginTransaction()) { try { Task_Main mainTask = new Task_Main(); mainTask.IsVirtual = false;//非虚拟入库 mainTask.TaskNo = TaskNoHelper.GenerateTaskNo("IN"); mainTask.TaskName = "入库"; mainTask.InOutFlag = (int)MainInOutFlagEnum.入库; mainTask.InOutFlagName = MainInOutFlagEnum.入库.ToString(); //起点 var sourcePlace = StationHandler.GetRgvPlace(edm, "RGV01"); if (sourcePlace == null) { return FunRetEntity.Fail("没有找到起点"); } //判断起点是否有任务被占用 if (StationHandler.IsAllowUsePlace(edm, sourcePlace, ref errMsg) == false) { return FunRetEntity.Fail(errMsg); } mainTask.SourcePlace = sourcePlace.Id; mainTask.RealSourcePlace = sourcePlace.RgvStationCode; //目标点 寻找空库位 var toPlace = StationHandler.FindBestEmptyPlaceForOrdinaryMaterial(edm, "", MaterialTypeEnum.一般物料); if (toPlace != null) { mainTask.ToPlace = toPlace.Id; mainTask.RealToPlace = toPlace.SrmStationCode; //记录区域 [EditBy shaocx,2022-05-02] var device = BusinessHelper.GetSrmDeviceByPlaceNo(toPlace.SrmStationCode); mainTask.Area = ((int)device).ToString(); } else { return FunRetEntity.Fail("没有找到目标空闲库位"); } //中间点 var midPlace = StationHandler.GetRgvPlaceBySrmPlaceForInStore(edm, toPlace); if (midPlace == null) { return FunRetEntity.Fail("没有找到RGV入库位置"); } var _taskType = MainTaskTypeEnum.自动入库; mainTask.TaskType = Convert.ToInt32(_taskType); mainTask.TaskTypeName = _taskType.ToString(); var _taskState = MainTaskStatusEnum.已组盘; mainTask.TaskState = Convert.ToInt32(_taskState); mainTask.TaskStateName = _taskState.ToString(); //绑定托盘和站点的关系 //新建物料 Base_Material newMaterial = MaterialHandler.CreateCargoMaterial(edm, "入库时,新建物料", param.CargoNo, param.CargoNo); //判断托盘是否存在,如果存在,就不需要重建,如果不存在,就新建托盘 Base_Salver salver = SalverHandler.GetSalveByCodeForInTask(edm, param.SalverCode, out errMsg); if (!string.IsNullOrEmpty(errMsg)) { return FunRetEntity.Fail(errMsg); } //绑定托盘和物料的关系 Salver_Material_Handler.CreateCvIRelation(edm, user.Name, salver, newMaterial, remark); //绑定托盘和站点的关系 Salver_Station_Handler.CreateCvPRelation(edm, user.Name, salver, sourcePlace, Salver_V_Station_StateEnum.入库绑定, remark); mainTask.CreateTime = mainTask.ModifyTime = mainTask.StartTime = DateTime.Now; mainTask.CreateBy = mainTask.ModifyBy = user.Name; mainTask.CreateId = mainTask.ModifyId = user.ID; mainTask.OperationRemark = "添加"; mainTask.SalverId = salver.Id; mainTask.SalverCode = salver.SalverCode; mainTask.MaterialId = newMaterial.Id; //物料信息 MainTaskHandler.SetMaterialForMainTask(ref mainTask, newMaterial); //序列号和订货号赋值 [Editby shaocx,2022-04-05] mainTask.SerialNumber = newMaterial.SerialNumber; mainTask.OrderNo = newMaterial.OrderNo; string taskSequenceGuid = ""; mainTask.TaskSequence = MainTaskHandler.GenerateTaskSequence(edm, ref taskSequenceGuid);//生成任务序列号 mainTask.TaskSequenceGuid = taskSequenceGuid; edm.Task_Main.Add(mainTask); edm.SaveChanges();//保存一次,此时mainTask的自增ID就有值了 var plcTaskNo = BusinessHelper.CreatePlcTaskIdForSrmTask(); var createTime = DateTime.Now; //创建RGV任务 FunRetEntity fre = PartTaskHandler.CreatePartTask(createTime, plcTaskNo, edm, EDeviceType.RGV, user.Name, 1, DeviceTaskTypeEnum.组盘入库, mainTask, salver, sourcePlace, midPlace, remark); if (fre.result == false) { throw new Exception(fr.resMsg); } //创建堆垛机任务 fre = PartTaskHandler.CreatePartTask(createTime, plcTaskNo, edm, EDeviceType.堆垛机, user.Name, 2, DeviceTaskTypeEnum.组盘入库, mainTask, salver, midPlace, toPlace, remark); if (fre.result == false) { throw new Exception(fr.resMsg); } edm.SaveChanges();//第二次保存 trans.Commit();//事务提交 } catch { trans.Rollback(); throw; } } return FunRetEntity.Success("成功"); } } catch (System.Exception ex) { throw ex; } } //*/ /// /// 新增出库任务 /// /// /// /// /// public static FunRetEntity AddOutStoreTask(Plan_OutTaskDetail outDetailTask, V_Store v_store, DbModel edm, MainTaskTypeEnum _taskType, SysUser user, Base_Station sourcePlace, int myTaskSequence, string myTaskSequenceGuid) { FunRetEntity fr = new FunRetEntity(); var errMsg = ""; var remark = "新增出库任务"; try { Task_Main mainTask = null; try { mainTask = new Task_Main(); mainTask.IsVirtual = false;//非虚拟入库 mainTask.TaskNo = TaskNoHelper.GenerateTaskNo("OUT"); mainTask.TaskName = "出库"; if (outDetailTask != null) { mainTask.Plan_OutTask_Id = outDetailTask.M_PlanId; mainTask.Plan_OutTask_PlanNo = outDetailTask.M_PlanNo; mainTask.Plan_OutTaskDetail_Id = outDetailTask.Id; } mainTask.InOutFlag = (int)MainInOutFlagEnum.出库; mainTask.InOutFlagName = MainInOutFlagEnum.出库.ToString(); //起点 var salver = SalverHandler.GetSalverByPlace(edm, sourcePlace); //中间点 var midPlace = StationHandler.GetRgvPlaceBySrmPlaceForOutStore(edm, sourcePlace); if (midPlace == null) { return FunRetEntity.Fail("没有找到RGV出库位置"); } //目标点 var toPlace = StationHandler.GetRgvPlace(edm, ((int)EDevice.出库口1012).ToString());//出库口 if (toPlace == null) { return FunRetEntity.Fail("没有找到RGV的出库口"); } //注释以下内容,不再校验 1012出库口的锁定状态,防止因为锁定无法并发下发堆垛机任务的情况 【EditBy shaocx,2022-04-29】 /* //判断目标点是否有任务被占用 if (StationHandler.IsAllowUsePlace(edm, toPlace, ref errMsg) == false) { return FunRetEntity.Fail(errMsg); } //*/ mainTask.SourcePlace = sourcePlace.Id; mainTask.RealSourcePlace = sourcePlace.SrmStationCode; //记录区域 [EditBy shaocx,2022-05-02] var device = BusinessHelper.GetSrmDeviceByPlaceNo(sourcePlace.SrmStationCode); mainTask.Area = ((int)device).ToString(); mainTask.ToPlace = toPlace.Id; mainTask.RealToPlace = toPlace.RgvStationCode; mainTask.TaskType = Convert.ToInt32(_taskType); mainTask.TaskTypeName = _taskType.ToString(); var _taskState = MainTaskStatusEnum.待出库; mainTask.TaskState = Convert.ToInt32(_taskState); mainTask.TaskStateName = _taskState.ToString(); mainTask.CreateTime = mainTask.ModifyTime = mainTask.StartTime = DateTime.Now; mainTask.CreateBy = mainTask.ModifyBy = user.Name; mainTask.CreateId = mainTask.ModifyId = user.ID; mainTask.OperationRemark = "添加"; mainTask.SalverId = v_store.SalverId; mainTask.SalverCode = v_store.SalverCode; mainTask.MaterialId = v_store.MaterialId; //物料信息 var newMaterial = edm.Base_Material.Where(x => x.Id == v_store.MaterialId).First(); MainTaskHandler.SetMaterialForMainTask(ref mainTask, newMaterial); //序列号和订货号赋值 [Editby shaocx,2022-04-05] mainTask.SerialNumber = v_store.SerialNumber; mainTask.OrderNo = v_store.OrderNo; if (myTaskSequence > 0) { mainTask.TaskSequence = myTaskSequence; mainTask.TaskSequenceGuid = myTaskSequenceGuid; } else { string taskSequenceGuid = ""; mainTask.TaskSequence = MainTaskHandler.GenerateTaskSequence(edm, ref taskSequenceGuid);//生成任务序列号 mainTask.TaskSequenceGuid = taskSequenceGuid; } edm.Task_Main.Add(mainTask); edm.SaveChanges();//保存一次,此时mainTask的自增ID就有值了 fr.resData = mainTask; //var plcTaskNo = BusinessHelper.CreatePlcTaskIdForSrmTask(); ////创建堆垛机任务 //PartTaskHandler.CreatePartTask(plcTaskNo, edm, EDeviceType.堆垛机, user.Name, 1, DeviceTaskTypeEnum.出库, mainTask, salver, sourcePlace, midPlace, remark); ////创建RGV任务 //PartTaskHandler.CreatePartTask(plcTaskNo, edm, EDeviceType.RGV, user.Name, 2, DeviceTaskTypeEnum.出库, mainTask, salver, midPlace, toPlace, remark); edm.SaveChanges();//第二次保存 } catch { throw; } return FunRetEntity.Success("成功", mainTask); } catch (System.Exception ex) { throw ex; } } /// /// 新增虚拟出库任务【Editby shaocx,2022-07-28】 /// /// /// /// /// public static FunRetEntity AddOutStoreTaskForVirtual(Plan_OutTaskDetail outDetailTask, Wms_VirtualStore v_store, DbModel edm, MainTaskTypeEnum _taskType, SysUser user) { FunRetEntity fr = new FunRetEntity(); var errMsg = ""; var remark = "新增虚拟出库任务"; try { Task_Main mainTask = null; try { mainTask = new Task_Main(); mainTask.IsNeedOnLine = true;//注意:必须是通知MES上线 mainTask.IsVirtual = true;//虚拟出库 mainTask.TaskNo = TaskNoHelper.GenerateTaskNo("OUT"); mainTask.TaskName = "出库"; if (outDetailTask != null) { mainTask.Plan_OutTask_Id = outDetailTask.M_PlanId; mainTask.Plan_OutTask_PlanNo = outDetailTask.M_PlanNo; mainTask.Plan_OutTaskDetail_Id = outDetailTask.Id; } mainTask.InOutFlag = (int)MainInOutFlagEnum.出库; mainTask.InOutFlagName = MainInOutFlagEnum.出库.ToString(); mainTask.TaskType = Convert.ToInt32(_taskType); mainTask.TaskTypeName = _taskType.ToString(); var _taskState = MainTaskStatusEnum.已完成;//注意:状态必须是已完成 mainTask.TaskState = Convert.ToInt32(_taskState); mainTask.TaskStateName = _taskState.ToString(); mainTask.CreateTime = mainTask.ModifyTime = mainTask.StartTime = mainTask.FinishTime = DateTime.Now; mainTask.CreateBy = mainTask.ModifyBy = user.Name; mainTask.CreateId = mainTask.ModifyId = user.ID; mainTask.OperationRemark = "添加"; //mainTask.SalverId = v_store.SalverId; //mainTask.SalverCode = v_store.SalverCode; mainTask.MaterialId = v_store.MaterialId; //物料信息 var newMaterial = edm.Base_Material.Where(x => x.Id == v_store.MaterialId).First(); MainTaskHandler.SetMaterialForMainTask(ref mainTask, newMaterial); //删除物料信息 edm.Base_Material.Remove(newMaterial); //序列号和订货号赋值 [Editby shaocx,2022-04-05] mainTask.SerialNumber = v_store.SerialNumber; mainTask.OrderNo = v_store.OrderNo; mainTask.TaskSequence = 0;//生成任务序列号 edm.Task_Main.Add(mainTask); edm.SaveChanges();//保存一次,此时mainTask的自增ID就有值了 fr.resData = mainTask; //保存出入库记录 //添加至虚拟库出入记录 Wms_VirtualStoreRecord newVirtualStoreRecord = new Wms_VirtualStoreRecord(); newVirtualStoreRecord.InOutFlag = (int)MainInOutFlagEnum.出库; newVirtualStoreRecord.InOutFlagName = "出库"; newVirtualStoreRecord.MaterialId = newMaterial.Id; newVirtualStoreRecord.OperationRemark = "出库任务完成"; newVirtualStoreRecord.CreateId = 0; newVirtualStoreRecord.CreateBy = SysGloble.WCSSystem; newVirtualStoreRecord.CreateTime = DateTime.Now; newVirtualStoreRecord.ModifyBy = SysGloble.WCSSystem; newVirtualStoreRecord.ModifyId = 0; newVirtualStoreRecord.ModifyTime = DateTime.Now; newVirtualStoreRecord.IsDeleted = false; newVirtualStoreRecord.SerialNumber = newMaterial.SerialNumber; newVirtualStoreRecord.MaterialModel = newMaterial.MaterialModel; newVirtualStoreRecord.MaterialModel_CodeItemId = newMaterial.MaterialModel_CodeItemId; newVirtualStoreRecord.CargoType_CodeItemId = newMaterial.CargoType_CodeItemId; newVirtualStoreRecord.CargoTypeName = newMaterial.CargoTypeName; newVirtualStoreRecord.SeriesName = newMaterial.SeriesName; newVirtualStoreRecord.Series_CodeItemId = newMaterial.Series_CodeItemId; newVirtualStoreRecord.Supplier = newMaterial.Supplier; newVirtualStoreRecord.OrderNo = newMaterial.OrderNo; edm.Wms_VirtualStoreRecord.Add(newVirtualStoreRecord); //删除虚拟库存 【Editby shaocx,2022-12-29】 var virtualStore = edm.Wms_VirtualStore.Where(x => x.SerialNumber == newMaterial.SerialNumber).FirstOrDefault(); if (virtualStore != null) { edm.Wms_VirtualStore.Remove(virtualStore); } edm.SaveChanges();//第二次保存 } catch { throw; } return FunRetEntity.Success("成功", mainTask); } catch (System.Exception ex) { throw ex; } } private static readonly object lockObject = new object(); /// /// 获取成最新的任务序列号 /// /// /// public static TaskSequenceEntity GetTaskSequenceEntity(DbModel edm) { TaskSequenceEntity entity = new TaskSequenceEntity(); string taskSequenceGuid = ""; entity.TaskSequence = MainTaskHandler.GenerateTaskSequence(edm, ref taskSequenceGuid); entity.TaskSequenceGuid = taskSequenceGuid; return entity; } /// /// 生成最新的任务序列号 /// /// /// public static int GenerateTaskSequence(DbModel edm, ref string taskSequenceGuid) { lock (lockObject) { taskSequenceGuid = ""; var query1 = (int)MainTaskStatusEnum.已完成; var query2 = (int)MainTaskStatusEnum.已取消; // 排除虚拟的出入库 var taskList = edm.Task_Main.Where(x => x.TaskState != query1 && x.TaskState != query2 && (x.IsVirtual == null || x.IsVirtual == false)).ToList(); if (taskList == null || taskList.Count == 0) { taskSequenceGuid = Guid.NewGuid().ToString();//从1开始,就要重新生成GUID [EditBy shaocx,2022-08-24] return 1; } else { //取最近的那个的GUID值 var first = taskList.OrderByDescending(x => x.Id).First(); taskSequenceGuid = first.TaskSequenceGuid; var task = taskList.Max(x => x.TaskSequence); return task + 1; } } } /// /// 根据主任务ID找到主任务 /// /// /// /// public static Task_Main GetMainTaskById(DbModel context, int mainTaskId) { var task = context.Task_Main.Where(x => x.Id == mainTaskId).FirstOrDefault(); if (task == null) throw new Exception("根据主任务ID" + mainTaskId + "没有找到主任务"); return task; } /// /// 更新主任务的状态 /// /// /// /// /// public static void UpdateTaskStatus(DbModel context, int mainTaskId, MainTaskStatusEnum changeTaskStatus, string remark) { Task_Main task = GetMainTaskById(context, mainTaskId); task.TaskState = (int)changeTaskStatus; task.TaskStateName = changeTaskStatus.ToString(); task.ModifyBy = SysGloble.WCSSystem; task.ModifyTime = DateTime.Now; task.OperationRemark = remark; if (changeTaskStatus == MainTaskStatusEnum.已完成) { task.FinishTime = DateTime.Now;//记录完成时间 } } } }