using Model.InterFaceModel; using Newtonsoft.Json; using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using System.Security.Policy; using System.Text; using Utility.Tools; 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 RcsServer:IRcsServer { private static readonly SqlSugarScope Db = DataContext.Db; /// /// RCS叫桶(净桶和脏桶) /// /// 库区 /// 叫料类型 /// public void GetPalletNo(Pallnetmsg model,string url) { DataStockDetail pallet = new DataStockDetail(); try { if (string.IsNullOrEmpty(model.Location)) { throw new Exception("设备所在位置不可为空"); } var locatInfo = Db.Queryable().First(w => w.IsDel == "0" && w.LocatNo == model.Location); if (locatInfo == null) { throw new Exception("设备储位信息不存在"); } var house = locatInfo.WareHouseNo;//叫桶位置,后续根据位置关联或定义,来判断叫桶位置所属车间 var urlMes = "";//回传MES的接口地址 var noticeno = "0";//出入库单据明细ID var sql = "select PalletNo,LocatNo from DataStockDetail where Status = '0'"; switch (model.Type) { case "0"://叫净桶 sql += $"and WareHouseNo = '{house}' and (AreaNo like '%01' or AreaNo like '%11' or AreaNo like '%21' or AreaNo like '%31') and PalletStatus = '0' order by CreateTime desc"; pallet = Db.Ado.SqlQuery(sql).FirstOrDefault(); if (pallet == null) { throw new Exception("暂无净桶可分配"); } break; case "1"://叫料桶(混料) //判断是否有批次号 if (string.IsNullOrWhiteSpace(model.LotNo)) { throw new Exception("批次号为空!"); } /*BllArrivalNoticeDetail ArriveMes = new BllArrivalNoticeDetail(); //判断该批次是否有对应入库单 sql = $"select * from BllArrivalNoticeDetail where LotNo = '{pallnetmsg.LotNo}' order by CreateTime desc"; ArriveMes = Db.Ado.SqlQuery(sql).FirstOrDefault(); if (ArriveMes == null) { throw new Exception("该批次没有对应的入库单"); } noticeno = ArriveMes.Id.ToString();*/ //查找库存中是否有可用的此批次的混料桶 sql= $@"select PalletNo,LocatNo from DataStockDetail where LotNo = '{model.LotNo}'and (AreaNo like '%02' or AreaNo like '%12' or AreaNo like '%22' or AreaNo like '%32') and WareHouseNo = '{house}' and status = '0' and PalletStatus = '1' order by CompleteTime desc"; pallet = Db.Ado.SqlQuery(sql).FirstOrDefault(); if (pallet == null) { throw new Exception("暂无混料桶可分配"); } break; case "2"://叫料桶(下料) BllExportNoticeDetail bllSo = new BllExportNoticeDetail(); //判断是否有批次号 if (string.IsNullOrWhiteSpace(model.LotNo)) { throw new Exception("批次号为空!"); } //查找是否有此批次出库单 sql = $"select * from BllExportNoticeDetail where LotNo = '{model.LotNo}' order by CreateTime desc"; bllSo = Db.Ado.SqlQuery(sql).FirstOrDefault(); if (bllSo == null) { throw new Exception("该批次没有对应的出库单"); } noticeno = bllSo.Id.ToString(); //查找库存中是否有此批次的合格下料桶 sql = $@"select PalletNo,LocatNo from DataStockDetail where LotNo = '{model.LotNo}'and (AreaNo like '%03' or AreaNo like '%13' or AreaNo like '%23' or AreaNo like '%33') and WareHouseNo = '{house}' and status = '0' and PalletStatus = '2' and InspectStatus = '1' order by CompleteTime desc"; pallet = Db.Ado.SqlQuery(sql).FirstOrDefault(); if (pallet == null) { throw new Exception("暂无下料桶可分配"); } break; case "3"://叫脏桶 sql += $"and WareHouseNo = '{house}' and (AreaNo like '%04' or AreaNo like '%14' or AreaNo like '%24' or AreaNo like '%34') and PalletStatus='3' order by CreateTime desc"; List palletList = Db.Ado.SqlQuery(sql).ToList(); if (palletList.Count <= 0) { throw new Exception("暂无脏桶可分配"); } //遍历库存脏桶,返回MES验证 foreach (var item in palletList) { #region 去掉MES //string jsonReq = JsonConvert.SerializeObject(item.PalletNo); //var response = HttpHelper.DoPost(urlMes, jsonReq, "回传MES脏桶编号", "RCS").ToString(); //var obj = JsonConvert.DeserializeObject(response);//解析返回数据 //if (obj.Success == "0") //{ // if (obj.Result != "1")//不可清洗,将脏桶冻结 // { // item.Status = "5";//异常冻结 // //修改该桶库存状态 // Db.Updateable(item).ExecuteCommand(); // continue; // } // //下发小车任务 // var task2 = new TaskDetial // { // Startport = item.LocatNo, // Endport = model.Location, // Pallno = item.PalletNo, // Type = model.Type, // Crtype = "1", // Noticedetailno = int.Parse(noticeno), // }; // CreateLotTask(task2); // return; //} //else //{ // throw new Exception("回传MES净桶编号失败!"); //} #endregion //下发小车任务 var task2 = new TaskDetial { Startport = item.LocatNo, Endport = model.Location, Pallno = item.PalletNo, Type = model.Type, Crtype = "1", Noticedetailno = int.Parse(noticeno), }; CreateLotTask(task2, url); return; } break; default: throw new Exception("任务类型无效"); } //下发小车任务 var task = new TaskDetial { Startport = pallet.LocatNo,//起始位置 Endport = model.Location,//目标位置 Pallno = pallet.PalletNo,//桶号 Type = model.Type,//桶类型 Crtype = "1", Noticedetailno = int.Parse(noticeno), LotNo = model.LotNo, }; CreateLotTask(task, url); return; } catch (Exception ex) { Db.Ado.RollbackTran(); throw new Exception(ex.Message); } } /// /// MES下发将净桶改为脏桶并拉到脏桶区 /// /// /// public void ChangePalletStatus(string PalletNo,string url) { try { var detail = Db.Queryable().First(w => w.PalletNo == PalletNo && w.PalletStatus == "0"); if (detail == null) { throw new Exception($"库存中不存在桶号为:{PalletNo}的库存!"); } //起始目标储位信息 var statrtLocat = Db.Queryable().First(w => w.WareHouseNo == detail.WareHouseNo && w.AreaNo == detail.AreaNo && w.LocatNo == detail.LocatNo); if (statrtLocat == null) { throw new Exception($"该桶所在的储位信息不存在!"); } //开启事务 Db.BeginTran(); //查找是否有空余脏桶位 var endLocat = Db.Queryable().First(w => w.WareHouseNo == detail.WareHouseNo && w.AreaNo.Contains("04") && w.Status == "0" && w.Flag=="0"); if (endLocat == null) { detail.Status = "5";//异常锁定 detail.PalletStatus = "3";//脏桶 //修改库存状态 Db.Updateable(detail).ExecuteCommand(); } else { //生成调度小车净桶去脏桶区任务 var ztask = new TaskDetial { Startport = detail.LocatNo, Endport = endLocat.LocatNo, Pallno = PalletNo, Type = "3", Crtype = "2", Noticedetailno = 0, }; CreateLotTask(ztask,url); statrtLocat.Status = "3";//出库中 //修改起始储位状态 Db.Updateable(statrtLocat).ExecuteCommand(); detail.Status = "5";//异常锁定 detail.PalletStatus = "3";//脏桶 //修改库存状态 Db.Updateable(detail).ExecuteCommand(); } Db.CommitTran(); } catch (Exception ex) { Db.RollbackTran(); throw ex; } } /// /// MES下发清洗锁定脏桶 /// /// public void CleanPallet(Pallnetmsg pallnetmsg,string url) { try { var detail = Db.Queryable().First(w => w.PalletNo == pallnetmsg.PalletNo && w.PalletStatus == "3"); if (detail == null) { throw new Exception($"库存中不存在桶号为:{pallnetmsg.PalletNo}的库存!"); } //下发小车任务 var task = new TaskDetial { Startport = detail.LocatNo, Endport = pallnetmsg.Location, Pallno = detail.PalletNo, Type = "3", Crtype = "1", Noticedetailno = 0, LotNo = "", }; CreateLotTask(task,url); } catch (Exception ex) { throw ex; } } /// /// 申请储位 /// /// /// public void ApplyLocatNo(Pallnetmsg model,string url) { var sql = $"select LocatNo from SysStorageLocat where status = '0'"; var sql2 = ""; var houseNo = "";//申请储位设备所在车间编号 var noticeno = "0";//出入库单据明细ID SysStorageLocat loction = new SysStorageLocat();//目标储位信息 BllArrivalNoticeDetail noticeDetail = new BllArrivalNoticeDetail();//入库单明细 try { //设备所在储位信息 var deviceLocatInfo = Db.Queryable().First(w => w.IsDel == "0" && w.LocatNo == model.LotNo); if (deviceLocatInfo == null) { throw new Exception($"未查询到该设备所在储位信息,Location:{model.Location}"); } houseNo = deviceLocatInfo.WareHouseNo;//设备所属车间 switch (model.Type) { case "3"://清洗设备申请储位(净桶申请储位) sql += $" and (AreaNo like '%01' or AreaNo like '%11' or AreaNo like '%21' or AreaNo like '%31') and WareHouseNo = '{houseNo}'"; loction = Db.Ado.SqlQuery(sql).OrderByDescending(a => a.CreateTime).FirstOrDefault(); if (loction == null) { throw new Exception("该车间净桶区暂无空余储位"); } break; case "0"://接料设备申请储位(预混料桶申请储位) //判断是否有批次号 if (string.IsNullOrWhiteSpace(model.LotNo)) { throw new Exception("批次号为空!"); } sql += $" and (AreaNo like '%02' or AreaNo like '%12' or AreaNo like '%22' or AreaNo like '%32') and WareHouseNo = '{houseNo}'"; loction = Db.Ado.SqlQuery(sql).OrderByDescending(a => a.CreateTime).FirstOrDefault(); if (loction == null) { throw new Exception("该车间预混区暂无空余储位"); } break; case "1"://混料设备申请储位(半成品桶申请储位) //判断是否有批次号 if (string.IsNullOrWhiteSpace(model.LotNo)) { throw new Exception("批次号为空!"); } //校验此批次是否有入库单 sql2 = $"select * from BllArrivalNoticeDetail where LotNo = '{model.LotNo}' order by CreateTime desc"; noticeDetail = Db.Ado.SqlQuery(sql2).FirstOrDefault(); if (noticeDetail == null) { throw new Exception("该批次没有对应的入库单"); } noticeno = noticeDetail.Id.ToString(); sql += $" and (AreaNo like '%03' or AreaNo like '%13' or AreaNo like '%23' or AreaNo like '%33') and WareHouseNo = '{houseNo}'"; loction = Db.Ado.SqlQuery(sql).OrderByDescending(a => a.CreateTime).FirstOrDefault(); if (loction == null) { throw new Exception("该车间半成品区暂无空余储位"); } break; case "2"://下料设备申请储位(脏桶申请储位) sql += $" and (AreaNo like '%04' or AreaNo like '%14' or AreaNo like '%24' or AreaNo like '%34') and WareHouseNo = '{houseNo}'"; loction = Db.Ado.SqlQuery(sql).OrderByDescending(a => a.CreateTime).FirstOrDefault(); if (loction == null) { throw new Exception("该车间脏桶区暂无空余储位"); } break; } var task = new TaskDetial { Startport = model.Location, Endport = loction.LocatNo, Pallno = model.PalletNo, Type = model.Type, Crtype = "0",//入库 Noticedetailno = int.Parse(noticeno), LotNo = model.LotNo, }; CreateLotTask(task,url); } catch (Exception ex) { throw new Exception(ex.Message); } } /// /// 生成任务单到LogTask /// /// /// public void CreateLotTask(TaskDetial taskDetial,string url) { try { var stockDetail = Db.Queryable().First(w => w.IsDel == "0" && w.PalletNo == taskDetial.Pallno);//桶库存明细 if (stockDetail == null) { throw new Exception($"该桶未在库存中,桶号:{taskDetial.Pallno}"); } //开启事务 Db.BeginTran(); var typeDesc = ""; switch (taskDetial.Crtype) { case "0": typeDesc = "入库"; break; case "1": typeDesc = "出库"; break; case "2": typeDesc = "移库"; break; } var msg = ""; switch (taskDetial.Type) { case "0": msg = "净桶"+ typeDesc + "任务"; break; case "1": msg = "预混料桶" + typeDesc + "任务"; break; case "2": msg = "半成品料桶" + typeDesc + "任务"; break; case "3": msg = "脏桶" + typeDesc + "任务"; break; } var sql = ""; var sql2 = ""; var ordertype = "3"; //涉及出入库单据的状态信息改变 if (taskDetial.Type == "2" && taskDetial.Crtype == "1")//半成品出库 { ordertype = "1"; sql = $"UPDATE BllExportNotice SET Status ='1' " + $"where SoNO = (select SoNO from BllExportNoticeDetail where id = {taskDetial.Noticedetailno})"; Db.Ado.ExecuteCommand(sql); } else if (taskDetial.Type == "0" && taskDetial.Crtype == "0")//接料设备申请储位(混料桶申请储位) { stockDetail.LotNo = taskDetial.LotNo;//批次号 //更新桶库存明细批次号 Db.Updateable(stockDetail).ExecuteCommand(); } else if (taskDetial.Type == "1" && taskDetial.Crtype == "0")//混料设备申请储位(半成品桶申请储位) { ordertype = "0"; var ArrivalMsg = Db.Queryable().First(it => it.Id == taskDetial.Noticedetailno); //修改入库单总表中单据状态为正在执行 sql = $"UPDATE BllArrivalNotice SET Status ='1' where asnno = '{ArrivalMsg.ASNNo}'"; Db.Ado.ExecuteCommand(sql); //库存中添加此托盘物料编码和编码名称 sql2 = $"UPDATE DataStockDetail SET SkuNo = '{ArrivalMsg.SkuNo}',SkuName = '{ArrivalMsg.SkuName}' " + $"where PalletNo = '{taskDetial.Pallno}'and LotNo = '{taskDetial.LotNo}'"; Db.Ado.ExecuteCommand(sql2); } //判断任务是否为新任务 if (string.IsNullOrWhiteSpace(taskDetial.Taskno)) { taskDetial.Taskno = new Common().GetMaxNo("TK"); } var logTaskEntry = new LogTask { TaskNo = taskDetial.Taskno, Sender = "WMS", Receiver = "RCS", //IsSuccess = 1, //是否下发成功 0失败 1成功 SendDate = DateTime.Now, //发送时间 //BackDate = DateTime.Now, //返回时间 StartLocat = taskDetial.Startport,//起始位置 EndLocat = taskDetial.Endport,//目标位置 PalletNo = taskDetial.Pallno,//托盘码 IsSend = 1,//是否可再次下发 IsCancel = 1,//是否可取消 IsFinish = 1,//是否可完成 Type = taskDetial.Crtype,//任务类型 0 入库任务 1 出库任务 2 移库任务 OrderType = ordertype,//单据类型 0 入库 1 出库 3其他 Status = "0",//任务状态0:等待执行1正在执行2执行完成 NoticeDetailNo = int.Parse(taskDetial.Noticedetailno.ToString()), Msg = msg, //关键信息 }; #region 呼叫小车代码 List agvTaskList = new List(); List pahtList = new List(); //起始位置 PositionCodePath path1 = new PositionCodePath(); path1.positionCode = taskDetial.Startport; if (taskDetial.Crtype == "1")//叫桶(桶出库) { path1.type = "00"; } else//申请储位(桶入库) { path1.type = "05"; } pahtList.Add(path1); //目标位置 PositionCodePath path2 = new PositionCodePath(); path2.positionCode = taskDetial.Endport; if (taskDetial.Crtype == "1")//叫桶(桶出库) { path2.type = "05"; } else//申请储位(桶入库) { path2.type = "00"; } pahtList.Add(path2); //下车任务单 AgvSchedulingTask agvTask = new AgvSchedulingTask(); agvTask.reqCode = logTaskEntry.TaskNo;//任务号 agvTask.ctnrTyp = "1"; agvTask.reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");//请求时间 agvTask.wbCode = ""; agvTask.positionCodePath = pahtList;//小车路径 agvTask.podCode = ""; agvTask.userCallCode = taskDetial.Endport;//目标位置 if (taskDetial.Crtype == "1")//叫桶(桶出库) { agvTask.taskTyp = "Z3";//任务类型 线边到托盘收集器 Z1, 托盘垛申请入库 Z2 } else//申请储位(桶入库) { agvTask.taskTyp = "Z4";//任务类型 线边到托盘收集器 Z1, 托盘垛申请入库 Z2 } agvTaskList.Add(agvTask); // 正式运行程序放开 string str = ""; var list2 = agvTaskList.Select(m => m.reqCode).ToList(); var jsonData = JsonConvert.SerializeObject(agvTaskList); jsonData = jsonData.Substring(1); jsonData = jsonData.Substring(0, jsonData.Length - 1); string response = ""; try { logTaskEntry.SendDate = DateTime.Now;//发送时间 response = HttpHelper.DoPost(url, jsonData, "下发给AGV转运命令", "AGV"); //解析返回数据 var agvModel = JsonConvert.DeserializeObject(response); if (agvModel.Code == "0") { str += "下发成功"; //请求成功修改任务表相应字段状态 logTaskEntry.IsSuccess = 1; logTaskEntry.BackDate = DateTime.Now; logTaskEntry.Status = "1"; if (taskDetial.Crtype == "0" || taskDetial.Crtype == "2") { sql = $"UPDATE SysStorageLocat SET Status = '2' where LocatNo = '{taskDetial.Endport}'"; if (taskDetial.Type == "2") { sql2 = $"UPDATE DataStockDetail SET PalletStatus = '{taskDetial.Type}'" + $"where PalletNo = '{taskDetial.Pallno}'"; Db.Ado.ExecuteCommand(sql2); } } else { sql = $"UPDATE SysStorageLocat SET Status = '3' where LocatNo = '{taskDetial.Startport}' "; } Db.Insertable(logTaskEntry).ExecuteCommand(); Db.Ado.ExecuteCommand(sql); } if (agvModel.Code == "1") { logTaskEntry.IsSuccess = 0; Db.Insertable(logTaskEntry).ExecuteCommand(); Db.CommitTran(); throw new Exception("RCS任务下发错误,RCS返回消息:" + agvModel.Message); } } catch (Exception ex) { throw new Exception(ex.Message); } #endregion //提交事务 Db.CommitTran(); } catch (Exception ex) { Db.RollbackTran(); throw ex; } } } }