using HH.WCS.JiaTong.device; using HH.WCS.JiaTong.dispatch; using HH.WCS.JiaTong.LISTA.models; using HH.WCS.JiaTong.process; using HH.WCS.JiaTong.util; using HH.WCS.JiaTong.wms; using Newtonsoft.Json; using NLog.Fluent; using S7.Net; using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using static HH.WCS.JiaTong.api.ApiModel; using static HH.WCS.JiaTong.api.OtherModel; using static HH.WCS.JiaTong.LISTA.process.HttpModel; namespace HH.WCS.JiaTong.api { /// /// api接口辅助类 /// public class ApiHelper { static ApiHelper() { } #region 佳通合肥接口业务 /// /// 立库任务下发=》创建任务 /// /// /// internal static Result Createtask(CreateTask model) { Result result = new Result() { code = "0", msg = "创建成功" }; if (model == null) { LogHelper.Info($"Createtask==> 参数为null"); result.code = "1"; result.msg = "参数为null值,请检查参数格式"; AddErrorInfo("下发参数为null", result.msg); return result; } partData partData = model.partData; taskData taskData = model.taskData; try { var db = new SqlHelper().GetInstance(); string CntrCode = "";//托盘编码 string ItemCode = "";//物料编码 if (partData != null) { CntrCode = partData.rfid;//托盘编码 ItemCode = partData.partNumber;//物料编码 } string Start = ""; //取货点 string End = ""; string areacode = ""; string note = ""; //立库下发任务需要通知mes接口物料到位,用备注自动进行区分 //根据物料获取对应库区 #region 根据物料确认出库来源 var iteminfo = db.Queryable().Where(a => a.S_ITEM_CODE.Trim() == ItemCode).First(); if (iteminfo != null) { //LogHelper.Info($"Createtask==>物料数据:{JsonConvert.SerializeObject(iteminfo)}"); areacode = iteminfo.S_WH_CODE; } if (string.IsNullOrEmpty(areacode)) { LogHelper.Info($"Createtask==>根据物料编码:{ItemCode}未能找到物料来源,需同步物料数据"); result.code = "1"; result.msg = $"根据物料编码:{ItemCode}未能找到物料来源,需同步物料数据"; AddErrorInfo("寻找出库区失败", result.msg); return result; } //var task = db.Queryable().Where(a => a.S_EQ_NO.Trim() == taskData.taskNum).First(); //if (task != null) //{ // LogHelper.Info($"Createtask==> 任务号{taskData.taskNum},该任务已经存在,不允许创建任务"); // result.code = "1"; // result.msg = $"任务号{taskData.taskNum},该任务已经存在,不允许创建任务"; // return result; //} int n_type = 0; //任务来源 1.钢丝立库 2.胶片库 3.预备库 ,4.原材料库,通过物料确认任务来源 string Source = ""; switch (areacode) { case "ML": n_type = 1; Source = "密炼"; break; case "JP": n_type = 2; Source = "井松"; break; case "YBK": n_type = 3; Source = "预备库"; break; case "wmwhse1": n_type = 4; Source = "原材料"; break; } LogHelper.Info($"Createtask==>任务类型:{n_type}"); if (n_type == 0) { result.code = "1"; result.msg = $"物料库区:{areacode}属于未定义库区,请检查物料表重新定义物料库区"; AddErrorInfo("物料库区未定义", result.msg); return result; } #endregion Location endloc = new Location(); Location startloc = new Location(); if (taskData.taskType == 1) //出库流程,通过物料机台计算线边货位 { note = "出库"; startloc = db.Queryable().Where(a => a.S_CODE.Trim() == taskData.pickStation).First(); if (startloc != null) { //创建托盘物料绑定信息,并计算终点货位 Start = taskData.pickStation; if (CreateCntrIteminfo(Start, CntrCode, ItemCode, partData.partDesc, partData.partType, partData.lotNumber, partData.unit, partData.weight, taskData.carrierType, taskData.grade)) { endloc = Computeloc(CntrCode, taskData.dropStation, taskData.carrierType); if (endloc != null) { End = endloc.S_CODE; } else { result.code = "1"; result.msg = $"机台编码:{taskData.dropStation},未找到可用货位"; AddErrorInfo("寻找出库货位失败", result.msg, Source); return result; } } else { result.code = "1"; result.msg = "创建托盘物料信息失败"; AddErrorInfo("创建托盘失败", result.msg, Source); return result; } } else { result.code = "1"; result.msg = $"Putin==> 任务起点:{taskData.pickStation}找不到对应货位,请检查货位表"; LogHelper.Info($"Putin==> {result.msg}"); AddErrorInfo("货位查找失败", result.msg, Source); } } else if (taskData.taskType == 2)//入库流程,直接使用起点货位和终点货位生成任务,起点需要有托盘 { startloc = db.Queryable().Where(a => a.S_CODE.Trim() == taskData.pickStation).First(); if (startloc != null) { var CntrRel = LocationHelper.GetLocCntrRel(startloc.S_CODE).FirstOrDefault(); if (CntrRel != null) { Start = startloc.S_CODE; CntrCode = CntrRel.S_CNTR_CODE; } else { result.code = "1"; result.msg = $"根据起点{Start},未找到托盘货位绑定关系"; AddErrorInfo("托盘查找失败", result.msg, Source); return result; } } //判断是否是空托回库 var CntrItem = db.Queryable().Where(a => a.S_CNTR_CODE.Trim() == CntrCode).First(); if (CntrItem == null) { note = "空托回库";//井松空托回库,需要与叠盘机安全交互 } endloc = db.Queryable().Where(a => a.S_CODE.Trim() == taskData.dropStation).First(); if (endloc != null) { End = taskData.dropStation; } else { result.code = "1"; result.msg = $"根据终点{End},找不到对应货位,请检查货位表"; AddErrorInfo("货位查找失败", result.msg, Source); return result; } } else if (taskData.taskType == 3)//移库流程,直接使用起点货位和终点货位生成任务, { //创建托盘物料绑定信息,并计算终点货位 startloc = db.Queryable().Where(a => a.S_CODE.Trim() == taskData.pickStation).First(); if (startloc != null) { Start = taskData.pickStation; } else { result.code = "1"; result.msg = $"根据起点{taskData.pickStation},找不到对应货位,请检查货位表"; AddErrorInfo("货位查找失败", result.msg, Source); return result; } endloc = db.Queryable().Where(a => a.S_CODE.Trim() == taskData.dropStation).First(); if (endloc != null) { End = taskData.dropStation; } else { result.code = "1"; result.msg = $"根据终点{taskData.dropStation},找不到对应货位,请检查货位表"; AddErrorInfo("货位查找失败", result.msg, Source); return result; } } else if (taskData.taskType == 4)//原材料库需要判断是否需要分配电梯任务,创建分档任务 { startloc = db.Queryable().Where(a => a.S_CODE.Trim() == taskData.pickStation).First(); if (startloc != null) { Start = taskData.pickStation; } endloc = db.Queryable().Where(a => a.S_CODE.Trim() == taskData.dropStation).First(); if (endloc != null) { End = taskData.dropStation; } //判断楼层是否相等,如果不相同需要生成分段任务进行电梯调用 if (!string.IsNullOrEmpty(Start) && !string.IsNullOrEmpty(End)) { var startArea = db.Queryable().Where(a => a.S_CODE.Trim() == startloc.S_AREA_CODE).First(); var endArea = db.Queryable().Where(a => a.S_CODE.Trim() == endloc.S_AREA_CODE).First(); if (startArea == null || endArea == null) { result.code = "1"; result.msg = $"创建任务失败,起点:{startloc.S_AREA_CODE},终点:{endloc.S_AREA_CODE}未找到对应库区"; AddErrorInfo("货位查找失败", result.msg, Source); return result; } if (startArea.N_FLOOR == endArea.N_FLOOR) { //创建wcs任务 var wcsTask = new WCSTask { S_CODE = WCSHelper.GenerateTaskNo(), S_TYPE = startArea.S_NAME + "->" + endArea.S_NAME, S_EQ_NO = taskData.taskNum, S_START_LOC = Start, S_END_LOC = End, N_CNTR_COUNT = 1, S_START_WH = startloc.S_WH_CODE, S_START_AREA = startloc.S_AREA_CODE, S_END_WH = endloc.S_WH_CODE, S_END_AREA = endloc.S_AREA_CODE, N_SCHEDULE_TYPE = 1, S_CNTR_CODE = CntrCode, N_PRIORITY = taskData.priority, N_START_LAYER = 1, N_END_LAYER = 1, S_WMS_NO = taskData.wmsTaskNo, Z_TYPE = n_type }; LogHelper.Info("创建任务:" + JsonConvert.SerializeObject(wcsTask), "CreateTask"); if (WCSHelper.CreateTask(wcsTask)) { LocationHelper.LockLoc(Start, 2); LogHelper.Info("创建任务成功"); } } else if (startArea.N_FLOOR != endArea.N_FLOOR) { //楼层电梯分配 var endloc1 = Settings.elevatorLoc.Find(a => a.Floor == startArea.N_FLOOR); var startloc1 = Settings.elevatorLoc.Find(a => a.Floor == endArea.N_FLOOR); //创建wcs分段任务 var wcsTask = new WCSTask { S_CODE = WCSHelper.GenerateTaskNo(), S_TYPE = "电梯1", S_EQ_NO = taskData.taskNum, S_START_LOC = Start, S_END_LOC = endloc1.Location[0], N_CNTR_COUNT = 1, S_START_WH = startloc.S_WH_CODE, S_START_AREA = startloc.S_AREA_CODE, S_END_WH = endloc.S_WH_CODE, S_END_AREA = endloc.S_AREA_CODE, N_SCHEDULE_TYPE = 1, S_CNTR_CODE = CntrCode, N_PRIORITY = taskData.priority, N_START_LAYER = 1, N_END_LAYER = 1, S_WMS_NO = taskData.wmsTaskNo, Z_TYPE = n_type }; var wcsTask1 = new WCSTask { S_CODE = WCSHelper.GenerateTaskNo(), S_TYPE = "电梯2", S_EQ_NO = taskData.taskNum, S_START_LOC = startloc1.Location[0], S_END_LOC = End, N_CNTR_COUNT = 1, S_START_WH = startloc.S_WH_CODE, S_START_AREA = startloc.S_AREA_CODE, S_END_WH = endloc.S_WH_CODE, S_END_AREA = endloc.S_AREA_CODE, N_SCHEDULE_TYPE = 1, S_CNTR_CODE = CntrCode, N_PRIORITY = taskData.priority, S_WMS_NO = taskData.wmsTaskNo, N_START_LAYER = 1, N_END_LAYER = 1, Z_TYPE = n_type }; LogHelper.Info("创建任务:" + JsonConvert.SerializeObject(wcsTask), "CreateTask"); if (WCSHelper.CreateTask(wcsTask) && WCSHelper.CreateTask(wcsTask1)) { LocationHelper.LockLoc(endloc.S_CODE, 1); LogHelper.Info("创建任务成功"); } } } else { result.code = "1"; result.msg = "创建任务失败,未找到对应的取货点或卸货点"; return result; } } else if (taskData.taskType == 5)//移库流程,直接使用起点货位和终点货位生成任务,并绑定托盘 { //创建托盘物料绑定信息,并计算终点货位 if (CreateCntrIteminfo(taskData.pickStation, CntrCode, ItemCode, partData.partDesc, partData.partType, partData.lotNumber, partData.unit, partData.weight, taskData.carrierType, taskData.grade)) { startloc = db.Queryable().Where(a => a.S_CODE.Trim() == taskData.pickStation).First(); if (startloc != null) { Start = taskData.pickStation; } else { result.code = "1"; result.msg = $"根据起点{taskData.pickStation},找不到对应货位,请检查货位表"; AddErrorInfo("货位查找失败", result.msg, Source); return result; } endloc = db.Queryable().Where(a => a.S_CODE.Trim() == taskData.dropStation).First(); if (endloc != null) { End = taskData.dropStation; } else { result.code = "1"; result.msg = $"根据终点{taskData.dropStation},找不到对应货位,请检查货位表"; AddErrorInfo("货位查找失败", result.msg, Source); return result; } } else { result.code = "1"; result.msg = "创建托盘物料信息失败"; AddErrorInfo("创建托盘失败", result.msg, Source); return result; } } //暂存位回库 else if (taskData.taskType == 6)//入库流程,直接使用起点货位和终点货位生成任务 { //根据托盘号找货位 var CntrRel = db.Queryable().Where(a => a.S_CNTR_CODE == partData.rfid).First(); if (CntrRel != null) { startloc = db.Queryable().Where(a => a.S_CODE.Trim() == CntrRel.S_LOC_CODE).First(); if (startloc != null) { Start = startloc.S_CODE; CntrCode = CntrRel.S_CNTR_CODE; } else { result.code = "1"; result.msg = $"根据托盘{partData.rfid},未找到托盘货位绑定关系"; AddErrorInfo("货位查找失败", result.msg, Source); return result; } } endloc = db.Queryable().Where(a => a.S_CODE.Trim() == taskData.dropStation).First(); if (endloc != null) { End = taskData.dropStation; } else { result.code = "1"; result.msg = $"根据终点{End},找不到对应货位,请检查货位表"; AddErrorInfo("货位查找失败", result.msg, Source); return result; } } //点对库区 else if (taskData.taskType == 7)//异常位 { note = "异常库区入库"; //创建托盘物料绑定信息,并计算终点货位 if (CreateCntrIteminfo(taskData.pickStation, CntrCode, ItemCode, partData.partDesc, partData.partType, partData.lotNumber, partData.unit, partData.weight, taskData.carrierType, taskData.grade)) { startloc = db.Queryable().Where(a => a.S_CODE.Trim() == taskData.pickStation).First(); if (startloc != null) { Start = taskData.pickStation; } var EndLocs = db.Queryable().Where(a => a.S_AREA_CODE.Trim() == taskData.dropStation).ToList(); if (EndLocs.Count > 0) { endloc = EndLocs.Find(a => a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0); if (endloc != null) { End = endloc.S_CODE; } else { result.code = "1"; result.msg = $"终点库区:{taskData.dropStation}无可用货位"; AddErrorInfo("查找库区失败", result.msg, Source); return result; } } else { result.code = "1"; result.msg = $"根据终点库区:{taskData.dropStation},未找到对应货位"; AddErrorInfo("查找库区失败", result.msg, Source); return result; } } else { result.code = "1"; result.msg = "创建托盘物料信息失败"; AddErrorInfo("创建托盘失败", result.msg, Source); return result; } } else if (taskData.taskType == 8)//叠盘机空托回库 { note = "空托回库";//井松空托回库,需要与叠盘机安全交互 startloc = db.Queryable().Where(a => a.S_CODE.Trim() == taskData.pickStation).First(); if (startloc != null) { Start = startloc.S_CODE; } else { result.code = "1"; result.msg = $"根据起点:{taskData.pickStation},找不到对应货位,请检查货位表"; AddErrorInfo("货位查找失败", result.msg, Source); return result; } endloc = db.Queryable().Where(a => a.S_CODE.Trim() == taskData.dropStation).First(); if (endloc != null) { End = taskData.dropStation; } else { result.code = "1"; result.msg = $"根据终点:{End},找不到对应货位,请检查货位表"; AddErrorInfo("货位查找失败", result.msg, Source); return result; } } else { LogHelper.Info($"Createtask==> 任务类型有误"); result.code = "1"; result.msg = "任务类型:{taskData.taskType}不在规定范围内"; AddErrorInfo("任务类型错误", result.msg, Source); } if (taskData.taskType != 4) { if (!string.IsNullOrEmpty(Start) && !string.IsNullOrEmpty(End)) { if (startloc.N_LOCK_STATE != 0) { result.code = "1"; result.msg = $"创建任务失败,起点{Start}有锁"; AddErrorInfo("货位有锁", result.msg); return result; } var startArea = db.Queryable().Where(a => a.S_CODE.Trim() == startloc.S_AREA_CODE.Trim()).First(); var endArea = db.Queryable().Where(a => a.S_CODE.Trim() == endloc.S_AREA_CODE.Trim()).First(); if (startArea == null || endArea == null) { LogHelper.Info($"起点:{JsonConvert.SerializeObject(startArea)}"); LogHelper.Info($"终点:{JsonConvert.SerializeObject(endArea)}"); result.code = "1"; result.msg = $"创建任务失败,起点:{startloc.S_AREA_CODE},终点{endloc.S_AREA_CODE}未找到对应库区"; AddErrorInfo("库区查找失败", result.msg); return result; } //创建wcs任务 var wcsTask = new WCSTask { S_CODE = WCSHelper.GenerateTaskNo(), S_TYPE = startArea.S_NAME + "->" + endArea.S_NAME, S_EQ_NO = taskData.taskNum, S_START_LOC = Start, S_END_LOC = End, N_CNTR_COUNT = 1, S_START_WH = startloc.S_WH_CODE, S_END_WH = endloc.S_WH_CODE, S_END_AREA = endloc.S_AREA_CODE, N_SCHEDULE_TYPE = 1, S_CNTR_CODE = CntrCode, N_PRIORITY = taskData.priority, Z_TYPE = n_type, N_START_LAYER = 1, N_END_LAYER = 1, S_WMS_NO = taskData.wmsTaskNo, S_NOTE = note }; LogHelper.Info("创建任务:" + JsonConvert.SerializeObject(wcsTask), "CreateTask"); if (WCSHelper.CreateTask(wcsTask)) { LocationHelper.LockLoc(Start, 2); LocationHelper.LockLoc(End, 1); LogHelper.Info("创建任务成功"); } } else { result.code = "1"; result.msg = "创建任务失败,未找到对应的取货点或卸货点"; return result; } } return result; } catch (Exception ex) { result.code = "1"; result.msg = ex.ToString(); LogHelper.Error("Createtask Error:" + ex.ToString() + "行号:" + ex.StackTrace, ex); return result; } } /// /// 预备库任务状态下发 /// /// /// internal static Result MstStateInquire(MstStateInquire model) { Result result = new Result() { code = "200", msg = "状态下发成功" }; var db = new SqlHelper().GetInstance(); if (model == null) { LogHelper.Info($"MstStateInquire==> 参数为null"); result.code = "1"; result.msg = "参数为null值,请检查参数格式"; AddErrorInfo("参数为空", result.msg); return result; } try { //找到任务,修改任务状态 var task = db.Queryable().Where(a => a.S_EQ_NO.Trim() == model.taskNum).First(); if (task != null) { task.S_NOTE = model.taskStatus; db.Updateable(task).ExecuteCommand(); } else { result.code = "1"; result.msg = $"根据下发任务号{model.taskNum}未找到对应任务"; AddErrorInfo("未找到任务", result.msg); return result; } return result; } catch (Exception ex) { result.code = "1"; result.msg = ex.ToString(); LogHelper.Error("TrayItembind Error:" + ex.ToString(), ex); return result; } } /// /// 原材料库安全交互通知行走 /// /// /// internal static Result AllowThrough(AllowThrough model) { Result result = new Result() { code = "0", msg = "状态下发成功" }; if (model == null) { LogHelper.Info($"AllowThrough==> 参数为null"); result.code = "1"; result.msg = "参数为null值,请检查参数格式"; AddErrorInfo("参数为空", result.msg, "", model.task_no); return result; } var db = new SqlHelper().GetInstance(); try { string[] state = new string[] { "取消", "失败", "错误", "完成" }; //找到任务 var task = db.Queryable().Where(a => a.S_EQ_NO.Trim() == model.task_no && !state.Contains(a.S_B_STATE)).First(); if (task != null) { if (model.type == "1" || model.type == "2") { NDCApi.ChangeOrderParam(task.S_CODE.Trim(), 6, "1"); } } else { result.code = "1"; result.msg = $"根据下发任务号{model.task_no}未找到对应任务"; AddErrorInfo("未找到任务", result.msg, "", model.task_no); return result; } return result; } catch (Exception ex) { result.code = "1"; result.msg = ex.ToString(); LogHelper.Error("AllowThrough Error:" + ex.ToString(), ex); return result; } } /// /// 产出信息 /// /// /// internal static Result TrayItembind(TrayItembind model) { Result result = new Result() { code = "200", msg = "产出信息下发成功" }; if (model == null) { result.code = "1"; result.msg = "参数为null"; AddErrorInfo("参数为空", result.msg); return result; } try { //创建托盘数据绑定关系 if (ContainerHelper.CreateCntrItem(model.Rfid, model.PartNumber, model.PartDesc, model.LotNumber, model.Weight, model.Qty)) { //创建成功流程 } else { result.code = "1"; result.msg = "产出信息下发失败,托盘物料绑定关系创建失败"; AddErrorInfo("创建绑定关系失败", result.msg, "Mes"); return result; } return result; } catch (Exception ex) { result.code = "1"; result.msg = ex.ToString(); LogHelper.Error("TrayItembind Error:" + ex.ToString(), ex); return result; } } /// /// 入平库 /// /// /// 0:pda下发任务,5:mes下发任务 /// internal static Result Putin(Putin model, int n_type) { Result result = new Result() { code = "200", msg = "入平库任务下发成功" }; string Source = "Mes"; if (n_type == 0) { Source = "PDA"; } if (model == null) { result.code = "1"; result.msg = "参数为null"; AddErrorInfo("参数为空", result.msg, Source); return result; } var db = new SqlHelper().GetInstance(); Location loc = new Location(); string Start = model.InitialLocation; //起点货位 string itemcode = model.PartNumber; //物料编码 string areacode = ""; try { #region 判断托盘绑定货位是否和下发绑定起点相同,如果没绑定托盘则绑定托盘 var CntrLoc = db.Queryable().Where(a => a.S_CNTR_CODE.Trim() == model.Rfid).First(); if (CntrLoc != null) { if (CntrLoc.S_LOC_CODE != Start) { result.code = "1"; result.msg = $"创建任务失败,托盘:{model.Rfid}绑定位置不是起点:{Start}"; LogHelper.Info($"ItemBack:{result.msg}"); AddErrorInfo("托盘绑定位置不同", result.msg, Source); return result; } } else { LocationHelper.BindingLoc(Start, new List { model.Rfid }); //LogHelper.Info($"ItemBack:创建任务失败,托盘:{model.Rfid}未找到绑定货位"); //result.code = "1"; //result.msg = $"创建任务失败,托盘:{model.Rfid}未找到绑定货位"; //AddErrorInfo("查找托盘货位失败", result.msg); //return result; } // Console.WriteLine("查询货位绑定关系"); //判断托盘与货位是否有绑定关系,如果没有则进行绑定 // var cntrloc = db.Queryable().Where(a => a.S_CNTR_CODE.Trim() == model.Rfid).First(); // Console.WriteLine($"获取绑定关系:{JsonConvert.SerializeObject(cntrloc)}"); //if (cntrloc == null) //{ // // Console.WriteLine("绑定托盘"); // List cntrs = new List() { model.Rfid }; // LocationHelper.BindingLoc(Start, cntrs); //} //else //{ // if (cntrloc.S_LOC_CODE != Start) // { // LogHelper.Info($"Putin==>托盘:{model.Rfid}已和货位{cntrloc.S_LOC_CODE}有绑定关系"); // result.code = "1"; // result.msg = $"托盘:{model.Rfid}已和货位{cntrloc.S_LOC_CODE}有绑定关系"; // } //} #endregion #region 根据起点货位的仓库编码 获取平库编码,并计算入库货位 string End = ""; var startloc = db.Queryable().Where(a => a.S_CODE.Trim() == Start).First(); if (startloc != null) { //根据仓库 计算库区 if (startloc.S_WH_CODE == "101") { areacode = "PMGQ"; } else { areacode = "PK2"; } areacode = "FLPK"; //判断有无相同物料排 loc = StorageCompute(itemcode, areacode); if (loc == null) { //无相同物料排找空排 loc = emptyRow(areacode); } if (loc != null) { End = loc.S_CODE; } else { result.code = "1"; result.msg = $"库区:{areacode}无可用货位"; LogHelper.Info($"Putin==> {result.msg}"); AddErrorInfo("查找库区失败", result.msg, Source); } } else { result.code = "1"; result.msg = $"任务起点:{Start}找不到对应货位,请检查货位表"; LogHelper.Info($"Putin==> {result.msg}"); AddErrorInfo("查找货位失败", result.msg, Source); } #endregion #region 创建任务 if (!string.IsNullOrEmpty(Start) && !string.IsNullOrEmpty(End)) { if (startloc.N_LOCK_STATE != 0) { result.code = "1"; result.msg = $"创建任务失败,起点:{Start}有锁"; AddErrorInfo("货位有锁", result.msg, Source); return result; } //创建wcs任务 var wcsTask = new WCSTask { S_CODE = WCSHelper.GenerateTaskNo(), S_TYPE = "入平库", S_EQ_NO = model.TaskNumber, S_START_LOC = Start, S_END_LOC = End, S_START_WH = startloc.S_WH_CODE, S_START_AREA = startloc.S_AREA_CODE, S_END_WH = loc.S_WH_CODE, S_END_AREA = loc.S_AREA_CODE, N_CNTR_COUNT = 1, N_SCHEDULE_TYPE = 1, S_CNTR_CODE = model.Rfid, N_START_LAYER = 1, N_END_LAYER = 1, Z_TYPE = n_type }; LogHelper.Info("创建入平库任务:" + JsonConvert.SerializeObject(wcsTask)); if (WCSHelper.CreateTask(wcsTask)) { LocationHelper.LockLoc(Start, 2); LocationHelper.LockLoc(End, 1); LogHelper.Info("创建任务成功"); } } else { result.code = "1"; result.msg = "创建任务失败,未找到对应的取货点或卸货点"; return result; } #endregion return result; } catch (Exception ex) { result.code = "1"; result.msg = ex.ToString(); LogHelper.Error("Putin Error:" + ex.ToString(), ex); return result; } } /// /// 出平库 /// /// /// 0:pda下发任务,5:mes下发任务 /// internal static Result PutOut(PutOut model, int n_type) { Result result = new Result() { code = "200", msg = "出平库任务下发成功" }; string Source = "Mes"; if (n_type == 0) { Source = "PDA"; } if (model == null) { result.code = "1"; result.msg = "参数为null"; AddErrorInfo("参数为空", result.msg, Source); return result; } #region 变量 string Start = ""; string End = ""; string CntrCode = ""; string itemcode = model.PartNumber; string cntrType = ""; string areacode = ""; var db = new SqlHelper().GetInstance(); #endregion try { #region 根据物料编码规则 计算出库库区 //粉料从平库出库,其他物料需要从暂存区出库 if (model.PartNumber.StartsWith("4X")) { areacode = "FLPK"; cntrType = "PM"; } else { if (model.PartNumber.StartsWith("3")) { cntrType = "RC"; areacode = "KJZCW"; } else { result.code = "1"; result.msg = $"创建任务失败,物料号{model.PartNumber}不属于规定物料"; LogHelper.Info($"ItemBack:{result.msg}"); AddErrorInfo("物料编码格式错误", result.msg, Source); return result; } } //根据物料获取对应库区 // var iteminfo = db.Queryable().Where(a => a.S_ITEM_CODE.Trim() == itemcode).First(); //if (iteminfo != null) //{ // areacode = iteminfo.S_WH_CODE; //} //areacode = computeArea(itemcode); //if (string.IsNullOrEmpty(areacode)) //{ // LogHelper.Info($"PutOut==> 根据物料编码:{itemcode}找不到对应库区,请检查配置文件"); // result.code = "1"; // result.msg = $"根据物料编码:{itemcode}找不到对应库区,物料表配置"; // AddErrorInfo("查找库区失败", result.msg); //} //if (itemcode == "测试1") //{ // areacode = "PMJP"; //} #endregion #region 根据物料编码计算出库货位,送往线边位置 var Endloc = new Location(); //根据物料编码计算出库货位 var loc = airlift(areacode, itemcode, model.PartLevel); if (loc != null) { Start = loc.S_CODE; //根据出库货位找到绑定托盘,获取入机台货位 var CntrRel = LocationHelper.GetLocCntrRel(loc.S_CODE).FirstOrDefault(); CntrCode = CntrRel.S_CNTR_CODE; Endloc = Computeloc(CntrCode, model.WorkCenter, cntrType); if (Endloc != null) { End = Endloc.S_CODE; } } else { result.code = "1"; result.msg = $"任务物料:{itemcode}找不到对应库存"; LogHelper.Info($"ItemBack:{result.msg}"); AddErrorInfo("查找库区失败", result.msg, Source); } #endregion #region 任务创建 if (!string.IsNullOrEmpty(Start) && !string.IsNullOrEmpty(End)) { if (loc.N_LOCK_STATE != 0) { result.code = "1"; result.msg = $"创建任务失败,起点{Start}有锁"; AddErrorInfo("货位有锁", result.msg, Source); return result; } //创建wcs任务 var wcsTask = new WCSTask { S_CODE = WCSHelper.GenerateTaskNo(), S_TYPE = "出平库", S_EQ_NO = model.TaskNumber, S_START_LOC = Start, S_END_LOC = End, S_START_WH = loc.S_WH_CODE, S_START_AREA = loc.S_AREA_CODE, S_END_WH = Endloc.S_WH_CODE, S_END_AREA = Endloc.S_AREA_CODE, N_CNTR_COUNT = 1, N_SCHEDULE_TYPE = 1, S_CNTR_CODE = CntrCode, N_START_LAYER = 1, N_END_LAYER = 1, Z_TYPE = n_type }; LogHelper.Info("创建出平库任务:" + JsonConvert.SerializeObject(wcsTask)); if (WCSHelper.CreateTask(wcsTask)) { LogHelper.Info("创建任务成功"); LocationHelper.LockLoc(Start, 2); LocationHelper.LockLoc(End, 1); } } else { result.code = "1"; result.msg = "创建任务失败,未找到对应的取货点或卸货点"; return result; } #endregion return result; } catch (Exception ex) { result.code = "1"; result.msg = ex.ToString(); LogHelper.Error("PutOut Error:" + ex.ToString(), ex); return result; } } /// /// 空工装回库 /// /// /// internal static Result Empty(Empty model) { Result result = new Result() { code = "200", msg = "空工装回库任务下发成功" }; string Source = "MES"; if (model == null) { result.code = "1"; result.msg = "参数为null"; AddErrorInfo("参数为空", result.msg, Source); return result; } #region 变量 var db = new SqlHelper().GetInstance(); string Start = model.InitialLocation; string itemcode = ""; int endlayer = 1; Location loc = new Location(); string areacode = ""; WCSTask mst = new WCSTask(); List msts = new List(); #endregion try { #region 判断托盘绑定货位是否和下发绑定起点相同 var CntrLoc = db.Queryable().Where(a => a.S_CNTR_CODE.Trim() == model.Rfid).First(); if (CntrLoc != null) { if (CntrLoc.S_LOC_CODE != Start) { LogHelper.Info($"ItemBack:创建任务失败,托盘:{model.Rfid}绑定位置不是起点:{Start}"); result.code = "1"; result.msg = $"创建任务失败,托盘:{model.Rfid}绑定位置不是起点:{Start}"; AddErrorInfo("托盘绑定位置不同", result.msg); return result; } } else { LogHelper.Info($"ItemBack:创建任务失败,托盘:{model.Rfid}未找到绑定货位"); result.code = "1"; result.msg = $"创建任务失败,托盘:{model.Rfid}未找到绑定货位"; AddErrorInfo("查找托盘货位失败", result.msg); return result; } #endregion #region 根据货位楼层判断,3楼去往叠盘位 其他的回库 var startloc = db.Queryable().Where(a => a.S_CODE.Trim() == Start).First(); if (startloc != null) { if (startloc.N_LAYER == 3) { //叠盘货位计算叠盘货位 var dploc = db.Queryable().Where(a => a.S_NOTE.Trim() == "叠盘" && a.N_LAYER == startloc.N_LAYER && a.S_WH_CODE.Trim() == startloc.S_WH_CODE).ToList(); if (dploc.Count > 0) { // LogHelper.Info($"获取叠盘货位:{JsonConvert.SerializeObject(dploc)}"); loc = dploc.FindAll(a => a.N_LOCK_STATE == 0 && a.N_CURRENT_NUM < 6).OrderByDescending(a => a.N_CURRENT_NUM).FirstOrDefault(); if (loc == null) { result.code = "1"; result.msg = $"叠盘货位不可用"; AddErrorInfo("查找库区失败", result.msg, Source); return result; } else { endlayer = loc.N_CURRENT_NUM + 1; } } else { result.code = "1"; result.msg = $"叠盘货位不可用"; LogHelper.Info($"根据货位备注:叠盘,货位楼层:{startloc.N_LAYER},货位仓库:{startloc.S_WH_CODE},找不到叠盘货位"); AddErrorInfo("查找货位失败", result.msg, Source); return result; } } else if (startloc.S_NOTE == "PM") { //找块胶堆叠区 var KjDploc = db.Queryable().Where(a => a.S_NOTE.Trim() == "片胶堆叠位" && a.S_WH_CODE.Trim() == startloc.S_WH_CODE).ToList(); if (KjDploc.Count > 0) { loc = KjDploc.FindAll(a => a.N_LOCK_STATE == 0 && a.N_CURRENT_NUM < 6).OrderByDescending(a => a.N_CURRENT_NUM).FirstOrDefault(); if (loc == null) { result.code = "1"; result.msg = $"叠盘货位不可用"; AddErrorInfo("查找库区失败", result.msg, Source); return result; } else { endlayer = loc.N_CURRENT_NUM + 1; } } else { LogHelper.Info($"根据货位备注:片胶堆叠位,货位仓库:{startloc.S_WH_CODE},找不到叠盘货位"); result.code = "1"; result.msg = $"叠盘货位不可用"; AddErrorInfo("查找货位失败", result.msg, Source); return result; } } else { #region 根据托盘找呼叫空托任务,并获得出库库区 msts = WCSHelper.GetTaskBycntrcode(model.Rfid.Trim()); if (msts.Count() > 0) { msts.RemoveAll(a => string.IsNullOrEmpty(a.S_CNTR_CODE)); mst = msts.OrderByDescending(a => a.T_CREATE).FirstOrDefault(); } if (mst != null) { LogHelper.Info($"找到出库任务:{JsonConvert.SerializeObject(mst)}"); areacode = mst.S_START_AREA; } else { result.code = "1"; result.msg = $"创建任务失败,根据托盘编码{model.Rfid}未找到托盘出库任务"; LogHelper.Info($"{result.msg}"); AddErrorInfo("查找任务失败", result.msg, Source); return result; } if (string.IsNullOrEmpty(areacode)) { result.code = "1"; result.msg = $"创建任务失败,根据托盘编码{model.Rfid}找到出库任务{mst.S_CODE}的起点库区为空"; LogHelper.Info($"{result.msg}"); AddErrorInfo("查找库区失败", result.msg, Source); return result; } #endregion //回库货位计算库区货位 loc = StorageCompute(itemcode, areacode); if (loc == null) { loc = emptyRow(areacode); if (loc == null) { LogHelper.Info($"库区:{areacode}没有空排"); } } else { result.code = "1"; result.msg = $"库区:{areacode}无可用货位"; LogHelper.Info($"{result.msg}"); AddErrorInfo("查找货位失败", result.msg, Source); return result; } } } else { result.code = "1"; result.msg = $"Empty==> 任务起点:{Start}找不到对应货位,请检查货位表"; LogHelper.Info($"{result.msg}"); AddErrorInfo("查找货位失败", result.msg, Source); return result; } #endregion #region 创建任务 if (!string.IsNullOrEmpty(Start) && loc != null) { if (startloc.N_LOCK_STATE != 0) { result.code = "1"; result.msg = $"创建任务失败,起点{Start}有锁"; AddErrorInfo("货位有锁", result.msg); return result; } //创建wcs任务 var wcsTask = new WCSTask { S_CODE = WCSHelper.GenerateTaskNo(), S_TYPE = "空工装回库", S_EQ_NO = model.TaskNumber, S_START_LOC = Start, S_END_LOC = loc.S_CODE, S_START_WH = startloc.S_WH_CODE, S_START_AREA = startloc.S_AREA_CODE, S_END_WH = loc.S_WH_CODE, S_END_AREA = loc.S_AREA_CODE, N_CNTR_COUNT = 1, N_SCHEDULE_TYPE = 1, S_CNTR_CODE = model.Rfid, N_START_LAYER = 1, N_END_LAYER = endlayer, Z_TYPE = 5 }; LogHelper.Info("创建出平库任务:" + JsonConvert.SerializeObject(wcsTask)); if (WCSHelper.CreateTask(wcsTask)) { LocationHelper.LockLoc(Start, 2); LocationHelper.LockLoc(loc.S_CODE, 1); // 空托回库判断托盘有无绑定物料信息 如果有则删除 var itemcntr = db.Queryable().Where(a => a.S_CNTR_CODE.Trim() == model.Rfid).First(); if (itemcntr != null) { db.Deleteable().Where(a => a.S_CNTR_CODE.Trim() == model.Rfid).ExecuteCommand(); } LogHelper.Info("创建任务成功"); } } else { result.code = "1"; result.msg = "创建任务失败,未找到对应的取货点或卸货点"; return result; } #endregion } catch (Exception ex) { result.code = "1"; result.msg = ex.ToString(); LogHelper.Error("空托回库 Error:" + ex.ToString(), ex); return result; } return result; } /// /// 空工装呼叫 /// /// /// internal static Result callfixture(callfixture model) { var db = new SqlHelper().GetInstance(); Result result = new Result() { code = "200", msg = "空工装呼叫任务下发成功" }; string Source = "MES"; if (model == null) { result.code = "1"; result.msg = "参数为null"; AddErrorInfo("参数为空", result.msg, Source); return result; } #region 变量 string Start = ""; string End = model.TargetLocation; string itemcode = ""; string areacode = ""; string cntrcode = ""; Location startloc = new Location(); #endregion try { #region 根据仓库编码判断库区 并计算出库货位 var endloc = db.Queryable().Where(a => a.S_CODE.Trim() == End).First(); if (endloc != null) { if (endloc.S_WH_CODE == "101") { // itemcode = "TP"; areacode = "PMGQ"; } else { //itemcode = "TP"; areacode = "PK2"; } areacode = "FLPK"; //计算出库托盘 startloc = airlift(areacode, itemcode); if (startloc != null) { var cntr = db.Queryable().Where(a => a.S_LOC_CODE.Trim() == startloc.S_CODE).First(); if (cntr != null) { Start = cntr.S_LOC_CODE; cntrcode = cntr.S_CNTR_CODE; } else { result.code = "1"; result.msg = $"创建空工装呼叫任务==>根据货位{endloc.S_CODE}未找到托盘货位绑定关系"; LogHelper.Info($"callfixture:{result.msg}"); AddErrorInfo("查找托盘失败", result.msg, Source); return result; } } } else { result.code = "1"; result.msg = $"任务起点:{End}找不到对应货位,请检查货位表"; LogHelper.Info($"callfixture:{result.msg}"); AddErrorInfo("查找货位失败", result.msg, Source); } #endregion #region 创建任务 if (!string.IsNullOrEmpty(Start) && !string.IsNullOrEmpty(End)) { if (startloc.N_LOCK_STATE != 0) { result.code = "1"; result.msg = $"创建任务失败,起点{Start}有锁"; AddErrorInfo("货位有锁", result.msg); return result; } //创建wcs任务 var wcsTask = new WCSTask { S_CODE = WCSHelper.GenerateTaskNo(), S_TYPE = "空工装呼叫", S_EQ_NO = model.TaskNumber, S_START_LOC = Start, S_END_LOC = End, S_START_WH = startloc.S_WH_CODE, S_START_AREA = startloc.S_AREA_CODE, S_END_WH = endloc.S_WH_CODE, S_END_AREA = endloc.S_AREA_CODE, N_CNTR_COUNT = 1, N_SCHEDULE_TYPE = 1, S_CNTR_CODE = cntrcode, N_START_LAYER = 1, N_END_LAYER = 1, Z_TYPE = 5 }; LogHelper.Info("创建出平库任务:" + JsonConvert.SerializeObject(wcsTask)); if (WCSHelper.CreateTask(wcsTask)) { LocationHelper.LockLoc(Start, 2); LocationHelper.LockLoc(End, 1); LogHelper.Info("创建任务成功"); } } else { result.code = "1"; result.msg = "创建任务失败,未找到对应的取货点或卸货点"; return result; } return result; #endregion } catch (Exception ex) { result.code = "1"; result.msg = ex.ToString(); LogHelper.Error("callfixture Error:" + ex.ToString(), ex); return result; } } /// /// 余料返回 /// /// /// internal static Result ItemBack(ItemBack model) { Result result = new Result() { code = "200", msg = "余料返回任务下发成功" }; string Source = "MES"; if (model == null) { result.code = "1"; result.msg = "参数为null"; AddErrorInfo("参数为空", result.msg, Source); return result; } #region 变量 var db = new SqlHelper().GetInstance(); string Start = model.InitialLocation; string End = ""; string itemcode = model.PartNumber; Location loc = new Location(); string areacode = ""; WCSTask mst = new WCSTask(); List msts = new List(); #endregion try { #region 判断托盘绑定货位是否和下发绑定起点相同 var CntrLoc = db.Queryable().Where(a => a.S_CNTR_CODE.Trim() == model.Rfid).First(); if (CntrLoc != null) { if (CntrLoc.S_LOC_CODE != Start) { result.code = "1"; result.msg = $"创建任务失败,托盘:{model.Rfid}绑定位置不是起点:{Start}"; LogHelper.Info($"ItemBack:{result.msg}"); AddErrorInfo("托盘绑定位置不同", result.msg, Source); return result; } } else { result.code = "1"; result.msg = $"创建任务失败,托盘:{model.Rfid}未找到绑定货位"; LogHelper.Info($"ItemBack:{result.msg}"); AddErrorInfo("查找托盘货位失败", result.msg, Source); return result; } #endregion #region 余料返回根据托盘找出库任务 //余料返回根据托盘找出库任务 //msts = WCSHelper.GetTaskBycntrcode(model.Rfid); //if (msts.Count() > 0) //{ // msts.RemoveAll(a => string.IsNullOrEmpty(a.S_CNTR_CODE)); // mst = msts.OrderByDescending(a => a.T_CREATE).FirstOrDefault(); //} //if (mst != null) //{ // areacode = mst.S_START_AREA; //} //else //{ // result.code = "1"; // result.msg = $"创建任务失败,根据托盘编码{model.Rfid}未找到托盘出库任务"; // AddErrorInfo("查找任务失败", result.msg); // return result; //} //if (string.IsNullOrEmpty(areacode)) //{ // LogHelper.Info($"创建任务失败,根据托盘编码{model.Rfid}找到出库任务{mst.S_CODE}的起点库区为空"); // result.code = "1"; // result.msg = $"创建任务失败,根据托盘编码{model.Rfid}找到出库任务{mst.S_CODE}的起点库区为空"; // AddErrorInfo("查找库区失败", result.msg); // return result; //} #endregion #region 根据物料编码 判断回库还是回到对应暂存区 var startloc = db.Queryable().Where(a => a.S_CODE.Trim() == Start).First(); if (startloc != null) { //粉料直接回库,其他物料需要去对应的暂存区 if (model.PartNumber.StartsWith("4X")) { areacode = "FLPK"; loc = StorageCompute(itemcode, areacode); if (loc == null) { loc = emptyRow(areacode); } } else { if (model.PartNumber.StartsWith("3")) { areacode = "KJYLZCW"; } else { result.code = "1"; result.msg = $"创建任务失败,物料号{model.PartNumber}不属于规定物料"; LogHelper.Info($"ItemBack:{result.msg}"); AddErrorInfo("物料编码格式错误", result.msg, Source); return result; } var EndLocs = db.Queryable().Where(a => a.S_AREA_CODE.Trim() == areacode).ToList(); if (EndLocs.Count > 0) { loc = EndLocs.Find(a => a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0); if (loc != null) { End = loc.S_CODE; } else { result.code = "1"; result.msg = $"终点库区:{areacode}无可用货位"; AddErrorInfo("查找库区失败", result.msg, Source); return result; } } else { result.code = "1"; result.msg = $"根据终点库区:{areacode},未找到对应货位"; AddErrorInfo("查找库区失败", result.msg, Source); return result; } //loc = StorageCompute(itemcode, areacode); //if (loc == null) //{ // loc = emptyRow(areacode); //} } if (loc != null) { End = loc.S_CODE; } else { result.code = "1"; result.msg = $"库区:{areacode}无可用货位"; AddErrorInfo("查找货位失败", result.msg, Source); return result; } } else { result.code = "1"; result.msg = $"货位:{Start}找不到对应货位"; AddErrorInfo("查找货位失败", result.msg, Source); return result; } #endregion #region 创建任务 if (!string.IsNullOrEmpty(Start) && !string.IsNullOrEmpty(End)) { if (startloc.N_LOCK_STATE != 0) { result.code = "1"; result.msg = $"创建任务失败,起点{Start}有锁"; AddErrorInfo("货位有锁", result.msg); return result; } //创建wcs任务 var wcsTask = new WCSTask { S_CODE = WCSHelper.GenerateTaskNo(), S_TYPE = "余料返回", S_EQ_NO = model.TaskNumber, S_START_LOC = Start, S_END_LOC = End, S_START_WH = startloc.S_WH_CODE, S_START_AREA = startloc.S_AREA_CODE, S_END_WH = loc.S_WH_CODE, S_END_AREA = loc.S_AREA_CODE, N_CNTR_COUNT = 1, N_SCHEDULE_TYPE = 1, S_CNTR_CODE = model.Rfid, N_START_LAYER = 1, N_END_LAYER = 1, Z_TYPE = 5 }; LogHelper.Info("创建出平库任务:" + JsonConvert.SerializeObject(wcsTask)); if (WCSHelper.CreateTask(wcsTask)) { LocationHelper.LockLoc(Start, 2); LocationHelper.LockLoc(End, 1); //创建任务成功 更新余料信息 var CntrItem = db.Queryable().Where(a => a.S_CNTR_CODE.Trim() == model.Rfid).First(); if (CntrItem != null) { CntrItem.F_WEIGHT = model.LotList[0].Weight.ToString(); CntrItem.S_BS_TYPE = "余料"; CntrItem.F_QTY = float.Parse(model.LotList[0].qty); CntrItem.S_ITEM_STATE = model.LotList[0].QualityStatus; db.Updateable(CntrItem).UpdateColumns(a => new { a.F_WEIGHT, a.S_BS_TYPE }).ExecuteCommand(); } LogHelper.Info("创建任务成功"); } } else { result.code = "1"; result.msg = "创建任务失败,未找到对应的取货点或卸货点"; return result; } #endregion return result; } catch (Exception ex) { result.code = "1"; result.msg = ex.ToString(); LogHelper.Error("ItemBack Error:" + ex.ToString(), ex); return result; } } /// /// 线边库存查询 /// /// /// internal static Result itemqtyfind(RequestList model) { Result result = new Result() { code = "200", msg = "线边库存查询成功" }; string Source = "MES"; if (model == null) { result.code = "1"; result.msg = "参数为null"; AddErrorInfo("参数为空", result.msg, Source); return result; } List iteminquires = new List(); try { model.data.ForEach(a => { // string purpose = "线边"; Iteminquire iteminquire = new Iteminquire() { PartNumber = a.PartNumber, Qty = 0 }; //根据物料查询所有线体托盘数量 //var cntrlist = ContainerHelper.GetItemCntrRel(a.PartNumber); //var loccntrlist = LocationHelper.GetLocListBycntrs(cntrlist.Select(b => b.S_CNTR_CODE).ToList()); //var loclist = LocationHelper.GetLocListBytype(loccntrlist.Select(b => b.S_LOC_CODE).ToList(), new string[] { "FLPK" }); iteminquire.Qty = LocationHelper.GetItemQtyByAre(new string[] { "FLPK" }, a.PartNumber); iteminquires.Add(iteminquire); }); result.data = iteminquires; return result; } catch (Exception ex) { result.code = "1"; result.msg = ex.ToString(); LogHelper.Error("itemqtyfind Error:" + ex.ToString(), ex); return result; } } /// /// 物料主数据创建 /// /// /// internal static Result add(add model) { Result result = new Result() { code = "200", msg = "物料主数据创建成功" }; string Source = "MES"; if (model == null) { result.code = "1"; result.msg = "参数为null"; AddErrorInfo("参数为空", result.msg,Source); return result; } try { var db = new SqlHelper().GetInstance(); if (db.Queryable().Where(a => a.S_ITEM_CODE == model.PartNumber).Count() > 0) { result.code = "1"; result.msg = "物料主数据已存在"; AddErrorInfo("物料主数据已存在", result.msg,Source); return result; } TN_Material itemInfo = new TN_Material(); itemInfo.S_ITEM_CODE = model.PartNumber; itemInfo.ITEM_TYPE = model.PartClass; itemInfo.S_ITEM_NAME = model.PartDesc; itemInfo.REMARK1 = model.StewingTime.ToString("yyyy-MM-dd"); itemInfo.REMARK2 = model.OverdueTime.ToString("yyyy-MM-dd"); itemInfo.S_MP_TYPE = model.Unit; db.Insertable(itemInfo).ExecuteCommand(); return result; } catch (Exception ex) { result.code = "1"; result.msg = $"物料主数据创建失败 错误信息:{ex}"; LogHelper.Error("add Error:" + ex.ToString(), ex); return result; } } /// /// 点对点任务创建 /// /// /// internal static Result CreatTask(CreatTask model) { Result result = new Result() { code = "200", msg = "点对点任务创建成功" }; string Source = "MES"; if (model == null) { result.code = "1"; result.msg = "参数为null"; AddErrorInfo("参数为空", result.msg, Source); return result; } string Start = ""; //取货点 var db = new SqlHelper().GetInstance(); // string CntrCode = model.partData.rfid;//托盘编码 // string ItemCode = model.partData.partNumber;//物料编码 string End = ""; string CntrCode = ""; Location endloc = new Location(); Location startloc = new Location(); try { startloc = db.Queryable().Where(a => a.S_CODE.Trim() == model.InitialLocation).First(); if (startloc != null) { Start = model.InitialLocation; var CntrRel = LocationHelper.GetLocCntrRel(startloc.S_CODE).FirstOrDefault(); if (CntrRel != null) { CntrCode = CntrRel.S_CNTR_CODE; } else { result.code = "1"; result.msg = $"创建任务失败,根据起点{model.InitialLocation}未找到对应货位绑定托盘托盘"; AddErrorInfo("查找托盘失败", result.msg, Source); return result; } } endloc = db.Queryable().Where(a => a.S_CODE.Trim() == model.TargetLocation).First(); if (endloc != null) { End = model.TargetLocation; } #region 创建任务 if (!string.IsNullOrEmpty(Start) && !string.IsNullOrEmpty(End)) { if (startloc.N_LOCK_STATE != 0) { result.code = "1"; result.msg = $"创建任务失败,起点{Start}有锁"; AddErrorInfo("货位有锁", result.msg); return result; } //创建wcs任务 var wcsTask = new WCSTask { S_CODE = WCSHelper.GenerateTaskNo(), // S_TYPE = model.taskData.taskType.ToString(), // S_EQ_NO = model.taskData.taskNum, S_START_LOC = Start, S_END_LOC = End, N_CNTR_COUNT = 1, S_START_WH = startloc.S_WH_CODE, S_START_AREA = startloc.S_AREA_CODE, S_END_WH = endloc.S_WH_CODE, S_END_AREA = endloc.S_AREA_CODE, N_SCHEDULE_TYPE = 1, S_CNTR_CODE = CntrCode, N_START_LAYER = 1, N_END_LAYER = 1, // N_TYPE = n_type }; LogHelper.Info("创建任务:" + JsonConvert.SerializeObject(wcsTask), "CreateTask"); if (WCSHelper.CreateTask(wcsTask)) { LocationHelper.LockLoc(Start, 2); LocationHelper.LockLoc(End, 1); LogHelper.Info("创建任务成功"); } } else { result.code = "1"; result.msg = "创建任务失败,未找到对应的取货点或卸货点"; return result; } #endregion return result; } catch (Exception ex) { result.code = "1"; result.msg = $"物料主数据创建失败 错误信息:{ex}"; LogHelper.Error("点对点任务 Error:" + ex.ToString(), ex); return result; } } /// /// 创建电梯搬运任务 /// /// /// internal static Result CreatelevatorTask(Elevator model) { Result result = new Result() { code = "200", msg = "点对点任务创建成功" }; string Source = "MES"; if (model == null) { result.code = "1"; result.msg = "参数为null"; AddErrorInfo("参数为空", result.msg,Source); return result; } try { var db = new SqlHelper().GetInstance(); var startloc = db.Queryable().Where(a => a.S_CODE.Trim() == model.Data.start_loc_code).First(); var endloc = db.Queryable().Where(a => a.S_AREA_CODE.Trim() == model.Data.end_loc_code && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0).First(); //判断楼层是否相等,如果不相同需要生成分段任务进行电梯调用 if (startloc != null && endloc != null) { if (startloc.N_LOCK_STATE != 0) { result.code = "1"; result.msg = $"创建任务失败,起点{startloc.S_CODE}有锁"; AddErrorInfo("货位有锁", result.msg,Source); return result; } var cntr = db.Queryable().Where(a => a.S_LOC_CODE.Trim() == startloc.S_CODE).First(); if (cntr == null) { result.code = "1"; result.msg = $"起点{model.Data.start_loc_code}未查询绑定托盘"; LogHelper.Info($"callfixture:创建空工装呼叫任务==>{result.msg}"); AddErrorInfo("查找托盘失败", result.msg, Source); return result; } // var startArea = db.Queryable().Where(a => a.S_CODE.Trim() == startloc.S_AREA_CODE).First(); //var endArea = db.Queryable().Where(a => a.S_CODE.Trim() == endloc.S_AREA_CODE).First(); string dtcode = "DT-01"; //楼层电梯分配 var Diantiloc = db.Queryable().Where(a => a.S_CODE.Trim() == dtcode).First(); if (Diantiloc == null) { result.code = "1"; result.msg = $"创建任务失败,根据货位编码:{dtcode}未找到电梯货位"; AddErrorInfo("查找货位失败", result.msg,Source); return result; } //根据电梯数量判断送往哪个电梯 (具体电梯流程根据现场电梯数量) //创建wcs分段任务 var wcsTask = new WCSTask { S_CODE = WCSHelper.GenerateTaskNo(), S_TYPE = "电梯1", S_EQ_NO = model.Data.task_no, S_START_LOC = startloc.S_CODE, S_END_LOC = Diantiloc.S_CODE, N_CNTR_COUNT = 1, S_START_WH = startloc.S_WH_CODE, S_START_AREA = startloc.S_AREA_CODE, S_END_WH = endloc.S_WH_CODE, S_END_AREA = endloc.S_AREA_CODE, N_SCHEDULE_TYPE = 1, S_CNTR_CODE = cntr.S_CNTR_CODE, N_END_LAYER = 1, Z_TYPE = 6 }; var wcsTask1 = new WCSTask { S_CODE = WCSHelper.GenerateTaskNo(), S_TYPE = "电梯2", S_EQ_NO = model.Data.task_no, S_START_LOC = Diantiloc.S_CODE, S_END_LOC = endloc.S_CODE, N_CNTR_COUNT = 1, S_START_WH = startloc.S_WH_CODE, S_START_AREA = startloc.S_AREA_CODE, S_END_WH = endloc.S_WH_CODE, S_END_AREA = endloc.S_AREA_CODE, N_SCHEDULE_TYPE = 1, S_CNTR_CODE = cntr.S_CNTR_CODE, N_END_LAYER = 1, Z_TYPE = 6 }; LogHelper.Info("创建任务:" + JsonConvert.SerializeObject(wcsTask), "CreateTask"); if (WCSHelper.CreateTask(wcsTask) && WCSHelper.CreateTask(wcsTask1)) { LocationHelper.LockLoc(startloc.S_CODE, 2); LocationHelper.LockLoc(endloc.S_CODE, 1); LogHelper.Info("创建任务成功"); } } else { result.code = "1"; result.msg = "创建任务失败,未找到对应的取货点或卸货点"; return result; } return result; } catch (Exception ex) { result.code = "1"; result.msg = $"物料主数据创建失败 错误信息:{ex}"; LogHelper.Error("点对点任务 Error:" + ex.ToString(), ex); return result; } } /// /// 货位信息上传 /// /// /// internal static Result UploadLoc(List model) { Result result = new Result() { code = "200", msg = "货位信息上传成功" }; String Source = "MES"; RequestList result1 = new RequestList(); List listuploadloc = new List(); var db = new SqlHelper().GetInstance(); foreach (var item in model) { var loc = db.Queryable().Where(a => a.S_CODE.Trim() == item.Location).First(); if (loc != null) { UploadLoc upload = new UploadLoc(); //获取时间戳 var time = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds(); result1.RequestId = "杭叉AGV" + time; result1.UseToken = "iFQ5fExGrLYLXliHYWzs"; upload.LocationNum = loc.S_CODE; upload.Type = loc.S_TYPE; upload.WorkCenter = loc.S_AREA_CODE; upload.Warehouse = loc.S_AREA_CODE; listuploadloc.Add(upload); } else { result.code = "1"; result.msg = $"货位上传失败,根据货位编码{item.Location}未找到对应的货位信息"; AddErrorInfo("查找货位失败", result.msg, Source); return result; } } result1.data = listuploadloc; HttpHelper httpHelper = new HttpHelper(); // Result result = new Result(); string date = JsonConvert.SerializeObject(result1); var url = Settings.tableUrls.Find(a => a.id == 6); if (url != null) { LogHelper.Info($"任务回报:地址:{url},内容:{date}"); var r = httpHelper.MesWebPost(url.url, date); result = JsonConvert.DeserializeObject(r); if (result.code == "200") { LogHelper.Info($"物料到位回报成功"); } else { LogHelper.Info($"物料到位回报失败=>msg:{result.msg}"); result.code = "1"; result.msg = result.msg; } } else { LogHelper.Info($"物料到位回报失败=>回报地址没有配置"); result.code = "1"; result.msg = $"物料到位回报失败=>回报地址没有配置"; AddErrorInfo("地址错误", result.msg, Source); } return result; } /// /// 库位清空 /// /// /// internal static Result ClearLoc(ClearTask model) { Result result = new Result() { code = "200", msg = "库位清除成功" }; string Source = "MES"; if (model == null) { result.code = "1"; result.msg = "参数为null"; AddErrorInfo("参数为空", result.msg, Source); return result; } string loc = model.LocationNum; var db = new SqlHelper().GetInstance(); try { var location = db.Queryable().Where(a => a.S_CODE.Trim() == loc).First(); if (location != null) { var loccntr = db.Queryable().Where(a => a.S_LOC_CODE.Trim() == loc).First(); if (loccntr != null) { string cntrcode = loccntr.S_CNTR_CODE; var CntrItem = db.Queryable().Where(a => a.S_CNTR_CODE.Trim() == cntrcode).First(); if (CntrItem != null) { LocationHelper.UnBindingLoc(loc, new List() { "cntrcode" }); // db.Deleteable().Where(it => it.S_LOC_CODE.Trim() == loc).ExecuteCommand(); db.Deleteable().Where(it => it.S_CNTR_CODE.Trim() == cntrcode).ExecuteCommand(); } else { LogHelper.Info($"ClearLoc 托盘{cntrcode}无物料绑定关系"); } } else { LogHelper.Info($"ClearLoc 货位{loc}无托盘货位绑定关系"); } } else { result.code = "1"; result.msg = $"根据货位:{loc}找不到货位关系"; AddErrorInfo("货位为空", result.msg, Source); return result; } } catch (Exception ex) { LogHelper.Info($"ClearLoc Error:{ex}"); db.Ado.CommitTran(); result.code = "1"; result.msg = $"Error:{ex}"; return result; } return result; } #endregion #region 合肥佳通业务方法 /// /// 托盘入库算法 /// /// /// /// internal static Location StorageCompute(string itemcode, string areacode) { var db = new SqlHelper().GetInstance(); Location result = null; //查询所有有托盘的排 var list = db.Queryable().Where(a => a.N_CURRENT_NUM > 0 && a.S_AREA_CODE.Trim() == areacode).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList(); if (list.Count > 0) { for (int i = 0; i < list.Count; i++) { LogHelper.Info($"有托盘排号{list[i].N_ROW},物料编码{itemcode},库区{areacode}"); //判断托盘物料是否相同物料信息相同 var cntr = db.Queryable().Where(a => a.S_LOC_CODE.Trim() == list[i].S_CODE).First(); if (cntr != null) { if (string.IsNullOrEmpty(itemcode))//空托入库 { var iteminfo = ContainerHelper.GetCntrItemRel(cntr.S_CNTR_CODE).FirstOrDefault(); if (iteminfo == null) { //物料相同入货位后一位货位 result = db.Queryable().OrderBy(a => a.N_COL).Where(a => a.S_AREA_CODE.Trim() == areacode && a.N_ROW == list[i].N_ROW && a.N_COL > list[i].N_COL).First(); } } else//满拖入库 { var iteminfo = ContainerHelper.GetCntrItemRel(cntr.S_CNTR_CODE).FirstOrDefault(); if (iteminfo != null) { if (iteminfo.S_ITEM_CODE == itemcode) { //物料相同入货位后一位货位 result = db.Queryable().OrderBy(a => a.N_COL).Where(a => a.S_AREA_CODE.Trim() == areacode && a.N_ROW == list[i].N_ROW && a.N_COL > list[i].N_COL).First(); } } } if (result != null) { return result; } } else { LogHelper.Info($"根据货物编码{list[i].S_CODE}未找到托盘货位绑定关系"); } } } return result; } /// /// 根据物料计算托盘出库 /// /// /// /// 物料等级 /// internal static Location airlift(string areacode, string itemcode, string level = "") { var db = new SqlHelper().GetInstance(); Location result = null; //根据物料编码获取货位信息 #region 废弃 //if (string.IsNullOrEmpty(itemcode)) //{ // //获取库区所有有托盘的货位 // var loclist = LocationHelper.GetLocListAny(areacode).FindAll(a => a.N_CURRENT_NUM == 1); // //LogHelper.Info($"获取库区{areacode}数量为1的货位{JsonConvert.SerializeObject(loclist)}"); // //根据货位获取托盘 // var loccntrlist = LocationHelper.GetLocListByLoc(loclist.Select(a => a.S_CODE).ToList()); // List locs = new List(); // // LogHelper.Info($"获取库区{areacode}数量为1的托盘{JsonConvert.SerializeObject(loccntrlist)}"); // //排除所有有物料的托盘 // foreach (var item in loccntrlist) // { // var list = db.Queryable().Where(a => a.S_CNTR_CODE.Trim() == item.S_CNTR_CODE).First(); // if (list == null) // { // LogHelper.Info($"获取库区{areacode}的空托{JsonConvert.SerializeObject(item.S_CNTR_CODE)}"); // var cntr = db.Queryable().Where(a => a.S_CNTR_CODE.Trim() == item.S_CNTR_CODE).First(); // var loc = db.Queryable().Where(a => a.S_CODE.Trim() == item.S_LOC_CODE).First(); // locs.Add(loc); // } // } // LogHelper.Info($"获取库区{areacode}的空托货位{JsonConvert.SerializeObject(locs)},计算出库货位"); // if (locs.Count > 0) // { // result = FindStartcolByLoclist(loclist); // } // else // { // LogHelper.Info($"airlift==> 根据库区编码:{areacode},找不到空托"); // } //} //else //{ // var cntrlist = ContainerHelper.GetItemCntrRel(itemcode).FindAll(a => a.LEV == level); // var loccntrlist = LocationHelper.GetLocListBycntrs(cntrlist.Select(a => a.S_CNTR_CODE).ToList()); // var loclist = LocationHelper.GetLocListByloc(loccntrlist.Select(a => a.S_LOC_CODE).ToList(), areacode); // if (loclist.Count() > 0) // { // //判断所处库区的货位是否是可出排 // // loclist = loclist.FindAll(a => a.S_AREA_CODE == areacode); // result = FindStartcolByLoclist(loclist); // } // else // { // LogHelper.Info($"airlift==> 根据库区编码:{areacode},物料编码:{itemcode}找不到对应出库货位"); // } //} #endregion var loc = LocationHelper.GetLocByItemCode(areacode, itemcode, level); result = FindStartcolByLoclist(loc); return result; } /// /// 找空排 /// /// /// internal static Location emptyRow(string areacode) { Location result = null; var db = new SqlHelper().GetInstance(); LogHelper.Info($"根据库区编码:{areacode},查找空排货位"); //查找所有数量是空的排; //简化查询只查每一排第一列 var list = db.Queryable().Where(a => a.S_AREA_CODE.Trim() == areacode).OrderBy(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList().Where(a => a.N_CURRENT_NUM == 0).FirstOrDefault(); if (list != null) { result = list; } return result; } /// /// 创建托盘物料绑定关系 /// /// 货位编码 /// 托盘编码 /// 物料编码 /// 物料描述 /// 物料类型 /// 托盘类型 /// 物料单位 /// 物料重量 internal static bool CreateCntrIteminfo(string loc, string cntr, string partNumber, string partDesc, string partType, string batch, string unit, string weight, string cntrtype = "1", string level = "") { return ContainerHelper.CreateCntrItem(loc, cntr, partNumber, partDesc, partType, cntrtype, batch, weight, unit, level); } /// /// 根据托盘编码,机台编码,工装类型计算机台线边区域 /// /// 托盘编码 /// 机台编码 /// internal static Location Computeloc(string cntrcode, string jtcode, string cntrType) { Location End = new Location(); var db = new SqlHelper().GetInstance(); // var location = db.Queryable().Where(a => a.S_CNTR_CODE.Trim() == cntrcode).First(); var loc = db.Queryable().Where(a => a.S_AREA_CODE.Trim() == jtcode.Trim() && a.S_NOTE == cntrType && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0).First(); if (loc != null) { End = loc; } else { LogHelper.Info($"Computeloc==》根据机台分组:{jtcode},工装类型:{cntrType} 未找到空货位数据,请检查货位表"); } return End; } /// /// 合肥佳通添加报错信息表数据 /// /// 错误 /// 任务号 /// 库区编码 /// 错误信息 /// public static bool AddErrorInfo(string errorInfo, string remake, string areacode = "", string taskno = "") { bool result = false; var db = new SqlHelper().GetInstance(); try { var error = new ErrorInfo { ERRORMESSAGE = errorInfo, TASKNO = taskno, AREACODE = areacode, REMAKE = remake, }; if (result = db.Insertable(error).ExecuteCommand() > 0) { } //else //{ // //添加失败重新添加 // AddErrorInfo(errorInfo, remake, areacode, taskno); //} } catch (Exception ex) { LogHelper.Info($"AddErrorInfo Error:{ex.Message}"); } return result; } /// /// 找终点空货位 /// /// /// internal static Location FindEndcolByLocList(List locations, string itemcode) { try { var db = new SqlHelper().GetInstance(); Location end = null; //根据终点货位找空闲货位 var rows = locations.Select(a => a.N_ROW).Distinct().ToList(); for (int i = 0; i < rows.Count; i++) { var rowList = locations.Where(r => r.N_ROW == rows[i]).ToList(); if (rowList.Count(a => a.N_CURRENT_NUM == 0) > 0) { Location other = null; //当前排没有锁并且有空位置 //先找满位,然后后面一层要么是空,要么不存在 other = rowList.OrderByDescending(a => a.N_COL).Where(a => a.N_CURRENT_NUM == 0).FirstOrDefault(); //if (full == null) //{ // //没有满位,那就找最小的空位 // other = rowList.OrderBy(a => a.N_LAYER).FirstOrDefault(); //} //else //{ // other = rowList.OrderBy(a => a.N_LAYER).Where(a => a.N_LAYER > full.N_LAYER).FirstOrDefault(); //} //if (other != null && (!string.IsNullOrEmpty(other.C_ENABLE) && other.C_ENABLE == "禁用")) //{ // //禁用了选择后面一个货位 // other = db.Queryable().OrderBy(a => a.N_LAYER).Where(a => (string.IsNullOrEmpty(a.C_ENABLE) || a.C_ENABLE.Trim() != "禁用") && a.S_AREA_CODE == other.S_AREA_CODE && a.N_ROW == other.N_ROW && a.N_COL > other.N_COL).First(); // //LogHelper.Info($"禁用选择后一个货位{result}", "成品"); //} if (other != null) { end = other; break; } } } return end; } catch (Exception) { throw; } } /// /// 找起点满货位 /// /// /// internal static Location FindStartcolByLoclist(List locations) { try { Location start = null; var rowsStart = locations.Select(a => a.N_ROW).Distinct().ToList(); for (int i = 0; i < rowsStart.Count; i++) { var rowList = locations.Where(r => r.N_ROW == rowsStart[i]).ToList().OrderByDescending(a => a.N_COL); //当前排没有锁并且有满货位 if (rowList.Count(a => a.S_LOCK_STATE.Trim() != "无") == 0 && rowList.Count(a => a.N_CURRENT_NUM == 1) > 0) { Location other = null; //找到最大的满位,如果有就直接出 var full = rowList.OrderByDescending(a => a.N_COL).Where(a => a.N_CURRENT_NUM == 1).FirstOrDefault(); if (full != null) { other = full; } if (other != null) { start = other; break; } } } return start; } catch (Exception) { throw; } } #endregion internal static CodeInfo GetCodeInfo(string code, string org) { //return new CodeInfo { Fitemid_XK=code, FSourceNo="123456"}; CodeInfo result = null; try { var db = new SqlHelper().GetInstance(Settings.SqlServer1); var nameP = new SugarParameter("@FBarCode", code); var orgP = new SugarParameter("@Forg", org); //var ageP = new SugarParameter("@age", null, true);//设置为output //var dt = db.Ado.UseStoredProcedure().GetDataTable("sp_school", nameP, ageP);//返回dt result = db.Ado.UseStoredProcedure().SqlQuery("WMS_FBarCode", nameP, orgP).First();//返回List Console.WriteLine($"读存储过程成功,result={result}"); } catch (Exception ex) { Console.WriteLine(ex.Message); } return result; } static object AGVDeviceReceiveLock = new object(); /// /// AGV状态处理 /// /// /// /// /// /// /// internal static void AGVDeviceReceiveSet(string forkliftNo, string battery, string errCode, string errCode2, string faildCode) { lock (AGVDeviceReceiveLock) { var db = new SqlHelper().GetInstance(); var agvDeviceInfo = db.Queryable().Where(a => a.agvNo.Trim() == forkliftNo).First(); if (agvDeviceInfo == null) { var agvInfo = new HangChaAGV() { agvNo = forkliftNo, agvBattery = battery, // agvCurrTaskInfo = agvCurrTaskInfo, agvErrCode = errCode, errCode2 = errCode2, faildCode = faildCode }; db.Insertable(agvInfo).ExecuteCommand(); } else { //判断中间表信息有无变化,无变化不更新中间表 if (agvDeviceInfo.agvErrCode == errCode && agvDeviceInfo.errCode2 == errCode2 && agvDeviceInfo.faildCode == faildCode) { return; } agvDeviceInfo.agvBattery = battery; // agvDeviceInfo.agvCurrTaskInfo = agvCurrTaskInfo; agvDeviceInfo.agvErrCode = errCode; agvDeviceInfo.errCode2 = errCode2; agvDeviceInfo.faildCode = faildCode; // agvDeviceInfo.ext1 = "0"; //agvDeviceInfo.agvRunStatus = agvDeviceInfo.agvRunStatus?.Trim() == "1" ? "1" : ""; //if (int.Parse(agvDeviceInfo.agvBattery) >= 1000) // agvDeviceInfo.agvRunStatus = ""; db.Updateable(agvDeviceInfo).UpdateColumns(a => new { a.agvBattery, a.agvCurrTaskInfo, a.agvErrCode, a.errCode2, a.faildCode, a.agvRunStatus }).ExecuteCommand(); } } } #region 数据模型 #endregion public class AddTaskModel { public string From { get; set; } public string To { get; set; } public string No { get; set; } } public class TN_LocationModel { public string TN_Location { get; set; } } public class CodeInfo { /// /// 生产订单内码 /// public string FInterID { get; set; } /// /// 生产订单编号 /// public string FSourceNo { get; set; } /// /// 批号 /// public string FGMPBatchNo { get; set; } public string FState { get; set; } /// /// 物料编码(内码就是编码) /// public string Fitemid_XK { get; set; } /// /// 分录id /// public string Fentryid { get; set; } } public class NoteInfo : CodeInfo { public string WmsBillNo { get; set; } } } }