chengsc
2025-05-10 3d6ef3897a77dec54be7057299e1be1d10589336
Wms/WMS.BLL/Logic/AllotLocation.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Model.ModelDto.SysDto;
using SqlSugar;
@@ -7,6 +8,7 @@
using WMS.Entity.BllAsnEntity;
using WMS.Entity.Context;
using WMS.Entity.DataEntity;
using WMS.Entity.LogEntity;
using WMS.Entity.SysEntity;
namespace WMS.BLL.Logic
@@ -16,6 +18,273 @@
    /// </summary>
    public class AllotLocation
    {
        /// <summary>
        /// 获取密集库合适的巷道(适用项目:JC34)
        /// </summary>
        /// <param name="roadways">巷道集合</param>
        /// <param name="areaList">区域集合</param>
        /// <param name="lotNo">批次号</param>
        /// <returns></returns>
        public string GetMiJiSuiTableRoad(string house, List<string> roadways, List<string> areaList, string sku, string lotNo = "")
        {
            var db = DataContext.Db;
            var dataStock = db.Queryable<DataStockDetail>().Where(m => m.IsDel == "0" && m.WareHouseNo == house && m.SkuNo == sku);
            if (!string.IsNullOrWhiteSpace(lotNo))
            {
                dataStock = dataStock.Where(m => m.LotNo == lotNo);
            }
            //库存查找相同物料/批次的巷道
            var yiYouRoad = dataStock.GroupBy(m => m.RoadwayNo).Select(m => m.RoadwayNo).OrderBy(m => m).ToList();
            foreach (var l in yiYouRoad)
            {
                // 判断当前巷道(组)是否有空余储位
                var locateCount = db.Queryable<SysStorageLocat>().Count(m => m.Status == "0" && m.Flag == "0" && areaList.Contains(m.AreaNo) && m.RoadwayNo == l);
                var bindNum = db.Queryable<LogTask>().Where(m => m.IsDel == "0" && (m.Status == "0" || m.Status == "1") && m.EndRoadway == l)
                            .GroupBy(m => m.PalletNo).Select(m => m.PalletNo).Count();
                if (locateCount - bindNum > 0)
                {
                    return l;
                }
            }
            //获取库存内已有物料的巷道
            var dataStockRoad = db.Queryable<DataStockDetail>().Where(m => m.IsDel == "0" && m.WareHouseNo == house).GroupBy(m => m.RoadwayNo).OrderBy(m => m.RoadwayNo).Select(m => m.RoadwayNo).ToList();
            //排除掉已有物料的巷道
            roadways = roadways.Where(m => !dataStockRoad.Contains(m)).ToList();
            foreach (var l in roadways)
            {
                var bl = true;
                //判断当前巷道(组)是否有任务
                var taskList = db.Queryable<LogTask>().Where(m => m.IsDel == "0" && m.EndRoadway == l && (m.Status == "0" || m.Status == "1")).ToList();
                if (taskList.Count > 0)
                {
                    //判断物料批次是否和当前一致
                    foreach (var item in taskList)
                    {
                        var palletBind = db.Queryable<BllPalletUpShelf>().First(m => m.IsDel == "0" && m.TaskNo == item.TaskNo);
                        if (palletBind != null)
                        {
                            if (palletBind.SkuNo !=sku || palletBind.LotNo != lotNo)
                            {
                                bl = false;
                                continue;
                            }
                        }
                    }
                    if (bl)
                    {
                        // 判断当前巷道(组)是否有空余储位
                        var locateCount = db.Queryable<SysStorageLocat>().Count(m => m.Status == "0" && m.Flag == "0" && areaList.Contains(m.AreaNo) && m.RoadwayNo == l);
                        var bindNum = db.Queryable<LogTask>().Where(m => m.IsDel == "0" && (m.Status == "0" || m.Status == "1") && m.EndRoadway == l)
                                    .GroupBy(m => m.PalletNo).Select(m => m.PalletNo).Count();
                        if (locateCount - bindNum > 0)
                        {
                            return l;
                        }
                    }
                }
            }
            return "";
        }
        /// <summary>
        /// 获取密集库合适的储位(适用项目:JC34)
        /// </summary>
        /// <param name="roadways">巷道集合</param>
        /// <param name="areaList">区域集合</param>
        /// <param name="lotNo">批次号</param>
        /// <returns></returns>
        public SysStorageLocat GetMiJiSuiTableLocate(string roadwayNo, List<string> areaList)
        {
            var db = DataContext.Db;
            // 判断当前巷道(组)是否有空余储位
            var locateList = db.Queryable<SysStorageLocat>().Where(m => m.IsDel == "0" && m.RoadwayNo == roadwayNo && areaList.Contains(m.AreaNo)).ToList();
            if (locateList.Count(m => m.Status == "0") > 0)
            {
                var bl = GetLocateASCOrDesc(roadwayNo);
                var locate = locateList.OrderBy(m => m.LocatNo).First();
                if (bl)
                {
                    locate = locateList.OrderByDescending(m => m.LocatNo).First();
                }
                var bl2 = MiJiLocateIsOk(locate, bl); //验证储位是否可入库方法
                if (bl2)
                {
                    return locate;
                }
            }
            return null;
        }
        /// <summary>
        /// 获取储位的排列顺序
        /// </summary>
        /// <param name="roadStr"></param>
        /// <returns>true:desc倒序 false:asc正序</returns>
        public bool GetLocateASCOrDesc(string roadStr)
        {
            var db = DataContext.Db;
            var locate = db.Queryable<SysStorageLocat>().First(m => m.IsDel == "0" && m.RoadwayNo == roadStr);
            var a = locate.LocatNo.Substring(2,2);//储位列
            var b = locate.AisleOne.Substring(2, 2);//通道口列
            return int.Parse(a) < int.Parse(b);
        }
        /// <summary>
        /// 验证储位是否可入库
        /// </summary>
        /// <param name="locate"></param>
        /// <returns></returns>
        private bool MiJiLocateIsOk(SysStorageLocat locate,bool bl)
        {
            var db = DataContext.Db;
            var a = int.Parse(locate.LocatNo.Substring(2, 2));//储位列
            var b = int.Parse(locate.AisleOne.Substring(2, 2));//通道口列
            var str1 = new List<string>() { "0", "3", "5" };
            var str2 = new List<string>() { "1", "2", "4" };
            var locatList1 = db.Queryable<SysStorageLocat>().Where(m => m.IsDel == "0" && m.RoadwayNo == locate.RoadwayNo && m.Column < a).ToList();
            var locatList2 = db.Queryable<SysStorageLocat>().Where(m => m.IsDel == "0" && m.RoadwayNo == locate.RoadwayNo && m.Column > a).ToList();
            if (bl)
            {
                if (locatList1.Count(m => str1.Contains(m.Status)) > 0)
                {
                    return false;
                }
                if (locatList2.Count(m => str2.Contains(m.Status)) > 0)
                {
                    return false;
                }
            }
            else
            {
                if (locatList1.Count(m => str2.Contains(m.Status)) > 0)
                {
                    return false;
                }
                if (locatList2.Count(m => str1.Contains(m.Status)) > 0)
                {
                    return false;
                }
            }
            return true;
        }
        /// <summary>
        /// 根据起始组获取位置最优的四项车取货工位
        /// </summary>
        /// <param name="straRoadway">起始组</param>
        /// <param name="outModel">出库口工位 9、 17、 18</param>
        /// <returns></returns>
        public string RoadwayToStationNum(string straRoadway, string outModel)
        {
            var db = DataContext.Db;
            string stationNum = "";
            string[] lists = straRoadway.Split("MR");
            var model = db.Queryable<SysStorageLocat>().First(m => m.RoadwayNo == straRoadway && m.IsDel == "0");
            string stat = model.AisleOne;
            if (model.Layer == 1)
            {   // 一层
                switch (outModel)       // 申请的入库口
                {
                    case "9":
                        var path13 = Math.Abs(19 - int.Parse(stat.Substring(0, 2))) + Math.Abs(6 - int.Parse(stat.Substring(2, 2)));
                        var path14 = Math.Abs(19 - int.Parse(stat.Substring(0, 2))) + Math.Abs(12 - int.Parse(stat.Substring(2, 2)));
                        if (path13 <= path14)
                        {
                            stationNum = "190601";
                        }
                        else
                        {
                            stationNum = "191201";
                        }
                        break;
                    case "17":
                        stationNum = "030401";
                        break;
                    case "18":
                        var path03 = Math.Abs(03 - int.Parse(stat.Substring(0, 2))) + Math.Abs(06 - int.Parse(stat.Substring(2, 2)));
                        var path05 = Math.Abs(03 - int.Parse(stat.Substring(0, 2))) + Math.Abs(12 - int.Parse(stat.Substring(2, 2)));
                        if (path03 <= path05)
                        {
                            stationNum = "030601";
                        }
                        else
                        {
                            stationNum = "031201";
                        }
                        break;
                    default: break;
                }
            }
            else
            {  // 二层
                switch (outModel)       // 申请的入库口
                {
                    case "9":
                        var path15 = Math.Abs(19 - int.Parse(stat.Substring(0, 2))) + Math.Abs(6 - int.Parse(stat.Substring(2, 2)));
                        var path16 = Math.Abs(19 - int.Parse(stat.Substring(0, 2))) + Math.Abs(12 - int.Parse(stat.Substring(2, 2)));
                        if (path15 <= path16)
                        {
                            stationNum = "190602";
                        }
                        else
                        {
                            stationNum = "191202";
                        }
                        break;
                    case "17":
                        stationNum = "030402";
                         break;
                    case "18":
                        var path03 = Math.Abs(03 - int.Parse(stat.Substring(0, 2))) + Math.Abs(06 - int.Parse(stat.Substring(2, 2)));
                        var path05 = Math.Abs(03 - int.Parse(stat.Substring(0, 2))) + Math.Abs(12 - int.Parse(stat.Substring(2, 2)));
                        if (path03 <= path05)
                        {
                            stationNum = "030602";
                        }
                        else
                        {
                            stationNum = "031202";
                        }
                        break;
                    default: break;
                }
            }
            return stationNum;
        }
        /// <summary>
        /// 获取合适的库位
        /// </summary>
@@ -44,7 +313,7 @@
                var dic = db.Queryable<SysDictionary>().First(m => m.Id.ToString() == house.Type);
                switch (dic.DictName)
                {
                    //是否指定巷道
                    //指定巷道
                    case "立体库" when !string.IsNullOrWhiteSpace(roadwayNo):
                        {
                            var roadwayList = new List<SysStorageRoadway>();
@@ -65,7 +334,7 @@
                            //查询该巷道并且标志为正常的的储位
                            roadwayList.Add(roadway);
                            var locate = GetLocateByRoadways(roadwayList,areaList,true);
                            var locate = GetLocateByRoadways(roadwayList,areaList,true,houseNo);
                            if (locate == null)
                            {
                                throw new Exception($"{roadwayNo}巷道没有合适的空储位");
@@ -77,7 +346,7 @@
                        {
                            var roadwayList = db.Queryable<SysStorageRoadway>().Where(m => m.WareHouseNo == houseNo && m.Status == "0" && roadList.Contains(m.RoadwayNo)).OrderBy(m => new { m.Priority, m.RoadwayNo }).ToList();
                            var locate = GetLocateByRoadways(roadwayList,areaList);
                            var locate = GetLocateByRoadways(roadwayList,areaList,false, houseNo);
                            if (locate == null)
                            {
                                throw new Exception($"{houseNo}仓库已启用的巷道中没有合适的空储位");
@@ -111,7 +380,7 @@
        /// <param name="areaList">区域集合</param>
        /// <param name="isRoadway">是否指定巷道</param>
        /// <returns></returns>
        private SysStorageLocat GetLocateByRoadways(List<SysStorageRoadway> roadways,List<string> areaList,bool isRoadway = false)
        private SysStorageLocat GetLocateByRoadways(List<SysStorageRoadway> roadways,List<string> areaList,bool isRoadway = false ,string houseNo = "W01")
        {
            try
            {
@@ -176,14 +445,14 @@
                SysStorageLocat locate = null; // 储位信息
                //SysStorageLocat log = db.Ado.SqlQuerySingle<SysStorageLocat>("select * from SysStorageLocat where LocatNo = (select Top(1) LocatNo from BllPalletBind order by CreateTime desc)"); //巷道最后一次使用记录
                SysRoadwayUseLog log= db.Ado.SqlQuerySingle<SysRoadwayUseLog>("select Top(1) * from SysRoadwayUseLog where IsDel=0 order by CreateTime desc"); //巷道最后一次使用记录
                SysRoadwayUseLog log= db.Ado.SqlQuerySingle<SysRoadwayUseLog>($"select Top(1) * from SysRoadwayUseLog where IsDel=0 and WareHouseNo ='{houseNo}' order by CreateTime desc"); //巷道最后一次使用记录
                if (laneAllot == 0)//跳巷道平均分配
                {
                    //如果同级巷道有多条则查上次位置日志
                    if (roadways.Count > 1)
                    {
                        log = db.Queryable<SysRoadwayUseLog>().OrderByDescending(l => l.Id).First();
                        log = db.Queryable<SysRoadwayUseLog>().Where(m=>m.WareHouseNo == houseNo).OrderByDescending(l => l.Id).First();
                    }
                    //取各巷道所有排第一个合适位
                    foreach (var l in roadways)
@@ -203,21 +472,25 @@
                            locate = GetLocateByRoadway(l.RoadwayNo, topOrBom, leftOrRight, areaList, list, ref count);
                            if (locate != null)
                            {
                                list.Add(locate.LocatNo);
                                var isOk = LocateIsOk(locate);
                                if (!isOk)
                                {
                                    locate = null;
                                }
                                if (isOk)
                                {
                                    break;
                                }
                                break;
                                //list.Add(locate.LocatNo);
                                //var isOk = LocateIsOk(locate);
                                //if (!isOk)
                                //{
                                //    locate = null;
                                //}
                                //if (isOk)
                                //{
                                //    break;
                                //}
                            }
                        } while (count != 0 && locate == null);//当查询储位数量不等0 并且储位为空时,再次循环巷道、区域查找储位
                        if (locate!=null)
                        {
                            break;
                        }
                    }
                    //如果跳巷道并且未找到合适空储位,则跳到最后一次使用的巷道查询
                    if (!isRoadway)
@@ -233,12 +506,13 @@
                                    locate = GetLocateByRoadway(log.RoadwayNo, topOrBom, leftOrRight, areaList, list, ref count);
                                    if (locate != null)
                                    {
                                        list.Add(locate.LocatNo);
                                        var isOk = LocateIsOk(locate);
                                        if (!isOk)
                                        {
                                            locate = null;
                                        }
                                        break;
                                        //list.Add(locate.LocatNo);
                                        //var isOk = LocateIsOk(locate);
                                        //if (!isOk)
                                        //{
                                        //    locate = null;
                                        //}
                                    }
                                    
                                    
@@ -260,21 +534,25 @@
                            locate = GetLocateByRoadway(item.RoadwayNo, topOrBom, leftOrRight, areaList, list, ref count);
                            if (locate != null)
                            {
                                list.Add(locate.LocatNo);
                                var isOk = LocateIsOk(locate);
                                if (!isOk)
                                {
                                    locate = null;
                                }
                                if (isOk)
                                {
                                    break;
                                }
                                break;
                                //list.Add(locate.LocatNo);
                                //var isOk = LocateIsOk(locate);
                                //if (!isOk)
                                //{
                                //    locate = null;
                                //}
                                //if (isOk)
                                //{
                                //    break;
                                //}
                            }
                        } while (count != 0 && locate == null);//当查询储位数量不等0 并且储位为空时,再次循环巷道、区域查找储位
                        if (locate != null)
                        {
                            break;
                        }
                    }
                }
@@ -340,6 +618,11 @@
        }
        /// <summary>
        /// 验证储位是否可入库 双深位验证
        /// </summary>
        /// <param name="locate"></param>
        /// <returns></returns>
        private bool LocateIsOk(SysStorageLocat locate)
        {
            try