| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.IO; |
| | | using System.Linq; |
| | | using Model.ModelDto.SysDto; |
| | | using SqlSugar; |
| | |
| | | using WMS.Entity.BllAsnEntity; |
| | | using WMS.Entity.Context; |
| | | using WMS.Entity.DataEntity; |
| | | using WMS.Entity.LogEntity; |
| | | using WMS.Entity.SysEntity; |
| | | |
| | | namespace WMS.BLL.Logic |
| | |
| | | /// </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> |
| | |
| | | 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>(); |
| | |
| | | |
| | | //查询该巷道并且标志为正常的的储位 |
| | | roadwayList.Add(roadway); |
| | | var locate = GetLocateByRoadways(roadwayList,areaList,true); |
| | | var locate = GetLocateByRoadways(roadwayList,areaList,true,houseNo); |
| | | if (locate == null) |
| | | { |
| | | throw new Exception($"{roadwayNo}巷道没有合适的空储位"); |
| | |
| | | { |
| | | 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}仓库已启用的巷道中没有合适的空储位"); |
| | |
| | | /// <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 |
| | | { |
| | |
| | | |
| | | 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) |
| | |
| | | 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) |
| | |
| | | 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; |
| | | //} |
| | | } |
| | | |
| | | |
| | |
| | | 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; |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 验证储位是否可入库 双深位验证 |
| | | /// </summary> |
| | | /// <param name="locate"></param> |
| | | /// <returns></returns> |
| | | private bool LocateIsOk(SysStorageLocat locate) |
| | | { |
| | | try |