using Model.InterFaceModel; using Model.ModelDto.LogDto; using Model.ModelDto.SysDto; using Newtonsoft.Json; using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using System.Security.Policy; using System.Text; using System.Threading.Tasks; using Utility.Tools; using WMS.BLL.LogServer; using WMS.DAL; using WMS.Entity.BllAsnEntity; using WMS.Entity.BllSoEntity; using WMS.Entity.Context; using WMS.Entity.DataEntity; using WMS.Entity.LogEntity; using WMS.Entity.SysEntity; using WMS.IBLL.IBllTransServer; using static Model.InterFaceModel.RCSModel; namespace WMS.BLL.BllTransServer { public class HopperTransportServer: IHopperTransportServer { private static readonly SqlSugarScope Db = DataContext.Db; private readonly object RcsLock = new object(); /// /// 根据用户角色权限获取当前角色的区域 /// /// /// /// public List GetAreaListByUser(int userId) { try { var user = Db.Queryable().First(m=>m.IsDel == "0" && m.Id == userId); if (user == null) { throw new Exception("没有查询到用户信息"); } var role = Db.Queryable().First(m => m.IsDel == "0" && m.RoleNo == user.RoleNo); if (role == null) { throw new Exception("没有查询到角色信息"); } var roleWareStr = Db.Queryable().Where(m => m.IsDel == "0" && m.RoleNo == role.RoleNo).Select(m=>m.WareHouseNo).ToList(); var area = Db.Queryable().Where(m => m.IsDel == "0" && m.Status == "0" && roleWareStr.Contains(m.WareHouseNo)).ToList(); //var layer = "3"; //var areaList = new List(); //if (layer == "3") //{ // areaList = area.Where(m => m.AreaName.Contains("3楼")).ToList(); //} //else if (layer == "4") //{ // areaList = area.Where(m => m.AreaName.Contains("4楼")).ToList(); //} return area; } catch (Exception e) { throw new Exception(e.Message); } } /// /// 根据区域获取储位地址 /// /// /// /// public List GetLocatByArea(string area) { try { var locate = Db.Queryable().Where(m => m.AreaNo == area && m.IsDel == "0" && m.Flag == "0").ToList(); return locate; } catch (Exception e) { throw new Exception(e.Message); } } /// /// 根据区域或者桶状态 /// /// /// /// public List GetPlnStatusByArea(string area) { try { var areaInfo = Db.Queryable().First(m => m.AreaNo == area && m.IsDel == "0"); var strList = new List(); var dev = new string[] {}; if (areaInfo!=null && !string.IsNullOrWhiteSpace(areaInfo.DeviceCode)) { dev = areaInfo.DeviceCode.Split(";"); } foreach (var item in dev) { if (string.IsNullOrWhiteSpace(item)) { continue; } if (strList.Count(m=>m.dic1 == item) == 0) { var v = ""; switch (item) { case "0": v = "净桶"; break; case "1": v = "预混桶"; break; case "2": v = "满桶"; break; case "3": v = "脏桶"; break; } strList.Add(new DicModel { dic1 = item, dic2 = v }); } } if (strList.Count == 0) { strList.Add(new DicModel { dic1 = "0", dic2 = "净桶" }); //strList.Add(new DicModel { dic1 = "1", dic2 = "预混桶" }); strList.Add(new DicModel { dic1 = "2", dic2 = "满桶" }); strList.Add(new DicModel { dic1 = "3", dic2 = "脏桶" }); } return strList; } catch (Exception e) { throw new Exception(e.Message); } } /// /// 根据桶状态获取物料编码 /// /// /// /// public List GetSkuByStatus(string palletStatus) { try { //获取储位上的库存物料 var detail = Db.Queryable().Where(m => m.IsDel == "0" && !string.IsNullOrWhiteSpace(m.LocatNo) && m.PalletStatus == palletStatus).Select(m=>m.SkuNo).Distinct().ToList(); return detail; } catch (Exception e) { throw new Exception(e.Message); } } /// /// 根据物料编码获取批次号 /// /// /// /// public List GetLotNoBySku(string skuNo) { try { var lotNoStr = Db.Queryable().Where(m => m.IsDel == "0" && m.SkuNo == skuNo).Select(m => m.LotNo).Distinct().ToList(); return lotNoStr; } catch (Exception e) { throw new Exception(e.Message); } } public List GetSku() { try { //获取储位上的库存物料 var detail = Db.Queryable().Where(m => m.IsDel == "0" ).Select(m => m.SkuNo).Distinct().ToList(); return detail; } catch (Exception e) { throw new Exception(e.Message); } } /// /// 叫料 分配物料 /// /// 区域 /// 起始位置 /// 桶类型 0净桶 2满桶 3脏桶 /// 桶规格 /// 物料号 /// 批次 /// 操作人 /// public void jiaoLiaoHopper(string areaNo,string endLocate,string plnStatus,string standard,string skuNo,string lotNo,string url, string bindUrl, int userId) { try { #region 判断 if (string.IsNullOrWhiteSpace(areaNo) || string.IsNullOrWhiteSpace(endLocate) || string.IsNullOrWhiteSpace(plnStatus) ) { throw new Exception("区域/目标位/桶类型不能为空"); } if (plnStatus == "0" && string.IsNullOrWhiteSpace(standard)) { throw new Exception("净桶请选择规格"); } else if(plnStatus == "2" && (string.IsNullOrWhiteSpace(skuNo) || string.IsNullOrWhiteSpace(lotNo))) { throw new Exception("满桶请选择物料与批次"); } //判断目标叫料储位状态 var endLocateInfo = Db.Queryable().First(m => m.IsDel == "0" && m.LocatNo == endLocate && m.AreaNo == areaNo); if (endLocateInfo == null) { throw new Exception("没有查询到目标储位信息"); } if (endLocateInfo.Flag != "0") { throw new Exception("目标储位标识不是正常可用的"); } if (endLocateInfo.Status != "0") { throw new Exception("目标储位状态不是空储位"); } #endregion //目标楼层 var layer = endLocateInfo.Layer; var houseStr = layer == 3 ? "3楼中间站" : layer == 4 ? "4楼中间站" : ""; //通过仓库名称查询仓库信息 var house = Db.Queryable().First(m => m.IsDel == "0" && m.WareHouseName == houseStr); if (house == null) { throw new Exception("没有查询到仓库信息"); } //查找状态是未分配且储位不为空的库存信息 var stockDetail = Db.Queryable().Where(m => m.Status == "0" && m.WareHouseNo == house.WareHouseNo && !string.IsNullOrWhiteSpace(m.LocatNo)).ToList(); //净桶 if (plnStatus == "0") { stockDetail = stockDetail.Where(m => m.PalletStatus == "0" && m.Standard == standard).OrderBy(m => m.LocatNo).ToList(); } //满桶 else if (plnStatus == "2") { stockDetail = stockDetail.Where(m => m.PalletStatus == "2" && m.SkuNo == skuNo && m.LotNo == lotNo).OrderBy(m => m.LocatNo).ToList(); } else { throw new Exception("桶类型错误"); } if (stockDetail == null || stockDetail.Count <= 0) { throw new Exception("没有查询到叫料的库存信息"); } //开启事务 Db.BeginTran(); //生产任务号 var taskNo = new Common().GetMaxNo("TK"); bool resultYi = false; #region#查找合适的 桶号 储位 //目标仓库所有储位 var locatList = Db.Queryable().Where(w => w.IsDel == "0" && w.WareHouseNo == house.WareHouseNo).ToList(); //目标仓库所有不需要移库的储位 var locatListWai = locatList.Where(w => string.IsNullOrEmpty(w.AisleOne)).Select(s => s.LocatNo); //先找不需要移库的桶 var palletModel = stockDetail.Where(w => locatListWai.Contains(w.LocatNo)).OrderBy(o => o.UpdateTime).FirstOrDefault(); if (palletModel == null) { //找需要移库的桶 palletModel= stockDetail.Where(w => !locatListWai.Contains(w.LocatNo)).OrderBy(o => o.UpdateTime).FirstOrDefault(); if (palletModel == null) { throw new Exception("未找到对应桶信息"); } resultYi = YikuTask(palletModel.PalletNo, taskNo, url,bindUrl); } #endregion //起始储位地址信息 var startLoction = Db.Queryable().First(w => w.IsDel == "0" && w.Status == "1" && w.LocatNo == palletModel.LocatNo); if (startLoction == null) { throw new Exception($"起始目标储位信息不存在,桶号:{palletModel.LocatNo}"); } //产生移库任务 if (resultYi) { taskNo = taskNo + "-1"; } //添加任务 var logTaskEntry = new LogTask { TaskNo = taskNo, Sender = "WMS", Receiver = "RCS", IsSuccess = 0, //是否下发成功 0失败 1成功 StartLocat = "",//起始位置 EndLocat = endLocate,//目标位置 PalletNo = "",//托盘码 IsSend = 1,//是否可再次下发 IsCancel = 1,//是否可取消 IsFinish = 1,//是否可完成 Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务 Status = "0",//任务状态0:等待执行1正在执行2执行完成 OrderType = "3",//0 入库单 1 出库单 2 盘点单 3 移库单 CreateTime = DateTime.Now }; Db.Insertable(logTaskEntry).ExecuteCommand(); //没有产生移库任务就直接给小车下发出库任务,若产生移库任务等小车把移库的桶抬起时再下发出库任务 if (!resultYi) { //组织下发小车任务信息 var task = new TaskDetial { Taskno = taskNo,//任务号 Startport = palletModel.LocatNo,//起始位置 Endport = endLocate,//目标位置 Pallno = palletModel.PalletNo,//桶号 Crtype = "1",//叫桶 }; string agvMsg = string.Empty; //给下车下发任务 logTaskEntry.SendDate = DateTime.Now;//发送时间 //下发载具类型 var bind = RcsHelper.BindPalletAndSite(palletModel.PalletNo, palletModel.LocatNo, url, out string agvBindMsg); if (bind) { var agvResult = RcsHelper.CreateTaskForAgv(task, url, out agvMsg); if (agvResult)//成功 { //请求成功修改任务表相应字段状态 logTaskEntry.IsSuccess = 1; logTaskEntry.IsSend = 0; //logTaskEntry.IsCancel = 0; logTaskEntry.BackDate = DateTime.Now; logTaskEntry.Status = "1";//正在执行 Db.Insertable(logTaskEntry).ExecuteCommand(); startLoction.Status = "3";//出库中 Db.Updateable(startLoction).ExecuteCommand(); endLocateInfo.Status = "2";//入库中 Db.Updateable(endLocateInfo).ExecuteCommand(); } else//失败 { logTaskEntry.IsSuccess = 0; logTaskEntry.Information = agvMsg; Db.Insertable(logTaskEntry).ExecuteCommand(); } } else { logTaskEntry.IsSuccess = 0; logTaskEntry.Information = "货架与货位绑定失败,原因:"+agvBindMsg; Db.Insertable(logTaskEntry).ExecuteCommand(); } } //提交事务 Db.CommitTran(); } catch (Exception e) { //回滚事务 Db.RollbackTran(); throw new Exception(e.Message); } } /// /// 叫车 分配储位 /// /// 区域 /// 起始位置 /// 桶号 /// 桶类型 0净桶 2满桶 3脏桶 /// 重量 /// 物料号 /// 批次 /// 操作人 /// public void jiaoCheHopper(string areaNo, string StartLocate, string plnNo, string plnStatus, decimal weight, string skuNo, string lotNo, string url,string bindUrl,int userId) { try { #region 判断 if (string.IsNullOrWhiteSpace(areaNo) || string.IsNullOrWhiteSpace(StartLocate) || string.IsNullOrWhiteSpace(plnStatus)) { throw new Exception("区域/起始位/桶类型不能为空"); } //if (plnStatus == "0" && string.IsNullOrWhiteSpace(standard)) //{ // throw new Exception("净桶请选择规格"); //}else if (plnStatus == "2" && (string.IsNullOrWhiteSpace(skuNo) || string.IsNullOrWhiteSpace(lotNo))) { throw new Exception("满桶请选择物料与批次"); } #endregion //开启事务 Db.BeginTran(); //桶信息 var pln = Db.Queryable().First(w => w.IsDel == "0" && w.PalletNo == plnNo); if (pln == null) { throw new Exception("未查询到桶信息"); } //起始储位信息 var startLoction = Db.Queryable().First(m => m.IsDel == "0" && m.AreaNo == areaNo && m.LocatNo == StartLocate); var skuName = "";//物料名称 var packagNo = ""; if (plnStatus == "2")//满桶 { //物料信息 var sku = Db.Queryable().First(m => m.IsDel == "0" && m.SkuNo == skuNo); if (sku == null) { throw new Exception("没有查询到物料信息"); } skuName = sku.SkuName; } else if (plnStatus == "3") { } //目标楼层 var layer = startLoction.Layer; var houseStr = layer == 3 ? "3楼中间站" : layer == 4 ? "4楼中间站" : ""; //通过仓库名称查询仓库信息 var house = Db.Queryable().First(m => m.IsDel == "0" && m.WareHouseName == houseStr); if (house == null) { throw new Exception("没有查询到仓库信息"); } //桶库存明细 var stockDetail = Db.Queryable().First(m => m.PalletNo == plnNo); if (stockDetail == null) { var stockDetailNew = new DataStockDetail() { LotNo = lotNo, SkuNo = skuNo, SkuName = skuName, Standard = pln.Standard, Qty = weight, LockQty = 0, FrozenQty = 0, InspectQty = 0, WareHouseNo = startLoction.WareHouseNo, AreaNo = areaNo, LocatNo = StartLocate, PalletNo = plnNo, PackagNo = packagNo, PalletTags = "0", CompleteTime = DateTime.Now, PalletStatus = plnStatus, Status = "0", InspectMark = "0", BitPalletMark = "0", InspectStatus = "1", }; Db.Insertable(stockDetailNew).ExecuteCommand(); } else { stockDetail.PalletStatus = plnStatus; stockDetail.SkuNo = skuNo; stockDetail.LotNo = lotNo; stockDetail.Qty = weight; Db.Updateable(stockDetail).ExecuteCommand(); } //分配储位 var endLocatInfo = GetLocatModel(house.WareHouseNo, plnStatus, skuNo, pln.Standard);//目标储位 //没有可用空储位 if (endLocatInfo == null) { throw new Exception("没有找到合适的目标储位"); } var taskNo = new Common().GetMaxNo("TK"); //添加任务 var logTaskEntry = new LogTask { TaskNo = taskNo, Sender = "WMS", Receiver = "WCS", IsSuccess = 0, //是否下发成功 0失败 1成功 StartLocat = StartLocate,//起始位置 EndLocat = endLocatInfo.LocatNo,//目标位置 PalletNo = plnNo,//托盘码 IsSend = 1,//是否可再次下发 IsCancel = 1,//是否可取消 IsFinish = 1,//是否可完成 Type = "2",//任务类型 0 入库任务 1 出库任务 2 移库任务 Status = "0",//任务状态0:等待执行1正在执行2执行完成 OrderType = "3",//0 入库单 1 出库单 2 盘点单 3 移库单 CreateTime = DateTime.Now }; Db.Insertable(logTaskEntry).ExecuteCommand(); //组织下发小车任务信息 var task = new TaskDetial { Taskno = taskNo,//任务号 Startport = StartLocate,//起始位置 Endport = endLocatInfo.LocatNo,//目标位置 Pallno = plnNo,//桶号 Crtype = "1",//叫桶 }; //调用AGV接口下发任务 string agvMsg = string.Empty; //给下车下发任务 logTaskEntry.SendDate = DateTime.Now;//发送时间 //下发载具与货位绑定 var bind = RcsHelper.BindPalletAndSite(plnNo, StartLocate, bindUrl, out string agvBindMsg); if (bind) { var agvResult = RcsHelper.CreateTaskForAgv(task, url, out agvMsg); if (agvResult)//成功 { //请求成功修改任务表相应字段状态 logTaskEntry.IsSuccess = 1; logTaskEntry.IsSend = 0; //logTaskEntry.IsCancel = 0; logTaskEntry.BackDate = DateTime.Now; logTaskEntry.Status = "1";//正在执行 Db.Insertable(logTaskEntry).ExecuteCommand(); startLoction.Status = "3";//出库中 Db.Updateable(startLoction).ExecuteCommand(); endLocatInfo.Status = "2";//入库中 Db.Updateable(endLocatInfo).ExecuteCommand(); } else//失败 { logTaskEntry.IsSuccess = 0; logTaskEntry.Information = agvMsg; Db.Insertable(logTaskEntry).ExecuteCommand(); } } else { logTaskEntry.IsSuccess = 0; logTaskEntry.Information = "货架与货位绑定失败,原因:"+agvBindMsg; Db.Insertable(logTaskEntry).ExecuteCommand(); } //提交事务 Db.CommitTran(); } catch (Exception e) { //回滚事务 Db.RollbackTran(); throw new Exception(e.Message); } } /// /// 小车反馈任务完成 /// /// /// /// /// /// public void RCSFinishTask(string taskNo, string status, string comeFrom, int userId = 0) { try { #region 条件判断 var resultModel = new ErpModel() { Success = -1, Message = "" }; if (string.IsNullOrEmpty(taskNo)) { throw new Exception("任务号不可为空"); } //任务信息 var taskInfo = Db.Queryable().First(w => w.TaskNo == taskNo); if (taskInfo == null) { throw new Exception($"任务号为:{taskNo}的任务不存在!"); } if (taskInfo.Status != "1" && comeFrom != "WMS") { throw new Exception($"任务号为:{taskNo}的任务状态异常"); } #endregion //开启事务 Db.BeginTran(); var comTime = DateTime.Now; if (status == "0") { taskInfo.Status = "3";//异常结束 //修改任务状态 Db.Updateable(taskInfo).ExecuteCommand(); resultModel.Success = 0; resultModel.Message = "成功"; //提交事务 Db.CommitTran(); return; } //库存明细 var stockDetail = Db.Queryable().First(w => w.PalletNo == taskInfo.PalletNo); if (stockDetail == null) { throw new Exception($"桶库存信息不存在"); } //起始储位信息 var startLocatInfo = Db.Queryable().First(w => w.LocatNo == taskInfo.StartLocat && w.IsDel == "0"); if (startLocatInfo == null) { throw new Exception($"起始储位信息不存在"); } startLocatInfo.Status = "0";//空储位 //修改起始储位状态 Db.Updateable(startLocatInfo).ExecuteCommand(); //目标储位信息 var endLocatInfo = Db.Queryable().First(w => w.LocatNo == taskInfo.EndLocat && w.IsDel == "0"); if (endLocatInfo == null) { throw new Exception($"目标储位信息不存在"); } endLocatInfo.Status = "1";//有物品 //修改目标储位状态 Db.Updateable(endLocatInfo).ExecuteCommand(); //目标储位所属区域 var endAreaInfo = Db.Queryable().First(w => w.IsDel == "0" && w.WareHouseNo == endLocatInfo.WareHouseNo && w.AreaNo == endLocatInfo.AreaNo); if (endAreaInfo == null) { throw new Exception($"目标储位所属区域信息不存在"); } stockDetail.WareHouseNo = endLocatInfo.WareHouseNo;//所属仓库 stockDetail.RoadwayNo = endLocatInfo.RoadwayNo;//所属巷道 stockDetail.AreaNo = endLocatInfo.AreaNo;//所属区域 stockDetail.LocatNo = endLocatInfo.LocatNo;//储位地址 stockDetail.UpdateTime = DateTime.Now;//更新时间 if (endAreaInfo.Type == "0")//净桶区 { stockDetail.PalletStatus = "0"; stockDetail.Status = "0";//待分配 } else if (endAreaInfo.Type == "1")//满桶区 { stockDetail.PalletStatus = "1"; stockDetail.Status = "0";//待分配 } else if (endAreaInfo.Type == "2")//脏桶区 { stockDetail.PalletStatus = "3"; stockDetail.LotNo = "";//批次 stockDetail.SkuNo = ""; stockDetail.SkuName = ""; stockDetail.Status = "0";//待分配 stockDetail.InspectStatus = "0";//待检验 } else if (endAreaInfo.Type == "4")//设备区 { } //修改库存明细 Db.Updateable(stockDetail).ExecuteCommand(); taskInfo.Status = "2";//执行完成 taskInfo.IsSend = 0; taskInfo.IsCancel = 0; taskInfo.IsFinish = 0; taskInfo.FinishDate = DateTime.Now;//完成时间 //修改任务状态 Db.Updateable(taskInfo).ExecuteCommand(); if (comeFrom == "WMS") { //添加操作日志记录 var k = new OperationCrServer().AddLogOperationCr("库内作业", "库内日志", taskInfo.TaskNo, "完成", $"点击完成按钮、任务号为:{taskInfo.TaskNo}的任务", userId); } //提交事务 Db.CommitTran(); } catch (Exception ex) { //回滚事务 Db.RollbackTran(); throw new Exception(ex.Message); } } /// /// 清洗机叫料状态 /// /// 清洗机编号 /// 叫料点位:”input”-入口(叫脏桶),”output”-出口(净桶申请储位) /// /// public void RCSCleanRequest(string deviceID,string deviceStation,string status,string url,string bindUrl) { try { if (string.IsNullOrEmpty(deviceID)) { throw new Exception("清洗机编号不能为空"); } if (status != "1") { throw new Exception("非叫料状态"); } //通过设备号查找到所属设备(区域) var deviceInfo = Db.Queryable().First(w => w.IsDel == "0" && w.DeviceCode == deviceID); if (deviceInfo == null) { throw new Exception("设备信息不存在"); } var houseNo = deviceInfo.WareHouseNo;//叫桶设备所属车间编号 var startLoction = new SysStorageLocat();//起始储位信息 var endLoction = new SysStorageLocat();//目标储位信息 var palletModel = new DataStockDetail();//分配桶信息 //开启事务 Db.BeginTran(); //叫料点位 switch (deviceStation) { case "input"://叫脏桶 //叫桶设备所在储位信息(目标储位) endLoction = Db.Queryable().First(w => w.IsDel == "0" && w.WareHouseNo == houseNo && w.AreaNo == deviceInfo.AreaNo); // 所有待分配的脏桶 var stockDetail = Db.Queryable().Where(w => w.Status == "0" && w.PalletStatus == "3"); //优先查找脏桶缓存车间 palletModel = stockDetail.Where(w => w.AreaNo == "C43").OrderByDescending(o => o.UpdateTime).First(); if (palletModel == null)//脏桶缓存车间没有脏桶,再从三楼中间站脏桶区查找 { palletModel = stockDetail.Where(w =>w.WareHouseNo=="M16" && w.AreaNo == "C26").OrderByDescending(o => o.UpdateTime).First(); } if (palletModel == null)//三楼中间站脏桶区没有脏桶,再从四楼中间站脏桶区查找 { palletModel = stockDetail.Where(w => w.WareHouseNo == "M01" && w.AreaNo == "C03").OrderByDescending(o => o.UpdateTime).First(); } if (palletModel == null) { throw new Exception("无脏桶可分配"); } //起始储位地址信息 startLoction = Db.Queryable().First(w => w.IsDel == "0" && w.Status == "1" && w.LocatNo == palletModel.LocatNo); if (startLoction == null) { throw new Exception($"起始目标储位信息不存在,桶号:{palletModel.LocatNo}"); } break; case "output"://净桶申请储位 //叫桶设备所在储位信息(起始储位) startLoction = Db.Queryable().First(w => w.IsDel == "0" && w.WareHouseNo == houseNo && w.AreaNo == deviceInfo.AreaNo); //桶信息 palletModel = Db.Queryable().Where(w => w.WareHouseNo==houseNo && w.AreaNo==deviceInfo.AreaNo && w.LocatNo==startLoction.LocatNo).First(); if (palletModel == null) { throw new Exception("未查询到净桶信息"); } //分配储位 //优先分配四楼中间站净桶区 endLoction= Db.Queryable().Where(w => w.IsDel == "0" && w.Status == "0" && w.Flag == "0" && w.WareHouseNo == "M01" && w.AreaNo == "C01") .OrderBy(o => o.Row).OrderByDescending(o => o.Column).First(); if (endLoction == null)//四楼中间站净桶区没有空储位,再从三楼中间站净桶区查找 { endLoction = Db.Queryable().Where(w => w.IsDel == "0" && w.Status == "0" && w.Flag == "0" && w.WareHouseNo == "M16" && w.AreaNo == "C24") .OrderBy(o => o.Row).OrderByDescending(o => o.Column).First(); } if (endLoction == null)//三楼中间站净桶区没有空储位,再从三楼清洗间缓存区查找 { endLoction = Db.Queryable().Where(w => w.IsDel == "0" && w.Status == "0" && w.Flag == "0" && w.WareHouseNo == "M44" && w.AreaNo == "C55") .OrderBy(o => o.Row).OrderByDescending(o => o.Column).First(); } if (endLoction == null) { throw new Exception("未查询到合适储位"); } break; default: throw new Exception("叫料点位异常"); } var taskNo = new Common().GetMaxNo("TK"); //添加任务 var logTaskEntry = new LogTask { TaskNo = taskNo, Sender = "WMS", Receiver = "RCS", IsSuccess = 0, //是否下发成功 0失败 1成功 StartLocat = "",//起始位置 EndLocat = endLoction.LocatNo,//目标位置 PalletNo = "",//托盘码 IsSend = 1,//是否可再次下发 IsCancel = 1,//是否可取消 IsFinish = 1,//是否可完成 Type = "1",//任务类型 0 入库任务 1 出库任务 2 移库任务 Status = "0",//任务状态0:等待执行1正在执行2执行完成 OrderType = "3",//0 入库单 1 出库单 2 盘点单 3 移库单 CreateTime = DateTime.Now }; Db.Insertable(logTaskEntry).ExecuteCommand(); //组织下发小车任务信息 var task = new TaskDetial { Taskno = taskNo,//任务号 Startport = palletModel.LocatNo,//起始位置 Endport = endLoction.LocatNo,//目标位置 Pallno = palletModel.PalletNo,//桶号 Crtype = "1",//叫桶 }; string agvMsg = string.Empty; //给下车下发任务 logTaskEntry.SendDate = DateTime.Now;//发送时间 //下发载具与货位绑定 var bind = RcsHelper.BindPalletAndSite(palletModel.PalletNo, palletModel.LocatNo, bindUrl, out string agvBindMsg); if (bind) { var agvResult = RcsHelper.CreateTaskForAgv(task, url, out agvMsg); if (agvResult)//成功 { //请求成功修改任务表相应字段状态 logTaskEntry.IsSuccess = 1; logTaskEntry.IsSend = 0; //logTaskEntry.IsCancel = 0; logTaskEntry.BackDate = DateTime.Now; logTaskEntry.Status = "1";//正在执行 Db.Insertable(logTaskEntry).ExecuteCommand(); startLoction.Status = "3";//出库中 Db.Updateable(startLoction).ExecuteCommand(); endLoction.Status = "2";//入库中 Db.Updateable(endLoction).ExecuteCommand(); } else//失败 { logTaskEntry.IsSuccess = 0; logTaskEntry.Information = agvMsg; Db.Insertable(logTaskEntry).ExecuteCommand(); } } else { logTaskEntry.IsSuccess = 0; logTaskEntry.Information = agvBindMsg; Db.Insertable(logTaskEntry).ExecuteCommand(); } //提交事务 Db.CommitTran(); } catch (Exception e) { //回滚事务 Db.RollbackTran(); throw new Exception(e.Message); } } private bool YikuTask(string palletNo, string taskNo, string url,string bindUrl) { try { //分配桶的库存信息 var palletInfo = Db.Queryable().First(w => w.IsDel == "0" && w.PalletNo == palletNo); if (palletInfo == null) { throw new Exception("未查询到分配桶的库存信息"); } //判断分配的桶有没有正在执行的任务(移库中) var taskIng = Db.Queryable().First(w => w.IsDel == "0" && (w.Status == "0" || w.Status == "1") && w.PalletNo == palletNo); if (taskIng != null) { throw new Exception("分配的桶有正在执行的任务,请稍后再试"); } //分配桶的储位信息 var locatInfo = Db.Queryable().First(w => w.IsDel == "0" && w.LocatNo == palletInfo.LocatNo); if (locatInfo == null) { throw new Exception("未查询到分配桶所在的储位信息"); } string WareHouseNo = locatInfo.WareHouseNo;//所属仓库编号 //判断该储位是否是内侧储位 if (!string.IsNullOrEmpty(locatInfo.AisleOne)) { //判断外侧储位是否有桶 var palletInfoYi = Db.Queryable().First(w => w.IsDel == "0" && w.LocatNo == locatInfo.AisleOne); if (palletInfoYi != null) { //判断要移库的桶是否被分配 if (palletInfoYi.Status != "0") { throw new Exception("要移库的桶已被分配,请稍后再试"); } //判断要移库的桶是否有正在执行的任务 var taskInfo = Db.Queryable().First(w => w.IsDel == "0" && (w.Status == "0" || w.Status == "1") && w.PalletNo == palletInfoYi.PalletNo); if (taskInfo != null) { throw new Exception("要移库的桶有正在执行的任务,请稍后再试"); } #region#给要移库的桶先移到中转储位 //找到中转储位所在区域 var transfeArea = Db.Queryable().First(w => w.IsDel == "0" && w.WareHouseNo == WareHouseNo && w.AreaName.Contains("转运区")); if (transfeArea == null) { throw new Exception("未找到转运区域"); } //找到中转储位 var transferLocat = Db.Queryable().First(w => w.IsDel == "0" && w.WareHouseNo == WareHouseNo && w.AreaNo == transfeArea.AreaNo); if (transferLocat == null) { throw new Exception("没有空闲中转储位,请稍后再试"); } #endregion //任务信息 var logTaskEntry = new LogTask { TaskNo = taskNo, Sender = "WMS", Receiver = "RCS", //IsSuccess = 1, //是否下发成功 0失败 1成功 SendDate = DateTime.Now, //发送时间 //BackDate = DateTime.Now, //返回时间 StartLocat = palletInfoYi.LocatNo,//起始位置 EndLocat = transferLocat.LocatNo,//目标位置 PalletNo = palletInfoYi.PalletNo,//托盘码 IsSend = 1,//是否可再次下发 IsCancel = 1,//是否可取消 IsFinish = 1,//是否可完成 Type = "2",//任务类型 0 入库任务 1 出库任务 2 移库任务 OrderType = "3",//单据类型 0 入库 1 出库 3移库 Status = "0",//任务状态0:等待执行1正在执行2执行完成 NoticeDetailNo = 0, Msg = $"将桶{palletInfoYi.PalletNo}从{palletInfoYi.LocatNo}移到{transferLocat.LocatNo}", //关键信息 LotNo = ""//批次号 }; //组织下发小车任务信息 var task = new TaskDetial { Taskno = taskNo,//任务号 Startport = palletInfoYi.LocatNo,//起始位置 Endport = transferLocat.LocatNo,//目标位置 Pallno = palletInfoYi.PalletNo,//桶号 Crtype = "1",//叫桶 WareHouseNo = palletInfoYi.WareHouseNo//车间编码 }; string agvMsg = string.Empty; //给下车下发任务 logTaskEntry.SendDate = DateTime.Now;//发送时间 //下发载具与货位绑定 var bind = RcsHelper.BindPalletAndSite(palletInfoYi.LocatNo, palletInfoYi.PalletNo, bindUrl, out string agvBindMsg); if (bind) { var agvResult = RcsHelper.CreateTaskForAgv(task, url, out agvMsg, "70"); if (agvResult)//成功 { //请求成功修改任务表相应字段状态 logTaskEntry.IsSuccess = 1; logTaskEntry.IsSend = 0; //logTaskEntry.IsCancel = 0; logTaskEntry.BackDate = DateTime.Now; logTaskEntry.Status = "1";//正在执行 Db.Insertable(logTaskEntry).ExecuteCommand(); //修改移出储位状态 locatInfo.Status = "5";//移出中 Db.Updateable(locatInfo).ExecuteCommand(); //修改移入储位状态 transferLocat.Status = "4";//移入中 Db.Updateable(transferLocat).ExecuteCommand(); } else//失败 { logTaskEntry.IsSuccess = 0; logTaskEntry.Information = agvMsg; Db.Insertable(logTaskEntry).ExecuteCommand(); throw new Exception($"给小车下发移库任务失败,桶号:{palletInfoYi.PalletNo}"); } } else { logTaskEntry.IsSuccess = 0; logTaskEntry.Information = agvBindMsg; Db.Insertable(logTaskEntry).ExecuteCommand(); throw new Exception($"给小车下发移库任务失败,桶号:{palletInfoYi.PalletNo}"); } } } return true; } catch (Exception e) { throw new Exception(e.Message); } } /// /// 小车走出储位回传事件 /// /// /// /// public void OutBinAgv(string taskNo,string url, string bindUrl) { try { //开启事务 Db.BeginTran(); //查找任务信息 var logTaskInfo = Db.Queryable().First(w => w.IsDel == "0" && w.Status == "1" && w.TaskNo == taskNo); if (logTaskInfo == null) { throw new Exception("未查询到该任务"); } //起始储位地址 var startLocatInfo = Db.Queryable().First(w => w.IsDel == "0" && w.LocatNo == logTaskInfo.StartLocat); if (startLocatInfo == null) { throw new Exception("未查询到起始储位地址信息"); } startLocatInfo.Status = "0";//空储位 //修改起始储位状态为空储位 Db.Updateable(startLocatInfo).ExecuteCommand(); //判断有无子任务 string taskNoZ = logTaskInfo.TaskNo + "-1"; var logTaskInfoZ = Db.Queryable().First(w => w.IsDel == "0" && w.Status == "0" && w.TaskNo == taskNoZ); if (logTaskInfoZ != null) { //子任务起始储位信息 var startLocatInfoZ= Db.Queryable().First(w => w.IsDel == "0" && w.LocatNo == logTaskInfoZ.StartLocat); if (startLocatInfoZ == null) { throw new Exception("未查询到子任务起始储位地址信息"); } //子任务目标储位信息 var endLocatInfoZ = Db.Queryable().First(w => w.IsDel == "0" && w.LocatNo == logTaskInfoZ.EndLocat); if (endLocatInfoZ == null) { throw new Exception("未查询到子任务目标储位地址信息"); } //组织下发小车任务信息 var task = new TaskDetial { Taskno = taskNo,//任务号 Startport = logTaskInfoZ.StartLocat,//起始位置 Endport = logTaskInfoZ.EndLocat,//目标位置 Pallno = logTaskInfoZ.PalletNo,//桶号 Crtype = "1",//叫桶 }; string agvMsg = string.Empty; //给下车下发任务 logTaskInfoZ.SendDate = DateTime.Now;//发送时间 //下发载具与货们绑定 var bind = RcsHelper.BindPalletAndSite(logTaskInfoZ.PalletNo, logTaskInfoZ.StartLocat, bindUrl, out string agvBindMsg); if (bind) { var agvResult = RcsHelper.CreateTaskForAgv(task, url, out agvMsg, "70"); if (agvResult)//成功 { //请求成功修改任务表相应字段状态 logTaskInfoZ.IsSuccess = 1; logTaskInfoZ.IsSend = 0; //logTaskEntry.IsCancel = 0; logTaskInfoZ.BackDate = DateTime.Now; logTaskInfoZ.Status = "1";//正在执行 Db.Insertable(logTaskInfoZ).ExecuteCommand(); //修改移出储位状态 startLocatInfoZ.Status = "5";//移出中 Db.Updateable(startLocatInfoZ).ExecuteCommand(); //修改移入储位状态 endLocatInfoZ.Status = "4";//移入中 Db.Updateable(endLocatInfoZ).ExecuteCommand(); } else//失败 { logTaskInfoZ.IsSuccess = 0; logTaskInfoZ.Information = agvMsg; Db.Insertable(logTaskInfoZ).ExecuteCommand(); throw new Exception($"给小车下发移库任务失败,桶号:{logTaskInfoZ.PalletNo}"); } } else { logTaskInfoZ.IsSuccess = 0; logTaskInfoZ.Information = agvBindMsg; Db.Insertable(logTaskInfoZ).ExecuteCommand(); throw new Exception($"给小车下发移库任务失败,桶号:{logTaskInfoZ.PalletNo}"); } } } catch (Exception e) { //回滚事务 Db.RollbackTran(); throw new Exception(e.Message); } } /// /// 定时将中转储位上的桶移走 /// /// /// public void TransferBackTimer(string url,string bindUrl) { try { //开启事务 Db.BeginTran(); //中间站仓库 var transferWareHouseList = new List() { "M01", "M16" }; foreach (var itemHouseNo in transferWareHouseList) { //找到中转储位所在区域 var transfeArea = Db.Queryable().First(w => w.IsDel == "0" && w.WareHouseNo == itemHouseNo && w.AreaName.Contains("转运区")); if (transfeArea == null) { throw new Exception("未找到转运区域"); } //找到中转储位 var transferLocatList = Db.Queryable().Where(w => w.IsDel == "0" && w.WareHouseNo == itemHouseNo && w.AreaNo == transfeArea.AreaNo).ToList(); foreach (var locatModel in transferLocatList) { //储位信息 if (locatModel.Status != "1") { continue; } //储位上库存信息 var detailInfo = Db.Queryable().First(w => w.IsDel == "0" && w.LocatNo == locatModel.LocatNo); if (detailInfo == null) { continue; } //分配储位 var endLocatInfo = GetLocatModel(itemHouseNo,detailInfo.PalletStatus,detailInfo.SkuNo,detailInfo.Standard);//目标储位 //没有可用空储位 if (endLocatInfo == null) { continue; } var taskNo = new Common().GetMaxNo("TK"); //任务信息 var logTaskEntry = new LogTask { TaskNo = taskNo, Sender = "WMS", Receiver = "RCS", //IsSuccess = 1, //是否下发成功 0失败 1成功 SendDate = DateTime.Now, //发送时间 //BackDate = DateTime.Now, //返回时间 StartLocat = detailInfo.LocatNo,//起始位置 EndLocat = endLocatInfo.LocatNo,//目标位置 PalletNo = detailInfo.PalletNo,//托盘码 IsSend = 1,//是否可再次下发 IsCancel = 1,//是否可取消 IsFinish = 1,//是否可完成 Type = "2",//任务类型 0 入库任务 1 出库任务 2 移库任务 OrderType = "3",//单据类型 0 入库 1 出库 3移库 Status = "0",//任务状态0:等待执行1正在执行2执行完成 NoticeDetailNo = 0, Msg = $"将桶{detailInfo.PalletNo}从{detailInfo.LocatNo}移到{endLocatInfo.LocatNo}", //关键信息 LotNo = ""//批次号 }; //组织下发小车任务信息 var task = new TaskDetial { Taskno = taskNo,//任务号 Startport = detailInfo.LocatNo,//起始位置 Endport = endLocatInfo.LocatNo,//目标位置 Pallno = detailInfo.PalletNo,//桶号 Crtype = "2"//叫桶 }; string agvMsg = string.Empty; //给下车下发任务 logTaskEntry.SendDate = DateTime.Now;//发送时间 //下发载具与货位绑定 var bind = RcsHelper.BindPalletAndSite(detailInfo.PalletNo, detailInfo.LocatNo, bindUrl, out string agvBindMsg); if (bind) { var agvResult = RcsHelper.CreateTaskForAgv(task, url, out agvMsg); if (agvResult)//成功 { //请求成功修改任务表相应字段状态 logTaskEntry.IsSuccess = 1; logTaskEntry.IsSend = 0; //logTaskEntry.IsCancel = 0; logTaskEntry.BackDate = DateTime.Now; logTaskEntry.Status = "1";//正在执行 Db.Insertable(logTaskEntry).ExecuteCommand(); //修改移出储位状态 locatModel.Status = "5";//移出中 Db.Updateable(locatModel).ExecuteCommand(); //修改移入储位状态 endLocatInfo.Status = "4";//移入中 Db.Updateable(endLocatInfo).ExecuteCommand(); } else//失败 { logTaskEntry.IsSuccess = 0; logTaskEntry.Information = agvMsg; Db.Insertable(logTaskEntry).ExecuteCommand(); throw new Exception($"给小车下发移库任务失败,桶号:{detailInfo.PalletNo}"); } } else { logTaskEntry.IsSuccess = 0; logTaskEntry.Information = agvBindMsg; Db.Insertable(logTaskEntry).ExecuteCommand(); throw new Exception($"给小车下发移库任务失败,桶号:{detailInfo.PalletNo}"); } } } //提交事务 Db.CommitTran(); } catch (Exception e) { //回滚事务 Db.RollbackTran(); throw new Exception(e.Message); } } /// /// 分配储位 /// /// 仓库编号 /// 桶状态 /// 物料编码 /// 桶规格 /// /// private SysStorageLocat GetLocatModel(string houseNo, string palletStatus,string skuNo="",string standard="") { try { var endLocatInfo = new SysStorageLocat();//目标储位 string areaNo = string.Empty; switch (palletStatus) { case "0"://净桶 //查到到净桶区域编号 areaNo = Db.Queryable().Where(w => w.IsDel == "0" && w.WareHouseNo == houseNo && w.Type == "0").Select(s => s.AreaNo).First(); //分配储位 endLocatInfo = Db.Queryable().Where(w => w.IsDel == "0" && w.Status == "0" && w.Flag == "0" && w.WareHouseNo == houseNo && w.AreaNo == areaNo) .OrderBy(o => o.Row).OrderByDescending(o => o.Column).First(); break; case "2"://满桶 //查到到满桶区域编号 areaNo = Db.Queryable().Where(w => w.IsDel == "0" && w.WareHouseNo == houseNo && w.Type == "1").Select(s => s.AreaNo).First(); //分配储位 //先查到同物料的组 string sql = $@"select Row from SysStorageLocat where WareHouseNo='{houseNo}' and AreaNo='{areaNo}' and LocatNo in( select LocatNo from DataStockDetail where SkuNo='{skuNo}' and Standard='{standard}' and WareHouseNo='{houseNo}' and AreaNo='{areaNo}' ) group by Row"; List RowList = Db.Ado.SqlQuery(sql).ToList(); foreach (var rowItem in RowList) { endLocatInfo = Db.Queryable().Where(w => w.IsDel == "0" && w.Status == "0" && w.Flag == "0" && w.WareHouseNo == houseNo && w.AreaNo == areaNo && w.Row == rowItem) .OrderByDescending(o => o.Column).First(); if (endLocatInfo != null) { break; } } //没有找到相同物料同组的空储位 if (endLocatInfo == null) { endLocatInfo = Db.Queryable().Where(w => w.IsDel == "0" && w.Status == "0" && w.Flag == "0" && w.WareHouseNo == houseNo && w.AreaNo == areaNo) .OrderBy(o => o.Row).OrderByDescending(o => o.Column).First(); } break; case "3"://脏桶 //查到到脏桶区域编号 areaNo = Db.Queryable().Where(w => w.IsDel == "0" && w.WareHouseNo == houseNo && w.Type == "2").Select(s => s.AreaNo).First(); //分配储位 endLocatInfo = Db.Queryable().Where(w => w.IsDel == "0" && w.Status == "0" && w.Flag == "0" && w.WareHouseNo == houseNo && w.AreaNo == areaNo) .OrderBy(o => o.Row).OrderByDescending(o => o.Column).First(); break; } return endLocatInfo; } catch (Exception ex) { throw new Exception(ex.Message); } } } }