using System; using System.Collections.Generic; using System.Linq; using Model.ModelDto.SysDto; using SqlSugar; using WMS.Entity.BllAsnEntity; using WMS.Entity.Context; using WMS.Entity.SysEntity; namespace WMS.BLL.Logic { /// /// 分配库位 /// public class AllotLocation { /// /// 获取合适的库位 /// /// 仓库号 /// 巷道号(可空) /// public SysStorageLocat GetSuiTableLocate(string houseNo, string roadwayNo = "") { try { var db = DataContext.Db; /* 1.先判断仓库(立库或者平库) * 2.如果是立库 再判断是否指定巷道号 */ var house = db.Queryable().First(m => m.WareHouseNo == houseNo); if (house == null) { throw new Exception($"未查询到{houseNo}仓库信息"); } //数据字典(获取字典中仓库类型) var dic = db.Queryable().First(m => m.Id.ToString() == house.Type); switch (dic.DictName) { //是否指定巷道 case "立体库" when !string.IsNullOrWhiteSpace(roadwayNo): { var roadwayList = new List(); var roadway = db.Queryable().First(m => m.RoadwayNo == roadwayNo); if (roadway == null) { throw new Exception($"未查询到{roadwayNo}巷道信息"); } if (roadway.Status == "1") { throw new Exception($"{roadwayNo}巷道已停用"); } //查询该巷道并且标志为正常的的储位 roadwayList.Add(roadway); var locate = GetLocateByRoadways(roadwayList); if (locate == null) { throw new Exception($"{roadwayNo}巷道没有合适的空储位"); } return locate; } //立体库没有指定巷道(循环巷道根据优先级分配) case "立体库" when string.IsNullOrWhiteSpace(roadwayNo): { var roadwayList = db.Queryable().Where(m => m.WareHouseNo == houseNo && m.Status == "0").OrderBy(m => new { m.Priority, m.RoadwayNo }).ToList(); var locate = GetLocateByRoadways(roadwayList); if (locate == null) { throw new Exception($"{houseNo}仓库已启用的巷道中没有合适的空储位"); } return locate; } //平库 该代码块目前是错误的逻辑、后期有库位信息了改 case "平库": { //查询该巷道并且标志为正常的的储位 var locates = db.Queryable() .Where(m => m.WareHouseNo == houseNo && m.Flag == "0" && m.Status == "0") .OrderBy(m => new { m.Layer, m.Column, m.Row }).ToList(); return locates.First(); } //没有仓库类型 default: throw new Exception($"未查询到{houseNo}仓库类型信息,无法为其分配储位"); } } catch (Exception e) { throw new Exception(e.Message); } } /// /// 获取合适空储位信息(根据巷道集合判断) /// /// 巷道集合 /// 区域号(子母托盘区) /// private SysStorageLocat GetLocateByRoadways(List roadways) { try { var db = DataContext.Db; #region 入库分配规则 var funSet = db.Queryable().First(m => m.IsDel == "0" && m.FunSetName == "储位分配上下" && m.IsEnable == "NO"); var funSet2 = db.Queryable().First(m => m.IsDel == "0" && m.FunSetName == "储位分配左右" && m.IsEnable == "NO"); var funSet3 = db.Queryable().First(m => m.IsDel == "0" && m.FunSetName == "储位跳巷分配" && m.IsEnable == "NO"); var topOrBom = 1; // 储位分配上下 0 上 1 下 var leftOrRight = 0; // 储位分配上下 0 左 1 右 var laneAllot = 0; //储位跳巷分配 0:跳着分配(一个一个分配)1:巷道按照优先级分配,同优先级顺序分配(一个巷道满了再分配下一个的巷道储位) if (funSet != null) { switch (funSet.SetValue) { case "Top": topOrBom = 0;//立库储位分配由上往下分配 break; case "Bottom": topOrBom = 1;//立库储位分配由下往上分配 break; default: topOrBom = 1;// 默认:由下往上 break; } } if (funSet2 != null) { switch (funSet2.SetValue) { case "Left": leftOrRight = 0;//立库储位分配由上往下分配 break; case "Right": leftOrRight = 1;//立库储位分配由下往上分配 break; default: leftOrRight = 1;// 默认:由下往上 break; } } if (funSet3 != null) { switch (funSet3.SetValue) { case "JumpLaneAllot": laneAllot = 0;//立库储位分配 巷道同优先级巷道跳着分配(一个一个分配) break; case "RankLaneAllot": laneAllot = 1;//立库储位分配 巷道按照优先级分配,同优先级顺序分配(一个巷道满了再分配下一个的巷道储位) break; default: laneAllot = 1;// 默认 跳着分配 break; } } #endregion #region MyRegion SysStorageLocat locate = null; // 储位信息 //SysStorageLocat log = db.Ado.SqlQuerySingle("select * from SysStorageLocat where LocatNo = (select Top(1) LocatNo from BllPalletBind order by CreateTime desc)"); //巷道最后一次使用记录 SysRoadwayUseLog log= db.Ado.SqlQuerySingle("select Top(1) * from SysRoadwayUseLog where IsDel=0 order by CreateTime desc"); //巷道最后一次使用记录 if (laneAllot == 0)//跳巷道平均分配 { //如果同级巷道有多条则查上次位置日志 if (roadways.Count > 1) { log = db.Queryable().OrderByDescending(l => l.Id).First(); } //取各巷道所有排第一个合适位 foreach (var l in roadways) { //如果上次是当前巷道则跳出 if (log != null && l.RoadwayNo == log.RoadwayNo) { continue; } //取当前巷最优位置 locate = GetLocateByRoadway(l.RoadwayNo, topOrBom, leftOrRight); //当前巷有位置则退出 if (locate != null) { break; } } //如果跳巷道并且未找到合适空储位,则跳到最后一次使用的巷道查询 if (locate == null) { if (log != null) { locate = GetLocateByRoadway(log.RoadwayNo, topOrBom, leftOrRight); } } } else//按照巷道优先级分配 { foreach (var item in roadways) { locate = GetLocateByRoadway(item.RoadwayNo, topOrBom, leftOrRight); } } #endregion return locate; } catch (Exception e) { throw new Exception(e.Message); } } /// /// 取当前巷最优位置 /// /// 巷道号 /// 储位分配上下 0 上 1 下 /// 储位分配上下 0 左 1 右 /// 区域号(子母托盘区) /// private SysStorageLocat GetLocateByRoadway(string roadwayNo, int topOrBom, int leftOrRight) { var db = DataContext.Db; var str = "''"; //查询该巷道并且标志为正常的的储位 do { var sql = $@"select * from SysStorageLocat where IsDel = 0 and Flag = 0 and [Status] = 0 and RoadwayNo = '{roadwayNo}' and LocatNo not in({str}) "; //sql += !string.IsNullOrWhiteSpace(areaNo) ? $"and AreaNo = '{areaNo}' " : ""; sql += "order by "; sql += topOrBom == 0 ? "Layer desc, " : "Layer, "; sql += leftOrRight == 0 ? "[Column], " : "[Column] desc, "; sql += " Row desc; "; var locateList = db.Ado.SqlQuery(sql); var data = locateList.FirstOrDefault(); if (data != null) { return data; } else { return null; } } while (true); } } }