111
cjs
3 天以前 7fda4aeb36beda46d767a78082573692e7b85651
HH.WCS.Mobox3.NongFuLinZhi/process/TaskProcess.cs
@@ -11,6 +11,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Threading.Tasks;
using System.Xml.Linq;
using static HH.WCS.Mobox3.NFLZ.api.OtherModel;
using static HH.WCS.Mobox3.NFLZ.dispatch.NDCApi;
@@ -65,7 +66,7 @@
                //起点终点解锁
                LocationHelper.UnLockLoc(mst.S_START_LOC);
                LocationHelper.UnLockLoc(mst.S_END_LOC);
            }
        }
@@ -677,14 +678,14 @@
        /// <exception cref="NotImplementedException"></exception>
        public static void EmptyTask(WCSTask mst)
        {
            //瓶盖注塑机空托上线,若急产急用库区没有多余的空托,则在非急产急用空托区拿空托
            //瓶盖注塑机空托上线,若即产急用库区没有多余的空托,则在非即产急用空托区拿空托
            var db = new SqlHelper<object>().GetInstance();
            Location startLoca = null;
            if (mst.S_TYPE.Contains("满托下线"))
            {
                LogHelper.Info($"空托任务生成处理,任务类型:{mst.S_TYPE}");
                string areaName = mst.S_TYPE.Contains("库存") ? "瓶胚非即产空框" : "瓶胚即产空框";
                string areaName = mst.S_TYPE.Contains("库存") ? "瓶坯非即产空框" : "瓶坯即产空框";
                var areaInfo = Settings.areaInfos.Where(a => a.areaName == areaName && a.enable == 1).First();
                if(areaInfo != null)
                {
@@ -729,14 +730,14 @@
                {
                    if (bcpW.S_UsingNow == "Y")
                    {
                        LogHelper.Info($"瓶胚即产满框 查找");
                        startArea = Settings.areaInfos.Where(a => a.areaName == "瓶胚即产满框" && a.enable == 1).FirstOrDefault().areaCode;
                        LogHelper.Info($"瓶坯即产满框 查找");
                        startArea = Settings.areaInfos.Where(a => a.areaName == "瓶坯即产满框" && a.enable == 1).FirstOrDefault().areaCode;
                        startLoca = DeviceProcess.getFDSXArea(db, bcpW, startArea);
                    }
                    else
                    {
                        LogHelper.Info($"瓶胚翻斗机非即产满框 查找");
                        string areaName = bcpW.S_PLineNo.Split('-')[1].Substring(0, 1) + "号瓶胚翻斗机非即产满框";
                        LogHelper.Info($"瓶坯翻斗机非即产满框 查找");
                        string areaName = bcpW.S_PLineNo.Split('-')[1].Substring(0, 1) + "号瓶坯翻斗机非即产满框";
                        startArea = Settings.areaInfos.Where(a => a.areaName == areaName && a.enable == 1).FirstOrDefault().areaCode;
                        startLoca = DeviceProcess.getFDSXArea(db, bcpW, startArea);
                    }
@@ -1105,12 +1106,29 @@
                        Extend2 = db.Queryable<Location>().Where(a => a.S_CODE == mst.S_END_LOC).First().S_AGV_SITE;
                        if (mst.N_START_LAYER > 1)
                        {
                            Extend1 = db.Queryable<LocationExt>().Where(a => a.S_LOC_CODE == mst.S_START_LOC && a.N_LAYER == mst.N_START_LAYER).First().S_AGV_SITE;
                            if(mst.S_TYPE != "瓶坯非即产空框入库" && mst.S_TYPE != "瓶坯接驳位入库" && mst.S_TYPE != "瓶盖空托入库")
                            {
                                Extend1 = db.Queryable<LocationExt>().Where(a => a.S_LOC_CODE == mst.S_START_LOC && a.N_LAYER == mst.N_START_LAYER).First().S_AGV_SITE;
                            }
                        }
                        if (mst.N_END_LAYER > 1)
                        {
                            Extend2 = db.Queryable<LocationExt>().Where(a => a.S_LOC_CODE == mst.S_START_LOC && a.N_LAYER == mst.N_END_LAYER).First().S_AGV_SITE;
                            Extend2 = db.Queryable<LocationExt>().Where(a => a.S_LOC_CODE == mst.S_END_LOC && a.N_LAYER == mst.N_END_LAYER).First().S_AGV_SITE;
                        }
                        if(mst.S_TYPE == "瓶坯非即产补满框" || mst.S_TYPE == "瓶盖非即产补满框大包装" || mst.S_TYPE == "瓶坯非即产补空框" || mst.S_TYPE == "瓶盖非即产补空框" || mst.S_TYPE == "注塑即产满托下线(瓶坯)")
                        {
                            Extend2 = Settings.dXSites.Where(it => it.loc == mst.S_END_LOC).First().site.ToString();
                        }
                        if(mst.S_TYPE == "接驳位入库")
                        {
                            if(mst.S_CNTR_CODE.Split(',').ToList().Count != 2)
                            {
                                Extend1 = db.Queryable<LocationExt>().Where(a => a.S_LOC_CODE == mst.S_START_LOC && a.N_LAYER == 1).First().S_AGV_SITE;
                            }
                        }
                        Extend3 = "0";
                        // 获取 任务参数4 DATA 数据
                        string startLayerValue = Convert.ToString(startLayer, 16).ToUpper();
@@ -1120,28 +1138,28 @@
                        //Extend4 = db.Queryable<LinjiangBCPWorkOrder>().Where(a => a.S_WorkNo == workNo).First().S_UsingNow == "N" ? "2" : "1";
                        //瓶坯注塑机站点根据配置文件获取
                        if (taskType.Contains("注塑") && taskType.Contains("瓶坯"))
                        {
                            var devInfo = Settings.deviceInfos.Where(a => (a.TN_Location.Contains(mst.S_START_LOC) || a.TN_Location.Contains(mst.S_END_LOC)) && a.enable == 1).FirstOrDefault();
                            string machine = (devInfo.TN_Location[0] == mst.S_START_LOC || devInfo.TN_Location[0] == mst.S_END_LOC) ? "A" : "B";
                            string machineTwo = devInfo.deviceName.Split('-')[1] + machine;
                            LogHelper.Info($"机台:{machineTwo}");
                            var siteInfo = Settings.pPZSJSites.Where(a => a.siteName == machineTwo && a.enable == 1).FirstOrDefault();
                            if (siteInfo != null)
                            {
                                if (taskType.Contains("空托上线"))
                                {
                                    //改变终点站点
                                    Extend2 = siteInfo.site[1];
                                }
                                else
                                {
                                    //改变起点站点
                                    Extend1 = siteInfo.site[0];
                                }
                            }
                            else LogHelper.Info("配置文件未配置瓶坯注塑机站点");
                        }
                        //if (taskType.Contains("注塑") && taskType.Contains("瓶坯"))
                        //{
                        //    var devInfo = Settings.deviceInfos.Where(a => (a.TN_Location.Contains(mst.S_START_LOC) || a.TN_Location.Contains(mst.S_END_LOC)) && a.enable == 1).FirstOrDefault();
                        //    string machine = (devInfo.TN_Location[0] == mst.S_START_LOC || devInfo.TN_Location[0] == mst.S_END_LOC) ? "A" : "B";
                        //    string machineTwo = devInfo.deviceName.Split('-')[1] + machine;
                        //    LogHelper.Info($"机台:{machineTwo}");
                        //    var siteInfo = Settings.pPZSJSites.Where(a => a.siteName == machineTwo && a.enable == 1).FirstOrDefault();
                        //    if (siteInfo != null)
                        //    {
                        //        if (taskType.Contains("空托上线"))
                        //        {
                        //            //改变终点站点
                        //            Extend2 = siteInfo.site[1];
                        //        }
                        //        else
                        //        {
                        //            //改变起点站点
                        //            Extend1 = siteInfo.site[0];
                        //        }
                        //    }
                        //    else LogHelper.Info("配置文件未配置瓶坯注塑机站点");
                        //}
                    }
                    Console.WriteLine($"[SendTask]:TaskNo={mst.S_CODE.Trim()},start={Extend1},end={Extend2}");
@@ -1285,127 +1303,141 @@
            if (action)
            {
                //瓶盖库区,两层密集型库区  空满在同一个库区,需要区分不同排
                var areaInfo = Settings.areaInfos.Where(a => a.areaName == areaName && a.enable == 1).First();
                if (areaInfo != null)
                var areaInfo = Settings.areaInfos.Where(a => a.areaName.Contains(areaName) && a.enable == 1).OrderByDescending(a => a.pri).ToList();
                if (areaInfo.Count > 0)
                {
                    //库区货位约定:列号越小越靠里
                    LogHelper.Info($"入库算法01:area:{areaInfo.areaCode},itemCode:{itemCode}");
                    try
                    foreach(var it in areaInfo)
                    {
                        if (result == null)
                        //库区货位约定:列号越小越靠里
                        LogHelper.Info($"入库算法01:area:{it.areaCode},itemCode:{itemCode}");
                        try
                        {
                            var locInfo = db.Queryable<Location>().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)
                            if (result == null)
                            {
                                LogHelper.Info($"入库算法02:查询到可入货位的数量为:{locInfo.Count}");
                                foreach (var a in locInfo)
                                var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == it.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)
                                {
                                    LogHelper.Info($"入库算法03:查询货位:{a.S_CODE},锁状态:{a.S_LOCK_STATE},当前数量:{a.N_CURRENT_NUM}");
                                    //去掉当前货位有锁,或者为空托的货位
                                    if (a.S_LOCK_STATE == "无")
                                    if(areaName == "瓶坯即产满框缓存")
                                    {
                                        string endItemCode = "";
                                        var endCntrInfo = db.Queryable<LocCntrRel>().Where(b => b.S_LOC_CODE == a.S_CODE).First();
                                        if (endCntrInfo != null)
                                        locInfo = locInfo.Where(a => a.N_ROW == 1 || a.N_ROW == 2).ToList();
                                    }
                                    LogHelper.Info($"入库算法02:查询到可入货位的数量为:{locInfo.Count}");
                                    foreach (var a in locInfo)
                                    {
                                        LogHelper.Info($"入库算法03:查询货位:{a.S_CODE},锁状态:{a.S_LOCK_STATE},当前数量:{a.N_CURRENT_NUM}");
                                        //去掉当前货位有锁,或者为空托的货位
                                        if (a.S_LOCK_STATE == "无")
                                        {
                                            var endItemInfo = db.Queryable<CntrItemRel>().Where(b => b.S_CNTR_CODE == endCntrInfo.S_CNTR_CODE).First();
                                            if (endItemInfo != null)
                                            string endItemCode = "";
                                            var endCntrInfo = db.Queryable<LocCntrRel>().Where(b => b.S_LOC_CODE == a.S_CODE).First();
                                            if (endCntrInfo != null)
                                            {
                                                endItemCode = endItemInfo.S_ITEM_CODE;
                                            }
                                        }
                                        else
                                        {
                                            LogHelper.Info($"终点货位未绑定托盘信息");
                                            continue;
                                        }
                                        LogHelper.Info($"入库算法04:查询到当前货位绑定的物料编码为:{endItemCode}");
                                        //判断是否和当前货位的物料编码相同
                                        if (itemCode == endItemCode)
                                        {
                                            //查询当前排是否可入(判断是是否有入库锁和出库锁)
                                            var lockInfo = db.Queryable<Location>().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
                                                var endItemInfo = db.Queryable<CntrItemRel>().Where(b => b.S_CNTR_CODE == endCntrInfo.S_CNTR_CODE).First();
                                                if (endItemInfo != null)
                                                {
                                                    //查询后面当前货位后一个
                                                    result = db.Queryable<Location>().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;
                                                    endItemCode = endItemInfo.S_ITEM_CODE + endItemInfo.S_BATCH_NO;
                                                }
                                            }
                                            else
                                            {
                                                LogHelper.Info($"入库算法05:查询到当前排有锁,排号:{a.N_ROW}");
                                                LogHelper.Info($"终点货位未绑定托盘信息");
                                                continue;
                                            }
                                        }
                                    }
                                }
                            }
                            else
                            {
                                LogHelper.Info($"入库算法02:未查询到可入货位");
                            }
                            if (result == null)
                            {
                                //todo 还需要判断锁
                                #region 查找所有数量是空的排
                                LogHelper.Info($"入库算法06:无可用货位,获取空排货位。", "WMSAlgoRithm");
                                //2.0 简化查询只查每一排第一列
                                var list = db.Queryable<Location>().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<Location>().Where(b => b.S_AREA_CODE == areaCode && b.N_ROW == row && (b.S_LOCK_STATE == "入库锁" || b.S_LOCK_STATE == "出库锁")).First();
                                            if (lockInfo == null)
                                            LogHelper.Info($"入库算法04:查询到当前货位绑定的物料编码为:{endItemCode}");
                                            //判断是否和当前货位的物料编码相同
                                            if (itemCode == endItemCode)
                                            {
                                                var locInfo1 = db.Queryable<Location>().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)
                                                //查询当前排是否可入(判断是是否有入库锁和出库锁)
                                                var lockInfo = db.Queryable<Location>().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)
                                                {
                                                    LogHelper.Info($"{locInfo1.sum},row:{row}");
                                                    if (locInfo1.sum == 0)
                                                    //当前排无任务
                                                    if (a.N_CURRENT_NUM < a.N_CAPACITY) result = a;
                                                    else
                                                    {
                                                        //空排
                                                        result = list[i];
                                                        //查询后面当前货位后一个
                                                        result = db.Queryable<Location>().Where(b => b.S_AREA_CODE == a.S_AREA_CODE && b.N_ROW == a.N_ROW && b.N_COL > a.N_COL && a.N_CURRENT_NUM < a.N_CAPACITY && b.S_LOCK_STATE == "无").OrderBy(b => b.N_COL).First();
                                                    }
                                                    if (result != null)
                                                    {
                                                        break;
                                                    }
                                                }
                                                else LogHelper.Info("未找到该排");
                                            }
                                            else
                                            {
                                                LogHelper.Info("该排有锁");
                                                else
                                                {
                                                    LogHelper.Info($"入库算法05:查询到当前排有锁,排号:{a.N_ROW}");
                                                }
                                            }
                                        }
                                    }
                                }
                                else LogHelper.Info($"未获取到空排,库区编码:{areaInfo.areaCode}");
                                #endregion
                                else
                                {
                                    LogHelper.Info($"入库算法02:未查询到可入货位");
                                }
                                if (result == null)
                                {
                                    //todo 还需要判断锁
                                    #region 查找所有数量是空的排
                                    LogHelper.Info($"入库算法06:无可用货位,获取空排货位。", "WMSAlgoRithm");
                                    //2.0 简化查询只查每一排第一列
                                    var list = db.Queryable<Location>().Where(a => a.S_AREA_CODE == it.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<Location>().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<Location>().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($"未获取到空排,库区编码:{it.areaCode}");
                                    #endregion
                                }
                                if(result != null)
                                {
                                    break;
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("GetLocationIn:" + ex.Message + ex.StackTrace);
                            LogHelper.Error("GetLocationIn:" + ex.Message, ex);
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("GetLocationIn:" + ex.Message + ex.StackTrace);
                        LogHelper.Error("GetLocationIn:" + ex.Message, ex);
                    }
                }
                else
                {
@@ -1414,47 +1446,59 @@
            }
            else
            {
                LogHelper.Info($"出库算法01:area:{areaName},itemCode:{itemCode}");
                var areaInfo = Settings.areaInfos.Where(a => a.areaName == areaName && a.enable == 1).FirstOrDefault();
                if(areaInfo != null)
                var areaInfo = Settings.areaInfos.Where(a => a.areaName.Contains(areaName) && a.enable == 1).OrderByDescending(a => a.pri).ToList();
                if(areaInfo.Count > 0)
                {
                    var locList = db.Queryable<Location>().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 it in areaInfo)
                    {
                        LogHelper.Info($"出库算法02:查询到可出货位数量:{locList.Count}");
                        foreach (var a in locList)
                        LogHelper.Info($"出库算法01:area:{it.areaName},itemCode:{itemCode}");
                        var locList = db.Queryable<Location>().Where(a => a.S_AREA_CODE == it.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)
                        {
                            LogHelper.Info($"出库算法03:查询货位:{a.S_CODE},锁状态:{a.S_LOCK_STATE}");
                            if (a.S_LOCK_STATE == "无")
                            if(areaName == "瓶坯即产满框缓存" && string.IsNullOrEmpty(itemCode))
                            {
                                var cntrInfo = db.Queryable<LocCntrRel>().Where(b => b.S_LOC_CODE == a.S_CODE).First();
                                if(cntrInfo != null)
                                locList = locList.Where(a => a.N_ROW == 3).ToList();
                            }
                            LogHelper.Info($"出库算法02:查询到可出货位数量:{locList.Count}");
                            foreach (var a in locList)
                            {
                                LogHelper.Info($"出库算法03:查询货位:{a.S_CODE},锁状态:{a.S_LOCK_STATE}");
                                if (a.S_LOCK_STATE == "无")
                                {
                                    LogHelper.Info($"出库算法04:当前货位绑定的托盘码为:{cntrInfo.S_CNTR_CODE}");
                                    string endItemCode = "";
                                    var itemInfo = db.Queryable<CntrItemRel>().Where(b => b.S_CNTR_CODE == cntrInfo.S_CNTR_CODE).First();
                                    if(itemInfo != null && itemInfo.S_ITEM_CODE == itemCode)
                                    var cntrInfo = db.Queryable<LocCntrRel>().Where(b => b.S_LOC_CODE == a.S_CODE).First();
                                    if (cntrInfo != null)
                                    {
                                        endItemCode = itemInfo.S_ITEM_CODE;
                                    }
                                    if(endItemCode == itemCode)
                                    {
                                        //判断当前排有无锁
                                        var lockInfo = db.Queryable<Location>().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)
                                        LogHelper.Info($"出库算法04:当前货位绑定的托盘码为:{cntrInfo.S_CNTR_CODE}");
                                        string endItemCode = "";
                                        var itemInfo = db.Queryable<CntrItemRel>().Where(b => b.S_CNTR_CODE == cntrInfo.S_CNTR_CODE).First();
                                        if (itemInfo != null && itemInfo.S_ITEM_CODE == itemCode)
                                        {
                                            result = a;
                                            break;
                                            endItemCode = itemInfo.S_ITEM_CODE;
                                        }
                                        else
                                        if (endItemCode == itemCode)
                                        {
                                            LogHelper.Info($"出库算法05:当前排有锁,货位号:{lockInfo.S_CODE}");
                                            //判断当前排有无锁
                                            var lockInfo = db.Queryable<Location>().Where(b => b.S_AREA_CODE == it.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($"出库算法05:当前排有锁,货位号:{lockInfo.S_CODE}");
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        if(result != null)
                        {
                            break;
                        }
                    }
                }
                else
                {
@@ -1470,7 +1514,7 @@
            if(usingNow == "Y")
            {
                //即产即用
                var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶胚即产空框" && a.enable == 1).FirstOrDefault();
                var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯即产空框" && a.enable == 1).FirstOrDefault();
                if (areaInfo != null)
                {
                    var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM > 0 && a.S_LOCK_STATE == "无").Includes(a => a.LocCntrRel).First();
@@ -1481,13 +1525,13 @@
                }
                else
                {
                    LogHelper.Info("瓶胚即产空框未配置");
                    LogHelper.Info("瓶坯即产空框未配置");
                }
            }
            else
            {
                //非即产即用
                var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶胚非即产空框" && a.enable == 1).FirstOrDefault();
                var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯非即产空框" && a.enable == 1).FirstOrDefault();
                if (areaInfo != null)
                {
                    var locList = db.Queryable<Location>().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();
@@ -1507,7 +1551,7 @@
                }
                else
                {
                    LogHelper.Info("瓶胚非即产空框未配置");
                    LogHelper.Info("瓶坯非即产空框未配置");
                }
            }
            
@@ -1528,8 +1572,8 @@
            LogHelper.Info($"瓶坯注塑满托下线:类型:{taskName},物料编码:{itemCode}");
            if (taskName.Contains("即产"))
            {
                //注塑机急产即用下线,首先下线到即产即用满框线边,满眶线边满了,下到即产即用满框缓存区,满框缓存区满了,下到入库接驳堆叠位
                var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶胚即产满框" && a.enable == 1).FirstOrDefault();
                //注塑机即产即用下线,首先下线到即产即用满框线边,满眶线边满了,下到即产即用满框缓存区,满框缓存区满了,下到入库接驳堆叠位
                var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯即产满框" && a.enable == 1).FirstOrDefault();
                if(areaInfo != null)
                {
                    var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM < a.N_CAPACITY && a.S_LOCK_STATE == "无").OrderBy(a => a.N_ROW).First();
@@ -1540,11 +1584,11 @@
                }
                else
                {
                    LogHelper.Info($"瓶坯注塑满托下线:瓶胚即产满框 未配置");
                    LogHelper.Info($"瓶坯注塑满托下线:瓶坯即产满框 未配置");
                }
                if (result == null)
                {
                    result = TaskProcess.BCPInOrOut(db, true, "瓶胚即产满框缓存", itemCode);
                    result = TaskProcess.BCPInOrOut(db, true, "瓶坯即产满框缓存", itemCode);
                }
                if(result == null)
                {
@@ -1561,7 +1605,7 @@
        private static Location getJBLoc(SqlSugarClient db, Location result)
        {
            //注塑机非即产即用下线,下到入库接驳堆叠位
            var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶胚入库接驳" && a.enable == 1).FirstOrDefault();
            var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯入库接驳" && a.enable == 1).FirstOrDefault();
            if (areaInfo != null)
            {
                var locInfo = db.Queryable<Location>().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();
@@ -1576,7 +1620,7 @@
            }
            else
            {
                LogHelper.Info($"瓶坯注塑满托下线:瓶胚入库接驳 未配置");
                LogHelper.Info($"瓶坯注塑满托下线:瓶坯入库接驳 未配置");
            }
            return result;
@@ -1593,7 +1637,7 @@
        {
            Location result = null;
            string endAreaName = taskName.Contains("瓶盖") ? "瓶盖非即产空框" : taskName.Contains("库存") ? "瓶胚非即产空框" : "瓶胚即产空框";
            string endAreaName = taskName.Contains("瓶盖") ? "瓶盖非即产空框" : taskName.Contains("库存") ? "瓶坯非即产空框" : "瓶坯即产空框";
            var areaInfo = Settings.areaInfos.Where(a => a.areaName == endAreaName && a.enable == 1).FirstOrDefault();
            if (areaInfo != null)
            {
@@ -1607,7 +1651,60 @@
            {
                LogHelper.Info($"{endAreaName}未配置");
            }
            if(result == null)
            {
                if(endAreaName == "翻斗机库存空托下线(瓶坯)")
                {
                    //瓶坯非即产空托下线 如果非即产空框库区无法入库,则下线到瓶坯即产满框缓存 4 5 排
                    areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯即产满框缓存" && a.enable == 1).FirstOrDefault();
                    if (areaInfo != null)
                    {
                        var locList = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && (a.N_ROW == 4 || a.N_ROW == 5) && a.N_CURRENT_NUM == 0).OrderBy(a => a.N_ROW).OrderBy(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList();
                        if (locList.Count > 0)
                        {
                            foreach (var a in locList)
                            {
                                var rowInfo = db.Queryable<RowLock>().Where(b => b.S_AREA_CODE == a.S_AREA_CODE && b.S_ROW == a.S_ROW && a.S_LOCK_STATE == "无").First();
                                if (rowInfo != null && a.S_LOCK_STATE == "无")
                                {
                                    result = a;
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        LogHelper.Info("瓶坯即产满框缓存未配置");
                    }
                }
                if(endAreaName == "翻斗机即产空托下线(瓶坯)")
                {
                    //瓶坯即产空托下线 如果即产空框库区无法入库,则下线到瓶坯即产满框缓存 3 排
                    areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯即产满框缓存" && a.enable == 1).FirstOrDefault();
                    if (areaInfo != null)
                    {
                        var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_ROW == 3 && a.N_CURRENT_NUM == 0).OrderBy(a => a.N_COL).First();
                        if (locInfo != null )
                        {
                            var rowInfo = db.Queryable<RowLock>().Where(b => b.S_AREA_CODE == locInfo.S_AREA_CODE && b.S_ROW == locInfo.S_ROW && locInfo.S_LOCK_STATE == "无").First();
                            if (rowInfo != null && locInfo.S_LOCK_STATE == "无")
                            {
                                result = locInfo;
                            }
                        }
                    }
                    else
                    {
                        LogHelper.Info("瓶坯即产满框缓存未配置");
                    }
                    if(result == null)
                    {
                        BCPEmptyOut(db, "翻斗机库存空托下线(瓶坯)");
                    }
                }
            }
            return result;
        }
@@ -1827,7 +1924,7 @@
        /// </summary>
        /// <param name="cntr"></param>
        /// <returns></returns>
        internal static bool BindLocCntr(string loc, string cntr, string itemCode, string batchNo, string deviceName = "", string itemlayer = "")
        internal static bool BindLocCntr(string loc, string cntr, string itemCode, string batchNo, string deviceName = "", string itemlayer = "",string itemName = "")
        {
            LogHelper.Info($"绑定货位容器表,loc:{loc},cntr:{cntr}");
            bool result = true;
@@ -1843,7 +1940,28 @@
                    {
                        var cir = new LocCntrRel { S_LOC_CODE = loc, S_CNTR_CODE = cntrCode, S_SRC = deviceName };
                        if (db.Insertable<LocCntrRel>(cir).ExecuteCommand() > 0) LogHelper.Info($"货位容器表绑定成功,货位号:{loc},托盘号:{cntrCode}");
                        BindCntrItem(cntrCode, itemCode, batchNo, itemlayer);
                        var Con = db.Queryable<Container>().Where(a => a.S_CODE == cntrCode).First();
                        if(Con == null)
                        {
                            int detallCount = 0;
                            if (!string.IsNullOrEmpty(itemCode))
                            {
                                detallCount = 1;
                            }
                            if(db.Insertable<Container>(new Container
                            {
                                S_CODE = cntrCode,
                                N_TYPE = 1,
                                N_DETAIL_COUNT = detallCount
                            }).ExecuteCommand() > 0)
                            {
                                LogHelper.Info($"容器表绑定成功,托盘号:{cntrCode}");
                            }
                        }
                        if (!string.IsNullOrEmpty(itemCode))
                        {
                            BindCntrItem(cntrCode, itemCode, batchNo, itemlayer, itemName);
                        }
                    }
                }
            });
@@ -1858,7 +1976,7 @@
        /// <param name="batchNo"></param>
        /// <param name="qty"></param>
        /// <returns></returns>
        internal static bool BindCntrItem(string trayCode, string itemCode, string batchNo, string itemlayer = "")
        internal static bool BindCntrItem(string trayCode, string itemCode, string batchNo, string itemlayer = "",string itemName = "")
        {
            LogHelper.Info($"绑定容器物料表,trayCode:{trayCode}");
            var res = false;
@@ -1873,8 +1991,8 @@
                var info = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE.Trim() == trayCode.Trim()).First();
                if (info == null)
                {
                    var cir = new CntrItemRel { S_CNTR_CODE = trayCode, S_BATCH_NO = batchNo, S_ITEM_CODE = itemCode, S_ITEM_MODEL = itemlayer };
                    if (db.Insertable<CntrItemRel>(cir).ExecuteCommand() > 0) LogHelper.Info($"容器物料表绑定成功,托盘号:{trayCode},物料编码:{itemCode},物料层数:{itemlayer}");
                    var cir = new CntrItemRel { S_CNTR_CODE = trayCode, S_BATCH_NO = batchNo, S_ITEM_CODE = itemCode, S_ITEM_MODEL = itemlayer,S_ITEM_NAME = itemName };
                    if (db.Insertable<CntrItemRel>(cir).ExecuteCommand() > 0) LogHelper.Info($"容器物料表绑定成功,托盘号:{trayCode},物料编码:{itemCode},物料层数:{itemlayer},物料名称:{itemName}");
                }
@@ -2356,6 +2474,95 @@
            }
        }
        /// <summary>
        /// 计算瓶坯非即产空托起点
        /// </summary>
        /// <returns></returns>
        internal static Location FJCKTLoc()
        {
            var db = new SqlHelper<object>().GetInstance();
            Location result = null;
            //在瓶坯即产满框 查询 4 5两排的空框
            var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯即产满框缓存" && a.enable == 1).FirstOrDefault();
            if(areaInfo != null)
            {
                var locList = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && (a.N_ROW == 4 || a.N_ROW == 5) && a.N_CURRENT_NUM > 0).OrderBy(a => a.N_ROW).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList();
                if(locList.Count > 0)
                {
                    foreach (var a in locList)
                    {
                        var cntrInfo = db.Queryable<LocCntrRel>().Where(b => b.S_LOC_CODE == a.S_CODE).First();
                        if(cntrInfo != null)
                        {
                            var itemInfo = db.Queryable<CntrItemRel>().Where(b => b.S_CNTR_CODE == cntrInfo.S_CNTR_CODE).First();
                            if(itemInfo == null)
                            {
                                var rowInfo = db.Queryable<RowLock>().Where(b => b.S_AREA_CODE == a.S_AREA_CODE && b.S_ROW == a.S_ROW && b.S_LOCK_STATE == "无").First();
                                if (rowInfo != null && a.S_LOCK_STATE == "无")
                                {
                                    result = a;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            if(result == null)
            {
                result = TaskProcess.BCPInOrOut(db, false, "瓶坯库区", "");
            }
            return result;
        }
        /// <summary>
        /// 取消任务
        /// </summary>
        /// <param name="tN_Task"></param>
        /// <exception cref="NotImplementedException"></exception>
        internal static void cancelTask(WCSTask TN_Task)
        {
            if(!WCSHelper.CheckActionRecordExist(TN_Task.S_CODE, 4))
            {
                //取消任务
                WCSHelper.UpdateStatus(TN_Task.S_CODE, 4);
                if (TN_Task.S_TYPE == "接驳位入库")
                {
                    new SqlHelper<object>().GetInstance().Deleteable<CntrItemRel>().Where(a => TN_Task.S_CNTR_CODE.Contains(a.S_CNTR_CODE)).ExecuteCommand();
                    new SqlHelper<object>().GetInstance().Deleteable<LocCntrRel>().Where(a => TN_Task.S_CNTR_CODE.Contains(a.S_CNTR_CODE)).ExecuteCommand();
                }
            }
            else
            {
                WCSHelper.UpdateStatus(TN_Task.S_CODE, 3);
            }
            var op = WMSHelper.GetWmsTask(TN_Task.S_OP_CODE);
            if (op != null)
            {
                if (op.N_B_STATE == 0)
                {
                    //等待直接修改状态为取消
                    op.N_B_STATE = 3;
                }
                else if (op.N_B_STATE == 1)
                {
                    if (WCSHelper.CheckActionRecordExist(TN_Task.S_CODE, 4))
                    {
                        op.N_B_STATE = 2;
                    }
                    else
                    {
                        op.N_B_STATE = 3;
                    }
                }
                WMSHelper.UpdateTaskState(op);
            }
            NDCApi.CancelOrder(TN_Task.S_CODE.Trim());
            OperateStatus(TN_Task, 7);
        }
    }
}