using Microsoft.IdentityModel.Protocols; using Newtonsoft.Json; using SqlSugar; using System; using System.Collections.Generic; using System.Linq; 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 pallnetmsg) { DataStockDetail pallet = new DataStockDetail(); SysStorageLocat locat = new SysStorageLocat(); try { var house = "W01";//叫桶位置,后续根据位置关联或定义,来判断叫桶位置所属车间 var url = "";//回传MES的接口地址 var noticeno = "0";//出入库单据明细ID var sql = "select PalletNo,LocatNo from DataStockDetail where Status = '0'"; switch (pallnetmsg.Type) { case "0"://叫净桶 List jtpallet = new List(); sql += $"and WareHouseNo = '{house}' and AreaNo like '%01' order by CreateTime desc"; jtpallet = Db.Ado.SqlQuery(sql).ToList(); if (jtpallet.Count == 0) { throw new Exception("暂无净桶可分配"); } //遍历库存净桶,返回MES验证 foreach (var item in jtpallet) { string jsonReq = JsonConvert.SerializeObject(item.PalletNo); var response = HttpHelper.DoPost(url, jsonReq, "回传MES净桶编号", "RCS").ToString(); var obj = JsonConvert.DeserializeObject(response);//解析返回数据 if (obj.Success == "0") { if (obj.Result != "0")//可用,生成小车拉净桶任务 { //查找是否有空余脏桶位 sql = $"select LocatNo from SysStorageLocat where AreaNo like '%04' and WareHouseNo = wareno and Status = 0"; locat = Db.Ado.SqlQuery(sql).FirstOrDefault(); if (locat == null) { Db.Ado.BeginTran(); //脏桶区无空余库位,则锁定此净桶库存,并重新遍历 sql = $"UPDATE DataStockDetail Set Status = '5' Where locat ='{locat.LocatNo}'"; Db.Ado.ExecuteCommand(sql); Db.Ado.CommitTran(); break; } //生成调度小车净桶去脏桶区任务 var ztask = new TaskDetial { Startport = item.LocatNo, Endport = locat.LocatNo, Pallno = item.PalletNo, Type = "4", Crtype = "0", Noticedetailno = int.Parse(noticeno), }; CreateLotTask(ztask); return; } //下发小车任务 var task2 = new TaskDetial { Startport = item.LocatNo, Endport = pallnetmsg.Location, Pallno = item.PalletNo, Type = pallnetmsg.Type, Crtype = "1", Noticedetailno = int.Parse(noticeno), }; CreateLotTask(task2); return; } else { throw new Exception("回传MES净桶编号失败!"); } } break; case "1"://叫料桶(混料) //判断是否有批次号 if (string.IsNullOrWhiteSpace(pallnetmsg.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 a.LotNo = '{pallnetmsg.LotNo}'and AreaNo like '%02' " + $"and a.WareHouseNo = '{house}' and b.status = '0' 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(pallnetmsg.LotNo)) { throw new Exception("批次号为空!"); } //查找是否有此批次出库单 sql = $"select * from BllSoNoticeDetail where LotNo = '{pallnetmsg.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 a.LotNo = '{pallnetmsg.LotNo}'and AreaNo like '%03' " + $"and a.WareHouseNo = '{house}' and b.status = '0' 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' order by CreateTime desc"; pallet = Db.Ado.SqlQuery(sql).FirstOrDefault(); if (pallet == null) { throw new Exception("暂无脏桶可分配"); } break; } //下发小车任务 var task = new TaskDetial { Startport = pallet.LocatNo, Endport = pallnetmsg.Location, Pallno = pallet.PackagNo, Type = pallnetmsg.Type, Crtype = "1", Noticedetailno = int.Parse(noticeno), }; CreateLotTask(task); return; } catch (Exception ex) { Db.Ado.RollbackTran(); throw ex; } } /// /// 申请储位 /// /// /// public void ApplyLocatNo(Pallnetmsg pallnetmsg) { var sql = $"select LocatNo from SysStorageLocat where status = '0'"; var sql2 = ""; var house = "W01";//……叫桶位置,后续根据位置关联或定义,来判断叫桶位置所属车间 var noticeno = "";//出入库单据明细ID SysStorageLocat loction = new SysStorageLocat(); BllArrivalNoticeDetail ArriveMes = new BllArrivalNoticeDetail(); try { switch (pallnetmsg.Type) { case "0"://净桶申请储位 sql += $"and AreaNo like '%01' and WareHouseNo = {house}"; loction = Db.Ado.SqlQuery(sql).OrderByDescending(a => a.CreateTime).FirstOrDefault(); if (loction == null) { throw new Exception("库内暂无空余净桶储位"); } break; case "1"://混料桶申请储位 //判断是否有批次号 if (string.IsNullOrWhiteSpace(pallnetmsg.LotNo)) { throw new Exception("批次号为空!"); } //校验此批次是否有入库单 /*sql2 = $"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 += $"and AreaNo like '%02' and WareHouseNo = {house}"; loction = Db.Ado.SqlQuery(sql).OrderByDescending(a => a.CreateTime).FirstOrDefault(); if (loction == null) { throw new Exception("库内暂无空余混料桶储位"); } break; case "2"://半成品桶申请储位 //判断是否有批次号 if (string.IsNullOrWhiteSpace(pallnetmsg.LotNo)) { throw new Exception("批次号为空!"); } //校验此批次是否有入库单 sql2 = $"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 += $"and AreaNo like '%03' and WareHouseNo = {house}"; loction = Db.Ado.SqlQuery(sql).OrderByDescending(a => a.CreateTime).FirstOrDefault(); if (loction == null) { throw new Exception("库内暂无空余半成品桶储位"); } break; case "3"://脏桶申请储位 sql += $"and AreaNo like '%04' and WareHouseNo = {house}"; loction = Db.Ado.SqlQuery(sql).OrderByDescending(a => a.CreateTime).FirstOrDefault(); if (loction == null) { throw new Exception("库内暂无空余脏桶储位"); } break; } var task = new TaskDetial { Startport = pallnetmsg.Location, Endport = loction.LocatNo, Pallno = pallnetmsg.Palletno, Type = pallnetmsg.Type, Crtype = "0", Noticedetailno = int.Parse(noticeno), }; CreateLotTask(task); } catch (Exception) { throw; } } /// /// RCS生成任务 /// /// /// /// 起始位置 /// 目的位置 /// /// RCS地址 /// public genAgvSchedulingTaskRep genAgvSchedulingTask(AgvTask agv,string url) { try { genAgvSchedulingTaskRep cbrep = new genAgvSchedulingTaskRep(); PositionCodePath pcd1 = new PositionCodePath() { positionCode = agv.startPos.ToString(), type = "00", }; PositionCodePath pcd2 = new PositionCodePath() { positionCode = agv.endPos.ToString(), type = "00", }; List lst = new List(); lst.Add(pcd1); lst.Add(pcd2); genAgvSchedulingTaskReq cbreq = new genAgvSchedulingTaskReq() { reqCode = agv.taskCode.ToString(), taskCode = agv.taskCode.ToString(), taskTyp = agv.taskType, positionCodePath = lst, podCode = "", agvCode = agv.agvCode, ctnrTyp = "1", //ctnrCode="2", }; cbrep = genAgvSchedulingTask(cbreq,url); return cbrep; } catch (Exception ex) { throw ex; } } /// /// 生成任务单 /// /// /// private genAgvSchedulingTaskRep genAgvSchedulingTask(genAgvSchedulingTaskReq req,string url) { genAgvSchedulingTaskRep rep = new genAgvSchedulingTaskRep() { code = "-1", message = "生产任务单失败" }; if (req == null) { return rep; } try { string jsonReq = JsonConvert.SerializeObject(req); string jsonRep = HttpHelper.DoPost(url + "/genAgvSchedulingTask", jsonReq,"小车任务下发","RCS"); jsonRep = jsonRep.TrimStart('\"'); jsonRep = jsonRep.TrimEnd('\"'); jsonRep = jsonRep.Replace("\\", ""); rep = JsonConvert.DeserializeObject(jsonRep); return rep; } catch (Exception ex) { throw ex; } } /// /// 生成任务单到LogTask /// /// /// public void CreateLotTask(TaskDetial taskDetial) { try { var na = taskDetial.Crtype == "0"?"入库":"出库"; var sql = ""; var sql2 = ""; var ordertype = "3"; if (taskDetial.Type == "2" && taskDetial.Crtype =="1") { ordertype = "1"; } else if(taskDetial.Type =="2" && taskDetial.Crtype == "0") { ordertype = "0"; } //开启事务 Db.BeginTran(); //判断任务是否为新任务 if (string.IsNullOrWhiteSpace(taskDetial.Taskno)) { taskDetial.Taskno = new Common().GetMaxNo("T"); } 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 = $"{taskDetial.Endport}的{na}任务", //关键信息 }; var Agv = new AgvTask { taskCode = taskDetial.Taskno, taskType = taskDetial.Type, startPos = taskDetial.Startport, endPos = taskDetial.Endport, agvCode = "1",//……需要和AGV确认此字段值 }; //请求小车 genAgvSchedulingTaskRep chrep =genAgvSchedulingTask(Agv, "url"); if (chrep.code != "0") { logTaskEntry.IsSuccess = 0; Db.Insertable(logTaskEntry).ExecuteCommand(); Db.CommitTran(); throw new Exception("RCS任务下发错误,RCS返回消息:" + chrep.message); } logTaskEntry.IsSuccess = 1; logTaskEntry.BackDate = DateTime.Now; logTaskEntry.Status = "1"; if (taskDetial.Crtype == "0") { sql = $"UPDATE SysStorageLocat SET Status = '2' where LocatNo = '{taskDetial.Endport}'"; 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); //提交事务 Db.CommitTran(); } catch (Exception ex) { Db.RollbackTran(); throw ex; } } } }