New file |
| | |
| | | using HH.WCS.Mobox3.FJJT.util; |
| | | using SqlSugar; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Security.Cryptography; |
| | | |
| | | namespace HH.WCS.Mobox3.FJJT.wms |
| | | { |
| | | /// <summary> |
| | | /// 密集型库区 |
| | | /// </summary> |
| | | internal class TEST |
| | | { |
| | | static TEST() { |
| | | //InitRowLockTable(new List<string> { "PGKQ", "PGKTK" }); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 根据库区和物料获取入库的货位(堆叠先考虑标准的,容量都是一样的,例如均州都是3+3;不考虑峨眉山非标2+2和2+1同时存在) |
| | | /// </summary> |
| | | /// <param name="area"></param> |
| | | /// <param name="itemCode">如果itemCode是空表示空容器</param> |
| | | /// <param name="standardCarryQty">标准搬运数量</param> |
| | | /// <returns></returns> |
| | | public static Location GetTN_Location4In(string area, string itemCode, string itemBatch, int standardCarryQty = 1) { |
| | | Location result = null; |
| | | |
| | | try { |
| | | //1.0 获取每一排最大的列 |
| | | //1.1 判断当前数量是不是满的,如果是满的并且是最大列,需要排除 |
| | | var listMaxCol = new SqlHelper<Location>().GetInstance().Queryable<Location>().Where(a => a.S_AREA_CODE == area).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList(); |
| | | |
| | | //1.1 查到所有有容器的排 |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | var list = db.Queryable<Location>().Where(a => a.N_CURRENT_NUM > 0 && a.S_AREA_CODE == area).Includes(a => a.LocCntrRel, a => a.CntrItemRels).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList(); |
| | | if (list.Count > 0) { |
| | | for (int i = list.Count - 1; i >= 0; i--) { |
| | | //排除已经锁定的货位 和 放满了且是最大列的货位 |
| | | //其它项目还需要查询排锁 |
| | | if (list[i].N_LOCK_STATE== 0 || (list[i].N_CURRENT_NUM == list[i].N_CAPACITY && listMaxCol.Count(a => a.S_CODE == list[i].S_CODE) > 0)) { |
| | | list.Remove(list[i]); |
| | | } |
| | | } |
| | | if (list.Count > 0) { |
| | | //1.21 加载货位的容器信息 (mapper之前只能是查询原始数据,如果有其他查询 mapper失效) |
| | | #region MyRegion |
| | | /* |
| | | Console.WriteLine("加载货位的容器信息"); |
| | | db.ThenMapper(list, loc => { |
| | | loc.LocCntrRel = db.Queryable<LocCntrRel>().SetContext(x => x.S_LOC_CODE, () => loc.S_LOC_CODE, loc).FirstOrDefault(); |
| | | }); |
| | | |
| | | //1.22 加载容器的物料信息 |
| | | Console.WriteLine("加载容器的物料信息"); |
| | | db.ThenMapper(list.Select(loc => loc.LocCntrRel), lcr => { |
| | | lcr.CntrItemRel = db.Queryable<CntrItemRel>().SetContext(x => x.S_CNTR_CODE, () => lcr.S_CNTR_CODE, lcr).FirstOrDefault(); |
| | | }); |
| | | */ |
| | | #endregion |
| | | //1.3 遍历判断物料类型是否相同 |
| | | for (int i = 0; i < list.Count; i++) { |
| | | |
| | | //todo 还需要判断锁 |
| | | |
| | | #region 空容器或者满容器判断 ,如果是空容器 容器物料信息为空 |
| | | if (list[i].LocCntrRel != null) { |
| | | //LogHelper.Info("itemCode=" + itemCode); |
| | | if ((itemCode != null && list[i].LocCntrRel.CntrItemRels != null && list[i].LocCntrRel.CntrItemRels[0].S_ITEM_CODE.Trim() == itemCode && list[i].LocCntrRel.CntrItemRels[0].S_BATCH_NO.Trim() == itemBatch.Trim()) || (itemCode == null && list[i].LocCntrRel.CntrItemRels == null)) { |
| | | if (list[i].N_CURRENT_NUM < list[i].N_CAPACITY) { |
| | | //1.31 如果搬运数量=1 |
| | | //1.32 搬运多个容器,例如3+3模式 ,必须当前数量=0或3;如果是3+3+,必须当前数量=0或3或6 |
| | | if (list[i].N_CURRENT_NUM % standardCarryQty == 0) { |
| | | result = list[i]; |
| | | } |
| | | else { |
| | | //1.33 不满足则选择后一列,后一列肯定是空货位 |
| | | result = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.N_COL > list[i].N_COL).OrderBy(a => a.N_COL).First(); |
| | | } |
| | | |
| | | } |
| | | else { |
| | | //当前货位满了,比他col大一位的货位,后一列肯定是空货位 |
| | | result = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.N_COL > list[i].N_COL).OrderBy(a => a.N_COL).First(); |
| | | } |
| | | |
| | | if (result != null) { |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | else { |
| | | LogHelper.Info("货位容器物料信息为空"); |
| | | } |
| | | |
| | | |
| | | #endregion |
| | | |
| | | } |
| | | } |
| | | } |
| | | if (result == null) { |
| | | //todo 还需要判断锁 |
| | | #region 查找所有数量是空的排 |
| | | //2.0 简化查询只查每一排第一列 |
| | | list = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area).OrderBy(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList().Where(a => a.N_CURRENT_NUM == 0).ToList(); |
| | | //2.1 选一个空排 |
| | | for (int i = 0; i < list.Count; i++) { |
| | | if (list[i].N_LOCK_STATE== 0) { |
| | | //二次校验当前排所有货位都是空的,防止系统数据错乱 |
| | | var rowSumInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW).Select(a => new { sum = SqlFunc.AggregateSum(a.N_CURRENT_NUM) }).First(); |
| | | if (rowSumInfo.sum == 0) { |
| | | result = list[i]; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | } |
| | | #endregion |
| | | } |
| | | } |
| | | catch (Exception ex) { |
| | | |
| | | Console.WriteLine("GetTN_Location4In:" + ex.Message + ex.StackTrace); |
| | | LogHelper.Error("GetTN_Location4In:" + ex.Message, ex); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 根据库区和物料获取出库的货位(堆叠先考虑标准的,容量都是一样的,例如均州都是3+3;不考虑峨眉山非标2+2和2+1同时存在) |
| | | /// </summary> |
| | | /// <param name="area"></param> |
| | | /// <param name="itemCode">如果itemCode是空表示空容器</param> |
| | | /// <param name="standardCarryQty">标准搬运数量</param> |
| | | /// <returns></returns> |
| | | /// <returns></returns> |
| | | public static Location GetTN_Location4Out(string area, string itemCode, string itemBatch, int standardCarryQty = 1) { |
| | | Console.WriteLine($"area={area}"); |
| | | Location result = null; |
| | | var db = new SqlHelper<Location>().GetInstance(); |
| | | |
| | | //1.0 查到所有有容器的排 var list = db.Queryable<TN_Location>().Where(a => a.N_CURRENT_NUM>0).Includes(a => a.LocCntrRel, a => a.CntrItemRel).ToList(); |
| | | var list = db.Queryable<Location>().Where(a => a.N_CURRENT_NUM > 0 && a.S_AREA_CODE == area).Includes(a => a.LocCntrRel, a => a.CntrItemRels).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).ToList(); |
| | | //1.1 判断当前数量是不是满的,如果是满的并且是最大列,需要排除 |
| | | if (list.Count > 0) { |
| | | //LogHelper.Info("GetTN_Location4Out:" + JsonConvert.SerializeObject(list)); |
| | | #region MyRegion |
| | | /* |
| | | //1.21 加载货位的容器信息 |
| | | db.ThenMapper(list, loc => { |
| | | loc.LocCntrRel = db.Queryable<LocCntrRel>().SetContext(x => x.S_LOC_CODE, () => loc.S_LOC_CODE, loc).FirstOrDefault(); |
| | | }); |
| | | //1.22 加载容器的物料信息 |
| | | db.ThenMapper(list.Select(loc => loc.LocCntrRel), lcr => { |
| | | lcr.CntrItemRel = db.Queryable<CntrItemRel>().SetContext(x => x.S_CNTR_CODE, () => lcr.S_CNTR_CODE, lcr).FirstOrDefault(); |
| | | }); |
| | | */ |
| | | #endregion |
| | | //1.3 遍历判断物料类型是否相同 |
| | | for (int i = 0; i < list.Count; i++) { |
| | | |
| | | //todo 还需要判断锁 |
| | | |
| | | #region 空容器或者满容器判断 ,如果是空容器 容器物料信息为空 |
| | | if (list[i].N_LOCK_STATE== 0 && list[i].LocCntrRel != null) { |
| | | if ((itemCode != null && list[i].LocCntrRel.CntrItemRels != null && list[i].LocCntrRel.CntrItemRels[0].S_ITEM_CODE.Trim() == itemCode && (itemBatch == null || list[i].LocCntrRel.CntrItemRels[0].S_BATCH_NO.Trim() == itemBatch.Trim())) || (itemCode == null && list[i].LocCntrRel.CntrItemRels == null)) { |
| | | //搬运选择货位 |
| | | //如果当前出库位后面有空位,不能是入库中 |
| | | var after = new SqlHelper<Location>().Get(a => a.S_AREA_CODE == area && a.N_ROW == list[i].N_ROW && a.N_COL == list[i].N_COL + 1); |
| | | if (after == null || after.N_LOCK_STATE== 0) { |
| | | result = list[i]; |
| | | } |
| | | if (result != null) { |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | #endregion |
| | | |
| | | } |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | |
| | | private static List<int> GetRowsByArea(string area) { |
| | | var list = new SqlHelper<Location>().GetInstance().Queryable<Location>().Where(a => a.S_AREA_CODE == area).Distinct().Select(a => a.N_ROW).ToList(); |
| | | return list; |
| | | } |
| | | internal static void Test() { |
| | | //UnLockLoc("PGKQ-02-02"); |
| | | //LockLoc("PGKQ-02-02", "入库锁"); |
| | | //Binding("PGKQ-02-03", "AAA", "", 3); |
| | | //UnBinding("PGKQ-02-03", 2); |
| | | |
| | | //var full = GetTN_Location4In("PGKQ", "AAA"); |
| | | //var empty = GetTN_Location4In("PGKQ", null); |
| | | //var fullOut = GetTN_Location4Out("PGKQ", "AAA"); |
| | | //var emptyOut = GetTN_Location4Out("PGKQ", null); |
| | | //var TN_Locations = new SqlHelper<TN_Location>().GetList(); |
| | | //var LocCntrRels = new SqlHelper<LocCntrRel>().GetList(); |
| | | //var CntrItemRels = new SqlHelper<CntrItemRel>().GetList(); |
| | | |
| | | //var list = new SqlHelper<TN_Location>().GetInstance().Queryable<TN_Location>().LeftJoin<LocCntrRel>((l, lc) => l.S_LOC_CODE == lc.S_LOC_CODE).ToList(); |
| | | //var results = context.Client.Queryable<Employee>().Mapper(t=>t.Person, p=>p.PersonId).ToList(); |
| | | var db = new SqlHelper<object>().GetInstance(); |
| | | |
| | | //var list = db.Queryable<TN_Location>().Mapper(l => l.LocCntrRel, lcr => lcr.S_LOC_CODE).Where(a=>a.S_LOC_CODE== "PGKQ-01-01").ToList(); |
| | | |
| | | //多级查询会嵌套,需要指定导航属性和主键,循环嵌套查询不建议 |
| | | //[Navigate(NavigateType.OneToOne, nameof(S_LOC_CODE))]、 [Navigate(NavigateType.OneToOne, nameof(S_CNTR_CODE))]、[SugarColumn(IsPrimaryKey = true)] |
| | | var list = db.Queryable<Location>().Where(a => a.N_CURRENT_NUM > 0).Includes(a => a.LocCntrRel, a => a.CntrItemRels).ToList(); |
| | | |
| | | |
| | | |
| | | #region MyRegion |
| | | /* |
| | | // SetContext不会生成循环操作,高性能 和直接Where性能是不一样的 |
| | | var list = db.Queryable<TN_Location>().Where(a => a.N_CURRENT_NUM > 0).ToList(); |
| | | //第一层 |
| | | db.ThenMapper(list, loc => { |
| | | loc.LocCntrRel = db.Queryable<LocCntrRel>().SetContext(x => x.S_LOC_CODE, () => loc.S_LOC_CODE, loc).FirstOrDefault(); |
| | | }); |
| | | //第二层 |
| | | db.ThenMapper(list.Select(loc => loc.LocCntrRel), lcr => { |
| | | lcr.CntrItemRel = db.Queryable<CntrItemRel>().SetContext(x => x.S_CNTR_CODE, () => lcr.S_CNTR_CODE, lcr).FirstOrDefault(); |
| | | }); |
| | | */ |
| | | #endregion |
| | | } |
| | | |
| | | } |
| | | } |