using HH.WCS.Mobox3.NFLZ.core; using HH.WCS.Mobox3.NFLZ.dispatch; using HH.WCS.Mobox3.NFLZ.util; using HH.WCS.Mobox3.NFLZ.wms; using Newtonsoft.Json; using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using static HH.WCS.Mobox3.NFLZ.api.OtherModel; namespace HH.WCS.Mobox3.NFLZ.process { internal class TaskProcess { #region 任务相关 //--------------------------------------------------任务相关-------------------------------------------------- /// /// 取货卸货完成,缓存位状态更新 /// /// /// internal static void CacheBitUpdate(WCSTask mst, bool load) { var trayCarryCount = mst.N_CNTR_COUNT > 0 ? mst.N_CNTR_COUNT : 1; if (load) { Console.WriteLine($"任务{mst.S_CODE} 货位{mst.S_START_LOC}取货完成,起点解绑容器{mst.S_CNTR_CODE}"); LogHelper.Info($"任务{mst.S_CODE} 货位{mst.S_START_LOC}取货完成,起点解绑容器{mst.S_CNTR_CODE}"); LocationHelper.UnBindingLoc(mst.S_START_LOC, mst.S_CNTR_CODE.Split(',').ToList()); } else { Console.WriteLine($"任务{mst.S_CODE} 货位{mst.S_END_LOC}卸货完成,终点绑定容器{mst.S_CNTR_CODE}"); LogHelper.Info($"任务{mst.S_CODE} 货位{mst.S_END_LOC}卸货完成,终点绑定容器{mst.S_CNTR_CODE}"); LocationHelper.BindingLoc(mst.S_END_LOC, mst.S_CNTR_CODE.Split(',').ToList()); } } /// /// 任务取消,缓存位状态更新 /// /// internal static void CacheBitCancelUpdate(WCSTask mst) { //任务取消,取货完成前的,起点的loadingCount和终点unLoadingCount都清除,取货完成的只处理终点 if (WCSHelper.CheckActionRecordExist(mst.S_CODE, 4)) { //根据客户现场要求,如果取货完成任务失败人工拉到终点,我们就当卸货完成处理;如果是人工拉走到其它区域,我们就解锁终点,删除托盘。 //终点绑定 CacheBitUpdate(mst, false); LocationHelper.UnLockLoc(mst.S_END_LOC); } else { //起点终点解锁 LocationHelper.UnLockLoc(mst.S_START_LOC); LocationHelper.UnLockLoc(mst.S_END_LOC); } } /// /// 安全请求 /// /// /// /// /// internal static void OperateReq(string no, int state, string forkliftNo, string extData) { if (state == 1101) { //请求取货, } if (state == 1102) { //请求卸货, //根据终点判断,是cb02的入口,判断内存中状态(要状态时间),允许卸货,通知agv改参数 var dic = new Dictionary(); //< Req >< Order No = 'TN2302020002' ParamNo = '18' Param1 = '12' /> dic.Add("No", no); dic.Add("ParamNo", "8"); dic.Add("Param1", "1"); NDC.ChangeOrder(dic); //改完参数车子就会自己卸货 } if (state == 1103) { //大铁框叉走以后通知,我们要通知输送线 } } internal static void UpdateAgvNo(WCSTask mst, string forkliftNo) { var db = new SqlHelper().GetInstance(); mst.S_EQ_NO = forkliftNo; db.Updateable(mst).UpdateColumns(it => new { it.S_EQ_NO }).ExecuteCommand(); } internal static void ThirdReportStatus(WCSTask mst, int state, string forkliftNo) { } /// /// 任务拦截 /// /// /// internal static bool Intercept(WCSTask mst) { var result = false; //出库任务是批量生成的,初始终点我们先给一个虚拟点,不推送。有单独的现场去判断出库缓存区光电,空了再给出库任务分配终点 if (mst.S_END_LOC.Trim() == "出库虚拟点") { result = true; } return result; } /// /// 任务状态更新处理 /// /// /// internal static void OperateStatus(WCSTask mst, int state) { if (state == 4) { claimGoodsTime(mst, state); CacheBitUpdate(mst, true); EmptyTask(mst); } if (state == 6)//卸货完成 { claimGoodsTime(mst, state); CacheBitUpdate(mst, false); } if (state == 7) { CacheBitCancelUpdate(mst); } } /// /// 瓶坯瓶盖机满托下线后生成空托上线任务 /// /// /// public static void EmptyTask(WCSTask mst) { ////瓶盖注塑机空托上线,若急产急用库区没有多余的空托,则在非急产急用空托区拿空托 //var db = new SqlHelper().GetInstance(); //Location startLoca = null; //bool result = false; // //if (mst.S_TYPE.Contains("满托下线")) //{ // LogHelper.Info($"空托任务生成处理,任务类型:{mst.S_TYPE}"); // startLoca = getMStartLoc1(db, startLoca, "瓶坯"); // #region // // if (startLoca != null) // { // LogHelper.Info("startLoca" + JsonConvert.SerializeObject(startLoca)); // var startArea = startLoca.S_AREA_CODE; // string taskType = ""; // if (mst.S_TYPE == "注塑即产满托下线(瓶坯)") taskType = "注塑即产空托上线(瓶坯)"; // if (mst.S_TYPE == "注塑库存满托下线(瓶坯)") taskType = "注塑库存空托上线(瓶坯)"; // int startLayer = startLoca.N_CURRENT_NUM; // var cntrInfo = db.Queryable().Where(a => a.S_LOC_CODE == startLoca.S_LOC_CODE).First(); // if (cntrInfo != null) // { // string cntr = cntrInfo.S_CNTR_CODE; // result = IntensiveArea.LinJiangCreateTransport(startArea, startLoca.S_LOC_CODE, mst.S_START_LOC, taskType, cntr, 1, 1, mst.S_SRC_SYS, startLoca.N_ROW, 1, 1); // if (result) LogHelper.Info($"{taskType}:{mst.S_SRC_SYS} 当前位置{mst.S_START_LOC} 任务创建成功", "注塑机空托上线"); // } // else LogHelper.Info($"未绑定托盘,货位号:{startLoca.S_LOC_CODE}"); // } //} // //if (mst.S_TYPE.Contains("空托下线")) //{ // LogHelper.Info($"满托任务生成处理,任务类型:{mst.S_TYPE}"); // string startArea = ""; // bool flage = false; // string jbw = ""; // string mk = ""; // string machine = ""; // LinjiangBCPWorkOrder bcpW = null; // if (mst.S_TYPE.Contains("瓶坯")) // { // jbw = "瓶坯接驳位"; // mk = "瓶坯满托出库接驳位"; // machine = "瓶坯翻斗机"; // bcpW = db.Queryable().Where(a => a.S_PLineNo.Contains("农夫临江-瓶坯翻斗机")).First(); // } // else // { // jbw = "瓶盖接驳位"; // mk = "瓶盖满托"; // bcpW = db.Queryable().Where(a => a.S_PLineNo.Contains("农夫临江-瓶盖翻斗机")).First(); // } // // if (bcpW.S_UsingNow == "Y") // { // LogHelper.Info("即产即用工单"); // //即产即用在起点为线边 // var bcpInfo = Settings.GetLinJiangBCPAreaList().Where(a => a.AreaName == jbw && a.Enable == "1").FirstOrDefault(); // if (bcpInfo != null) // { // startArea = bcpInfo.AreaNo; // } // } // else // { // LogHelper.Info("非即产即用工单"); // //非即产即用起点为库区 // var bcpInfo = Settings.GetLinJiangBCPAreaList().Where(a => a.AreaName == mk && a.Enable == "1").FirstOrDefault(); // if (bcpInfo != null) // { // startArea = bcpInfo.AreaNo; // } // } // // if (bcpW.S_UsingNow == "Y") // { // bool action = false; // if (jbw == "瓶坯接驳位") // { // flage = true; // action = DeviceProcess.queryBCPFDJRow(db, ref startLoca); // } // LogHelper.Info($"即产即用库区查找"); // if (startLoca == null) // { // startLoca = DeviceProcess.getFDSXArea(db, bcpW, startArea, machine); // //startLoca = db.Queryable().Where(a => a.S_AREA_CODE == startArea && a.N_CURRENT_NUM != 0 && a.S_LOCK_STATE == "无").First(); // //startLoca = TempleteOverExtendService.GetLocation(startArea, workInfo.S_ItemCode, "", false); // if (startLoca == null) // { // flage = false; // if (jbw == "瓶坯接驳位") // { // LogHelper.Info($"即产即用库区未找到满托,去满托库区查找"); // // //即产即用库区无满托,去非即产即用库区查询 // LogHelper.Info($"mk:{mk}"); // startArea = Settings.GetLinJiangBCPAreaList().Where(a => a.AreaName == mk && a.Enable == "1").FirstOrDefault().AreaNo; // LogHelper.Info($"startArea:{startArea}"); // //startLoca = TempleteOverExtendService.GetLocation(startArea, workInfo.S_ItemCode, "", false, true, true); // startLoca = DeviceProcess.getFDSXArea(db, bcpW, startArea); // } // } // else // { // if (action) // { // CPXXTable table = new CPXXTable // { // S_AREA_CODE = startArea, // S_ROW = startLoca.N_ROW, // S_TASK_TYPE = "瓶坯注塑机" // }; // db.Insertable(table).ExecuteCommand(); // } // } // } // } // else // { // startLoca = DeviceProcess.getFDSXArea(db, bcpW, startArea); // } // // if (startLoca != null) // { // LogHelper.Info("startLoca" + JsonConvert.SerializeObject(startLoca)); // string taskType = ""; // if (mst.S_TYPE == "翻斗机即产空托下线(瓶坯)") taskType = "翻斗机即产满托上线(瓶坯)"; // if (mst.S_TYPE == "翻斗机库存空托下线(瓶坯)") taskType = "翻斗机库存满托上线(瓶坯)"; // if (mst.S_TYPE == "翻斗机即产空托下线(瓶盖)") taskType = "翻斗机即产满托上线(瓶盖)"; // if (mst.S_TYPE == "翻斗机库存空托下线(瓶盖)") taskType = "翻斗机库存满托上线(瓶盖)"; // int startLayer = startLoca.N_CURRENT_NUM; // var cntrInfo = db.Queryable().Where(a => a.S_LOC_CODE == startLoca.S_LOC_CODE).First(); // if (cntrInfo != null) // { // string cntr = cntrInfo.S_CNTR_CODE; // if (flage) // { // result = TaskHelper.LinJiangCreateTask("", startLoca.S_LOC_CODE, mst.S_START_LOC, taskType, 1, cntr, mst.S_SRC_SYS); // if (result) // { // LocationHelper.LockLoc(startLoca.S_LOC_CODE, "出库锁"); // LocationHelper.LockLoc(mst.S_START_LOC, "入库锁"); // var rowInfo = db.Queryable().Where(a => a.S_AREA_CODE == startArea && a.N_ROW == startLoca.N_ROW).First(); // if (rowInfo != null) // { // rowInfo.S_LOCK_STATE = "即产出库锁"; // db.Updateable(rowInfo).UpdateColumns(a => new { a.S_LOCK_STATE }).ExecuteCommand(); // } // } // } // else // { // int pri = 1; // if (taskType.Contains("瓶盖")) pri = 10; // result = IntensiveArea.LinJiangCreateTransport(startArea, startLoca.S_LOC_CODE, mst.S_START_LOC, taskType, cntr, 1, 1, mst.S_SRC_SYS, startLoca.N_ROW, 1, pri); // } // if (result) LogHelper.Info($"{taskType}:{mst.S_SRC_SYS} 当前位置{mst.S_START_LOC} 任务创建成功", "翻斗机满托上线"); // } // else LogHelper.Info($"未绑定托盘,货位号:{startLoca.S_LOC_CODE}"); // } //} } private static void claimGoodsTime(WCSTask mst, int state) { //将取货完成时间存入中间表 var db = new SqlHelper().GetInstance(); if (state == 6 && (mst.S_TYPE == "栈板上线" || mst.S_TYPE.Contains("空托上线") || mst.S_TYPE.Contains("满托上线"))) { LogHelper.Info($"任务{mst.S_TYPE}卸货时间存入中间表,当前时间:{DateTime.Now}"); var cgInfo = db.Queryable().Where(a => a.Bit == mst.S_END_LOC).First(); if (cgInfo != null) { cgInfo.time = DateTime.Now; if (db.Updateable(cgInfo).UpdateColumns(a => new { a.time }).ExecuteCommand() > 0) LogHelper.Info($"数据更改成功,终点:{mst.S_END_LOC}"); } else { CGTTable cg = new CGTTable { Bit = mst.S_END_LOC, time = DateTime.Now, }; if (db.Insertable(cg).ExecuteCommand() > 0) LogHelper.Info($"数据插入成功,终点:{mst.S_END_LOC}"); } } if (state == 4 && (mst.S_TYPE.Contains("空托下线") || mst.S_TYPE.Contains("满托下线"))) { LogHelper.Info($"任务{mst.S_TYPE}取货时间存入中间表,当前时间:{DateTime.Now},点位:{mst.S_START_LOC}"); var cgInfo = db.Queryable().Where(a => a.Bit == mst.S_START_LOC).First(); if (cgInfo != null) { cgInfo.time = DateTime.Now; if (db.Updateable(cgInfo).UpdateColumns(a => new { a.time }).ExecuteCommand() > 0) LogHelper.Info($"数据更改成功,起点:{mst.S_START_LOC}"); } else { CGTTable cg = new CGTTable { Bit = mst.S_START_LOC, time = DateTime.Now, }; if (db.Insertable(cg).ExecuteCommand() > 0) LogHelper.Info($"数据插入成功,起点:{mst.S_START_LOC}"); } } } private static object locLocker = new object(); /// /// 堆叠库区出入库任务申请 /// /// /// /// /// /// /// /// /// internal static bool ApplyTN_Task(Location ls, ref List cntrs, string area, string itemCode, string itemBatch, string taskType, bool insStock = true) { var result = false; lock (locLocker) { try { if (insStock) { Console.WriteLine($"MoboxHelperCreateTask: {area}-{itemCode}-{itemBatch}-{taskType}"); var endTN_Location = GetLocation4In(area, itemCode, itemBatch, 3); if (endTN_Location != null) { var endLayer = endTN_Location.N_CURRENT_NUM == 0 ? 1 : 2; var taskNo = DateTime.Now.Ticks.ToString(); result = TaskProcess.CreateTransport(ls.S_CODE, endTN_Location.S_CODE, taskType, cntrs, 1, endLayer, 3, 70); } else { Console.WriteLine($"MoboxHelperCreateTask: 未找到终点货位"); } } else { var startTN_Location = GetLocation4Out(area, itemCode, itemBatch, 3); if (startTN_Location != null) { var startLayer = startTN_Location.N_CURRENT_NUM <= 3 ? 1 : 2; var taskNo = DateTime.Now.Ticks.ToString(); var carryCount = startTN_Location.N_CURRENT_NUM > 3 ? startTN_Location.N_CURRENT_NUM - 3 : startTN_Location.N_CURRENT_NUM; //出库要从起点获取托盘 var cntrList = LocationHelper.GetLocCntr(startTN_Location.S_CODE); if (cntrList.Count == startTN_Location.N_CURRENT_NUM) { cntrs = cntrList.OrderByDescending(a => a.T_CREATE).Take(carryCount).Select(a => a.S_CNTR_CODE.Trim()).ToList(); result = TaskProcess.CreateTransport(startTN_Location.S_CODE, ls.S_CODE, taskType, cntrs, startLayer, 1, carryCount, 65); } else { Console.WriteLine($"起点托盘数量和货位容器表不符合,请检查【货位表】和【货位容器表】"); } } } } catch (Exception ex) { Console.WriteLine("MoboxHelperCreateTask:" + ex.Message); LogHelper.Error("MoboxHelperCreateTask:" + ex.Message, ex); } } return result; } private static Location GetLocation4Out(string area, string itemCode, string itemBatch, int v) { throw new NotImplementedException(); } private static Location GetLocation4In(string area, string itemCode, string itemBatch, int v) { throw new NotImplementedException(); } /// /// 普通货架区的出入库申请 /// /// /// /// /// /// /// /// internal static bool ApplyNormalTN_Task(Location ls, ref List cntrs, string area, string taskType, string itemCode, bool insStock = true) { var result = false; lock (locLocker) { try { if (insStock) { Console.WriteLine($"MoboxHelperCreateTask: {area}-{taskType}"); var endTN_Location = new Location(); if (endTN_Location != null) { var taskNo = DateTime.Now.Ticks.ToString(); result = TaskProcess.CreateTransport(ls.S_CODE, endTN_Location.S_CODE, taskType, cntrs, 70); } else { Console.WriteLine($"MoboxHelperCreateTask: 未找到终点货位"); } } else { var startTN_Location = new Location(); if (startTN_Location != null) { //出库要从起点获取托盘 var cntrList = LocationHelper.GetLocCntr(startTN_Location.S_CODE); if (cntrList.Count == startTN_Location.N_CURRENT_NUM) { result = TaskProcess.CreateTransport(startTN_Location.S_CODE, ls.S_CODE, taskType, new List { cntrList[0].S_CNTR_CODE }, 65); } else { Console.WriteLine($"起点托盘数量和货位容器表不符合,请检查【货位表】和【货位容器表】"); } } } } catch (Exception ex) { Console.WriteLine("MoboxHelperCreateTask:" + ex.Message); LogHelper.Error("MoboxHelperCreateTask:" + ex.Message, ex); } } return result; } /// /// 推送任务 /// /// internal static bool SendTask(WCSTask mst) { var result = false; var start = "0"; var end = "0"; var taskType = mst.S_TYPE.Trim(); if (mst.N_B_STATE == 0) { //if (mst.S_SCHEDULE_TYPE == "NDC") { // start = LocationHelper.GetAgvSite(mst.S_START_LOC); // end = LocationHelper.GetAgvSite(mst.S_END_LOC); // // // Console.WriteLine($"SendTask {mst.S_CODE}"); // Console.WriteLine("start=" + start); // Console.WriteLine("end= " + end); // var dic = new Dictionary(); // dic.Add("Pri", mst.N_PRIORITY.ToString()); // dic.Add("From", start.ToString()); // dic.Add("To", end.ToString()); // dic.Add("No", mst.S_CODE.Trim());// dic.Add("Ext1", "1"); dic.Add("Ext2", "CALLADDAGV"); dic.Add("N_CNTR_COUNT", ""); // var res = NDC.AddNewOrder(1, dic); // if (res != null && (res.Res.ErrCode == 0 || res.Res.ErrCode == 50009)) { // //推送成功,修改任务优先级 mst.N_B_STATE = 1; WCSHelper.UpdateStatus(mst, "已推送"); result = true; // } // } // else if (mst.S_SCHEDULE_TYPE == "WCS") { // //调第三方接口 // var model = new HanAo.TaskInfoModel // { // requestPk = mst.S_CODE, // frmPos = mst.S_START_LOC, // toPos = mst.S_END_LOC, // trkType = mst.S_OP_NAME == "入库" ? "1" : "2", // contNo = mst.S_CNTR_CODE // }; // //if (HanAo.CreateOrder(model)) { // mst.N_B_STATE = 1; // WCSHelper.UpdateStatus(mst); // //} // } } return result; } /// /// 创建搬运任务 /// /// /// /// /// /// /// /// /// /// public static bool CreateTransport(string start, string end, string taskType, List cntrs, int startLayer, int endLayer, int trayCarryCount = 1, int priority = 1) { var result = false; //批次号存托盘号,1~3个托盘 var trayCodes = string.Join(",", cntrs); var taskNo = DateTime.Now.Ticks.ToString(); var res = WCSHelper.CreateTask(taskNo, start.Trim(), end.Trim(), taskType, priority, trayCodes, trayCarryCount, startLayer, endLayer); if (res) { result = true; //任务创建成功,起点货位出库锁定,终点货位入库锁定 LocationHelper.LockLoc(start, 1); LocationHelper.LockLoc(end, 2); } return result; } public static bool CreateTransport(string start, string end, string taskType, List cntrs, int priority = 1) { var result = false; //批次号存托盘号,1~3个托盘 var trayCodes = string.Join(",", cntrs); var taskNo = DateTime.Now.Ticks.ToString(); var res = WCSHelper.CreateTask(taskNo, start.Trim(), end.Trim(), taskType, priority, trayCodes, 1, 1, 1); if (res) { result = true; LocationHelper.LockLoc(start, 2); LocationHelper.LockLoc(end, 1); } return result; } #endregion /// /// 半成品出入库 /// /// /// true:入库 false:出库 /// /// public static Location BCPInOrOut(SqlSugarClient db, bool action, string startCode = "", string areaName = "", LinZhiBCPWorkOrder workInfo = null) { Location result = null; if (action) { var cntrInfo = db.Queryable().Where(a => a.S_LOC_CODE == startCode).First(); var itemInfo = db.Queryable().Where(a => a.S_CNTR_CODE == cntrInfo.S_CNTR_CODE).First(); if (itemInfo != null) { //瓶盖库区,两层密集型库区 空满在同一个库区,需要区分不同排 var areaInfo = Settings.areaInfos.Where(a => a.areaName == areaName && a.enable == 1).First(); if (areaInfo != null) { //库区货位约定:列号越小越靠里 LogHelper.Info($"入库算法01:area:{areaInfo.areaCode},itemCode:{itemInfo.S_ITEM_CODE},itemBatch:{itemInfo.S_BATCH_NO}", "WMSAlgoRithm"); try { if (result == null) { var locInfo = db.Queryable().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM > 0).OrderBy(a => a.N_ROW).OrderByDescending(a => a.N_COL) .PartitionBy(a => a.N_ROW).Take(1) .ToList(); if (locInfo.Count > 0) { foreach (var a in locInfo) { string itemCode = ""; var endCntrInfo = db.Queryable().Where(b => b.S_LOC_CODE == a.S_CODE).First(); if (endCntrInfo != null) { var endItemInfo = db.Queryable().Where(b => b.S_CNTR_CODE == endCntrInfo.S_CNTR_CODE).First(); if (endItemInfo != null) { itemCode = endItemInfo.S_ITEM_CODE; } else { LogHelper.Info($"终点货位未绑定物料信息"); continue; } } else { LogHelper.Info($"终点货位未绑定托盘信息"); continue; } //去掉当前货位有锁,或者为空托的货位 if (a.S_LOCK_STATE == "无") { //判断是否和当前货位的物料编码相同 if (itemCode == itemInfo.S_ITEM_CODE) { //查询当前排是否可入(判断是是否有入库锁和出库锁) var lockInfo = db.Queryable().Where(b => b.S_AREA_CODE == a.S_AREA_CODE && b.N_ROW == a.N_ROW && (b.S_LOCK_STATE == "入库锁" || b.S_LOCK_STATE == "出库锁")).First(); if (lockInfo == null) { //当前排无任务 if (a.N_CURRENT_NUM < a.N_CAPACITY) result = a; else { //查询后面当前货位后一个 result = db.Queryable().Where(b => b.S_AREA_CODE == a.S_AREA_CODE && b.N_ROW > a.N_ROW && b.S_LOCK_STATE == "无").OrderBy(b => b.N_COL).First(); } if (result != null) { break; } } } } } } if (result == null) { //todo 还需要判断锁 #region 查找所有数量是空的排 LogHelper.Info($"入库算法06:无可用货位,获取空排货位。", "WMSAlgoRithm"); //2.0 简化查询只查每一排第一列 var list = db.Queryable().Where(a => a.S_AREA_CODE == areaInfo.areaCode).OrderBy(a => a.N_ROW).OrderBy(a => a.N_COL).PartitionBy(a => a.N_ROW).ToList().Where(a => a.N_CURRENT_NUM == 0).ToList(); //2.1 选一个空排 if (list.Count > 0) { LogHelper.Info($"入库算法06:无可用货位,获取空排货位数量为:{list.Count}。", "WMSAlgoRithm"); for (int i = 0; i < list.Count; i++) { LogHelper.Info($"入库算法07:获取空排货位:货位编码:{list[i].S_CODE.Trim()},当前数量:{list[i].N_CURRENT_NUM},排号:{list[i].N_ROW},库区编码:{list[i].S_AREA_CODE.Trim()}", "WMSAlgoRithm"); if (list[i].S_LOCK_STATE.Trim().Contains("无")) { //二次校验当前排所有货位都是空的,防止系统数据错乱 int row = list[i].N_ROW; string areaCode = list[i].S_AREA_CODE.Trim(); var lockInfo = db.Queryable().Where(b => b.S_AREA_CODE == areaCode && b.N_ROW == row && (b.S_LOCK_STATE == "入库锁" || b.S_LOCK_STATE == "出库锁")).First(); if (lockInfo == null) { var locInfo1 = db.Queryable().Where(a => a.S_AREA_CODE == areaCode && a.N_ROW == row).Select(a => new { sum = SqlFunc.AggregateSum(a.N_CURRENT_NUM) }).First(); if (locInfo1 != null) { LogHelper.Info($"{locInfo1.sum},row:{row}"); if (locInfo1.sum == 0) { //空排 result = list[i]; break; } } else LogHelper.Info("未找到该排"); } else { LogHelper.Info("该排有锁"); } } } } else LogHelper.Info($"未获取到空排,库区编码:{areaInfo.areaCode}"); #endregion } } } catch (Exception ex) { Console.WriteLine("GetLocationIn:" + ex.Message + ex.StackTrace); LogHelper.Error("GetLocationIn:" + ex.Message, ex); } } else { LogHelper.Info($"入库任务 瓶盖库区未配置"); } } else { LogHelper.Info($"入库任务 起点货位未绑定物料信息"); } } else { string itemCode = ""; if (string.IsNullOrEmpty(startCode)) { var cntrInfo = db.Queryable().Where(a => a.S_LOC_CODE == startCode).First(); var itemInfo = db.Queryable().Where(a => a.S_CNTR_CODE == cntrInfo.S_CNTR_CODE).First(); if(itemInfo != null) { itemCode = itemInfo.S_ITEM_CODE; } } if (workInfo != null) { itemCode = workInfo.S_ItemCode; } var areaInfo = Settings.areaInfos.Where(a => a.areaName == areaName && a.enable == 1).FirstOrDefault(); if(areaInfo != null) { var locList = db.Queryable().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM > 0).OrderBy(a => a.N_ROW).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).Includes(a => a.LocCntrRel).ToList(); if(locList.Count > 0) { foreach(var a in locList) { if(a.S_LOCK_STATE == "无") { var cntrInfo = db.Queryable().Where(b => b.S_LOC_CODE == a.S_CODE).First(); if(cntrInfo != null) { var itemInfo = db.Queryable().Where(b => b.S_CNTR_CODE == cntrInfo.S_CNTR_CODE).First(); if(itemInfo != null && itemInfo.S_ITEM_CODE == itemCode) { //判断当前排有无锁 var lockInfo = db.Queryable().Where(b => b.S_AREA_CODE == areaInfo.areaCode && b.N_ROW == a.N_ROW && (b.S_LOCK_STATE == "入库锁" || b.S_LOCK_STATE == "出库锁")).First(); if(lockInfo == null) { result = a; break; } } } } } } } else { LogHelper.Info($"{areaName}未配置"); } } return result; } internal static Location getMStartLoc(SqlSugarClient db) { Location result = null; var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯注塑机空托" && a.enable == 1).FirstOrDefault(); if(areaInfo != null) { var locInfo = db.Queryable().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM > 0 && a.S_LOCK_STATE == "无").Includes(a => a.LocCntrRel).First(); if(locInfo != null) { result = locInfo; } } else { LogHelper.Info("瓶坯注塑机空托未配置"); } return result; } /// /// 瓶坯注塑满托下线 /// /// /// /// /// internal static Location BCPFullOut(SqlSugarClient db, string taskName, string S_START_LOC) { Location result = null; if (taskName.Contains("即产")) { //即产即用工单,下线到即产即用库区 //即产即用库区有两个线边库,如果即产即用A库区满,则放到即产即用B库区,若即产即用库区都满,则放到瓶坯库区 var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯即产即用A" && a.enable == 1).FirstOrDefault(); if(areaInfo != null) { var locInfo = db.Queryable().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM < a.N_CAPACITY && a.S_LOCK_STATE == "无").OrderBy(a => a.N_COL).First(); if(locInfo != null) { result = locInfo; } } if (result == null) { result = TaskProcess.BCPInOrOut(db, true, S_START_LOC, "瓶坯即产即用B"); } if(result == null) { result = TaskProcess.BCPInOrOut(db, true, S_START_LOC,"瓶坯库区"); } } else { //非即产即用工单,下线到非即产即用库区 //非即产即用库区只有一个线边库,如果线边库满,则放到瓶坯库区 var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯非即产即用" && a.enable == 1).FirstOrDefault(); if (areaInfo != null) { var locInfo = db.Queryable().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM < a.N_CAPACITY && a.S_LOCK_STATE == "无").OrderBy(a => a.N_COL).First(); if (locInfo != null) { result = locInfo; } } if (result == null) { result = TaskProcess.BCPInOrOut(db, true, S_START_LOC, "瓶坯库区"); } } return result; } /// /// 翻斗机空托下线 /// /// /// /// /// internal static Location BCPEmptyOut(SqlSugarClient db, string taskName) { Location result = null; //翻斗机库存空托下线(瓶盖) string endAreaName = taskName.Contains("瓶盖") ? "瓶盖空托" : "瓶坯空托"; var areaInfo = Settings.areaInfos.Where(a => a.areaName == endAreaName && a.enable == 1).FirstOrDefault(); if(areaInfo != null) { var locInfo = db.Queryable().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM > 0 && a.S_LOCK_STATE == "无").OrderBy(a => a.N_COL).First(); if(locInfo != null) { result = locInfo; } } else { LogHelper.Info($"{endAreaName}未配置"); } return result; } } }