using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using yunneiWCS.Common; using yunneiWCS.data; using yunneiWCS.DataAccess; using yunneiWCS.EnumDefine; using yunneiWCS.EnumDefine.Device; using yunneiWCS.EnumDefine.InStockOrder; using yunneiWCS.ORM; using yunneiWCS.SystemInteraction.tianyong; namespace yunneiWCS.ExtendFunction { /// /// 增补创建的扩展方法 【EditBy shaocx,2022-02-05】 /// public class MyExtend { public static string HandlerNoIssuedTaskFor旁路工位缸体空托或余料回库(dbmodel mod, string convPlace, task item, string[] agvSendStatus) { //注意:这个middlePlace是工人自己选的! if (convPlace != "") { SystemWarningMsg.Thread_SendTask_NoIssue_GT_ErrMsg = DateTime.Now.ToString("dd日HH:mm:ss") + "更新状态为已下发成功,任务ID:" + item.taskId; item.middlePlace = convPlace; //item.taskStatus = 3; item.taskStatus = (int)taskStatus.已下发; item.remark = "已下发"; item.remark = "更新状态为已下发成功"; position unlockPosition = mod.position.FirstOrDefault(x => x.positionName == convPlace); if (unlockPosition != null) { //unlockPosition.isLock = true; PositionHandler.Lock(true, unlockPosition, "处理未下发的任务(缸体)", SysGloble.WCSNAME, item); } //起点库位解锁、设置无货 【EditBy shaocx,2022-03-23】 position _sourcePlace = mod.position.FirstOrDefault(x => x.positionName == item.sourcePlace); PositionHandler.LockAndFree(false, false, _sourcePlace, "处理未下发的任务(缸体),修改起点", SysGloble.WCSNAME, item); int saveRes = mod.SaveChanges(); #region 检验保存是否成功 for (int i = 0; i < 4; i++) { if (saveRes < 1) { saveRes = mod.SaveChanges(); } else { break; } } if (saveRes < 1) { WZ.Useful.Commons.LogTextHelper.WriteLine("Form1", "sendTask", "数据库保存失败! 任务id:" + item.taskId); return "数据库保存失败! 任务id:" + item.taskId; } #endregion } else { agvSendStatus[0] = DateTime.Now.ToString("dd日HH:mm:ss") + "更新状态为已下发失败,输送线都被占用,任务ID:" + item.taskId; //保存失败信息到任务表中 【EditBy shaocx,2022-03-16】 item.remark = "更新状态为已下发失败,输送线都被占用"; mod.SaveChanges(); return DateTime.Now.ToString("dd日HH:mm:ss") + "更新状态为已下发失败,输送线都被占用,任务ID:" + item.taskId; } return "任务处理成功"; } /// /// 处理未下发的直达上线点的任务 /// /// /// /// /// /// /// 错误消息 public static string HandleTaskForNoIssuedForDirectOnLinePoint(dbmodel mod, List agvs, task item, string[] agvSendStatus ) { var errMsg_1 = "处理未下发的任务(HandleTaskForNoIssued):"; bool isReadAgv = false; taskType _taskType = (taskType)Enum.Parse(typeof(taskType), item.taskType.ToString()); if (_taskType == taskType.缸体下线直接去上线点) { isReadAgv = MyExtendHelper.ValidateAgvIsFree(item, TaskAreaEnum.缸体侧, agvs, agvSendStatus); } else if (_taskType == taskType.缸盖下线直接去上线点) { isReadAgv = MyExtendHelper.ValidateAgvIsFree(item, TaskAreaEnum.缸盖侧, agvs, agvSendStatus); } var errMsg = ""; _HandleTaskForNoIssuedForDirectOnLinePoint(isReadAgv, _taskType, mod, agvs, item, agvSendStatus, ref errMsg); if (!string.IsNullOrEmpty(errMsg)) return errMsg_1 + errMsg; return errMsg; } /// /// 处理未下发的直达上线点的任务 /// /// /// /// /// /// /// /// private static void _HandleTaskForNoIssuedForDirectOnLinePoint(bool isReadAgv, taskType _taskType, dbmodel mod, List agvs, task item, string[] agvSendStatus, ref string errMsg ) { #region 发送rgv任务 if (isReadAgv) { //起点,起点在数据库中没有定义,因此不需要使用 //目标点 position to_positionStation = mod.position.FirstOrDefault(x => x.positionName == item.toPlace); if (to_positionStation == null) { errMsg = "未找到目标库位" + item.toPlace; WZ.Useful.Commons.LogTextHelper.WriteLine("MyExtend", "_HandleTaskForNoIssued", errMsg); return; } #region 验证上线点是否有库存 var to_Stock = MyExtendHelper.GetProductStockById(mod, to_positionStation.positionId); if (to_Stock != null) { errMsg = "发现目标库位有库存,不允许发送agv任务到该上线点,上线点:" + item.toPlace; WZ.Useful.Commons.LogTextHelper.WriteLine("MyExtend", "_HandleTaskForNoIssued", errMsg); return; } #endregion #region 发送AGV任务 并清空库存 string res = "失败"; if (!MyExtendHelper.IsAllowSimulatorHandle(item)) {//生产环境 res = baseData.sendAgvTask(item, item.taskId, item.sourcePlace, item.toPlace, 1); } else {//虚拟模式或强制完成 res = ""; } string tasktype = _taskType.ToString(); if (res == "") { #region 清空库存更新状态 item.taskStatus = (int)taskStatus.完成;//注意:一定是任务完成,发送给AGV任务后,直接修改为任务完成,将库存转移到天永机器人那边的上线点 item.remark = "完成"; mod.SaveChanges(); agvSendStatus[0] = DateTime.Now.ToString("dd日HH:mm:ss") + "发送成功,任务ID:" + item.taskId; #region 增加库存 inStockOrder finishCode = mod.inStockOrder.FirstOrDefault(x => x.orderCode == item.createListCode); if (finishCode == null) { errMsg = "没有找到入库单! 单号:" + item.createListCode; WZ.Useful.Commons.LogTextHelper.WriteLine("MyExtend", "_HandleTaskForNoIssued", errMsg); return; } material mat = mod.material.FirstOrDefault(x => x.materialCode == finishCode.productCode); productStock stock = new productStock(); stock.positionId = to_positionStation.positionId; stock.createTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); stock.materialId = mat != null ? mat.materialId : 0; stock.supplier = finishCode.supplier;//供应商 stock.quantity = finishCode.quantity; stock.updateTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); stock.taskType = (int)_taskType; // stock.productCode = mat != null ? "" : finishCode.productCode;//没有维护物料数据就把数据放到 stock.containerCode = finishCode.containerCode; mod.productStock.Add(stock); var orderList = mod.inStockOrderList.Where(x => x.orderCodeId == finishCode.orderCodeId).ToList(); foreach (var myitem in orderList) { productStockList stockList = new productStockList(); stockList.stockId = to_positionStation.positionId; stockList.productCode = myitem.productCode; stockList.productName = myitem.productName; stockList.serialNumber = myitem.serialNumber; mod.productStockList.Add(stockList); } // to_positionStation.isfree = true; PositionHandler.Free(true, to_positionStation, "处理未下发的直达上线点的任务", SysGloble.WCSNAME, item); OutInStockRecordHandler.AddOutInStockRecord(mod, OutInFlag.入库, item.sourcePlace, "Virtual", item, "入库类型的任务"); OutInStockRecordHandler.AddOutInStockRecord(mod, OutInFlag.出库, "Virtual", item.toPlace, item, "出库类型的任务"); #endregion #endregion } else { //保存失败信息到任务表中 【EditBy shaocx,2022-03-16】 item.remark = "发送AGV任务失败:" + res; mod.SaveChanges(); agvSendStatus[0] = DateTime.Now.ToString("dd日HH:mm:ss") + "发送AGV任务失败:" + res + ",任务ID:" + item.taskId; errMsg = tasktype + "发送RGV任务失败,接口返回:" + res; WZ.Useful.Commons.LogTextHelper.WriteLine("MyExtend", "_HandleTaskForNoIssued", errMsg); } #endregion if (_taskType == taskType.缸盖下线直接去上线点) {//给天永发信号 TianYongSystem.UpdateStoreByTaskID(mod, item, item.toPlace, (int)item.taskId, "缸盖下线直接去上线点,进入天永站点"); } int saveRes = mod.SaveChanges(); #region 验证是否保存成功 if (saveRes < 1) { errMsg = "数据库保存失败! 任务id:" + item.taskId; WZ.Useful.Commons.LogTextHelper.WriteLine("MyExtend", "_HandleTaskForNoIssued", errMsg); } #endregion } else { errMsg = agvSendStatus[0] = DateTime.Now.ToString("dd日HH:mm:ss") + "没发送任务-ARV繁忙,任务ID:" + item.taskId + ",起点:" + item.sourcePlace + ",目标点:" + item.toPlace; } #endregion } /// /// 堆垛机出库任务,发送任务给设备 /// /// /// /// /// public static bool HandleTaskForutStoreBySrm(dbmodel mod, task _task, ref string errMsg) { taskType _taskType = (taskType)Enum.Parse(typeof(taskType), _task.taskType.ToString()); #region 发送堆垛机任务 if (!MyExtendHelper.IsAllowSimulatorHandle(_task)) { //if (srm.mode == "自动" && srm.Alarm_info == "无故障" && srm.state == "待机") if (MyExtendHelper.IsAllowSendNewTaskToSrm()) { baseData.sendSrmTask(_task, _task.taskId, _task.sourcePlace, _task.toPlace, 1); } else { errMsg = "堆垛机目前状态不满足下发任务给他,不能下发任务" + _task.taskId; return false; } } position toPlace = mod.position.FirstOrDefault(x => x.positionName == _task.toPlace); if (toPlace != null) { //toPlace.isLock = true; PositionHandler.Lock(true, toPlace, _taskType.ToString() + "任务,发送堆垛机任务时,锁定该库位", SysGloble.WCSNAME, _task); } position sorucePlace = mod.position.FirstOrDefault(x => x.positionName == _task.sourcePlace); if (sorucePlace != null) { //sorucePlace.isLock = true; PositionHandler.Lock(true, sorucePlace, _taskType.ToString() + "任务,发送堆垛机任务时,锁定该库位", SysGloble.WCSNAME, _task); } //保存任务记录 _task.taskStatus = (int)taskStatus.已下发; _task.remark = "已下发"; #endregion int saveRes = mod.SaveChanges(); if (saveRes < 1) { errMsg = "数据库保存失败! 任务id:" + _task.taskId; WZ.Useful.Commons.LogTextHelper.WriteLine("Form1", "HandleTaskForutStoreBySrm", "数据库保存失败! 任务id:" + _task.taskId); return false; } else { return true; } } /// /// 人工入库任务,发送任务给设备 /// /// /// /// /// public static bool HandleTaskForHandInStore(dbmodel mod, task _task, ref string errMsg) { #region 发送堆垛机任务 if (!MyExtendHelper.IsAllowSimulatorHandle(_task)) { //if (srm.mode == "自动" && srm.Alarm_info == "无故障" && srm.state == "待机") if (MyExtendHelper.IsAllowSendNewTaskToSrm()) { #region 发送输送线放料完成信号任务 TransEnum _TransEnum = MyExtendHelper.GetTransByPlace(_task.sourcePlace); TransService.LoadMaterialConfirm(Convert.ToInt32(_TransEnum) - 1); #endregion baseData.sendSrmTask(_task, _task.taskId, _task.sourcePlace, _task.toPlace, 1); } else { errMsg = "堆垛机目前状态不满足下发任务给他,不能下发任务" + _task.taskId; return false; } } position toPlace = mod.position.FirstOrDefault(x => x.positionName == _task.toPlace); if (toPlace != null) { //toPlace.isLock = true; PositionHandler.Lock(true, toPlace, "人工入库任务,发送堆垛机任务时,锁定该库位", SysGloble.WCSNAME, _task); } position sorucePlace = mod.position.FirstOrDefault(x => x.positionName == _task.sourcePlace); if (sorucePlace != null) { //sorucePlace.isLock = true; PositionHandler.Lock(true, sorucePlace, "人工入库任务,发送堆垛机任务时,锁定该库位", SysGloble.WCSNAME, _task); } //保存任务记录 _task.taskStatus = (int)taskStatus.已下发; _task.remark = "已下发"; #endregion int saveRes = mod.SaveChanges(); if (saveRes < 1) { errMsg = "数据库保存失败! 任务id:" + _task.taskId; WZ.Useful.Commons.LogTextHelper.WriteLine("Form1", "HandleTaskForHandInStore", "数据库保存失败! 任务id:" + _task.taskId); return false; } else { return true; } } /// /// 更新库存时间 /// /// /// /// public static void UpdateProductStock_updateTime(dbmodel mod, position toPlace, string remark) { //更新库存的时间 [EditBy shaocx,2022-05-07] productStock stock = mod.productStock.Where(x => x.positionId == toPlace.positionId).FirstOrDefault(); if (stock == null) { throw new Exception(remark + ",更新库存时间时未找到" + toPlace.positionName + "的库存"); } stock.updateTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); } #region 堆垛机任务完成后的数据处理 /// /// 堆垛机任务完成后的数据处理 /// /// /// /// /// public static bool HandleSrmfinishConfirm(dbmodel mod, task finishTask, ref string errMsg) { long taskID = finishTask.taskId; //事务处理 using (var trans = mod.Database.BeginTransaction()) { try { position sourcePlace, toPlace = null; #region 库存数据处理 taskType currentTaskType = (taskType)Enum.Parse(typeof(taskType), finishTask.taskType.ToString()); switch (currentTaskType) { case taskType.空托回库: case taskType.空托下线入库: case taskType.空托手动入库: case taskType.余料回库: case taskType.旁路工位缸体空托回库: case taskType.旁路工位缸体余料回库: #region 空托回库、余料回库 toPlace = mod.position.FirstOrDefault(x => x.positionName == finishTask.toPlace); sourcePlace = mod.position.FirstOrDefault(x => x.positionName == finishTask.sourcePlace); if (sourcePlace != null) { //fromPos.isfree = false; //fromPos.isLock = false; PositionHandler.LockAndFree(false, false, sourcePlace, "堆垛机任务完成后的数据处理", SysGloble.WCSNAME, finishTask); } if (toPlace != null) { bool ishaveGG = SysGloble.GG_OnLine_Stations.Contains(finishTask.sourcePlace.Trim()); #region 空托盘回库或余料回库 //if (finishTask.taskName == "缸体空托回库" || finishTask.taskName == "缸盖空托回库")//如果是 if (finishTask.taskType == (int)taskType.空托回库 || finishTask.taskType == (int)taskType.旁路工位缸体空托回库)//如果是 { productStock stock = new productStock(); stock.positionId = toPlace.positionId; stock.createTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); stock.materialId = ishaveGG == true ? 3 : 4;//缸体4,缸盖3 固定不变的 stock.quantity = 0;//默认3个 stock.status = 1; stock.taskType = 6;//空托盘回库 stock.updateTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); stock.containerCode = finishTask.containerCode;//增加托盘号赋值 mod.productStock.Add(stock); toPlace.positionType = (byte)positionType.空托盘; } else if (finishTask.taskType == (int)taskType.空托下线入库 || finishTask.taskType == (int)taskType.空托手动入库 )//如果是 { productStock stock = new productStock(); stock.positionId = toPlace.positionId; stock.createTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); stock.materialId = finishTask.materialCode == "GG-KTP" ? 3 : 4;//缸体4,缸盖3 固定不变的 stock.quantity = 0;//默认3个 stock.status = 1; stock.taskType = 6;//空托盘回库 stock.updateTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); stock.containerCode = finishTask.containerCode;//增加托盘号赋值 mod.productStock.Add(stock); toPlace.positionType = (byte)positionType.空托盘; } else { toPlace.positionType = (byte)positionType.余料回库; //更新库存的时间 [EditBy shaocx,2022-05-07] UpdateProductStock_updateTime(mod, toPlace, "堆垛机任务完成后"); //if (finishTask.taskName == "缸体余料回库") //{ // pos.positionType = (byte)positionType.缸体; //} //else //{ // pos.positionType = (byte)positionType.缸盖; //} } //pos.isfree = true; //pos.isLock = false; PositionHandler.LockAndFree(false, true, toPlace, "堆垛机任务完成后的数据处理", SysGloble.WCSNAME, finishTask); UnLockConverPlaceForInStore(mod, finishTask, "堆垛机任务完成后的数据处理,任务是入库类型,解除输送线的锁定和有货状态"); //finishTask.taskStatus = 5; finishTask.taskStatus = (int)taskStatus.完成; finishTask.remark = "完成"; finishTask.finishTime = DateTime.Now; #endregion } else { throw new Exception("入库任务,目标站点找不到,toPlace:" + finishTask.toPlace); } OutInStockRecordHandler.AddOutInStockRecord(mod, OutInFlag.入库, finishTask.sourcePlace, finishTask.toPlace, finishTask, "入库类型的任务"); #endregion break; case taskType.缸体下线: case taskType.缸盖下线: case taskType.手动入库: #region 缸体下线、缸盖下线、手动入库 inStockOrder finishCode = mod.inStockOrder.FirstOrDefault(x => x.orderCode == finishTask.createListCode); if (finishCode != null) { if (finishTask.taskType == (int)taskType.手动入库) {//释放输送线锁定状态 [EditBy shaocx,2022-03-21] position fromPos = mod.position.FirstOrDefault(x => x.positionName == finishTask.sourcePlace);//输送线地址 if (fromPos != null) { //fromPos.isfree = false;//释放输送线地址 //fromPos.isLock = false; PositionHandler.LockAndFree(false, false, fromPos, "手动入库,堆垛机任务完成后的数据处理", SysGloble.WCSNAME, finishTask); } } UnLockConverPlaceForInStore(mod, finishTask, "堆垛机任务完成后的数据处理,任务是入库类型,解除输送线的锁定和有货状态"); #region 缸体缸盖下线数据处理 //finishCode.status = 4; finishCode.status = (int)InStockOrderStatus.完成; //finishTask.taskStatus = 5; finishTask.taskStatus = (int)taskStatus.完成; finishTask.remark = "完成"; finishTask.finishTime = DateTime.Now; position pos = mod.position.FirstOrDefault(x => x.positionName == finishTask.toPlace); var orderList = mod.inStockOrderList.Where(x => x.orderCodeId == finishCode.orderCodeId).ToList(); material mat = mod.material.FirstOrDefault(x => x.materialCode == finishCode.productCode); long materialId = 0; if (mat == null)//不存在就创建一个物料 { material newMaterial = new material(); newMaterial.materialCode = finishCode.productCode; newMaterial.materialName = "待更新"; newMaterial.materialType = finishCode.orderCode.Trim().Substring(0, 2) == "GT" ? (int)materialType.缸体 : (int)materialType.缸盖; newMaterial.createTime = DateTime.Now; newMaterial.creator = "WCS"; newMaterial.version = ""; mod.material.Add(newMaterial); int resAdd = mod.SaveChanges();//必须先SaveChanges,否则 newMaterial.materialId无法赋值 if (resAdd > 0) { materialId = newMaterial.materialId; } } if (pos != null && orderList.Count > 0) { productStock stock = new productStock(); stock.positionId = pos.positionId; stock.createTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); stock.materialId = mat != null ? mat.materialId : materialId; stock.supplier = finishCode.supplier;//供应商 stock.quantity = finishCode.quantity; stock.updateTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); stock.taskType = finishTask.taskType; // stock.productCode = mat != null ? "" : finishCode.productCode;//没有维护物料数据就把数据放到 stock.containerCode = finishCode.containerCode; mod.productStock.Add(stock); pos.positionType = finishCode.orderCode.Trim().Substring(0, 2) == "GT" ? (byte)positionType.缸体 : (byte)positionType.缸盖;//用表单首2字母判断是缸体还是缸盖 //pos.isfree = true; //pos.isLock = false; PositionHandler.LockAndFree(false, true, pos, "堆垛机任务完成后的数据处理", SysGloble.WCSNAME, finishTask); int res = mod.SaveChanges();//必须先SaveChanges,否则 newMaterial.materialId无法赋值 if (res > 0) { foreach (var item in orderList) { productStockList stockList = new productStockList(); stockList.stockId = pos.positionId; stockList.productCode = item.productCode; stockList.productName = item.productName; stockList.serialNumber = item.serialNumber; mod.productStockList.Add(stockList); } } } else { WZ.Useful.Commons.LogTextHelper.WriteLine("Form1", "finishConfirm", "任务ID:" + taskID + "找库位或者找物料失败"); errMsg = "任务ID:" + taskID + "找库位或者找物料失败"; throw new Exception(errMsg); } #endregion OutInStockRecordHandler.AddOutInStockRecord(mod, OutInFlag.入库, finishTask.sourcePlace, finishTask.toPlace, finishTask, "入库类型的任务"); } else { WZ.Useful.Commons.LogTextHelper.WriteLine("Form1", "finishConfirm", "任务ID:" + taskID + "找不到出库单"); finishTask.taskStatus = 6;//6是异常 finishTask.remark = "异常"; } #endregion break; case taskType.手动出库://增加手动出库的分支 【EditBy shaocx,2022-03-02】 case taskType.空托人工出库: #region 手动出库 //库存清除 sourcePlace = mod.position.FirstOrDefault(x => x.positionName == finishTask.sourcePlace); toPlace = mod.position.FirstOrDefault(x => x.positionName == finishTask.toPlace); //sourcePlace.isfree = true; //sourcePlace.isLock = false; PositionHandler.LockAndFree(false, true, sourcePlace, "堆垛机任务完成后的数据处理", SysGloble.WCSNAME, finishTask); //toPlace.isfree = true; //toPlace.isLock = false; PositionHandler.LockAndFree(false, true, toPlace, "堆垛机任务完成后的数据处理", SysGloble.WCSNAME, finishTask); finishTask.taskStatus = (int)taskStatus.完成; finishTask.remark = "完成"; finishTask.finishTime = DateTime.Now; var result = deleteProduct(false, "sys", mod, finishTask.sourcePlace, finishTask, ref errMsg);//删除库存 if (result == false) throw new Exception(errMsg); OutInStockRecordHandler.AddOutInStockRecord(mod, OutInFlag.出库, finishTask.sourcePlace, finishTask.toPlace, finishTask, "出库类型的任务"); #endregion break; case taskType.缸体上线去旁路工位://增加 缸体上线去旁路工位 的分支 【EditBy shaocx,2022-04-24】 _HandleTaskFor缸体上线去旁路工位WhenSrmTaskFinish(currentTaskType, mod, finishTask, ref errMsg); break; case taskType.出库分拣://增加出库分拣的分支 【EditBy shaocx,2022-03-02】 #region 出库分拣 //1、如果任务状态为 已下发,表示是堆垛机出库任务,此时只更新任务状态=待分拣 //2、待分拣状态-》分拣完成状态,是在WMS中由用户分拣点击时更改的。 //3、分拣完成状态-》分拣完成后下发设备任务状态,是在WCS中线程处理任务【分拣完成】中更改的。 //4、如果任务状态为 分拣完成后下发设备任务,表示是堆垛机入库任务,此时要将解锁库位,并且状态改为 已完成 if (finishTask.taskStatus == (int)taskStatus.已下发) { finishTask.taskStatus = (int)taskStatus.待分拣; finishTask.remark = "待分拣"; } else if (finishTask.taskStatus == (int)taskStatus.分拣完成后下发设备任务) { finishTask.taskStatus = (int)taskStatus.完成; finishTask.remark = "完成"; finishTask.finishTime = DateTime.Now; //解锁库位 sourcePlace = mod.position.FirstOrDefault(x => x.positionName == finishTask.sourcePlace); toPlace = mod.position.FirstOrDefault(x => x.positionName == finishTask.toPlace); //sourcePlace.isLock = false; PositionHandler.Lock(false, sourcePlace, "堆垛机任务完成后的数据处理", SysGloble.WCSNAME, finishTask); //toPlace.isfree = true; //toPlace.isLock = false; PositionHandler.LockAndFree(false, true, toPlace, "堆垛机任务完成后的数据处理", SysGloble.WCSNAME, finishTask); } else { errMsg = "任务类型是出库分拣时,堆垛机完成前,任务状态只能是 分拣完成后下发设备任务或已下发,不能是:" + finishTask.taskStatus; throw new Exception(errMsg); } #endregion break; case taskType.缸盖上线: case taskType.缸体上线: //解除输送点的锁定 [EditBy shaocx,2022-03-23] if (!string.IsNullOrEmpty(finishTask.middlePlace)) { var convPlace = mod.position.FirstOrDefault(x => x.positionName == finishTask.middlePlace); PositionHandler.Lock(false, convPlace, "缸盖上线,缸体上线,堆垛机任务完成后的数据处理,解除输送点的锁定", SysGloble.WCSNAME, finishTask); } else { errMsg = "缸盖上线/缸体上线任务,中转位为空,暂不处理"; return false; } break; default://其他,出库确认 //finishTask.taskStatus = 3; finishTask.taskStatus = (int)taskStatus.已下发; finishTask.remark = "已下发"; break; } #endregion int saveRes = mod.SaveChanges(); if (saveRes < 1) { errMsg = "更新条数为" + saveRes; throw new Exception(errMsg); } trans.Commit(); } catch (Exception) { trans.Rollback(); throw; } finally { } } return true; } #region 堆垛机任务完成后,对任务 缸体上线到旁路工位的处理 /// /// 堆垛机任务完成后,对任务 缸体上线到旁路工位的处理 /// /// /// /// /// private static void _HandleTaskFor缸体上线去旁路工位WhenSrmTaskFinish(taskType _taskType, dbmodel mod, task item, ref string errMsg ) { //起点 position source_positionStation = mod.position.FirstOrDefault(x => x.positionName == item.sourcePlace); if (source_positionStation == null) { errMsg = "未找到起点库位" + item.sourcePlace; WZ.Useful.Commons.LogTextHelper.WriteLine("MyExtend", "_HandleTaskFor缸体上线去旁路工位", errMsg); return; } //中间点 position mid_positionStation = mod.position.FirstOrDefault(x => x.positionName == item.middlePlace); if (mid_positionStation == null) { errMsg = "未找到输送线库位" + item.middlePlace; WZ.Useful.Commons.LogTextHelper.WriteLine("MyExtend", "_HandleTaskFor缸体上线去旁路工位", errMsg); return; } //目标点 position to_positionStation = mod.position.FirstOrDefault(x => x.positionName == item.toPlace); if (to_positionStation == null) { errMsg = "未找到目标库位" + item.toPlace; WZ.Useful.Commons.LogTextHelper.WriteLine("MyExtend", "_HandleTaskFor缸体上线去旁路工位", errMsg); return; } #region 验证上线点是否有库存 var to_Stock = MyExtendHelper.GetProductStockById(mod, to_positionStation.positionId); if (to_Stock != null) { errMsg = "发现目标库位有库存,不允许结束任务到该上线点,上线点:" + item.toPlace; WZ.Useful.Commons.LogTextHelper.WriteLine("MyExtend", "_HandleTaskFor缸体上线去旁路工位", errMsg); return; } #endregion item.taskStatus = (int)taskStatus.完成;//注意:一定是任务完成,发送给AGV任务后,直接修改为任务完成,将库存转移到天永机器人那边的上线点 item.remark = "完成"; #region 库存转移 productStock stock = mod.productStock.FirstOrDefault(x => x.positionId == source_positionStation.positionId); if (stock != null) { stock.positionId = to_positionStation.positionId; stock.updateTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); //positionStation.isfree = true; PositionHandler.Free(true, to_positionStation, "处理任务是下发中,任务类型是 呼叫空托And缸体上线And缸盖上线的库存管理", SysGloble.WCSNAME, item); } else { errMsg = "没有找到库存! 库位号:" + item.sourcePlace; WZ.Useful.Commons.LogTextHelper.WriteLine("MyExtend", "_HandleTaskFor缸体上线去旁路工位", errMsg); return; } List stocklist = mod.productStockList.Where(x => x.stockId == source_positionStation.positionId).ToList(); if (stocklist.Count > 0) { foreach (var itemList in stocklist) { itemList.stockId = to_positionStation.positionId; } } else { errMsg = "没有找到库存明细! 库位号:" + item.sourcePlace; WZ.Useful.Commons.LogTextHelper.WriteLine("MyExtend", "_HandleTaskFor缸体上线去旁路工位", errMsg); return; } #endregion //站点释放 PositionHandler.LockAndFree(false, false, source_positionStation, "处理 缸体上线到旁路工位的处理 的任务", SysGloble.WCSNAME, item); PositionHandler.LockAndFree(false, false, mid_positionStation, "处理 缸体上线到旁路工位的处理 的任务", SysGloble.WCSNAME, item); //设置目标位有货 PositionHandler.Free(true, to_positionStation, "处理 缸体上线到旁路工位的处理 的任务", SysGloble.WCSNAME, item); OutInStockRecordHandler.AddOutInStockRecord(mod, OutInFlag.出库, item.sourcePlace, item.toPlace, item, "出库类型的任务"); //通知天永,给天永发信号 TianYongSystem.UpdateStoreByTaskID(mod, item, item.toPlace, (int)item.taskId, "缸体上线到旁路工位,进入天永站点"); //注释掉SaveChanges,因为上层就SaveChanges了 【Editby shaocx,2022-05-04】 //int saveRes = mod.SaveChanges(); //#region 验证是否保存成功 //if (saveRes < 1) //{ // errMsg = "数据库保存失败! 任务id:" + item.taskId; // WZ.Useful.Commons.LogTextHelper.WriteLine("MyExtend", "_HandleTaskFor缸体上线去旁路工位", errMsg); //} //else //{ //} //#endregion } #endregion /// /// 堆垛机任务完成后,对入库类型的任务,解除输送线的锁定 /// /// /// /// private static void UnLockConverPlaceForInStore(dbmodel mod, task finishTask, string remark) { //解除输送点的锁定 [EditBy shaocx,2022-03-23] if (!string.IsNullOrEmpty(finishTask.middlePlace)) { var convPlace = mod.position.FirstOrDefault(x => x.positionName == finishTask.middlePlace); PositionHandler.LockAndFree(false, false, convPlace, remark, SysGloble.WCSNAME, finishTask); } } #endregion /// /// 处理新建的出库表单[缸体上线、缸盖上线] /// /// /// /// /// public static bool DoHandleOutStockList(dbmodel mod, task _task, ref string errMsg) { try { string sourcePlace = ""; VproductStock outStock = null; //根据配置供应商查询 var supplier = BasicDataSetHandler.GetBasicDataSetForSupplier(); outStock = FindOutStockFromSrm(mod, supplier, _task); if (outStock == null) { _task.isQueLiao = 1; _task.queLiaoSupplier = supplier; errMsg = "库存无此物料," + (string.IsNullOrEmpty(supplier) ? "不按供应商查询" : "按照供应商" + supplier + "查询"); //更新到数据库中 _task.remark = errMsg; mod.SaveChanges(); return false; } _task.isQueLiao = 0; _task.queLiaoSupplier = supplier; sourcePlace = outStock.positionName; _task.sourcePlace = sourcePlace; var changeStatus = taskStatus.未下发; _task.taskStatus = (int)changeStatus; _task.remark = "未下发"; var obj_sourcePlace = mod.position.Where(x => x.positionId == outStock.positionId).FirstOrDefault(); //锁定起点 PositionHandler.Lock(true, obj_sourcePlace, _task.taskName + ",寻找到库存,锁定库位", "调度", _task); //更新任务表的信息 _task.materialName = outStock.materialName; _task.supplier = outStock.supplier;//供应商 【EditBy shaocx,2022-01-15】 _task.containerCode = outStock.containerCode;//托盘号 【EditBy shaocx,2022-01-15】 _task.quantity = outStock.quantity; //更新出库表单的信息 var outStockList = mod.outStockList.Where(x => x.outStockOrder == _task.createListCode).FirstOrDefault(); if (outStockList != null) { outStockList.materialName = outStock.materialName; outStockList.quantity = outStock.quantity; outStockList.version = outStock.version;//机型 【EditBy shaocx,2022-01-18】 } int saveRes = mod.SaveChanges(); if (saveRes < 1) { errMsg = "更新条数为" + saveRes; return false; } return true; } catch (Exception) { throw; } finally { } } /// /// 获取要出库的立体库库存 /// /// /// /// /// private static VproductStock FindOutStockFromSrm(dbmodel mod, string supplier, task _task) { try { List outStockList = null; if (string.IsNullOrEmpty(supplier)) { outStockList = mod.VproductStock.OrderBy(x => x.createTime).Where(x => x.materialCode == _task.materialCode.Trim() && x.isLock == false).ToList(); } else { outStockList = mod.VproductStock.OrderBy(x => x.createTime).Where(x => x.supplier == supplier && x.materialCode == _task.materialCode.Trim() && x.isLock == false).ToList(); } //注意:要删选掉那些不是立体库位的站点 【EditBy shaocx,2022-05-04】 if (outStockList != null && outStockList.Count > 0) { outStockList = outStockList.Where(x => !SysGloble.TransStations.Contains(x.positionName) && !SysGloble.GG_OffLine_Stations.Contains(x.positionName) && !SysGloble.GT_OffLine_Stations.Contains(x.positionName) && !SysGloble.GG_OnLine_Stations.Contains(x.positionName) && !SysGloble.GT_OnLine_Stations.Contains(x.positionName) ).ToList(); } if (outStockList != null && outStockList.Count > 0) { foreach (var item in outStockList) { List stockSerialNumber = mod.productStockList.Where(x => x.stockId == item.positionId).ToList(); if (stockSerialNumber.Count < 1) { continue; } return item; } } else { return null; } } catch (Exception) { throw; } return null; } /// /// 根据库位删除数据 /// /// 是否人工删除 /// /// /// /// public static bool deleteProduct(bool isPerson, string user, dbmodel mod, string positionName, task _task, ref string res) { res = ""; string[] stations = { "GTU1", "GTU2", "GTU3", "GGU1", "GGU2", "GGU3" }; try { VproductStock delteData = mod.VproductStock.FirstOrDefault(x => x.positionName == positionName); if (delteData != null) { List delteStockData = mod.productStock.Where(x => x.positionId == delteData.positionId).ToList(); if (delteStockData.Count > 0) { res = "删除成功"; foreach (var item in delteStockData) { mod.productStock.Remove(item); } position reset = mod.position.FirstOrDefault(x => x.positionId == delteData.positionId); if (reset != null) { //reset.isfree = false; //reset.isLock = false; PositionHandler.LockAndFree(false, false, reset, "根据库位删除数据", SysGloble.WCSNAME, _task); if (!stations.Contains(delteData.positionName.Trim())) { reset.positionType = (int)positionType.空库位; } } List delteStockDatalist = mod.productStockList.Where(x => x.stockId == delteData.positionId).ToList(); if (delteStockDatalist.Count > 0) { foreach (var itemList in delteStockDatalist) { mod.productStockList.Remove(itemList); //记录日志 [EditBy shaocx,2022-03-16] StockClearLog _StockClearLog = new StockClearLog() { ID = Guid.NewGuid().ToString(), serialNumber = itemList.serialNumber, containerCode = delteStockData[0].containerCode, materialCode = delteData.materialCode, materialName = delteData.materialName, positionName = delteData.positionName, qty = delteData.quantity, supplier = delteData.supplier, version = delteData.version, Remark = isPerson ? "人工清除库存" : "自动清除库存", CreateTime = DateTime.Now, LastModifyTime = DateTime.Now, Creator = user, LastModifier = user }; mod.StockClearLog.Add(_StockClearLog); } } } } return true; } catch (Exception ex) { res = "删除异常,请检查参数"; WZ.Useful.Commons.LogTextHelper.WriteLine("IyunneiWcf", "TaskDisplay", ex.ToString()); throw ex; } } /// /// 计算产量,并写入PLC /// /// public static void CalcQty() { //Task.Run(() => //{ try { using (dbmodel mod = new dbmodel()) { //总产量 //var queryTask1 = (int)taskType.缸盖上线; //var queryTask2 = (int)taskType.缸体上线; //var queryTask3 = (int)taskType.手动入库; //var queryTask4 = (int)taskType.缸体下线直接去上线点; //var queryTask5 = (int)taskType.缸盖下线直接去上线点; //var queryTask6 = (int)taskType.余料回库; var queryStats = (int)taskStatus.完成; var allQty = mod.task.Where(x => //( //x.taskType == queryTask1 //|| x.taskType == queryTask2 //|| x.taskType == queryTask3 //|| x.taskType == queryTask4 //|| x.taskType == queryTask5 //|| x.taskType == queryTask6 //) && x.taskStatus == queryStats).Count(); var nowDateTimeStr_1 = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd") + " 00:00:00"); var nowDateTimeStr_2 = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd") + " 23:59:59"); var todayQty = mod.task.Where(x => //( //x.taskType == queryTask1 //|| x.taskType == queryTask2 //|| x.taskType == queryTask3 //|| x.taskType == queryTask4 //|| x.taskType == queryTask5 //|| x.taskType == queryTask6 //) && x.taskStatus == queryStats && x.finishTime != null && x.finishTime >= nowDateTimeStr_1 && x.finishTime <= nowDateTimeStr_2 ).Count(); var nowDateTimeStr_3 = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM") + "-01 00:00:00"); var nowDateTimeStr_4 = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM") + "-30 23:59:59"); var monthQty = mod.task.Where(x => // ( // x.taskType == queryTask1 // || x.taskType == queryTask2 // || x.taskType == queryTask3 // || x.taskType == queryTask4 // || x.taskType == queryTask5 // || x.taskType == queryTask6 //) && x.taskStatus == queryStats && x.finishTime != null && x.finishTime >= nowDateTimeStr_3 && x.finishTime <= nowDateTimeStr_4 ).Count(); TransService.WriteQty((allQty), todayQty, monthQty); WZ.Useful.Commons.LogTextHelper.WriteLine("MyExtend", "CalcQty", "计算产量,并写入PLC成功,allQty:" + allQty + ",todayQty:" + todayQty + ",monthQty:" + monthQty); } } catch { throw; } //}); } } }