using HH.WCS.Hexafluo;
|
using HH.WCS.Hexafluo.util;
|
using HH.WCS.Hexafluo.wms;
|
using HH.WCS.SJML.Comm;
|
using HH.WCS.SJML.Entitys;
|
using HH.WCS.ZCQTJ.Entitys;
|
using Newtonsoft.Json;
|
using SqlSugar;
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Text;
|
|
namespace HH.WCS.SJML.Bll
|
{
|
public class In_AlgorBLL
|
{
|
public InAssignResultEntity InAssign(InAssignEntity model)
|
{
|
//定义返回实体
|
InAssignResultEntity resultEntity = new InAssignResultEntity();
|
resultEntity.Msg = "";
|
resultEntity.errCode = "";
|
LogHelper.Info("入库算法", "入库算法参数:" + JsonConvert.SerializeObject(model));
|
var chi = new SqlHelper<object>().GetInstance();
|
var newDb = chi.CopyNew();
|
try
|
{
|
#region 传入参数判断
|
if (model == null)
|
{
|
resultEntity.Success = false;
|
resultEntity.errCode = "6";
|
resultEntity.Msg = "参数实体不能为 null !";
|
return resultEntity;
|
}
|
//判断传入库区列表不能为空
|
if (model.lstAreaPrior == null || model.lstAreaPrior.Count == 0)
|
{
|
resultEntity.Success = false;
|
resultEntity.errCode = "6";
|
resultEntity.Msg = "指定的入作业库库区列表不能为空!";
|
return resultEntity;
|
}
|
#endregion
|
//(流离式、平库、立库)标准入库算法
|
string areaType = newDb.Queryable<TN_AreaEntitys>().Where(e => e.S_AREA_CODE == model.lstAreaPrior[0].areaCode).First()?.S_NOTE;
|
if (string.IsNullOrEmpty(areaType))
|
{
|
resultEntity.Success = false;
|
resultEntity.errCode = "6";
|
resultEntity.Msg = "终点的库区类型为空!";
|
return resultEntity;
|
}
|
if (areaType == Constants.Area_Struc_PingStock || areaType == Constants.Area_Struc_LiStock)
|
{
|
resultEntity = FlatAreaGetLocation(model);
|
}
|
else
|
{
|
throw new Exception("入库的库区类型 即不是平库也不是立库");
|
}
|
resultEntity.areaType = areaType;
|
LogHelper.Info("入库算法", "入库返回结果:" + JsonConvert.SerializeObject(resultEntity));
|
return resultEntity;
|
}
|
|
catch (Exception ex)
|
{
|
LogHelper.Info("入库算法", "异常日志:" + ex.Message);
|
resultEntity.errCode = "5";
|
resultEntity.Msg = "算法异常," + ex.Message;
|
return resultEntity;
|
}
|
|
}
|
|
public InAssignResultEntity FlatAreaGetLocation(InAssignEntity model)
|
{
|
InAssignResultEntity resultEntity = new InAssignResultEntity();
|
resultEntity.Success = false;
|
List<Location> lstTrueLocation = new List<Location>();//货位实体
|
List<Location> lstTmpLocation = new List<Location>();//货位实体
|
List<TN_LogicEntitys> lstALR = null;//逻辑分区
|
List<Location> lstLocation = new List<Location>();
|
List<Location> lstLockLItem = new List<Location>();
|
List<Location> locationInLock = new List<Location>();
|
List<Location> lstEmptyLocation = new List<Location>();
|
List<Location> lstTrueLItem = new List<Location>();
|
List<areaPriorClass> lstAreaPrior = model.lstAreaPrior.OrderByDescending(o => o.Prior).ToList();
|
StringBuilder sbDetailError = new StringBuilder();
|
var chi = new SqlHelper<object>().GetInstance();
|
var newDb = chi.CopyNew();
|
#region 从autobom和货位扩展表中获取可用货位集合
|
//按优先级循环处理库区获取可用货位集合
|
foreach (areaPriorClass item in lstAreaPrior)
|
{
|
TN_AreaEntitys areaModel = newDb.Queryable<TN_AreaEntitys>().Where(e => e.S_AREA_CODE == item.areaCode.ToString()).First();
|
model.stockCode = areaModel.S_WH_CODE;
|
resultEntity.isControlQty = areaModel.S_CONTROL_QTY;
|
resultEntity.areaCode = item.areaCode;
|
//这里判断库区是否可用 并且哪些巷道可用 且必须库区类型是立库
|
var Subs = Expressionable.Create<TN_SubsidiaryEntitys>();
|
Subs.And(it => it.S_WH_CODE == areaModel.S_WH_CODE);
|
Subs.And(it => it.S_AREA_CODE == item.areaCode);
|
// Subs.And(it => it.S_IS_IN_OUT == "入库");
|
var Subsidiary = newDb.Queryable<TN_SubsidiaryEntitys>().Where(Subs.ToExpression()).ToList();
|
List<TN_SubsidiaryEntitys> tNs = new List<TN_SubsidiaryEntitys>();//将不能入的接驳位放进去
|
var IsJb = newDb.Queryable<TN_IsopenBitEntitys>().Where(e => e.S_IsOpen == "N").ToList();
|
LogHelper.Info("入库算法", "关闭的接驳位:" + JsonConvert.SerializeObject(IsJb));
|
//筛选出辅助表里入库的
|
var ttg = Subsidiary.FindAll(e => e.S_IS_IN_OUT == "入库" && e.S_FlowNo == item.S_FlowNo).ToList();
|
foreach (var itm in ttg)
|
{
|
var Location = itm.S_CONNECTION.Split(',').ToList();
|
bool pp = false;
|
foreach (var em in Location)
|
{
|
if (IsJb.FindAll(e => e.S_JbBit == em).ToList().Count() == 0)
|
{
|
pp = true;
|
}
|
}
|
if (!pp)
|
{
|
tNs.Add(itm);
|
}
|
}
|
if (model.needCalLock)
|
{
|
model.lockLocation = resultEntity.isControlQty.Equals("Y") ? true : false;//不管控数量时,不锁定目的货位
|
}
|
//定义传入变量实体 获取可用货位集合
|
LogicTrue logicModel = new LogicTrue();
|
logicModel.stockCode = "";
|
if (string.IsNullOrEmpty(model.logicAreaCode))
|
{
|
logicModel.type = 2;
|
logicModel.areaCode = item.areaCode;
|
}
|
else
|
{
|
//只支持逻辑分区关联货位、库区
|
logicModel.areaCode = item.areaCode;
|
var Texp = Expressionable.Create<TN_LogicEntitys>();
|
Texp.AndIF(!string.IsNullOrEmpty(model.logicAreaCode), it => it.S_ZONAL_CODE == model.logicAreaCode);
|
Texp.And(it => it.S_AREA_CODE == item.areaCode);
|
Texp.And(it => it.S_START_USING == "Y");
|
lstALR = newDb.Queryable<TN_LogicEntitys>().Where(Texp.ToExpression()).ToList();
|
|
// CreateDAL<TN_WMS_AREADAL>().GetLocationByLogicArea(model.logicAreaCode, item.areaCode);
|
if (lstALR != null && lstALR.Count > 0)
|
{
|
if (lstALR[0].S_TYPE == 2)
|
{
|
logicModel.type = 2;
|
logicModel.areaCode = item.areaCode;
|
}
|
else if (lstALR[0].S_TYPE == 3)
|
{
|
logicModel.type = 3;
|
logicModel.lstLocationCode = lstALR.Where(o => o.S_TYPE == 3).Select(o => o.S_LOCATION_CODE).ToList();
|
}
|
}
|
if (!string.IsNullOrEmpty(model.logicAreaCode) && lstALR.Count() == 0)
|
{
|
resultEntity.Success = false;
|
resultEntity.errCode = "8";
|
resultEntity.Msg = "当有指定逻辑分区编号的时候,逻辑分区表必须要有与之对应的数据";
|
return resultEntity;
|
}
|
}
|
//获取在autobom中可用货位的集合(去除废弃的货位)
|
LogHelper.Info("入库算法", "求可用货位的logicModel参数:" + JsonConvert.SerializeObject(logicModel));
|
lstLocation = LocationTrue(logicModel);
|
// LogHelper.Info("入库算法", $"lstLocation {lstLocation.Count()}");
|
//获取在货位扩展表中可用的货位的集合(去除锁定的货位)
|
lstEmptyLocation.AddRange(lstLocation);
|
lstTrueLocation.AddRange(lstLocation);
|
lstTrueLItem = lstLocation.ToList();
|
// LogHelper.Info("入库算法", $"lstTrueLItem {lstTrueLItem.Count()}");
|
// LogHelper.Info("入库算法", "没锁且当前容量等于0的货位有:" + JsonConvert.SerializeObject(lstLocation));
|
|
#region 密集型库区定制代码
|
|
//获取入库算法策略
|
var exp = Expressionable.Create<TN_ArithmeticEntitys>();
|
exp.And(it => it.S_WH_CODE == model.stockCode);
|
exp.And(it => it.S_AREA_CODE == resultEntity.areaCode);
|
exp.And(it => it.S_STRATEGY_TYPE == "入库");
|
exp.And(it => it.S_START_USING == "Y");
|
List<TN_ArithmeticEntitys> lstStrategy = newDb.Queryable<TN_ArithmeticEntitys>().Where(exp.ToExpression()).ToList();
|
|
//获取预出库锁定的货位
|
if (lstStrategy.Select(o => o.S_STRATEGY_CODE).ToList().Contains("FirstInLastOut"))//先进后出
|
{
|
var loca = Expressionable.Create<Location>();
|
loca.And(it => it.S_WH_CODE == model.stockCode);
|
loca.And(it => it.S_AREA_CODE == resultEntity.areaCode);
|
loca.And(it => logicModel.lstLocationCode.Contains(it.S_LOC_CODE));
|
loca.And(it => it.S_LOCK_STATE == "出库锁");
|
List<Location> locationOutLock = newDb.Queryable<Location>().Where(loca.ToExpression()).ToList();
|
LogHelper.Info("入库算法", "当前有出库锁的货位:" + JsonConvert.SerializeObject(locationOutLock));
|
foreach (Location lEntity in locationOutLock)
|
{
|
lstTrueLItem.RemoveAll(o => o.N_ROW == lEntity.N_ROW && o.N_COL == lEntity.N_COL && o.N_LAYER == lEntity.N_LAYER);
|
}
|
LogHelper.Info("入库算法", "去除预出库锁定后的lstTrueLItem数据:" + JsonConvert.SerializeObject(lstTrueLItem));
|
//去除被外侧预入库锁定的货位
|
var lca = Expressionable.Create<Location>();
|
lca.And(it => it.S_WH_CODE == model.stockCode);
|
lca.And(it => it.S_AREA_CODE == resultEntity.areaCode);
|
lca.And(it => logicModel.lstLocationCode.Contains(it.S_LOC_CODE));
|
lca.And(it => it.S_LOCK_STATE == "入库锁");
|
locationInLock = newDb.Queryable<Location>().Where(lca.ToExpression()).ToList();
|
LogHelper.Info("入库算法", "当前有入库锁的货位:" + JsonConvert.SerializeObject(locationOutLock));
|
foreach (Location lEntity in locationInLock)
|
{
|
lstTrueLItem.RemoveAll(o => o.N_ROW == lEntity.N_ROW && o.N_COL == lEntity.N_COL && o.N_LAYER == lEntity.N_LAYER && o.N_SIDE > lEntity.N_SIDE);
|
lstTrueLItem.RemoveAll(o => o.N_ROW == lEntity.N_ROW && o.N_COL == lEntity.N_COL && o.N_LAYER == lEntity.N_LAYER && o.N_SIDE < lEntity.N_SIDE);
|
}
|
//去除被外侧货物阻挡的货位
|
var ca = Expressionable.Create<Location>();
|
ca.And(it => it.S_WH_CODE == model.stockCode);
|
ca.And(it => it.S_AREA_CODE == resultEntity.areaCode);
|
var locations = newDb.Queryable<Location>().Where(ca.ToExpression()).ToList();
|
LogHelper.Info("入库算法", "locations数据:" + JsonConvert.SerializeObject(locations));
|
foreach (Location itemC in locations)
|
{
|
lstTrueLItem.RemoveAll(o => o.N_ROW == itemC.N_ROW && o.N_COL == itemC.N_COL && o.N_LAYER == itemC.N_LAYER && o.N_SIDE > itemC.N_SIDE);
|
}
|
LogHelper.Info("入库算法", "去除阻挡后的lstTrueLItem数据:" + JsonConvert.SerializeObject(lstTrueLItem));
|
}
|
#endregion
|
#region 地堆型库区定制代码
|
if (areaModel.S_AREA_TYPE == "地堆")
|
{
|
if (lstTrueLItem.Count > 0)
|
{
|
var Inloca = Expressionable.Create<Location>();
|
Inloca.And(it => it.S_WH_CODE == model.stockCode);
|
Inloca.And(it => it.S_AREA_CODE == resultEntity.areaCode);
|
Inloca.And(it => logicModel.lstLocationCode.Contains(it.S_LOC_CODE));
|
Inloca.And(it => it.S_LOCK_STATE == "入库锁");
|
locationInLock = newDb.Queryable<Location>().Where(Inloca.ToExpression()).ToList();
|
foreach (Location lEntity in locationInLock)
|
{
|
lstTrueLItem.RemoveAll(o => o.N_ROW == lEntity.N_ROW);
|
}
|
LogHelper.Info("入库算法", "过滤预入库锁定货位后的数据:" + JsonConvert.SerializeObject(lstTrueLItem));
|
|
var Outloca = Expressionable.Create<Location>();
|
Outloca.And(it => it.S_WH_CODE == model.stockCode);
|
Outloca.And(it => it.S_AREA_CODE == resultEntity.areaCode);
|
Outloca.And(it => logicModel.lstLocationCode.Contains(it.S_LOC_CODE));
|
Outloca.And(it => it.S_LOCK_STATE == "出库锁");
|
List<Location> locationOutLock = newDb.Queryable<Location>().Where(Outloca.ToExpression()).ToList();
|
foreach (Location lEntity in locationOutLock)
|
{
|
lstTrueLItem.RemoveAll(o => o.N_ROW == lEntity.N_ROW);
|
}
|
LogHelper.Info("入库算法", "过滤预出库锁定货位后的数据:" + JsonConvert.SerializeObject(lstTrueLItem));
|
lstTrueLItem = lstTrueLItem.OrderBy(c => c.N_ROW).ThenBy(e => e.N_COL).ToList();
|
}
|
}
|
#endregion
|
//判断库区是否为立库 如果是则经过二次过滤
|
if (areaModel.S_NOTE == Constants.Area_Struc_LiStock)
|
{
|
if (Subsidiary.Any())
|
{
|
if (Subsidiary.FindAll(e => e.S_AREA_TYPE != Constants.Area_Struc_LiStock).Count() == 0)
|
{
|
//先排除掉不可用巷道
|
var SubNo = Subsidiary.FindAll(e => e.N_Y_ROADWAY == "N").ToList();
|
if (model.S_Roadway.Count() > 0)
|
{
|
LogHelper.Info("入库算法", $"入参固定巷道{JsonConvert.SerializeObject(model.S_Roadway)} ");
|
lstTrueLItem = lstTrueLItem.FindAll(e => model.S_Roadway.Contains(e.N_ROADWAY.ToString()));
|
// LogHelper.Info("入库算法", $"入参固定巷道 选择后符合条件的货位{JsonConvert.SerializeObject(lstTrueLItem)} ");
|
}
|
if (SubNo.Any() && model.IsChangeBit == 0)
|
{
|
foreach (var Su in SubNo)
|
{
|
|
lstTrueLItem.RemoveAll(e => e.N_ROADWAY == Su.N_ROADWAY);
|
LogHelper.Info("入库算法", $"巷道关闭移除对应巷道 {Su.N_ROADWAY}");
|
}
|
}
|
if (tNs.Any())
|
{
|
foreach (var Su in tNs)
|
{
|
lstTrueLItem.RemoveAll(e => e.N_ROADWAY == Su.N_ROADWAY);
|
LogHelper.Info("入库算法", $"接驳位关闭移除对应巷道 {Su.N_ROADWAY}");
|
}
|
}
|
if (item.areaCode == "LC11M")
|
{
|
//查询几个特殊的接驳位
|
var Jbw1 = IsJb.Find(e => e.S_JbBit == "TMRKHCW-01");
|
var Jbw2 = IsJb.Find(e => e.S_JbBit == "TMRKJBW-01");
|
var Jbw3 = IsJb.Find(e => e.S_JbBit == "TMRKHCW-02");
|
var Jbw4 = IsJb.Find(e => e.S_JbBit == "TMRKJBW-04");
|
if (Jbw1 != null && Jbw2 != null)
|
{
|
lstTrueLItem.RemoveAll(e => e.N_ROADWAY == 1);
|
LogHelper.Info("入库算法", $"LC11M库 巷道中间的接驳位和可入巷道的接驳位都关闭了则排除巷道 1");
|
}
|
if (Jbw3 != null && Jbw4 != null)
|
{
|
lstTrueLItem.RemoveAll(e => e.N_ROADWAY == 4);
|
LogHelper.Info("入库算法", $"LC11M库 巷道中间的接驳位和可入巷道的接驳位都关闭了则排除巷道 4");
|
}
|
}
|
var Sudiary = Subsidiary.GroupBy(e => e.N_ROADWAY).Select(c => c.First()).ToList();
|
// LogHelper.Info("入库算法", $"Sudiary {JsonConvert.SerializeObject(Sudiary)}");
|
//lstTrueLItem = (from l1 in lstTrueLItem
|
// join l2 in Subsidiary
|
// on l1.N_ROADWAY equals l2.N_ROADWAY
|
// orderby l2.N_ROADWAY descending
|
// select l1).ToList();
|
lstTrueLItem = (from l1 in lstTrueLItem
|
join l2 in Sudiary
|
on l1.N_ROADWAY equals l2.N_ROADWAY
|
orderby l2.N_ROADWAY_PRIORITY descending
|
select l1).ToList();
|
// LogHelper.Info("入库算法", $"lstTrueLItem {lstTrueLItem.Count()}");
|
}
|
}
|
if (resultEntity.areaCode == "LC11L" && !string.IsNullOrEmpty(model.itemCode))
|
{
|
lstTrueLItem.RemoveAll(e => e.N_LAYER == 5);
|
LogHelper.Info("入库算法", $"满托移除第五层货位");
|
}
|
|
if (lstTrueLItem.Count > 0 && (resultEntity.areaCode == "LC11L" || resultEntity.areaCode == "LC11X"))
|
{
|
List<Location> Remo = new List<Location>();
|
var gghhj = lstTrueLItem.GroupBy(e => e.N_ROADWAY).Select(c => c.First()).ToList();
|
foreach (var gg in gghhj)
|
{
|
var RemoL = lstTrueLItem.FindAll(e => e.N_ROADWAY == gg.N_ROADWAY).ToList().Take(2);
|
if (RemoL != null && RemoL.Count() > 0)
|
{
|
foreach (var aaaf in RemoL)
|
{
|
Remo.Add(aaaf);
|
}
|
}
|
}
|
LogHelper.Info("入库算法", $"固定排除两个货位:{JsonConvert.SerializeObject(Remo)} ");
|
if (Remo.Count > 0)
|
{
|
foreach (var ro in Remo)
|
{
|
lstTrueLItem.Remove(ro);
|
}
|
}
|
}
|
}
|
|
if (lstTrueLItem.Count > 0)
|
{
|
if (resultEntity.isControlQty == "N")
|
{
|
//该库区中的货位如果为不管控数量,则对所有货位平均分配入库任务
|
resultEntity = AverageLocation(lstTrueLItem, model.lockLocation, resultEntity.isControlQty);
|
}
|
else
|
{
|
if (resultEntity.areaCode == "LC11L" && string.IsNullOrEmpty(model.itemCode))
|
{
|
var ggj = lstTrueLItem.FindAll(e => e.N_LAYER == 5).ToList();
|
if (ggj.Count() > 0)
|
{
|
LogHelper.Info("入库算法", $"空托有五层时 只算五层的");
|
lstTrueLItem = ggj;
|
}
|
}
|
//根据入库策略计算货位
|
resultEntity = CalLocationByStraty(resultEntity, lstTrueLItem, lstLocation, lstLockLItem, model.lockLocation, logicModel);
|
}
|
}
|
if (resultEntity.Success)
|
{
|
break;
|
}
|
}
|
if (!resultEntity.Success)
|
{
|
if (lstEmptyLocation == null || lstEmptyLocation.Count == 0)
|
{
|
resultEntity.Success = false;
|
resultEntity.errCode = "8";
|
resultEntity.Msg = "空货位不足";
|
return resultEntity;
|
}
|
if (lstTrueLocation == null || lstTrueLocation.Count == 0)
|
{
|
resultEntity.Success = false;
|
resultEntity.errCode = "8";
|
resultEntity.Msg = "两表关联后无可用的货位!请根据ID在日志管理中查询详细原因";
|
return resultEntity;
|
}
|
resultEntity.Success = false;
|
resultEntity.errCode = "8";
|
resultEntity.Msg = "启用策略后无可用的货位";
|
return resultEntity;
|
}
|
#endregion
|
|
return resultEntity;
|
}
|
|
public List<Location> LocationTrue(LogicTrue model)
|
{
|
List<string> locationCodes = new List<string>();
|
List<Location> lstLocation = new List<Location>();
|
var chi = new SqlHelper<object>().GetInstance();
|
var newDb = chi.CopyNew();
|
var exp = Expressionable.Create<Location, LocCntrRel>();
|
exp.AndIF(model.type == 1, (it, b) => it.S_WH_CODE == model.stockCode);
|
exp.AndIF(model.type == 2, (it, b) => it.S_AREA_CODE == model.areaCode);
|
exp.AndIF(model.type == 3, (it, b) => model.lstLocationCode.Contains(it.S_LOC_CODE));
|
exp.And((it, b) => it.S_LOCK_STATE == "无");
|
exp.And((it, b) => it.C_ENABLE == "Y");
|
exp.And((it, b) => it.N_CURRENT_NUM == 0);
|
exp.And((it, b) => string.IsNullOrEmpty(b.S_CNTR_CODE));
|
lstLocation = newDb.Queryable<Location>().LeftJoin<LocCntrRel>((it, b) => it.S_LOC_CODE == b.S_LOC_CODE).Where(exp.ToExpression()).ToList();
|
return lstLocation;
|
}
|
|
private InAssignResultEntity AverageLocation(List<Location> lstTrueLocation, bool lockLocation, string isControlQty)
|
{
|
InAssignResultEntity resultEntity = new InAssignResultEntity();
|
//策略实体
|
TN_ArithmeticEntitys Trctics = new TN_ArithmeticEntitys();
|
Location at_l_Entity = AverageBalance(lstTrueLocation);
|
//bool result = CreateDAL<TN_WMS_LOCATIONDAL>().UpdateLocationTaskQty(at_l_Entity.CN_S_LOCATION_CODE, at_l_Entity.CN_N_INTASK_QTY + 1);
|
resultEntity.Success = true;
|
resultEntity.Msg = "";
|
resultEntity.locationCode = at_l_Entity.S_LOC_CODE;
|
resultEntity.stockCode = at_l_Entity.S_WH_CODE;
|
|
return resultEntity;
|
}
|
|
#region 货位平均使用原则 只返回一个货位实体
|
/// <summary>
|
/// 货位平均使用原则
|
/// </summary>
|
/// <param name="lstTrueLocation">一个巷道内的所有货位数据</param>
|
/// <returns></returns>
|
public Location AverageBalance(List<Location> lstTrueLocation)
|
{
|
Location nearLocationEntity = new Location();
|
if (lstTrueLocation == null || lstTrueLocation.Count == 0)
|
{
|
return nearLocationEntity;
|
}
|
//按照排分组 并获得排中可用货位的数据
|
|
var v = lstTrueLocation.OrderBy(o => o.N_ROW).OrderByDescending(c => c.N_COL).ToList();//按照货位可用数量进行升序, 找到CN_N_INTASK_QTY最小的货位
|
|
nearLocationEntity = v.FirstOrDefault();
|
return nearLocationEntity;
|
}
|
#endregion
|
|
|
/// <summary>
|
/// 获取平库立库货架中最近的一个可用货位
|
/// </summary>
|
/// <param name="trayCode"></param>
|
/// <param name="lstDevice"></param>
|
/// <param name="lstTrueLocation"></param>
|
/// <returns></returns>
|
private InAssignResultEntity CalLocationByStraty(InAssignResultEntity resultEntity, List<Location> lstTrueLocation, List<Location> lstAllLocation, List<Location> lstLockLItem, bool lockLocation, LogicTrue logicModel)
|
{
|
List<Location> lstTmp_Location = new List<Location>();
|
#region 查询该库区配置的入库策略及优先级
|
List<TN_ArithmeticEntitys> lstStrategy = new List<TN_ArithmeticEntitys>();
|
var exp = Expressionable.Create<TN_ArithmeticEntitys>();
|
var chi = new SqlHelper<object>().GetInstance();
|
var newDb = chi.CopyNew();
|
// exp.And(it => it.S_WH_CODE == resultEntity.stockCode);
|
exp.And(it => it.S_AREA_CODE == resultEntity.areaCode);
|
exp.And(it => it.S_STRATEGY_TYPE == "入库");
|
exp.And(it => it.S_START_USING == "Y");
|
lstStrategy = newDb.Queryable<TN_ArithmeticEntitys>().Where(exp.ToExpression()).ToList();
|
// List<string> lstStrate = lstStrategy.OrderByDescending(a => a.I_PRIORITY).Select(o => o.S_STRATEGY_CODE).ToList();
|
#endregion
|
LogHelper.Info("入库算法", "循环前lstTmp_Location数据:" + JsonConvert.SerializeObject(lstTmp_Location));
|
lstTmp_Location = CalculateLocByStegy(lstTrueLocation, lstAllLocation, lstLockLItem, lstStrategy, logicModel);
|
LogHelper.Info("入库算法", "循环后lstTmp_Location数据:" + JsonConvert.SerializeObject(lstTmp_Location));
|
|
|
if (lstTmp_Location == null || lstTmp_Location.Count == 0)
|
{
|
resultEntity.Success = false;
|
resultEntity.errCode = "8";
|
resultEntity.Msg = "库区有空货位但启用算法策略后计算出货位不足";
|
return resultEntity;
|
}
|
Location at_l_Entity = lstTmp_Location[0];
|
if (lockLocation)
|
{
|
#region 锁定入库货位
|
newDb.BeginTran();
|
try
|
{
|
var I = newDb.Updateable<Location>().SetColumns(it => it.S_LOCK_STATE == "入库锁").Where(x => x.S_LOC_CODE == at_l_Entity.S_LOC_CODE && x.S_LOCK_STATE == "无").ExecuteCommand();
|
if (I == 0)
|
{
|
newDb.RollbackTran();
|
throw new System.Exception("锁定终点货位失败!");
|
}
|
newDb.CommitTran();
|
LogHelper.Info("入库算法", at_l_Entity.S_LOC_CODE + "货位更改为入库锁,锁定影响数据结果:" + I);
|
if (I > 0)
|
{
|
resultEntity.Success = true;
|
resultEntity.Msg = "";
|
resultEntity.locationCode = at_l_Entity.S_LOC_CODE;
|
resultEntity.stockCode = at_l_Entity.S_WH_CODE;
|
}
|
else
|
{
|
resultEntity.Success = false;
|
resultEntity.errCode = "5";
|
resultEntity.Msg = "锁定货位状态失败";
|
}
|
}
|
catch (Exception ex)
|
{
|
newDb.RollbackTran();
|
resultEntity.Success = false;
|
resultEntity.errCode = "5";
|
resultEntity.Msg = "锁定货位状态失败";
|
}
|
#endregion
|
}
|
else
|
{
|
resultEntity.Success = true;
|
resultEntity.Msg = "";
|
resultEntity.locationCode = at_l_Entity.S_LOC_CODE;
|
resultEntity.stockCode = at_l_Entity.S_WH_CODE;
|
}
|
return resultEntity;
|
}
|
|
/// <summary>
|
/// 根据入库策略筛选符合条件的货位
|
/// </summary>
|
/// <param name="lstDevice"></param>
|
/// <param name="lstLocation"></param>
|
/// <param name="lstStrate"></param>
|
/// <param name="deviceCode"></param>
|
/// <returns></returns>
|
public List<Location> CalculateLocByStegy(List<Location> lstLocation, List<Location> lstAllLocation, List<Location> lstLockLItem, List<TN_ArithmeticEntitys> lstStrategy, LogicTrue logicModel)
|
{
|
List<Location> lstFilterLoc = lstLocation;
|
List<Location> lstTmp = new List<Location>();
|
TN_ArithmeticEntitys Trctics = new TN_ArithmeticEntitys();
|
List<string> lstStrate = lstStrategy.OrderByDescending(a => a.I_PRIORITY).Select(o => o.S_STRATEGY_CODE).ToList();
|
foreach (string stegy in lstStrate)
|
{
|
//逐个策略进行计算
|
switch (stegy)
|
{
|
case "TaskNumberBalance"://任务均衡
|
lstFilterLoc = TaskNumberBalance(lstFilterLoc);
|
break;
|
case "RoadWayBalance": //巷道均衡
|
lstFilterLoc = RoadWayBalance(lstFilterLoc);
|
break;
|
case "NearByRoadWay": //巷道由近及远
|
lstFilterLoc = RoadWayBalance(lstFilterLoc);
|
break;
|
case "NearbyBalance": //就近原则
|
lstFilterLoc = NearbyBalance(lstFilterLoc);
|
break;
|
case "DistantBalance": //就远原则
|
lstFilterLoc = DistantBalance(lstFilterLoc);
|
break;
|
case "NearbyBalanceLayRe": //一左一右放
|
lstFilterLoc = NearbyBalanceLayRe(lstFilterLoc);
|
break;
|
case "NearbyBalanceRow": //排就近原则
|
lstFilterLoc = NearbyBalanceRow(lstFilterLoc);
|
break;
|
case "NearbyBalanceLay": //层就近原则
|
lstFilterLoc = NearbyBalanceLay(lstFilterLoc);
|
break;
|
case "EmptyFullPercentageBalance"://空满百分比均衡
|
lstFilterLoc = EmptyFullPercentageBalance(lstFilterLoc, logicModel);
|
break;
|
}
|
|
}
|
return lstFilterLoc;
|
}
|
#region 巷道均衡 返回巷道对应的货位列表
|
/// <summary>
|
/// 巷道均衡策略
|
/// </summary>
|
/// <param name="lstTrueLocation">可用的货位信息数据</param>
|
/// <returns>计算后返回的实体</returns>
|
public List<Location> RoadWayBalance(List<Location> lstTrueLocation)
|
{
|
//指定计算后返回的实体
|
List<Location> location_roadray = new List<Location>();
|
|
//按照巷道分组 并获得巷道中可用货位的数据
|
//之后进行倒叙 找到可用货位最多的巷道
|
var v = lstTrueLocation.GroupBy(x => x.N_ROADWAY).Select(g => (new
|
{
|
roadWay = g.Key,
|
qty = g.Count()
|
})).OrderByDescending(o => o.qty);
|
|
//倒叙排列后的巷道 循环
|
foreach (var item in v)
|
{
|
//取得巷道列表中可用货位最多的巷道 并获取巷道中所有货位
|
location_roadray = lstTrueLocation.Where(o => o.N_ROADWAY == item.roadWay).ToList();
|
|
if (location_roadray != null && location_roadray.Count > 0)
|
{
|
break;
|
}
|
}
|
return location_roadray;
|
}
|
#endregion
|
#region 任务数均衡
|
/// <summary>
|
/// 任务数均衡
|
/// </summary>
|
/// <param name="lstTrueLocation"></param>
|
/// <returns></returns>
|
public List<Location> TaskNumberBalance(List<Location> lstTrueLocation)
|
{
|
var model = lstTrueLocation.FirstOrDefault();
|
var Roadray = lstTrueLocation.Select(e => e.N_ROADWAY).Distinct().ToList();
|
var Inloca = Expressionable.Create<Location>();
|
Inloca.And(it => it.S_WH_CODE == model.S_WH_CODE);
|
Inloca.And(it => it.S_AREA_CODE == model.S_AREA_CODE);
|
Inloca.And(it => Roadray.Contains(it.N_ROADWAY));
|
Inloca.And(it => it.S_LOCK_STATE == "入库锁");
|
var locationInLock = SqlSugarHelper.Db.Queryable<Location>().Where(Inloca.ToExpression()).ToList();
|
//LogHelper.Info("入库算法", "查询入库锁的数据:" + JsonConvert.SerializeObject(locationInLock));
|
if (locationInLock.Count() == 0)
|
{
|
return lstTrueLocation;
|
}
|
else
|
{
|
var InLock = locationInLock.Select(e => e.N_ROADWAY).Distinct().ToList();
|
// LogHelper.Info("入库算法", "筛序出第一次出现的接驳位 (分组):" + JsonConvert.SerializeObject(InLock));
|
var ffr = Roadray.Except(InLock).ToList();
|
// LogHelper.Info("入库算法", "筛序出 所有入库的巷道和有任务的巷道的差集:" + JsonConvert.SerializeObject(ffr));
|
if (ffr.Count > 0)
|
{
|
var lstTLocation = lstTrueLocation.FindAll(e => ffr.Contains(e.N_ROADWAY)).ToList();
|
// LogHelper.Info("入库算法", "筛序出--所有入库的巷道和有任务的巷道的差集所在的巷道的货位:" + JsonConvert.SerializeObject(lstTLocation));
|
if (lstTLocation.Count() > 0)
|
{
|
return lstTLocation;
|
}
|
else
|
{
|
return lstTrueLocation;
|
}
|
}
|
else
|
{
|
var gg = locationInLock.GroupBy(x => x.N_ROADWAY).Select(g => (new
|
{
|
roadWay = g.Key,
|
qty = g.Count()
|
})).OrderBy(o => o.qty).ToList();
|
// LogHelper.Info("入库算法", "筛选出--没有差集则进行分组算任务量:" + JsonConvert.SerializeObject(gg));
|
var v = locationInLock.GroupBy(x => x.N_ROADWAY).Select(g => (new
|
{
|
roadWay = g.Key,
|
qty = g.Count()
|
})).OrderBy(o => o.qty).ToList().FirstOrDefault();
|
// LogHelper.Info("入库算法", "筛选出--没有差集则进行分组算任务量 排序取第一个:" + JsonConvert.SerializeObject(v));
|
var lseLocation = lstTrueLocation.FindAll(e => e.N_ROADWAY == v.roadWay).ToList();
|
// LogHelper.Info("入库算法", "筛选出--查询出筛选出的第一个巷道的所有货位数据:" + JsonConvert.SerializeObject(lseLocation));
|
if (lseLocation.Count() > 0)
|
{
|
return lseLocation;
|
}
|
return lstTrueLocation;
|
}
|
}
|
}
|
#endregion
|
#region 就近原则 只返回一个货位实体
|
/// <summary>
|
/// 就近原则
|
/// </summary>
|
/// <param name="lstTrueLocation">一个巷道内的所有货位数据</param>
|
/// <returns></returns>
|
public List<Location> NearbyBalance(List<Location> lstTrueLocation)
|
{
|
List<Location> lstNearLocation = new List<Location>();
|
if (lstTrueLocation == null || lstTrueLocation.Count == 0)
|
{
|
return lstNearLocation;
|
}
|
//先判断是否存在多个巷道,如果存在就近选择一个巷道
|
var location_roadray = lstTrueLocation.OrderBy(o => o.N_ROADWAY).Select(o => o.N_ROADWAY).Distinct().ToList();
|
if (location_roadray != null && location_roadray.Count > 1)
|
{
|
lstTrueLocation = lstTrueLocation.Where(o => o.N_ROADWAY == location_roadray[0]).ToList();
|
}
|
//找到最小的列
|
var v_col = lstTrueLocation.OrderBy(o => o.N_ROW).ThenBy(o => o.N_COL).ToList();
|
//找到一个排下最小的列对应的所有货位 找层
|
var v_f = v_col.Where(o => o.N_COL == v_col[0].N_COL && o.N_ROW == v_col[0].N_ROW).OrderBy(o => o.N_LAYER).ToList();
|
//找到符合条件的层的内侧
|
var v_side = v_f.Where(o => o.N_LAYER == v_f[0].N_LAYER).OrderByDescending(o => o.N_SIDE).ToList();
|
var max_side = v_side[0].N_SIDE;
|
//获得侧最大的货位
|
lstNearLocation.Add(v_side.Where(o => o.N_SIDE == max_side).FirstOrDefault());
|
return lstNearLocation;
|
}
|
#endregion
|
|
|
public List<Location> NearbyBalanceLayRe(List<Location> lstTrueLocation)
|
{
|
List<Location> lstNearLocation = new List<Location>();
|
if (lstTrueLocation == null || lstTrueLocation.Count == 0)
|
{
|
return lstNearLocation;
|
}
|
//先判断是否存在多个巷道,如果存在就近选择一个巷道
|
var location_roadray = lstTrueLocation.OrderBy(o => o.N_ROADWAY).Select(o => o.N_ROADWAY).Distinct().ToList();
|
if (location_roadray != null && location_roadray.Count > 1)
|
{
|
lstTrueLocation = lstTrueLocation.Where(o => o.N_ROADWAY == location_roadray[0]).ToList();
|
}
|
var v_col = lstTrueLocation.OrderBy(e => e.N_LAYER).ThenByDescending(o => o.N_SIDE).ThenBy(e => e.N_ROW).ThenBy(o => o.N_COL).ToList();
|
//LogHelper.Info("入库算法", "排序后:" + JsonConvert.SerializeObject(v_col));
|
//获得侧最大的货位
|
lstNearLocation.Add(v_col.FirstOrDefault());
|
return lstNearLocation;
|
}
|
|
#region 就远原则 只返回一个货位实体
|
/// <summary>
|
/// 就远原则
|
/// </summary>
|
/// <param name="lstTrueLocation">一个巷道内的所有货位数据</param>
|
/// <returns></returns>
|
public List<Location> DistantBalance(List<Location> lstTrueLocation)
|
{
|
List<Location> lstNearLocation = new List<Location>();
|
if (lstTrueLocation == null || lstTrueLocation.Count == 0)
|
{
|
return lstNearLocation;
|
}
|
//先判断是否存在多个巷道,如果存在就近选择一个巷道
|
var location_roadray = lstTrueLocation.OrderBy(o => o.N_ROADWAY).Select(o => o.N_ROADWAY).Distinct().ToList();
|
if (location_roadray != null && location_roadray.Count > 1)
|
{
|
var len = location_roadray.Count - 1;
|
lstTrueLocation = lstTrueLocation.Where(o => o.N_ROADWAY == location_roadray[len]).ToList();
|
}
|
//找到最大的列
|
var v_col = lstTrueLocation.OrderByDescending(o => o.N_ROW).ThenByDescending(o => o.N_COL).ToList();
|
//找到一个排下最小的列对应的所有货位 找层
|
var v_f = v_col.Where(o => o.N_COL == v_col[0].N_COL && o.N_ROW == v_col[0].N_ROW).OrderBy(o => o.N_LAYER).ToList();
|
//找到符合条件的层的内侧
|
var v_side = v_f.Where(o => o.N_LAYER == v_f[0].N_LAYER).OrderByDescending(o => o.N_SIDE).ToList();
|
var max_side = v_side[0].N_SIDE;
|
//获得侧最大的货位
|
lstNearLocation.Add(v_side.Where(o => o.N_SIDE == max_side).FirstOrDefault());
|
return lstNearLocation;
|
}
|
#endregion
|
|
public List<Location> NearbyBalanceRow(List<Location> lstTrueLocation)
|
{
|
List<Location> lstNearLocation = new List<Location>();
|
if (lstTrueLocation == null || lstTrueLocation.Count == 0)
|
{
|
return lstNearLocation;
|
}
|
//先判断是否存在多个巷道,如果存在就近选择一个巷道
|
var location_row = lstTrueLocation.OrderBy(o => o.N_ROW).Select(o => o.N_ROW).Distinct().ToList();
|
|
//找到排空货位最多的排
|
var v_row = lstTrueLocation.Where(o => o.N_ROW == location_row[0]).ToList();
|
|
//找到最小的列
|
var v_col = v_row.OrderBy(o => o.N_COL).ToList();
|
var min_col = v_col[0].N_COL;
|
|
//找到一个排下最小的列对应的所有货位
|
var v_f = v_row.Where(o => o.N_COL == min_col).OrderBy(o => o.N_LAYER).ToList();
|
|
//先按照层倒叙取最小的层
|
var min_floor = v_f[0].N_LAYER;
|
|
//获得层最小的单个
|
lstNearLocation.Add(v_f.Where(o => o.N_LAYER == min_floor).FirstOrDefault());
|
return lstNearLocation;
|
}
|
|
|
public List<Location> NearbyBalanceLay(List<Location> lstTrueLocation)
|
{
|
List<Location> lstNearLocation = new List<Location>();
|
if (lstTrueLocation == null || lstTrueLocation.Count == 0)
|
{
|
return lstNearLocation;
|
}
|
//先判断是否存在多个巷道,如果存在就近选择一个巷道
|
var location_roadray = lstTrueLocation.OrderBy(o => o.N_ROADWAY).Select(o => o.N_ROADWAY).Distinct().ToList();
|
if (location_roadray != null && location_roadray.Count > 1)
|
{
|
lstTrueLocation = lstTrueLocation.Where(o => o.N_ROADWAY == location_roadray[0]).ToList();
|
}
|
//找到最小的排 层 侧
|
var v_col = lstTrueLocation.OrderBy(o => o.N_ROW).ThenBy(o => o.N_LAYER).ThenByDescending(e => e.N_SIDE).ThenBy(e => e.N_COL).ToList();
|
//获得侧最大的货位
|
lstNearLocation.Add(v_col.FirstOrDefault());
|
return lstNearLocation;
|
}
|
public static int I = 0;
|
public List<Location> EmptyFullPercentageBalance(List<Location> lstTrueLocation, LogicTrue logicModel)
|
{
|
var chi = new SqlHelper<object>().GetInstance();
|
var newDb = chi.CopyNew();
|
Dictionary<int, double> percentage = new Dictionary<int, double>();
|
var location_roadray = lstTrueLocation.OrderBy(o => o.N_ROADWAY).Select(o => o.N_ROADWAY).Distinct().ToList();
|
if (logicModel != null && logicModel?.lstLocationCode?.Count() > 0)
|
{
|
var Inloca = Expressionable.Create<Location>();
|
Inloca.And(it => logicModel.lstLocationCode.Contains(it.S_LOC_CODE));
|
Inloca.And(it => it.C_ENABLE == "Y");
|
var locationInLock = newDb.Queryable<Location>().Where(Inloca.ToExpression()).ToList();
|
foreach (var item in location_roadray)
|
{
|
LogHelper.Info("入库算法", $"开始巷道:{item}");
|
var ggf = lstTrueLocation.FindAll(e => e.N_ROADWAY == item).ToList();//空货位数
|
var ffg = locationInLock.FindAll(e => e.N_ROADWAY == item).ToList();//总货位数
|
LogHelper.Info("入库算法", $"空货位数:{ggf.Count()}");
|
LogHelper.Info("入库算法", $"总货位数:{ffg.Count()}");
|
double Bfb = ((double)ggf.Count() / (double)ffg.Count()) * 100;
|
// var ff = Math.Round(Bfb, 2);
|
LogHelper.Info("入库算法", $"巷道:{item} 空满比例{Bfb}%");
|
percentage.Add(item, Bfb);
|
}
|
}
|
else
|
{
|
var model = lstTrueLocation.FirstOrDefault();
|
var Roadray = lstTrueLocation.Select(e => e.N_ROADWAY).Distinct().ToList();
|
var Inloca = Expressionable.Create<Location>();
|
Inloca.And(it => it.S_WH_CODE == model.S_WH_CODE);
|
Inloca.And(it => it.S_AREA_CODE == model.S_AREA_CODE);
|
Inloca.And(it => it.C_ENABLE == "Y");
|
var locationInLock = newDb.Queryable<Location>().Where(Inloca.ToExpression()).ToList();
|
foreach (var item in location_roadray)
|
{
|
LogHelper.Info("入库算法", $"开始巷道:{item}");
|
var ggf = lstTrueLocation.FindAll(e => e.N_ROADWAY == item).ToList();//空货位数
|
var ffg = locationInLock.FindAll(e => e.N_ROADWAY == item).ToList();//总货位数
|
LogHelper.Info("入库算法", $"空货位数:{ggf.Count()}");
|
LogHelper.Info("入库算法", $"总货位数:{ffg.Count()}");
|
double Bfb = ((double)ggf.Count() / (double)ffg.Count()) * 100;
|
// var ff = Math.Round(Bfb, 2);
|
LogHelper.Info("入库算法", $"巷道:{item} 空满比例{Bfb}%");
|
percentage.Add(item, Bfb);
|
}
|
}
|
if (lstTrueLocation.FirstOrDefault()?.S_AREA_CODE == "LC11T")
|
{
|
LogHelper.Info("入库算法", $"库区编码:LC11T 判断是否超过阈值");
|
//判断两个巷道的空满比值 查看字段第一条数据是否是大于0
|
var Bz = percentage.OrderBy(e => e.Value).ToDictionary(x => x.Key, x => x.Value).FirstOrDefault();
|
LogHelper.Info("入库算法", $"空货位少的巷道是{Bz.Key} 有空货位(空满比值) {Bz.Value}");
|
var BzT = percentage.OrderBy(e => e.Value).ToDictionary(x => x.Key, x => x.Value).LastOrDefault();
|
LogHelper.Info("入库算法", $"空货位多的巷道是{BzT.Key} 有空货位(空满比值){BzT.Value}");
|
if (Bz.Value > 0 && BzT.Value > 0)
|
{
|
if (Bz.Value <= 20) //查询最小的值是否小于等于20
|
{
|
LogHelper.Info("入库算法", $"空货位少的巷道是{BzT.Key} 有空货位(空满比值){BzT.Value} 小于等于20% 启动任务比值均衡算法(自动)");
|
double BzNumb = Math.Round((double)Bz.Value / BzT.Value * 100, 0);
|
LogHelper.Info("入库算法", $"两个巷道的空货位比值为 {BzNumb}% 换算成百分比 1/2就是50% 1/3就是33%");
|
var model = lstTrueLocation.FirstOrDefault();
|
var Roadray = lstTrueLocation.Select(e => e.N_ROADWAY).Distinct().ToList();
|
var Inloca = Expressionable.Create<Location>();
|
Inloca.And(it => it.S_WH_CODE == model.S_WH_CODE);
|
Inloca.And(it => it.S_AREA_CODE == model.S_AREA_CODE);
|
Inloca.And(it => Roadray.Contains(it.N_ROADWAY));
|
Inloca.And(it => it.S_LOCK_STATE == "入库锁");
|
var locationInLock = newDb.Queryable<Location>().Where(Inloca.ToExpression()).ToList();
|
if (BzNumb <= 25)
|
{
|
LogHelper.Info("入库算法", $"比值小于等于25 则按照最大比例1/4下达任务 ");
|
// 1/4
|
var OneTask = locationInLock.FindAll(e => e.N_ROADWAY == BzT.Key).ToList();
|
LogHelper.Info("入库算法", $"空货位最多的巷道{BzT.Key} 任务数为:{OneTask.Count()}");
|
var TwoTask = locationInLock.FindAll(e => e.N_ROADWAY == Bz.Key).ToList();
|
LogHelper.Info("入库算法", $"空货位最少的巷道{Bz.Key} 任务数为:{TwoTask.Count()}");
|
if (OneTask.Count() <= 3)
|
{
|
lstTrueLocation = lstTrueLocation.FindAll(e => e.N_ROADWAY == BzT.Key).ToList();
|
return lstTrueLocation;
|
}
|
else
|
{
|
if (TwoTask.Count() == 0)//
|
{
|
lstTrueLocation = lstTrueLocation.FindAll(e => e.N_ROADWAY == Bz.Key).ToList();
|
return lstTrueLocation;
|
}
|
else
|
{
|
if (OneTask.Count() / 4 == TwoTask.Count())//空货位少的/空货位多的 看是否大于25%大于则下到空货位多的 否则下到空货位少的
|
{
|
lstTrueLocation = lstTrueLocation.FindAll(e => e.N_ROADWAY == BzT.Key).ToList();
|
return lstTrueLocation;
|
}
|
else
|
{
|
lstTrueLocation = lstTrueLocation.FindAll(e => e.N_ROADWAY == Bz.Key).ToList();
|
return lstTrueLocation;
|
}
|
}
|
}
|
}
|
else if (25 < BzNumb && BzNumb <= 33)
|
{
|
// 1/3
|
LogHelper.Info("入库算法", $"比值大于25小于等于33 则按照最大比例1/3下达任务 ");
|
var OneTask = locationInLock.FindAll(e => e.N_ROADWAY == BzT.Key).ToList();
|
LogHelper.Info("入库算法", $"空货位最多的巷道{BzT.Key} 任务数为:{OneTask.Count()}");
|
var TwoTask = locationInLock.FindAll(e => e.N_ROADWAY == Bz.Key).ToList();
|
LogHelper.Info("入库算法", $"空货位最少的巷道{BzT.Key} 任务数为:{TwoTask.Count()}");
|
if (OneTask.Count() <= 2)
|
{
|
lstTrueLocation = lstTrueLocation.FindAll(e => e.N_ROADWAY == BzT.Key).ToList();
|
return lstTrueLocation;
|
}
|
else
|
{
|
if (TwoTask.Count() == 0)//
|
{
|
lstTrueLocation = lstTrueLocation.FindAll(e => e.N_ROADWAY == Bz.Key).ToList();
|
return lstTrueLocation;
|
}
|
else
|
{
|
if (OneTask.Count() / 3 == TwoTask.Count())
|
{
|
lstTrueLocation = lstTrueLocation.FindAll(e => e.N_ROADWAY == BzT.Key).ToList();
|
return lstTrueLocation;
|
}
|
else
|
{
|
lstTrueLocation = lstTrueLocation.FindAll(e => e.N_ROADWAY == Bz.Key).ToList();
|
return lstTrueLocation;
|
}
|
}
|
}
|
}
|
else if (33 < BzNumb && BzNumb <= 50)
|
{
|
// 1/2
|
LogHelper.Info("入库算法", $"比值大于33小于等于50 则按照最大比例1/2下达任务 ");
|
var OneTask = locationInLock.FindAll(e => e.N_ROADWAY == BzT.Key).ToList();
|
LogHelper.Info("入库算法", $"空货位最多的巷道{BzT.Key} 任务数为:{OneTask.Count()}");
|
var TwoTask = locationInLock.FindAll(e => e.N_ROADWAY == Bz.Key).ToList();
|
LogHelper.Info("入库算法", $"空货位最少的巷道{BzT.Key} 任务数为:{TwoTask.Count()}");
|
if (OneTask.Count() <= 1)
|
{
|
lstTrueLocation = lstTrueLocation.FindAll(e => e.N_ROADWAY == BzT.Key).ToList();
|
return lstTrueLocation;
|
}
|
else
|
{
|
if (TwoTask.Count() == 0)//
|
{
|
lstTrueLocation = lstTrueLocation.FindAll(e => e.N_ROADWAY == Bz.Key).ToList();
|
return lstTrueLocation;
|
}
|
else
|
{
|
if (OneTask.Count() / 2 == TwoTask.Count())
|
{
|
lstTrueLocation = lstTrueLocation.FindAll(e => e.N_ROADWAY == BzT.Key).ToList();
|
return lstTrueLocation;
|
}
|
else
|
{
|
lstTrueLocation = lstTrueLocation.FindAll(e => e.N_ROADWAY == Bz.Key).ToList();
|
return lstTrueLocation;
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
var abc = percentage.OrderByDescending(e => e.Value).ToDictionary(x => x.Key, x => x.Value);
|
var roa = abc.First().Key;
|
lstTrueLocation = lstTrueLocation.FindAll(e => e.N_ROADWAY == roa).ToList();
|
return lstTrueLocation;
|
}
|
}
|
}
|