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.Text; using System.Threading.Tasks; using Utility.Tools; using WMS.DAL; 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,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); } #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 agvResult = 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(); } } //提交事务 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, 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("满桶请选择物料与批次"); } //判断目标叫料储位状态 var endLocateInfo = Db.Queryable().First(m => m.IsDel == "0" && m.LocatNo == StartLocate && 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 pln = Db.Queryable().First(m => m.IsDel == "0" && m.PalletNo == plnNo); var locate = 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 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 = locate.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 taskNo = new Common().GetMaxNo("TK"); //添加任务 var task = new LogTask { TaskNo = taskNo, Sender = "WMS", Receiver = "WCS", IsSuccess = 0, //是否下发成功 0失败 1成功 StartLocat = "",//起始位置 EndLocat = StartLocate,//目标位置 PalletNo = "",//托盘码 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(task).ExecuteCommand(); //调用AGV接口下发任务 } catch (Exception e) { throw new Exception(e.Message); } } private bool YikuTask(string palletNo, string taskNo, string url) { 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 agvResult = 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}"); } } } return true; } catch (Exception e) { throw new Exception(e.Message); } } /// /// 小车走出储位回传事件 /// /// /// /// public void OutBinAgv(string taskNo,string url) { 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 agvResult = 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}"); } } } catch (Exception e) { //回滚事务 Db.RollbackTran(); throw new Exception(e.Message); } } /// /// 定时将中转储位上的桶移走 /// /// /// public void TransferBackTimer(string url) { 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 = new SysStorageLocat();//目标储位 string areaNo = string.Empty; switch (detailInfo.PalletStatus) { case "0"://净桶 //查到到净桶区域编号 areaNo = Db.Queryable().Where(w => w.IsDel == "0" && w.WareHouseNo == itemHouseNo && w.Type == "0").Select(s => s.AreaNo).First(); //分配储位 endLocatInfo = Db.Queryable().Where(w => w.IsDel == "0" && w.Status == "0" && w.Flag == "0" && w.WareHouseNo == detailInfo.WareHouseNo && 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 == itemHouseNo && w.Type == "1").Select(s => s.AreaNo).First(); //分配储位 //先查到同物料的组 string sql = $@"select Row from SysStorageLocat where WareHouseNo='{itemHouseNo}' and AreaNo='{areaNo}' and LocatNo in( select LocatNo from DataStockDetail where SkuNo='{detailInfo.SkuNo}' and SkuName='{detailInfo.SkuName}' and Standard='{detailInfo.Standard}' and WareHouseNo='{itemHouseNo}' 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 == detailInfo.WareHouseNo && 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 == detailInfo.WareHouseNo && 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 == itemHouseNo && w.Type == "2").Select(s => s.AreaNo).First(); //分配储位 endLocatInfo = Db.Queryable().Where(w => w.IsDel == "0" && w.Status == "0" && w.Flag == "0" && w.WareHouseNo == detailInfo.WareHouseNo && w.AreaNo == areaNo) .OrderBy(o => o.Row).OrderByDescending(o => o.Column).First(); break; } //没有可用空储位 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 agvResult = 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}"); } } } //提交事务 Db.CommitTran(); } catch (Exception e) { //回滚事务 Db.RollbackTran(); throw new Exception(e.Message); } } /// /// 给小车下发任务 /// /// /// public bool CreateTaskForAgv(TaskDetial taskDetial, string url, out string agvMsg, string priority = null) { bool result = false; #region 呼叫小车代码 List pahtList = new List(); //起始位置 PositionCodePath path1 = new PositionCodePath(); path1.positionCode = taskDetial.Startport; if (taskDetial.Crtype == "1")//叫桶(桶出库) { path1.type = "05"; } else if (taskDetial.Crtype == "0")//申请储位(桶入库) { path1.type = "00"; } else//同车间平层搬运 { path1.type = "05"; } pahtList.Add(path1); //目标位置 PositionCodePath path2 = new PositionCodePath(); path2.positionCode = taskDetial.Endport; if (taskDetial.Crtype == "1")//叫桶(桶出库) { path2.type = "00"; } else if (taskDetial.Crtype == "1")//申请储位(桶入库) { path2.type = "05"; } else //同车间平层搬运 { path2.type = "05"; } pahtList.Add(path2); //下车任务单 AgvSchedulingTask agvTask = new AgvSchedulingTask(); agvTask.reqCode = taskDetial.Taskno;//请求编号 agvTask.taskCode = taskDetial.Taskno;//任务号 agvTask.ctnrCode = taskDetial.Pallno;//桶号 agvTask.reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");//请求时间 agvTask.wbCode = ""; agvTask.positionCodePath = pahtList;//小车路径 agvTask.podCode = ""; agvTask.userCallCode = "";//taskDetial.Endport;//目标位置 agvTask.priority = priority;//优先级 //判断容器类型 agvTask.ctnrTyp = "1";// 1:桶 2:桶(小) 3:托盘 //判断任务类型 if (taskDetial.Crtype == "1")//叫桶(桶出库) { agvTask.taskTyp = "Z3";//任务类型 线边到托盘收集器 Z1, 托盘垛申请入库 Z2 } else if (taskDetial.Crtype == "0")//申请储位(桶入库) { agvTask.taskTyp = "Z4";//任务类型 线边到托盘收集器 Z1, 托盘垛申请入库 Z2 } else//同车间平层搬运 { agvTask.taskTyp = "Z5"; } // 正式运行程序放开 var jsonData = JsonConvert.SerializeObject(agvTask); string response = HttpHelper.DoPost(url, jsonData, "下发给AGV转运命令", "AGV"); //解析返回数据 var agvModel = JsonConvert.DeserializeObject(response); if (agvModel.Code == "0") { result = true;//给下车下发任务成功 agvMsg = ""; } else { string logMsg = ""; if (taskDetial.Crtype == "1")//叫桶(桶出库) { logMsg = "申请叫桶"; } else if (taskDetial.Crtype == "0")//申请储位(桶入库) { logMsg = "申请储位"; } var logStr = $@".\log\AGV\AGV{logMsg}" + DateTime.Now.ToString("yyyyMMdd") + ".txt"; LogFile.SaveLogToFile($"AGV{logMsg}异常:( {agvModel.Message} ),", logStr); agvMsg = agvModel.Message; } return result; #endregion } } }