海波 张
4 天以前 27e00e4c0d354727728ac4b8770b1575b5077399
wms/LocationHelper.cs
@@ -1,15 +1,23 @@
using HH.WCS.ZhongCeJinTan;
using HH.WCS.ZhongCeJinTan.dispatch;
using HH.WCS.ZhongCeJinTan.util;
using HH.WCS.ZhongCeJinTan.wms;
using Microsoft.Owin;
using Newtonsoft.Json;
using Org.BouncyCastle.Utilities;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Top.Api;
using WebSocketSharp.Frame;
using static HH.WCS.ZhongCeJinTan.api.ApiModel;
using static HH.WCS.ZhongCeJinTan.util.Settings;
using static HH.WCS.ZhongCeJinTan.wms.WcsModel;
using static ICSharpCode.SharpZipLib.Zip.ExtendedUnixData;
namespace HH.WCS.ZhongCeJinTan.wms
{
@@ -20,15 +28,15 @@
        static LocationHelper() {
            //初始化location加入到字典缓存
            locations = new Dictionary<string, Location>();
            var list = GetAllLocList();
            if (list.Count > 0) {
                list.ForEach(a => {
                    if (!locations.ContainsKey(a.S_CODE)) {
                        locations.Add(a.S_CODE, a);
                    }
                });
            }
            //locations = new Dictionary<string, Location>();
            //var list = GetAllLocList();
            //if (list.Count > 0) {
            //    list.ForEach(a => {
            //        if (!locations.ContainsKey(a.S_CODE)) {
            //            locations.Add(a.S_CODE, a);
            //        }
            //    });
            //}
            //初始化locationExt加入到集合缓存
            //locationExts = new Dictionary<string, LocationExt>();
            //var exts = GetAllLocExtList();
@@ -81,13 +89,14 @@
        }
        /// <summary>
        /// 获取货位信息,参数库区编号
        /// </summary>
        internal static List<string> GetConnectionList(string S_AREA_CODE)
        {
            var db = new SqlHelper<object>().GetInstance();
            var ConnectionList =  db.Queryable<Location>().Where(s => s.S_AREA_CODE == S_AREA_CODE && s.C_ENABLE == "Y").OrderBy(a => a.N_ROW).OrderBy(a => a.N_COL).ToList();
            var ConnectionList = db.Queryable<Location>().Where(s => s.S_AREA_CODE == S_AREA_CODE && s.C_ENABLE == "Y").OrderBy(a => a.N_ROW).OrderBy(a => a.N_COL).ToList();
            List<string> result = new List<string>();
            foreach (var item in ConnectionList)
            {
@@ -95,6 +104,94 @@
            }
            return result;
        }
        /// <summary>
        /// 获取货位信息,参数库区编号
        /// </summary>
        internal static List<string> GetConnectionListByN(string S_AREA_CODE)
        {
            var db = new SqlHelper<object>().GetInstance();
            var ConnectionList = db.Queryable<Location>().Where(s => s.S_AREA_CODE == S_AREA_CODE && s.C_ENABLE == "N").OrderBy(a => a.N_ROW).OrderBy(a => a.N_COL).ToList();
            List<string> result = new List<string>();
            foreach (var item in ConnectionList)
            {
                result.Add(item.S_CODE);
            }
            return result;
        }
        internal static Location GetConnectionByEnd(string S_AREA_CODE,int rodway)
        {
            var db = new SqlHelper<object>().GetInstance();
            return db.Queryable<Location>().Where(s => s.S_AREA_CODE == S_AREA_CODE && s.C_ENABLE == "Y" &&s.CONNEC_ROADWAY==rodway).First();
        }
        /// <summary>
        /// 返回均衡的接驳位集合
        /// </summary>
        internal static List<connectionBalance> GetBalanceConnectionList(List<string> locList)
        {
            var db = new SqlHelper<object>().GetInstance();
            List<connectionBalance> result = new List<connectionBalance>();
            foreach (var item in locList)
            {
                var ConnectionList = 0;
                ConnectionList = db.Queryable<WMSTask>().Where(a => (a.S_END_LOC.Contains(item) || a.S_START_LOC.Contains(item)) && a.S_B_STATE != "完成" && a.S_B_STATE != "取消" && a.S_B_STATE != "失败" && a.S_B_STATE != "已完成" &&  a.S_B_STATE != "未执行").ToList().Count();
                var re = new connectionBalance();
                var con = LocationHelper.GetLoc(item);
                re.loc = con;
                re.taskCount = ConnectionList;
                result.Add(re);
            }
            return result.OrderBy(a => a.taskCount).ToList();
        }
        /// <summary>
        /// 返回出库agv任务
        /// </summary>
        internal static WMSTask GetConnectionTask(string jbLoc,string type)
        {
            var db = new SqlHelper<object>().GetInstance();
          return db.Queryable<WMSTask>().Where(a => ( a.S_START_LOC.Contains(jbLoc)&& a.S_SCHEDULE_TYPE.Contains(type)  && a.S_B_STATE != "完成" && a.S_B_STATE != "取消" && a.S_B_STATE != "失败" && a.S_B_STATE != "已完成" && a.S_B_STATE != "未执行")).OrderBy(b=>b.T_CREATE).First();
        }
        /// <summary>
        /// 返回接驳位集合
        /// </summary>
        internal static List<Location> GetConnectionListByst(List<string> locList)
        {
            var db = new SqlHelper<object>().GetInstance();
            List<Location> result = new List<Location>();
            foreach (var item in locList)
            {
                var con = LocationHelper.GetLoc(item);
                result.Add(con);
            }
            return result;
        }
        /// <summary>
        /// 返回当前接驳位执行任务数量
        /// </summary>
        internal static int GetConnectionTaskCount(string connection)
        {
            var db = new SqlHelper<object>().GetInstance();
                var ConnectionList = 0;
                ConnectionList = db.Queryable<WMSTask>().Where(a => (a.S_END_LOC.Contains(connection) || a.S_START_LOC.Contains(connection)) && a.S_B_STATE != "完成" && a.S_B_STATE != "取消" && a.S_B_STATE != "失败" && a.S_B_STATE != "已完成" ).ToList().Count();
            return ConnectionList;
        }
        /// <summary>
        /// 找终点巷道可用空货位
@@ -200,6 +297,517 @@
        }
        /// <summary>
        /// 找终点巷道可用空货位 均衡
        /// </summary>
        /// <param name="locations"></param>
        /// <returns></returns>
        internal static Location FindBalanceEndcolByLocList(List<Location> locations, string endArea, string rodway = "",string CONNECTION = "",string taskNo="")
        {
            try
            {
                var db = new SqlHelper<object>().GetInstance();
                Location end = null;
                //根据终点货位找空闲货位
                var rows = locations.Select(a => a.N_ROW).Distinct().ToList();
                //作业流程的巷道
                var xd = new List<string>();
                //获取string接驳位集合
                var connectionList = LocationHelper.GetConnectionList(CONNECTION);
                //不可用接驳位集合
                var flaseConnectionList = LocationHelper.GetConnectionListByst(connectionList);
                List<Location> jblist = new List<Location>();
                //询问立库可用接驳位
                var usableConnectionList = WcsTask.WcsPositionAvailable(taskNo,connectionList);
                if (usableConnectionList != null && usableConnectionList.code == "0")
                {
                    var balanceConnectionList = LocationHelper.GetConnectionListByst(usableConnectionList.available);
                    List<Location> difference = flaseConnectionList
    .Where(loc1 => !balanceConnectionList.Any(loc2 => loc2.S_CODE == loc1.S_CODE))
    .ToList();
                    jblist = difference;
                    LogHelper.Info($"ZCSendTask入库任务下发不可用接驳位" + JsonConvert.SerializeObject(jblist), "Mes任务下发");
                }
                else
                {
                    LogHelper.Info($"ZCSendTask入库任务{taskNo}下发失败,接驳位返回失败", "Mes任务下发");
                    throw new Exception($"{taskNo}下发失败,接驳位返回失败");
                }
                List<RoadWayEnable> rowdwa = null;
                if (!string.IsNullOrEmpty(rodway))
                {
                    xd = rodway.Split('-').ToList();
                    rowdwa = db.Queryable<RoadWayEnable>().Where(x => x.areaCode == endArea && x.status == "0" && xd.Contains(x.roadWay)).ToList();
                }
                else
                {
                    //查找可用巷道
                    rowdwa = db.Queryable<RoadWayEnable>().Where(x => x.areaCode == endArea && x.status == "0").ToList();
                }
                for (int i = 0; i < rows.Count; i++)
                {
                    var rowList = locations.Where(r => r.N_ROW == rows[i]).ToList();
                    var flag = false;
                    var flag1 = false;
                    var flag2 = false;
                    foreach (var item in rowdwa)
                    {
                        if (rowList.Count(a => a.N_ROADWAY.ToString() == item.roadWay) > 0)
                        {
                            flag = true;
                            break;
                        }
                    }
                    foreach (var item1 in xd)
                    {
                        if (rowList.Count(a => a.N_ROADWAY.ToString() != item1) > 0)
                        {
                            flag1 = true;
                            break;
                        }
                    }
                    foreach (var item2 in jblist)
                    {
                        if (rowList.Count(a => a.N_ROADWAY == item2.CONNEC_ROADWAY) > 0)
                        {
                            flag2 = true;
                            break;
                        }
                    }
                    if (flag1 || flag || flag2)
                    {
                       locations.RemoveAll(a => a.N_ROW == rows[i]);
                    }
                    if (rowList.Count(a => a.N_CURRENT_NUM == 0) == 0)
                    {
                        locations.RemoveAll(a => a.N_ROW == rows[i]);
                    }
                }
                var balanceLocList = RoadWayBalance(locations);
                foreach (var item in balanceLocList)
                {
                    if (item.S_LOCK_STATE=="无" && item.N_CURRENT_NUM==0)
                    {
                        end = item;
                        break;
                    }
                }
                return end;
            }
            catch (Exception)
            {
                throw;
            }
        }
        /// <summary>
        /// 找终点巷道可用空货位  巷道均衡物料均衡
        /// </summary>
        /// <param name="locations"></param>
        /// <returns></returns>
        internal static Location FindBalanceEndcolByLocListItem(List<Location> locations, string endArea, string rodway = "", string CONNECTION = "", string taskNo = "",string itemCode="")
        {
            try
            {
                var db = new SqlHelper<object>().GetInstance();
                Location end = null;
                //根据终点货位找空闲货位
                var rows = locations.Select(a => a.N_ROW).Distinct().ToList();
                //作业流程的巷道
                var xd = new List<string>();
                //获取string接驳位集合
                var connectionList = LocationHelper.GetConnectionList(CONNECTION);
                //不可用接驳位集合
                var flaseConnectionList = LocationHelper.GetConnectionListByst(connectionList);
                List<Location> jblist = new List<Location>();
                //询问立库可用接驳位
                var usableConnectionList = WcsTask.WcsPositionAvailable(taskNo, connectionList);
                if (usableConnectionList != null && usableConnectionList.code == "0")
                {
                    var balanceConnectionList = LocationHelper.GetConnectionListByst(usableConnectionList.available);
                    List<Location> difference = flaseConnectionList
                    .Where(loc1 => !balanceConnectionList.Any(loc2 => loc2.S_CODE == loc1.S_CODE))
                    .ToList();
                    jblist = difference;
                    LogHelper.Info($"ZCSendTask入库任务下发不可用接驳位" + JsonConvert.SerializeObject(jblist), "Mes任务下发");
                }
                else
                {
                    LogHelper.Info($"ZCSendTask入库任务{taskNo}下发失败,接驳位返回失败", "Mes任务下发");
                    throw new Exception($"{taskNo}下发失败,接驳位返回失败");
                }
                List<RoadWayEnable> rowdwa = null;
                if (!string.IsNullOrEmpty(rodway))
                {
                    xd = rodway.Split('-').ToList();
                    rowdwa = db.Queryable<RoadWayEnable>().Where(x => x.areaCode == endArea && x.status == "0" && xd.Contains(x.roadWay)).ToList();
                }
                else
                {
                    //查找可用巷道
                    rowdwa = db.Queryable<RoadWayEnable>().Where(x => x.areaCode == endArea && x.status == "0").ToList();
                }
                for (int i = 0; i < rows.Count; i++)
                {
                    var rowList = locations.Where(r => r.N_ROW == rows[i]).ToList();
                    var flag = false;
                    var flag1 = false;
                    var flag2 = false;
                    foreach (var item in rowdwa)
                    {
                        if (rowList.Count(a => a.N_ROADWAY.ToString() == item.roadWay) > 0)
                        {
                            flag = true;
                            break;
                        }
                    }
                    foreach (var item1 in xd)
                    {
                        if (rowList.Count(a => a.N_ROADWAY.ToString() != item1) > 0)
                        {
                            flag1 = true;
                            break;
                        }
                    }
                    foreach (var item2 in jblist)
                    {
                        if (rowList.Count(a => a.N_ROADWAY == item2.CONNEC_ROADWAY) > 0)
                        {
                            flag2 = true;
                            break;
                        }
                    }
                    if (flag1 || flag || flag2)
                    {
                        locations.RemoveAll(a => a.N_ROW == rows[i]);
                    }
                    if (rowList.Count(a => a.N_CURRENT_NUM == 0) == 0)
                    {
                        locations.RemoveAll(a => a.N_ROW == rows[i]);
                    }
                }
                var balanceLocList = RoadWayBalance(locations);
                balanceLocList = LocationHelper.RoadWayBalance1ByItem(balanceLocList, itemCode);
                foreach (var item in balanceLocList)
                {
                    if (item.S_LOCK_STATE == "无")
                    {
                        end = item;
                        break;
                    }
                }
                return end;
            }
            catch (Exception)
            {
                throw;
            }
        }
        /// <summary>
        /// 找终点巷道可用空货位集合 均衡
        /// </summary>
        /// <param name="locations"></param>
        /// <returns></returns>
        internal static List<Location> FindBalanceEndLocList(List<Location> locations, string endArea, string rodway = "")
        {
            try
            {
                var db = new SqlHelper<object>().GetInstance();
                Location end = null;
                //根据终点货位找空闲货位
                var rows = locations.Select(a => a.N_ROW).Distinct().ToList();
                //作业流程的巷道
                var xd = new List<string>();
                List<RoadWayEnable> rowdwa = null;
                if (!string.IsNullOrEmpty(rodway))
                {
                    xd = rodway.Split('-').ToList();
                    rowdwa = db.Queryable<RoadWayEnable>().Where(x => x.areaCode == endArea && x.status == "0" && xd.Contains(x.roadWay)).ToList();
                }
                else
                {
                    //查找可用巷道
                    rowdwa = db.Queryable<RoadWayEnable>().Where(x => x.areaCode == endArea && x.status == "0").ToList();
                }
                for (int i = 0; i < rows.Count; i++)
                {
                    var rowList = locations.Where(r => r.N_ROW == rows[i]).ToList();
                    var flag = false;
                    var flag1 = false;
                    foreach (var item in rowdwa)
                    {
                        if (rowList.Count(a => a.N_ROADWAY.ToString() == item.roadWay) > 0)
                        {
                            flag = true;
                            break;
                        }
                    }
                    foreach (var item1 in xd)
                    {
                        if (rowList.Count(a => a.N_ROADWAY.ToString() != item1) > 0)
                        {
                            flag1 = true;
                            break;
                        }
                    }
                    if (flag1 || flag)
                    {
                        locations.RemoveAll(a => a.N_ROW == rows[i]);
                    }
                    if (rowList.Count(a => a.N_CURRENT_NUM == 0) == 0)
                    {
                        locations.RemoveAll(a => a.N_ROW == rows[i]);
                    }
                }
                    //寻找均衡巷道
                    var balanceLocList = RoadWayBalance1(locations);
                return balanceLocList;
            }
            catch (Exception)
            {
                throw;
            }
        }
        /// <summary>
        /// 巷道均衡策略
        /// </summary>
        /// <param name="lstTrueLocation">可用的货位信息数据</param>
        /// <returns>计算后返回的实体</returns>
        public static List<Location> RoadWayBalance(List<Location> lstTrueLocation)
        {
            //指定计算后返回的实体
            List<Location> location_roadray = new List<Location>();
            //按照巷道分组   并获得巷道中可用货位的数据
            //之后进行倒叙   找到可用货位最多的巷道
            var v = lstTrueLocation.GroupBy(x => x.N_ROADWAY).Select(g => (new
            {
                roadWay = g.Key,
                qty = g.Count(p => p.S_LOCK_STATE=="无")
            })).OrderByDescending(o => o.qty);
            //倒叙排列后的巷道  循环
            foreach (var item in v)
            {
                //取得巷道列表中可用货位最多的巷道  并获取巷道中所有货位
                location_roadray = lstTrueLocation.Where(o => o.N_ROADWAY == item.roadWay).ToList();
                if (location_roadray != null && location_roadray.Count > 0)
                {
                    break;
                }
            }
            return location_roadray;
        }
        /// <summary>
        /// 巷道均衡策略
        /// </summary>
        /// <param name="lstTrueLocation">可用的货位信息数据</param>
        /// <returns>计算后返回的实体</returns>
        public static List<Location> RoadWayBalance1(List<Location> lstTrueLocation)
        {
            //指定计算后返回的实体
            List<Location> location_roadray = new List<Location>();
            //按照巷道分组   并获得巷道中可用货位的数据
            //之后进行倒叙   找到可用货位最多的巷道
            var v = lstTrueLocation.GroupBy(x => x.N_ROADWAY).Select(g => (new
            {
                roadWay = g.Key,
                qty = g.Count(p => p.S_LOCK_STATE == "无")
            })).OrderByDescending(o => o.qty);
            //倒叙排列后的巷道  循环
            foreach (var item in v)
            {
                //取得巷道列表中可用货位最多的巷道  并获取巷道中所有货位
                var loclist = lstTrueLocation.Where(o => o.N_ROADWAY == item.roadWay).OrderBy(b => b.N_ROW).OrderBy(b=>b.N_COL).ToList();
                foreach (var item1 in loclist)
                {
                    location_roadray.Add(item1);
                }
            }
            return location_roadray;
        }
        /// <summary>
        /// 物料均衡
        /// </summary>
        /// <param name="lstTrueLocation"></param>
        /// <returns></returns>
        public static List<Location> RoadWayBalance1ByItem(List<Location> lstTrueLocation, string itemCode)
        {
            var db = new SqlHelper<object>().GetInstance();
            //指定计算后返回的实体
            List<Location> location_roadray = new List<Location>();
            List<connectionBalance> result = new List<connectionBalance>();
            var newlstTrueLocation = lstTrueLocation.GroupBy(c => c.N_ROADWAY)
    .Select(g => g.First()) // 或者 g.FirstOrDefault()
    .ToList();
            foreach (var item in newlstTrueLocation)
            {
                var ConnectionList = 0;
                var loclist = lstTrueLocation.Where(o => o.N_ROADWAY == item.N_ROADWAY && o.N_CURRENT_NUM>0).OrderBy(b => b.N_ROW).OrderBy(b => b.N_COL).ToList();
                foreach (var item1 in loclist)
                {
                    var tp = db.Queryable<LocCntrRel>().Where(s => s.S_LOC_CODE == item1.S_CODE).First();
                    // LogHelper.Info($"ZCSendTask出库任务下发起点货位容器信息" + JsonConvert.SerializeObject(tp), "Mes任务下发");
                    if (tp != null && item1.S_LOCK_STATE == "无")
                    {
                        var tp1 = db.Queryable<CntrItemRel>().Where(s => s.S_CNTR_CODE == tp.S_CNTR_CODE).First();
                        //LogHelper.Info($"ZCSendTask出库任务下发起点容器物料信息" + JsonConvert.SerializeObject(tp1), "Mes任务下发");
                        if (tp1 != null && tp1.S_ITEM_CODE == itemCode)
                        {
                            ConnectionList += 1;
                        }
                    }
                }
                var re = new connectionBalance();
                var con = LocationHelper.GetLoc(item.S_CODE);
                re.loc = con;
                re.taskCount = ConnectionList;
                result.Add(re);
            }
               result =  result.OrderBy(a=>a.taskCount).ToList();
                foreach (var item in result)
                {
                    var loclist = lstTrueLocation.Where(o => o.N_ROADWAY == item.loc.N_ROADWAY && o.N_CURRENT_NUM==0 ).OrderBy(b => b.N_ROW).OrderBy(b => b.N_COL).ToList();
                    foreach (var item1 in loclist)
                    {
                        location_roadray.Add(item1);
                    }
                }
                return location_roadray;
            }
        /// <summary>
        /// 返回均衡的接驳位集合
        /// </summary>
        internal static List<connectionBalance> GetBalanceConnectionList3(List<string> locList)
        {
            var db = new SqlHelper<object>().GetInstance();
            List<connectionBalance> result = new List<connectionBalance>();
            foreach (var item in locList)
            {
                var ConnectionList = 0;
                ConnectionList = db.Queryable<WMSTask>().Where(a => (a.S_END_LOC.Contains(item) || a.S_START_LOC.Contains(item)) && a.S_B_STATE != "完成" && a.S_B_STATE != "取消" && a.S_B_STATE != "失败" && a.S_B_STATE != "已完成" && a.S_B_STATE != "未执行").ToList().Count();
                var re = new connectionBalance();
                var con = LocationHelper.GetLoc(item);
                re.loc = con;
                re.taskCount = ConnectionList;
                result.Add(re);
            }
            return result.OrderBy(a => a.taskCount).ToList();
        }
        /// <summary>
        /// 找终点可用空货位排除不可用巷道
@@ -382,14 +990,21 @@
        /// </summary>
        /// <param name="locations"></param>
        /// <returns></returns>
        internal static Location FindStartcolByLoclistAndcntr(List<Location> locations,string startArea) {
        internal static Location FindStartcolByLoclistAndcntr(List<Location> locations,string startArea, string CONNECTION = "") {
            var db = new SqlHelper<object>().GetInstance();
            try
            {
               var connectionList = LocationHelper.GetConnectionList(CONNECTION);
                var balanceConnectionList = LocationHelper.GetConnectionListByst(connectionList);
                Location start = null;
                var rowsStart = locations.Select(a => a.N_ROW).Distinct().ToList();
                //查找可用巷道
                //查找不可用巷道
                var rowdwa = db.Queryable<RoadWayEnable>().Where(x => x.areaCode == startArea && x.status == "0").ToList();
                for (int i = 0; i < rowsStart.Count; i++)
@@ -398,6 +1013,8 @@
                    var flag = false;
                    var flag2 = false;
                    foreach (var item in rowdwa)
                    {
@@ -408,7 +1025,17 @@
                        }
                    }
                    if (flag)
                    foreach (var item2 in balanceConnectionList)
                    {
                        if (rowList.Count(a => a.N_ROADWAY != item2.CONNEC_ROADWAY) > 0)
                        {
                            flag2 = true;
                            break;
                        }
                    }
                    if (flag || flag2)
                    {
                        continue;
                    }
@@ -447,6 +1074,50 @@
                throw;
            }
        }
        /// <summary>
        /// 根据起点立库区找空托 校验库存
        /// </summary>
        /// <param name="locations"></param>
        /// <returns></returns>
        internal static bool FindStartcolByLoclistAndcntrFlag(List<Location> locations, string startArea)
        {
            var db = new SqlHelper<object>().GetInstance();
            try
            {
                var start = false;
                var rowsStart = locations.Select(a => a.N_ROW).Distinct().ToList();
                foreach (var item in locations)
                {
                    if (item.N_CURRENT_NUM == 0)
                    {
                        continue;
                    }
                    var tp = db.Queryable<LocCntrRel>().Where(s => s.S_LOC_CODE == item.S_CODE).First();
                    if (tp != null && item.S_LOCK_STATE == "无")
                    {
                        var tp1 = db.Queryable<Container>().Where(s => s.S_CODE == tp.S_CNTR_CODE).First();
                        if (tp1 != null && tp1.N_DETAIL_COUNT == 0)
                        {
                            return true;
                        }
                    }
                }
                return start;
            }
            catch (Exception)
            {
                throw;
            }
        }
        /// <summary>
        /// 根据起点货架区找空托
@@ -573,13 +1244,21 @@
        /// </summary>
        /// <param name="locations"></param>
        /// <returns></returns>
        internal static Location FindStartcolByLoclistAndItem(List<Location> locations,string itemCode,string endArea,string rodway="")
        internal static Location FindStartcolByLoclistAndItem(List<Location> locations,string itemCode,string endArea,string rodway="",string CONNECTION="")
        {
            var db = new SqlHelper<object>().GetInstance();
            try
            {
                Location start = null;
                var rowsStart = locations.Select(a => a.N_ROW).Distinct().ToList();
                var connectionList = LocationHelper.GetConnectionListByN(CONNECTION);
                var balanceConnectionList = LocationHelper.GetConnectionListByst(connectionList);
                LogHelper.Info($"ZCSendTask出库任务排除不可用巷道开始", "Mes任务下发");
                //作业流程的巷道
@@ -594,7 +1273,7 @@
                }
                else
                {
                    //查找可用巷道
                    //查找不可用巷道
                    rowdwa = db.Queryable<RoadWayEnable>().Where(x => x.areaCode == endArea && x.status == "0").ToList();
                }
@@ -603,7 +1282,7 @@
                //    LogHelper.Info($"ZCSendTask出库任务起点库区{endArea}找不到可用巷道", "Mes任务下发");
                //    return null;
                //}
                for (int i = 0; i < rowsStart.Count; i++)
                {
@@ -611,6 +1290,7 @@
                    var flag = false;
                    var flag1 = false;
                    var flag2 = false;
                    foreach (var item in rowdwa)
                    {
@@ -629,65 +1309,133 @@
                        }
                    }
                    if (flag1 || flag)
                    foreach (var item2 in balanceConnectionList)
                    {
                        locations.RemoveAll(a => a.N_ROW == rowsStart[i]);
                    }
                    //rowList.Count(a => a.S_LOCK_STATE.Trim() != "无") > 0 ||
                    //当前排有锁并且没有满货位,排除
                    if ( rowList.Count(a => a.N_CURRENT_NUM == 1) == 0)
                    {
                        locations.RemoveAll(a => a.N_ROW == rowsStart[i]);
                    }
                }
                DateTime date = DateTime.Now;
                List<CntrItemRel> startList = new List<CntrItemRel>(); ;
                LogHelper.Info($"ZCSendTask出库任务排除不可用巷道完成", "Mes任务下发");
                foreach (var item in locations) {
                    if (item.N_CURRENT_NUM==0)
                    {
                        continue;
                    }
                    var tp = db.Queryable<LocCntrRel>().Where(s => s.S_LOC_CODE == item.S_CODE).First();
                    LogHelper.Info($"ZCSendTask出库任务下发起点货位容器信息" + JsonConvert.SerializeObject(tp), "Mes任务下发");
                    if (tp != null && item.S_LOCK_STATE == "无")
                    {
                        var tp1 = db.Queryable<CntrItemRel>().Where(s => s.S_CNTR_CODE == tp.S_CNTR_CODE).First();
                        LogHelper.Info($"ZCSendTask出库任务下发起点容器物料信息" + JsonConvert.SerializeObject(tp1), "Mes任务下发");
                        if (tp1 != null && tp1.S_ITEM_CODE== itemCode&& tp1.S_ITEM_STATE == "合格" && tp1.takeEffectTime < date && tp1.expireTime > date)
                        if (rowList.Count(a => a.N_ROADWAY == item2.CONNEC_ROADWAY) > 0)
                        {
                            LogHelper.Info($"ZCSendTask出库任务下发起点合格容器物料,容器号{tp1.S_CNTR_CODE}", "Mes任务下发");
                            startList.Add(tp1);
                            flag2 = true;
                            break;
                        }
                    }
                }
                LogHelper.Info($"ZCSendTask出库任务下发起点合格物料数量{startList.Count}", "Mes任务下发");
                var startItem = startList.OrderBy(a => a.PRODUCTIONDATE).FirstOrDefault();
                        if (flag1 || flag || flag2)
                        {
                            locations.RemoveAll(a => a.N_ROW == rowsStart[i]);
                        }
                LogHelper.Info($"ZCSendTask出库任务下发起点按生产时间排序物料信息" + JsonConvert.SerializeObject(startItem), "Mes任务下发");
                if (startItem!=null)
                {
                    var tp = db.Queryable<LocCntrRel>().Where(s => s.S_CNTR_CODE == startItem.S_CNTR_CODE).First();
                    start = LocationHelper.GetLocOne(tp.S_LOC_CODE);
                    LogHelper.Info($"ZCSendTask出库任务下发起点货位信息" + JsonConvert.SerializeObject(start), "Mes任务下发");
                }
                return start;
                        //rowList.Count(a => a.S_LOCK_STATE.Trim() != "无") > 0 ||
                        //当前排有锁并且没有满货位,排除
                        if (rowList.Count(a => a.N_CURRENT_NUM == 1) == 0)
                        {
                            locations.RemoveAll(a => a.N_ROW == rowsStart[i]);
                        }
                    }
                    DateTime date = DateTime.Now;
                    List<CntrItemRel> startList = new List<CntrItemRel>(); ;
                    LogHelper.Info($"ZCSendTask出库任务排除不可用巷道完成", "Mes任务下发");
                LogHelper.Info($"ZCSendTask出库任务排除完成货位数量{locations.Count}", "Mes任务下发");
                foreach (var item in locations)
                    {
                        if (item.N_CURRENT_NUM == 0)
                        {
                            continue;
                        }
                        var tp = db.Queryable<LocCntrRel>().Where(s => s.S_LOC_CODE == item.S_CODE).First();
                        LogHelper.Info($"ZCSendTask出库任务下发起点货位容器信息" + JsonConvert.SerializeObject(tp), "Mes任务下发");
                        if (tp != null && item.S_LOCK_STATE == "无")
                        {
                            var tp1 = db.Queryable<CntrItemRel>().Where(s => s.S_CNTR_CODE == tp.S_CNTR_CODE).First();
                            LogHelper.Info($"ZCSendTask出库任务下发起点容器物料信息" + JsonConvert.SerializeObject(tp1), "Mes任务下发");
                            if (tp1 != null && tp1.S_ITEM_CODE == itemCode && tp1.S_ITEM_STATE == "合格" && tp1.takeEffectTime < date && tp1.expireTime > date)
                            {
                                LogHelper.Info($"ZCSendTask出库任务下发起点合格容器物料,容器号{tp1.S_CNTR_CODE}", "Mes任务下发");
                                startList.Add(tp1);
                            }
                        }
                    }
                //var queryable = db.Queryable<Location>().LeftJoin<LocCntrRel>((a, b) => a.S_CODE == b.S_LOC_CODE)
                //    .LeftJoin<CntrItemRel>((a, b, c) => b.S_CNTR_CODE == c.S_CNTR_CODE)
                //    .Where((a, b, c) => a.N_CURRENT_NUM > 0 && a.N_LOCK_STATE == 0 && a.S_AREA_CODE == endArea);
                    LogHelper.Info($"ZCSendTask出库任务下发起点合格物料数量{startList.Count}", "Mes任务下发");
                    var startItem = startList.OrderBy(a => a.PRODUCTIONDATE).FirstOrDefault();
                    LogHelper.Info($"ZCSendTask出库任务下发起点按生产时间排序物料信息" + JsonConvert.SerializeObject(startItem), "Mes任务下发");
                    if (startItem != null)
                    {
                        var tp = db.Queryable<LocCntrRel>().Where(s => s.S_CNTR_CODE == startItem.S_CNTR_CODE).First();
                        start = LocationHelper.GetLocOne(tp.S_LOC_CODE);
                        LogHelper.Info($"ZCSendTask出库任务下发起点货位信息" + JsonConvert.SerializeObject(start), "Mes任务下发");
                    }
                    return start;
            }
            catch (Exception)
            {
                throw;
            }
        }
        /// <summary>
        /// 根据物料编码找立库区起点满货位 校验有库存但是设备报警
        /// </summary>
        /// <param name="locations"></param>
        /// <returns></returns>
        internal static bool FindStartcolByLoclistAndItemFlag(List<Location> locations, string itemCode, string endArea)
        {
            var db = new SqlHelper<object>().GetInstance();
            var res = false;
            try
            {
                var rowsStart = locations.Select(a => a.N_ROW).Distinct().ToList();
                DateTime date = DateTime.Now;
                List<CntrItemRel> startList = new List<CntrItemRel>(); ;
                foreach (var item in locations)
                {
                    if (item.N_CURRENT_NUM == 0)
                    {
                        continue;
                    }
                    var tp = db.Queryable<LocCntrRel>().Where(s => s.S_LOC_CODE == item.S_CODE).First();
                   // LogHelper.Info($"ZCSendTask出库任务下发起点货位容器信息" + JsonConvert.SerializeObject(tp), "Mes任务下发");
                    if (tp != null && item.S_LOCK_STATE == "无")
                    {
                        var tp1 = db.Queryable<CntrItemRel>().Where(s => s.S_CNTR_CODE == tp.S_CNTR_CODE).First();
                        //LogHelper.Info($"ZCSendTask出库任务下发起点容器物料信息" + JsonConvert.SerializeObject(tp1), "Mes任务下发");
                        if (tp1 != null && tp1.S_ITEM_CODE == itemCode && tp1.S_ITEM_STATE == "合格" && tp1.takeEffectTime < date && tp1.expireTime > date)
                        {
                            res = true;
                            return res;
                        }
                    }
                }
                return res;
            }
            catch (Exception)
            {
                throw;
            }
        }
        /// <summary>
        /// 根据物料编码找货架区起点满货位
@@ -708,9 +1456,6 @@
                for (int i = 0; i < rowsStart.Count; i++)
                {
                    var rowList = locations.Where(r => r.N_ROW == rowsStart[i]).ToList().OrderByDescending(a => a.N_COL);
                    //rowList.Count(a => a.S_LOCK_STATE.Trim() != "无") > 0 ||
                    //当前排有锁并且没有满货位,排除
@@ -1031,6 +1776,25 @@
        }
        /// <summary>
        /// 获取异常库区
        /// </summary>
        /// <returns></returns>
        internal static bool GetErroArea(string area)
        {
            var db = new SqlHelper<object>().GetInstance();
            var erroArea = db.Queryable<Area>().Where(a => a.S_NAME.Contains("异常") && a.S_CODE.Contains(area)).First();
            if (erroArea == null)
            {
                return false;
            }
            else {
                return true;
            }
        }
        /// <summary>
        /// 入库锁定终点,出库锁定起点
        /// </summary>
        /// <param name="loc"></param>
@@ -1290,5 +2054,34 @@
            }
            return res;
        }
        /// <summary>
        /// 获取逻辑库区货位
        /// </summary>
        /// <param name="zoneCode"></param>
        /// <returns></returns>
        public static List<Location> GetZoneLoc(string zoneCode) {
            var db = new SqlHelper<object>().GetInstance();
            LogHelper.Info($"ZCSendTask入库任务寻找逻辑库区参数{zoneCode}", "Mes任务下发");
            var zones = db.Queryable<Zone>().Where(a => a.S_ZONE_CLS_CODE == zoneCode).ToList();
            LogHelper.Info($"ZCSendTask入库任务寻找逻辑库区信息" +JsonConvert.SerializeObject(zones), "Mes任务下发");
            var locList = new List<Location>();
            foreach (var item in zones)
            {
                var locations = db.Queryable<ZoneLoc>().Includes(t => t.Loc).Where(a => a.S_ZONE_CODE == item.S_CODE).ToList();
                foreach (var item1 in locations)
                {
                    locList.Add(item1.Loc);
                }
            }
            LogHelper.Info($"ZCSendTask入库任务寻找逻辑货位数量信息{locList.Count}", "Mes任务下发");
            return locList.OrderBy(a => a.N_ROW).OrderBy(a => a.N_COL).ToList(); ;
        }
    }
}