using HH.WMS.BLL.Common;
|
using HH.WMS.Common;
|
using HH.WMS.Common.Algorithm;
|
using HH.WMS.DAL.Algorithm;
|
using HH.WMS.DAL.Basic;
|
using HH.WMS.Entitys.Algorithm;
|
using HH.WMS.Entitys.Basic;
|
using HH.WMS.Entitys.Common;
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Text;
|
using System.Threading.Tasks;
|
using HH.WMS.DAL.InStock;
|
using Newtonsoft.Json;
|
using HH.WMS.Entitys.Autobom;
|
using HH.WMS.Entitys;
|
using HH.WMS.Entitys.Sys;
|
|
|
|
|
namespace HH.WMS.BLL.Algorithm
|
{
|
/// <summary>
|
/// 入库算法业务层
|
/// </summary>
|
public class In_AlgorBLL : BaseBLL
|
{
|
/**************非作业区入库算法(平库、立库) 开始/**************/
|
#region 非作业区 入库算法
|
/// <summary>
|
/// 入库算法
|
/// </summary>
|
/// <param name="model"></param>
|
public InResultEntity In(InAlgorEnitty model)
|
{
|
Log.AlgorInfo("In", "入库算法参数:" + JsonConvert.SerializeObject(model));
|
//定义返回实体
|
InResultEntity resultEntity = new InResultEntity();
|
resultEntity.Success = false;
|
resultEntity.Msg = "库区货位不足";
|
#region 传入参数判断
|
//判断参数实体
|
if (model == null)
|
{
|
resultEntity.Success = false;
|
resultEntity.Msg = "参数实体不能为 null !";
|
return resultEntity;
|
}
|
//判断库区不能为空
|
if (string.IsNullOrEmpty(model.stockAreaCode))
|
{
|
resultEntity.Success = false;
|
resultEntity.Msg = "库区编码不能为空!";
|
return resultEntity;
|
}
|
//判断托盘码不能为空
|
//if (string.IsNullOrEmpty(model.trayCode))
|
//{
|
// resultEntity.Success = false;
|
// resultEntity.Msg = "托盘码不能为空!";
|
// return resultEntity;
|
//}
|
//必须指定获取的货位数量
|
if (model.locationQty == 0)
|
{
|
resultEntity.Success = false;
|
resultEntity.Msg = "请指定获取货位的数量!";
|
return resultEntity;
|
}
|
#endregion
|
//获取该库区结构类型(流离式、平库、立库)
|
string areaType = CreateDAL<TN_WMS_AREADAL>().GetAreaTypeByCode(model.stockAreaCode);
|
List<Device> lstDevice = model.lstDevice;
|
if (areaType == "平库" || areaType == "立库")
|
{
|
|
if (!string.IsNullOrEmpty(model.itemCode))
|
{
|
//指定物料
|
resultEntity = In_ItemCode(model.itemCode, model.logicCode, model.stockAreaCode, model.locationQty, model.lstDevice, model.lockLocation);
|
}
|
else
|
{
|
//不指定物料,空托盘入库
|
resultEntity = In_TrayCode(model.stockAreaCode, model.logicCode, model.locationQty, model.lstDevice, model.lockLocation);
|
}
|
}
|
Log.AlgorInfo("In—算法结束", "计算结果:" + JsonConvert.SerializeObject(resultEntity));
|
return resultEntity;
|
}
|
#endregion
|
|
#region 非作业区 平库立库入库算法
|
#region 非作业区立库入库算法 指定物料(通过库区关联逻辑分区,物料关联逻辑分区)
|
/// <summary>
|
/// 入库 指定物料(通过库区关联逻辑分区,物料关联逻辑分区)
|
/// </summary>
|
/// <param name="itemCode">物料编码</param>
|
/// <param name="logicCode">逻辑分区编码</param>
|
/// <param name="stockAreaCode">库区编码</param>
|
/// <param name="locationQty">需要货位的数量</param>
|
/// <param name="lstDevice">设备信息 AMS给出</param>
|
/// <returns></returns>
|
private InResultEntity In_ItemCode(string itemCode, string logicCode, string stockAreaCode, int locationQty, List<Device> lstDevice, bool lockLocation)
|
{
|
InResultEntity resultEntity = new InResultEntity();
|
//需要纳入计算的逻辑分区集合
|
List<LogicTrue> lstLogic = new List<LogicTrue>();
|
string logicCheckMsg = string.Empty;
|
//如果逻辑分区为空
|
if (string.IsNullOrEmpty(logicCode))
|
{
|
|
lstLogic = GetLogicList(itemCode, stockAreaCode, out logicCheckMsg);
|
if (!string.IsNullOrEmpty(logicCheckMsg))
|
{
|
resultEntity.Success = false;
|
resultEntity.Msg = logicCheckMsg;
|
return resultEntity;
|
}
|
|
}
|
else//逻辑分区不为空
|
{
|
#region 固定逻辑分区和库区
|
//将逻辑分区编码转换成List
|
List<string> lstLogics = new List<string>(logicCode.Split(new string[] { ", " }, StringSplitOptions.RemoveEmptyEntries));
|
//通过逻辑分区编码集合以及库区编码获得逻辑分区仓库/库区/货位关联
|
List<AutoBomAreaLocation_REntity> lstLogicEntityByArea = CreateDAL<TN_WMS_AREADAL>().GetLogicListByLogicAndArea(lstLogics, stockAreaCode);
|
lstLogic = lstLogicEntityByArea.Select(o => new LogicTrue
|
{
|
stockCode = o.CN_S_STOCK_CODE,
|
areaCode = o.CN_S_STOCK_AREA,
|
locationCode = o.CN_S_LOCATION_CODE,
|
stockarea_position = o.CN_S_PRIORITY,
|
type = o.CN_N_TYPE
|
}).OrderBy(o => o.stockarea_position).ToList();
|
if (lstLogic == null || lstLogic.Count == 0)
|
{
|
resultEntity.Success = false;
|
resultEntity.Msg = "根据逻辑分区编码集合以及库区编码未获得对应的逻辑分区!";
|
return resultEntity;
|
}
|
#endregion
|
}
|
|
//调用通过逻辑分区取货位的算法
|
List<locationEntity> lstLocations = AlgorIn(stockAreaCode, locationQty, lstDevice, lstLogic, lockLocation);
|
if (lstLocations != null && lstLocations.Count > 0)
|
{
|
resultEntity.Success = true;
|
resultEntity.lstLocation = lstLocations;
|
}
|
else
|
{
|
resultEntity.Success = false;
|
resultEntity.Msg = "计算未得到货位!";
|
}
|
return resultEntity;
|
}
|
#endregion
|
#region 非作业区立库入库算法 不指定物料(直接通过库区计算货位)
|
/// <summary>
|
/// 入库 不指定物料(直接通过库区对应逻辑分区计算货位)
|
/// </summary>
|
/// <param name="trayCode"></param>
|
/// <param name="stockAreaCode"></param>
|
/// <param name="locationQty"></param>
|
/// <param name="lstDevice"></param>
|
/// <returns></returns>
|
private InResultEntity In_TrayCode(string stockAreaCode, string logicCode, int locationQty, List<Device> lstDevice, bool lockLocation)
|
{
|
//返回类型
|
InResultEntity resultEntity = new InResultEntity();
|
//需要纳入计算的逻辑分区集合
|
List<LogicTrue> lstLogic = new List<LogicTrue>();
|
//如果逻辑分区不为空
|
if (!string.IsNullOrEmpty(logicCode))
|
{
|
|
List<string> lstLogics = new List<string>(logicCode.Split(new string[] { ", " }, StringSplitOptions.RemoveEmptyEntries));
|
//通过逻辑分区编码集合以及库区编码获得逻辑分区仓库/库区/货位关联
|
List<AutoBomAreaLocation_REntity> lstLogicEntityByArea = CreateDAL<TN_WMS_AREADAL>().GetLogicListByLogicAndArea(lstLogics, stockAreaCode);
|
lstLogic = lstLogicEntityByArea.Select(o => new LogicTrue
|
{
|
stockCode = o.CN_S_STOCK_CODE,
|
areaCode = o.CN_S_STOCK_AREA,
|
locationCode = o.CN_S_LOCATION_CODE,
|
stockarea_position = o.CN_S_PRIORITY,
|
type = o.CN_N_TYPE
|
}).OrderBy(o => o.stockarea_position).ToList();
|
if (lstLogic == null || lstLogic.Count == 0)
|
{
|
resultEntity.Success = false;
|
resultEntity.Msg = "根据逻辑分区编码集合以及库区编码未获得对应的逻辑货位!";
|
return resultEntity;
|
}
|
|
}
|
else
|
{
|
LogicTrue logicModel = new LogicTrue();
|
logicModel.areaCode = stockAreaCode;
|
logicModel.item_position = "1";
|
logicModel.locationCode = "";
|
logicModel.stockarea_position = "1";
|
logicModel.stockCode = "";
|
logicModel.type = 2;
|
lstLogic.Add(logicModel);
|
}
|
List<locationEntity> lstLocations = AlgorIn(stockAreaCode, locationQty, lstDevice, lstLogic, lockLocation);
|
|
|
if (lstLocations != null && lstLocations.Count > 0)
|
{
|
resultEntity.Success = true;
|
resultEntity.lstLocation = lstLocations;
|
}
|
else
|
{
|
resultEntity.Success = false;
|
resultEntity.Msg = "计算未得到货位!";
|
}
|
return resultEntity;
|
}
|
#endregion
|
#region 非作业区立库入库算法 通过逻辑分区计算符合条件的货位信息(指定物料专用)
|
/// <summary>
|
/// 计算 通过逻辑分区计算符合条件的货位信息(指定物料专用)
|
/// </summary>
|
/// <param name="locationQty">获得空位的数量</param>
|
/// <param name="lstDevice">设备信息</param>
|
/// <param name="lstLogic">逻辑分区详细</param>
|
/// <returns></returns>
|
private List<locationEntity> AlgorIn(string areaCode, int locationQty, List<Device> lstDevice, List<LogicTrue> lstLogic, bool lockLocation)
|
{
|
//货位列表
|
List<locationEntity> lstLocations = new List<locationEntity>();
|
|
//循环逻辑分区关联的仓库/库区/货位
|
foreach (LogicTrue logicEntity in lstLogic)
|
{
|
//获得真实可用的货位数据
|
Log.AlgorInfo("In_AlgorBLL-AlgorIn", "logicEntity实体数据" + JsonConvert.SerializeObject(logicEntity));
|
List<AutoBomLocationAbbreEntity> lstTrueLocation = GetLocationByArea_R(logicEntity);
|
Log.AlgorInfo("In_AlgorBLL-AlgorIn", "获得真实可用的货位数据结束" + lstTrueLocation.Count);
|
if (lstTrueLocation == null || lstTrueLocation.Count == 0)
|
{
|
continue;
|
}
|
//需要货位的数量 = 前台传递需要的数量-已获得数量
|
int GetQty = locationQty - lstLocations.Count;
|
//添加货位
|
lstLocations.AddRange(GetLocationsByStrategyAlgor(areaCode, GetQty, ref lstDevice, ref lstTrueLocation, lockLocation));
|
|
//如果货位数量足够 则结束循环
|
if (lstLocations.Count >= locationQty)
|
{
|
break;
|
}
|
}
|
return lstLocations;
|
}
|
#endregion
|
#region 非作业区立库入库算法 利用入库策略计算得到货位列表(公用)
|
/// <summary>
|
/// 利用入库策略计算得到货位列表(公用)
|
/// </summary>
|
/// <param name="locationQty"></param>
|
/// <param name="lstDevice"></param>
|
/// <param name="lstTrueLocation"></param>
|
/// <returns></returns>
|
public List<locationEntity> GetLocationsByStrategyAlgor(string areaCode, int locationQty, ref List<Device> lstDevice, ref List<AutoBomLocationAbbreEntity> lstTrueLocation, bool lockLocation)
|
{
|
#region 查询该库区配置的入库策略及优先级
|
List<STRATEGYALGOREntity> lstStrategy = new List<STRATEGYALGOREntity>();
|
lstStrategy = CreateDAL<TN_WM_B_STRATEGYDAL>().GetStrateListByAreaOrStock("", areaCode, "入库");
|
List<string> lstStrate = lstStrategy.OrderByDescending(a => a.CN_N_PRIORITY).Select(o => o.CN_S_CODE).ToList();
|
#endregion
|
//策略实体
|
AlgorTacticsCommon Trctics = new AlgorTacticsCommon();
|
List<AutoBomLocationAbbreEntity> lstTmp_Location = new List<AutoBomLocationAbbreEntity>();
|
//返回货位实体列表
|
List<locationEntity> lstLocations = new List<locationEntity>();
|
|
for (int i = 0; i < locationQty; i++)
|
{
|
locationEntity l_Entity = new locationEntity();
|
string deviceCode = string.Empty;
|
lstTmp_Location = CalculateLocByStegy(ref lstDevice, lstTrueLocation, lstStrate, out deviceCode);
|
//如果没有可计算的货位 则直接结束循环
|
if (lstTmp_Location == null || lstTmp_Location.Count == 0)
|
{
|
break;
|
}
|
string location_true = lstTmp_Location[0].CN_S_LOCATION_CODE;//货位编码
|
int agv_location_true = lstTmp_Location[0].CN_N_AGV_LOCATION;//对应AGV编号
|
//更新货位状态
|
if (lockLocation)
|
{
|
SqlExecuteResult result = CreateDAL<TN_WM_LOCATION_EXTDAL>().UpdateLocationState(location_true, Constants.Location_State_InLock, "入库", null);
|
Log.AlgorInfo("更新货位状态-UpdateLocationState", "货位" + location_true + "更改为预入库锁定,执行结果为:" + result.Success.ToString() + result.Row.ToString());
|
if (result.Success && result.Row > 0)
|
{
|
l_Entity.locationCode = location_true;//货位编码
|
l_Entity.avcLocationCode = agv_location_true;//对应AGV编号
|
//新增计算得到的货位
|
lstLocations.Add(l_Entity);
|
if (!string.IsNullOrEmpty(deviceCode))
|
{
|
//增加设备任务数
|
lstDevice = lstDevice.Select(o =>
|
{
|
o.taskNum = o.deviceCode == deviceCode ? o.taskNum + 1 : o.taskNum;
|
return o;
|
}).ToList();
|
}
|
}
|
}
|
else
|
{
|
l_Entity.locationCode = location_true;//货位编码
|
l_Entity.avcLocationCode = agv_location_true;//对应AGV编号
|
//新增计算得到的货位
|
lstLocations.Add(l_Entity);
|
}
|
|
//删除已经添加的货位
|
lstTrueLocation.RemoveAll(o => o.CN_S_LOCATION_CODE == location_true);
|
}
|
|
//如果未获得足够的货位并且可用货位还存在
|
if (lstLocations.Count < locationQty && lstTrueLocation.Count > 0)
|
{
|
//重新定义数量=前台传递过来的货位数-已获得的货位数量
|
int qty = locationQty - lstLocations.Count;
|
lstLocations.AddRange(GetLocationsByStrategyAlgor(areaCode, qty, ref lstDevice, ref lstTrueLocation, lockLocation));
|
}
|
return lstLocations;
|
}
|
#endregion
|
#region 根据策略及优先级计算货位
|
public List<AutoBomLocationAbbreEntity> CalculateLocByStegy(ref List<Device> lstDevice, List<AutoBomLocationAbbreEntity> lstLocation, List<string> lstStrate, out string deviceCode)
|
{
|
List<AutoBomLocationAbbreEntity> lstFilterLoc = lstLocation;
|
deviceCode = string.Empty;
|
//策略实体
|
AlgorTacticsCommon Trctics = new AlgorTacticsCommon();
|
foreach (string stegy in lstStrate)
|
{
|
//逐个策略进行计算
|
switch (stegy)
|
{
|
|
case "EquipmentBalance": //设备均衡
|
lstFilterLoc = Trctics.EquipmentBalance(lstDevice, lstFilterLoc, out deviceCode);
|
break;
|
case "RoadWayBalance": //巷道均衡
|
lstFilterLoc = Trctics.RoadWayBalance(lstFilterLoc); ;
|
break;
|
case "NearbyBalance": //就近原则
|
lstFilterLoc = Trctics.NearbyBalance(lstFilterLoc); ;
|
break;
|
|
}
|
|
}
|
return lstFilterLoc;
|
}
|
|
#endregion
|
#endregion
|
/**************非作业区入库算法(可处理流离式、平库、立库)结束/**************/
|
#region 公用方法 根据物料、库区与逻辑分区的对应关系求交集
|
public List<LogicTrue> GetLogicList(string itemCode, string stockAreaCode, out string errMsg)
|
{
|
errMsg = "";
|
#region 通过物料取逻辑分区 逻辑分区关联物料
|
//需要纳入计算的逻辑分区集合
|
List<LogicTrue> lstLogic = new List<LogicTrue>();
|
//逻辑分区集合
|
List<AutoBomPartition_Item_REntity> lstLogicEntityByItem = CreateDAL<TN_WMS_AREADAL>().GetPartitionItem(itemCode, 2);
|
|
if (lstLogicEntityByItem == null || lstLogicEntityByItem.Count == 0)
|
{
|
//根据物料编码获得物料信息
|
AutoBomItemEntity itemEntity = CreateDAL<TN_WMS_ITEMDAL>().GetItemEntity(itemCode);
|
if (itemEntity != null && !string.IsNullOrEmpty(itemEntity.CN_S_STORE_TYPE))
|
{
|
//获得物料类型
|
string itemType = itemEntity.CN_S_STORE_TYPE;
|
lstLogicEntityByItem = CreateDAL<TN_WMS_AREADAL>().GetPartitionItem(itemType, 1);
|
|
}
|
}
|
#endregion
|
|
//如果物料未分配逻辑分区则根据库区编码计算货位
|
if (lstLogicEntityByItem == null || lstLogicEntityByItem.Count == 0)
|
{
|
//errMsg = "根据物料编码未获得对应的逻辑分区!";
|
LogicTrue logicModel = new LogicTrue();
|
logicModel.areaCode = stockAreaCode;
|
logicModel.item_position = "1";
|
logicModel.locationCode = "";
|
logicModel.stockarea_position = "1";
|
logicModel.stockCode = "";
|
logicModel.type = 2;
|
lstLogic.Add(logicModel);
|
}
|
else
|
{
|
#region 通过库区取逻辑分区 逻辑分区关联仓库/库区/货位
|
List<AutoBomAreaLocation_REntity> lstLogicEntityByArea = CreateDAL<TN_WMS_AREADAL>().GetLogicListByAreaCode(stockAreaCode);
|
//如果物料未分配逻辑分区则返回空货位
|
if (lstLogicEntityByArea == null || lstLogicEntityByArea.Count == 0)
|
{
|
errMsg = "库区" + stockAreaCode + "或库区中货位未关联逻辑分区!";
|
}
|
#endregion
|
|
#region 取交集
|
//取交集
|
lstLogic = lstLogicEntityByItem.Join(lstLogicEntityByArea,
|
u => u.CN_S_AREA_CODE, d => d.CN_S_AREA_CODE, (u, d) => new { u, d })
|
.Select(o => new LogicTrue
|
{
|
stockCode = o.d.CN_S_STOCK_CODE,
|
areaCode = o.d.CN_S_STOCK_AREA,
|
locationCode = o.d.CN_S_LOCATION_CODE,
|
item_position = o.u.CN_S_PRIORITY,
|
stockarea_position = o.d.CN_S_PRIORITY,
|
type = o.d.CN_N_TYPE
|
}).ToList();
|
|
if (lstLogic == null || lstLogic.Count == 0)
|
{
|
errMsg = "物料关联的逻辑货位与库区关联的货位不存在交集!";
|
}
|
//排序 先根据物料优先级 再根据仓库/库区/货位优先级
|
lstLogic = lstLogic.OrderBy(o => o.item_position).OrderBy(o => o.stockarea_position).ToList();
|
#endregion
|
}
|
return lstLogic;
|
}
|
#endregion
|
#region 公用方法 获得真实可用的货位数据(公用)
|
/// <summary>
|
/// 获得真实可用的货位数据 指已在关系型数据库中验证货位状态后的货位集合数据
|
/// </summary>
|
/// <param name="model">取交集后的逻辑分区列表</param>
|
/// <returns></returns>
|
public List<AutoBomLocationAbbreEntity> GetLocationByArea_R(LogicTrue model)
|
{
|
//用于存储真实可用的数据 注:此列表已在关系型数据库中验证了货位扩展表的状态
|
//可以用于入库策略计算与生成
|
List<AutoBomLocationAbbreEntity> lstTrueLocation = new List<AutoBomLocationAbbreEntity>();
|
|
//根据逻辑分区查询出来可用的货位列表 注:此列表暂未在关系型数据库中货位扩展验证状态
|
List<string> locationCodes = new List<string>();
|
|
List<AutoBomLocationAbbreEntity> lstLocation = new List<AutoBomLocationAbbreEntity>();
|
switch (model.type)
|
{
|
case 1://返回仓库对应的货位列表
|
lstLocation = CreateDAL<TN_WMS_LOCATIONDAL>().GetLocationByStockCode(model.stockCode);
|
break;
|
case 2://返回库区对应的货位列表
|
lstLocation = CreateDAL<TN_WMS_LOCATIONDAL>().GetLocationByAreaCode(model.areaCode);
|
break;
|
case 3://直接返回货位编号
|
locationCodes = new List<string>(model.locationCode.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries));// new List<string>() { model.locationCode };
|
lstLocation = CreateDAL<TN_WMS_LOCATIONDAL>().GetLocationByLocationCode(locationCodes);
|
break;
|
case 4://返回库区对应的货位列表
|
lstLocation = CreateDAL<TN_WMS_LOCATIONDAL>().GetLocationByAreaCode(model.areaCode);
|
break;
|
case 5://返回库区对应的货位列表
|
locationCodes = new List<string>() { model.locationCode };
|
lstLocation = CreateDAL<TN_WMS_LOCATIONDAL>().GetLocationByLocationCode(locationCodes);
|
break;
|
case 6://返回库区对应的货位列表
|
lstLocation = CreateDAL<TN_WMS_LOCATIONDAL>().GetLocationByAreaCode(model.areaCode);
|
break;
|
|
default:
|
break;
|
}
|
if (lstLocation.Count > 0)
|
{
|
// Log.AlgorInfo("GetLocationByArea_R", "monogo中(lstLocation)中可用货位数据" + string.Join(",", lstLocation.Select(o => o.CN_S_LOCATION_CODE).ToList()));
|
}
|
else
|
{
|
Log.AlgorInfo("GetLocationByArea_R", "monogo中(lstLocation)没有数据" + lstLocation.Count);
|
}
|
//if (lstLocation.Count == 0)
|
//{
|
// Log.Debug("Inasign", "TN_AB_STOCK_LOCATION中没有数据");
|
//}
|
//else
|
//{
|
// List<string> locationLog = lstLocation.Select(o => o.CN_S_LOCATION_CODE).ToList();
|
// Log.Debug("Inasign", "TN_AB_STOCK_LOCATION中货位数据" + string.Join(",", locationLog));
|
//}
|
//货位扩展表中可用的货位
|
//List<TN_WM_LOCATION_EXTEntity> locationTrueCodes = GetTrueLocationCodes(model.stockCode, locationCodes, model.type);
|
List<TN_WM_LOCATION_EXTEntity> locationTrueCodes = GetTrueLocationCodes(model.stockCode.Trim(), model.areaCode, locationCodes, model.type);
|
if (locationTrueCodes.Count == 0)
|
{
|
Log.AlgorInfo("GetLocationByArea_R", "货位扩展表中没有数据");
|
}
|
//else
|
//{
|
// List<string> locationLog = locationTrueCodes.Select(o => o.CN_S_LOCATION_CODE).ToList();
|
// Log.AlgorInfo("GetLocationByArea_R", "tn_wm_b_location_ext中货位数据" + string.Join(",", locationLog));
|
//}
|
if (locationTrueCodes != null && locationTrueCodes.Count != 0)
|
{
|
lstTrueLocation = lstLocation.Join(locationTrueCodes, u => u.CN_S_LOCATION_CODE, d => d.CN_S_LOCATION_CODE, (u, d) => new { u, d })
|
.Select(o => o.u).ToList();
|
}
|
if (lstTrueLocation.Count == 0)
|
{
|
Log.AlgorInfo("GetLocationByArea_R", "lstTrueLocation中没有数据");
|
}
|
else
|
{
|
List<string> locationLog = lstTrueLocation.Select(o => o.CN_S_LOCATION_CODE).ToList();
|
Log.AlgorInfo("GetLocationByArea_R", "lstTrueLocation中货位数据" + string.Join(",", locationLog));
|
}
|
return lstTrueLocation;
|
}
|
public List<AutoBomLocationAbbreEntity> GetLocationByArea_R(LogicTrue model, string locationType)
|
{
|
//用于存储真实可用的数据 注:此列表已在关系型数据库中验证了货位扩展表的状态
|
//可以用于入库策略计算与生成
|
List<AutoBomLocationAbbreEntity> lstTrueLocation = new List<AutoBomLocationAbbreEntity>();
|
|
//根据逻辑分区查询出来可用的货位列表 注:此列表暂未在关系型数据库中货位扩展验证状态
|
List<string> locationCodes = new List<string>();
|
|
List<AutoBomLocationAbbreEntity> lstLocation = new List<AutoBomLocationAbbreEntity>();
|
switch (model.type)
|
{
|
case 1://返回仓库对应的货位列表
|
lstLocation = CreateDAL<TN_WMS_LOCATIONDAL>().GetLocationByStockCode(model.stockCode);
|
break;
|
case 2://返回库区对应的货位列表
|
lstLocation = CreateDAL<TN_WMS_LOCATIONDAL>().GetLocationByAreaCode(model.areaCode, locationType);
|
break;
|
case 3://直接返回货位编号
|
locationCodes = new List<string>(model.locationCode.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries));// new List<string>() { model.locationCode };
|
lstLocation = CreateDAL<TN_WMS_LOCATIONDAL>().GetLocationByLocationCode(locationCodes, locationType);
|
break;
|
case 4://返回库区对应的货位列表
|
lstLocation = CreateDAL<TN_WMS_LOCATIONDAL>().GetLocationByAreaCode(model.areaCode);
|
break;
|
case 5://返回库区对应的货位列表
|
locationCodes = new List<string>() { model.locationCode };
|
lstLocation = CreateDAL<TN_WMS_LOCATIONDAL>().GetLocationByLocationCode(locationCodes);
|
break;
|
case 6://返回库区对应的货位列表
|
lstLocation = CreateDAL<TN_WMS_LOCATIONDAL>().GetLocationByAreaCode(model.areaCode);
|
break;
|
|
default:
|
break;
|
}
|
if (lstLocation.Count > 0)
|
{
|
// Log.AlgorInfo("GetLocationByArea_R", "monogo中(lstLocation)中可用货位数据" + string.Join(",", lstLocation.Select(o => o.CN_S_LOCATION_CODE).ToList()));
|
}
|
else
|
{
|
Log.AlgorInfo("GetLocationByArea_R", "monogo中(lstLocation)没有数据" + lstLocation.Count);
|
}
|
//if (lstLocation.Count == 0)
|
//{
|
// Log.Debug("Inasign", "TN_AB_STOCK_LOCATION中没有数据");
|
//}
|
//else
|
//{
|
// List<string> locationLog = lstLocation.Select(o => o.CN_S_LOCATION_CODE).ToList();
|
// Log.Debug("Inasign", "TN_AB_STOCK_LOCATION中货位数据" + string.Join(",", locationLog));
|
//}
|
//货位扩展表中可用的货位
|
//List<TN_WM_LOCATION_EXTEntity> locationTrueCodes = GetTrueLocationCodes(model.stockCode, locationCodes, model.type);
|
List<TN_WM_LOCATION_EXTEntity> locationTrueCodes = GetTrueLocationCodes(model.stockCode.Trim(), model.areaCode, locationCodes, model.type);
|
if (locationTrueCodes.Count == 0)
|
{
|
Log.AlgorInfo("GetLocationByArea_R", "货位扩展表中没有数据");
|
}
|
//else
|
//{
|
// List<string> locationLog = locationTrueCodes.Select(o => o.CN_S_LOCATION_CODE).ToList();
|
// Log.AlgorInfo("GetLocationByArea_R", "tn_wm_b_location_ext中货位数据" + string.Join(",", locationLog));
|
//}
|
if (locationTrueCodes != null && locationTrueCodes.Count != 0)
|
{
|
lstTrueLocation = lstLocation.Join(locationTrueCodes, u => u.CN_S_LOCATION_CODE, d => d.CN_S_LOCATION_CODE, (u, d) => new { u, d })
|
.Select(o => o.u).ToList();
|
}
|
//if (lstTrueLocation.Count == 0)
|
//{
|
// Log.AlgorInfo("GetLocationByArea_R", "lstTrueLocation中没有数据");
|
//}
|
//else
|
//{
|
// List<string> locationLog = lstTrueLocation.Select(o => o.CN_S_LOCATION_CODE).ToList();
|
// Log.AlgorInfo("GetLocationByArea_R", "lstTrueLocation中货位数据" + string.Join(",", locationLog));
|
//}
|
return lstTrueLocation;
|
}
|
/// <summary>
|
/// 获得货位扩展表中可用的货位
|
/// </summary>
|
/// <param name="lstLocation"></param>
|
/// <param name="type"></param>
|
/// <returns></returns>
|
private List<TN_WM_LOCATION_EXTEntity> GetTrueLocationCodes(string stockCode, string areaCode, List<string> locationCodes, int type)
|
{
|
|
List<TN_WM_LOCATION_EXTEntity> lstTrueLocations = new List<TN_WM_LOCATION_EXTEntity>();
|
switch (type)
|
{
|
case 1://仓库 只根据仓库编号获得可用货位
|
lstTrueLocations = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLocationCodeExtListBy(stockCode, areaCode, null, "入库");
|
break;
|
case 2://库区 根据货位编码集合 in 查询关系型数据库中的扩展货位表数据
|
lstTrueLocations = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLocationCodeExtListBy(stockCode, areaCode, null, "入库");
|
break;
|
case 3://货位 根据单个货位编码 = 查询关系型数据库中的扩展货位表数据
|
|
lstTrueLocations = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLocationCodeExtListBy(stockCode, areaCode, locationCodes, "入库");
|
break;
|
case 4://库区(流离式货架) 根据货位编码集合 in 查询关系型数据库中的扩展货位表数据
|
lstTrueLocations = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLocationCodeExtListBy(stockCode, areaCode, null, "入流离库");
|
break;
|
case 5://库区(流离式货架) 根据货位编码集合 in 查询关系型数据库中的扩展货位表数据
|
lstTrueLocations = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLocationCodeExtListBy(stockCode, areaCode, locationCodes, "入流离库");
|
break;
|
}
|
return lstTrueLocations;
|
}
|
#endregion
|
|
|
#region 作业区(流离式、平库、立库)入库算法入扣
|
public InAssignResultEntity InAssign(InAssignEntity model)
|
{
|
//定义返回实体
|
InAssignResultEntity resultEntity = new InAssignResultEntity();
|
resultEntity.Msg = "";
|
resultEntity.errCode = "";
|
Log.AlgorInfo("InAssign", "入库算法参数:" + JsonConvert.SerializeObject(model));
|
try
|
{
|
#region 传入参数判断
|
if (model == null)
|
{
|
resultEntity.Success = false;
|
resultEntity.errCode = "6";
|
resultEntity.Msg = "参数实体不能为 null !";
|
return resultEntity;
|
}
|
//判断对象编号不能为空
|
//if (string.IsNullOrEmpty(model.objectCode))
|
//{
|
// resultEntity.Success = false;
|
// resultEntity.Msg = "指定的入作业库对象编号不能为空!";
|
// return resultEntity;
|
//}
|
//判断传入库区列表不能为空
|
if (model.lstAreaPrior == null || model.lstAreaPrior.Count == 0)
|
{
|
resultEntity.Success = false;
|
resultEntity.errCode = "6";
|
resultEntity.Msg = "指定的入作业库库区列表不能为空!";
|
return resultEntity;
|
}
|
#endregion
|
//(流离式、平库、立库)标准入库算法
|
string areaType = CreateDAL<TN_WMS_AREADAL>().GetAreaTypeByCode(model.lstAreaPrior[0].areaCode.ToString());
|
if (areaType == Constants.Area_Struc_PingStock || areaType == Constants.Area_Struc_LiStock)
|
{
|
resultEntity = FlatAreaGetLocation(model, model.lstDevice);
|
}
|
resultEntity.areaType = areaType;
|
Log.AlgorInfo("InAssign", "入库返回结果:" + JsonConvert.SerializeObject(resultEntity));
|
return resultEntity;
|
}
|
|
catch (Exception ex)
|
{
|
Log.AlgorInfo("InAssign", "异常日志:" + ex.Message + ex.StackTrace);
|
resultEntity.errCode = "5";
|
resultEntity.Msg = "算法异常," + ex.Message + ex.StackTrace;
|
return resultEntity;
|
}
|
|
}
|
#endregion
|
|
#region 作业区 平库入库算法
|
public InAssignResultEntity FlatAreaGetLocation(InAssignEntity model, List<Device> lstDevice)
|
{
|
InAssignResultEntity resultEntity = new InAssignResultEntity();
|
resultEntity.Success = false;
|
List<AutoBomLocationAbbreEntity> lstTrueLocation = new List<AutoBomLocationAbbreEntity>();
|
List<AutoBomLocationAbbreEntity> lstTmpLocation = new List<AutoBomLocationAbbreEntity>();
|
List<AutoBomAreaLocation_REntity> lstALR = null;
|
List<AutoBomLocationAbbreEntity> lstLocation = new List<AutoBomLocationAbbreEntity>();
|
List<AutoBomLocationAbbreEntity> lstLockLItem = new List<AutoBomLocationAbbreEntity>();
|
List<TN_WM_LOCATIONCODE_EXT_Entity> lstEmptyLocation = new List<TN_WM_LOCATIONCODE_EXT_Entity>();
|
List<AutoBomLocationAbbreEntity> lstTrueLItem = new List<AutoBomLocationAbbreEntity>();
|
List<areaPriorClass> lstAreaPrior = model.lstAreaPrior.OrderBy(o => o.Prior).ToList();
|
StringBuilder sbDetailError = new StringBuilder();
|
#region 从autobom和货位扩展表中获取可用货位集合
|
//按优先级循环处理库区获取可用货位集合
|
foreach (areaPriorClass item in lstAreaPrior)
|
{
|
AutoBomStockAreaEntity areaModel = CreateDAL<TN_WMS_AREADAL>().GetModel(item.areaCode.ToString());
|
model.stockCode = areaModel.CN_S_STOCK_CODE;
|
resultEntity.isControlQty = areaModel.CN_C_IS_CONTROL_QTY;
|
resultEntity.isControlInv = areaModel.CN_C_IS_INVENTORY;
|
resultEntity.areaCode = item.areaCode;
|
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;
|
lstALR = CreateDAL<TN_WMS_AREADAL>().GetLocationByLogicArea(model.logicAreaCode, item.areaCode);
|
if (lstALR != null && lstALR.Count > 0)
|
{
|
if (lstALR[0].CN_N_TYPE == 2)
|
{
|
logicModel.type = 2;
|
logicModel.areaCode = item.areaCode;
|
}
|
else if (lstALR[0].CN_N_TYPE == 3)
|
{
|
logicModel.type = 3;
|
logicModel.lstLocationCode = lstALR.Where(o => o.CN_N_TYPE == 3).Select(o => o.CN_S_LOCATION_CODE).ToList();
|
}
|
}
|
}
|
//获取在autobom中可用货位的集合(去除废弃的货位)
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "求可用货位的logicModel参数:" + JsonConvert.SerializeObject(logicModel));
|
lstLocation = BLLCreator.Create<AlgorCommonBLL>().AutoBomLocationTrue(logicModel);
|
// Log.AlgorInfo("InAssign-FlatAreaGetLocation", "lstLocation:" + JsonConvert.SerializeObject(lstLocation));
|
//获取在货位扩展表中可用的货位的集合(去除锁定的货位)
|
List<TN_WM_LOCATIONCODE_EXT_Entity> locationTrueCodes = BLLCreator.Create<AlgorCommonBLL>().GetTrueLocationCodes(model.stockCode.Trim(), item.areaCode, logicModel.lstLocationCode, logicModel.type, Constants.Area_Struc_PingStock);
|
lstEmptyLocation.AddRange(locationTrueCodes);
|
|
//获取交集
|
if (locationTrueCodes != null && locationTrueCodes.Count != 0)
|
{
|
lstTrueLItem = lstLocation.Join(locationTrueCodes, u => u.CN_S_LOCATION_CODE, d => d.CN_S_LOCATION_CODE, (u, d) => new { u, d })
|
.Select(o => o.u).ToList();
|
lstTrueLocation.AddRange(lstTrueLItem);
|
}
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "与monog交集lstTrueLItem:" + JsonConvert.SerializeObject(lstTrueLItem));
|
if (model.projectCode == "jxhn")
|
{
|
string areaClass = CreateDAL<TN_WMS_AREADAL>().GetAreaClassByCode(item.areaCode.ToString());
|
//控制该库区的任务总数阀值
|
if (areaClass == "高架库")
|
{
|
#region 高架库
|
//获取系统配置的巷道最大任务数限制
|
long maxTaskQty = 0;
|
List<TN_WM_B_STRATEGY_VALUEEntity> list = BLLCreator.Create<DapperBLL<TN_WM_B_STRATEGY_VALUEEntity>>().GetList(); ;
|
TN_WM_B_STRATEGY_VALUEEntity strategy = list.Where(o => o.CN_S_CODE == "RoadMaxTask").FirstOrDefault();
|
if (strategy != null)
|
{
|
if (!string.IsNullOrEmpty(strategy.CN_S_VALUE))
|
{
|
maxTaskQty = long.Parse(strategy.CN_S_VALUE);
|
}
|
}
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "高架库中RoadMaxTask:" + maxTaskQty.ToString());
|
//获取该库区中所有未执行或执行中的出入库任务
|
List<TN_WM_TASKEntity> lstTask = CreateDAL<HH.WMS.DAL.SysMgr.TN_WM_TASKDAL>().GetTaskByAreaCode(item.areaCode);
|
List<RoadTask> lstRoadTask = new List<RoadTask>();
|
lstRoadTask = lstTrueLItem.GroupBy(o => o.CN_S_ROW).Select(g => (new RoadTask
|
{
|
roadWay = g.Key,
|
taskNum = 0
|
})).Distinct().ToList();
|
List<string> lstTmpL = new List<string>();
|
List<RoadTask> lstNewRoadTask = new List<RoadTask>();
|
foreach (RoadTask roadT in lstRoadTask)
|
{
|
lstTmpL = lstLocation.Where(o => o.CN_S_ROW == roadT.roadWay).Select(a => a.CN_S_LOCATION_CODE).ToList();
|
roadT.taskNum = lstTask.Where(o => lstTmpL.Contains(o.CN_S_START_BIT) || lstTmpL.Contains(o.CN_S_END_BIT)).Count();
|
if (roadT.taskNum < maxTaskQty)
|
{
|
lstNewRoadTask.Add(roadT);
|
}
|
}
|
if (lstNewRoadTask.Count > 0)
|
{
|
lstNewRoadTask = lstNewRoadTask.OrderBy(o => o.taskNum).ThenBy(o => o.roadWay).ToList();
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "lstNewRoadTask:" + JsonConvert.SerializeObject(lstNewRoadTask));
|
lstTrueLItem = lstTrueLItem.Where(o => o.CN_S_ROW == lstNewRoadTask.FirstOrDefault().roadWay).ToList();
|
}
|
else
|
{
|
lstTrueLItem.Clear();
|
}
|
#endregion
|
}
|
else if (areaClass == "缓存区")
|
{
|
#region 缓存区
|
//巷道内有入不能有出 有出不能有入 巷道任务尽量平均分配
|
// 获取预入库锁定的货位
|
List<TN_WM_LOCATIONCODE_EXT_Entity> locationInLock = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLockLocationByState(model.stockCode.Trim(), item.areaCode, null, Constants.Location_State_InLock);
|
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "locationInLock数据:" + JsonConvert.SerializeObject(locationInLock));
|
|
// 获取预出库锁定的货位
|
List<TN_WM_LOCATIONCODE_EXT_Entity> locationOutLock = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLockLocationByState(model.stockCode.Trim(), item.areaCode, null, Constants.Location_State_OutLock);
|
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "locationOutLock数据:" + JsonConvert.SerializeObject(locationOutLock));
|
List<string> lstOutLockRow = locationOutLock.Select(o => o.CN_S_ROW).Distinct().ToList();
|
|
lstTrueLItem.RemoveAll(o => lstOutLockRow.Contains(o.CN_S_ROW));
|
|
//获取货位所在行的预入库任务数量
|
List<RoadTask> lstTask = new List<RoadTask>();
|
lstTask = lstTrueLItem.Select(o => new RoadTask
|
{
|
roadWay = o.CN_S_ROW,
|
taskNum = 0
|
}).Distinct().ToList();
|
foreach (RoadTask roadT in lstTask)
|
{
|
roadT.taskNum = locationInLock.Where(o => o.CN_S_ROW == roadT.roadWay).Count();
|
}
|
lstTask = lstTask.OrderBy(o => o.taskNum).ToList();
|
lstTrueLItem = lstTrueLItem.Where(o => o.CN_S_ROW == lstTask.FirstOrDefault().roadWay).ToList();
|
#endregion
|
}
|
else if (areaClass == "地堆")
|
{
|
#region 地堆
|
//去除被(异形件)人工绑定阻挡的货位
|
List<AutoBomLocationAbbreEntity> lstLocationHasItem = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLocationByItemCode("", "", item.areaCode);
|
List<AutoBomLocationAbbreEntity> lstLocationRowCols = new List<AutoBomLocationAbbreEntity>();
|
|
List<string> lstRows = lstLocationHasItem.Select(o => o.CN_S_ROW).Distinct().ToList();
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "lstLocationSameItem数据:" + JsonConvert.SerializeObject(lstLocationHasItem));
|
List<AutoBomLocationAbbreEntity> tmpTrueItem = new List<AutoBomLocationAbbreEntity>();
|
List<AutoBomLocationAbbreEntity> tmpGreaterItem = new List<AutoBomLocationAbbreEntity>();
|
foreach (string sRow in lstRows)
|
{
|
lstLocationRowCols = lstLocationHasItem.Where(o => o.CN_S_ROW == sRow).OrderByDescending(a => int.Parse(a.CN_S_COL)).ToList();
|
tmpGreaterItem = lstTrueLItem.Where(o => o.CN_S_ROW == sRow && int.Parse(o.CN_S_COL) > int.Parse(lstLocationRowCols[0].CN_S_COL)).ToList();
|
lstTrueLItem.RemoveAll(o => o.CN_S_ROW == sRow && int.Parse(o.CN_S_COL) < int.Parse(lstLocationRowCols[0].CN_S_COL));
|
if (tmpGreaterItem.Count > 0)
|
{
|
tmpTrueItem.AddRange(tmpGreaterItem);
|
}
|
|
}
|
if (tmpTrueItem.Count > 0)
|
{
|
lstTrueLItem = tmpTrueItem;
|
}
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "lstTrueLItem数据:" + JsonConvert.SerializeObject(lstTrueLItem));
|
|
//地堆中只有入库任务,获取预入库锁定的货位
|
List<TN_WM_LOCATIONCODE_EXT_Entity> locationInLock = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLockLocationByState(model.stockCode.Trim(), item.areaCode, logicModel.lstLocationCode, Constants.Location_State_InLock);
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "去除被(异形件)人工绑定阻挡的货位数据:" + JsonConvert.SerializeObject(locationInLock));
|
//获取货位所在行的预入库任务数量
|
List<RoadTask> lstTask = new List<RoadTask>();
|
lstTask = lstTrueLItem.Select(o => new RoadTask
|
{
|
roadWay = o.CN_S_ROW,
|
taskNum = 0
|
}).Distinct().ToList();
|
foreach (RoadTask roadT in lstTask)
|
{
|
roadT.taskNum = locationInLock.Where(o => o.CN_S_ROW == roadT.roadWay).Count();
|
}
|
lstTask = lstTask.OrderBy(o => o.taskNum).ToList();
|
lstTrueLItem = lstTrueLItem.Where(o => o.CN_S_ROW == lstTask.FirstOrDefault().roadWay).ToList();
|
#endregion
|
}
|
}
|
if (model.projectCode == "ys001")
|
{
|
#region 宇寿算法定制代码
|
//获取该托盘中的物料信息
|
List<TN_WM_B_TRAY_ITEM_MSTEntity> lstOriginalMST = BLLCreator.Create<DapperBLL<TN_WM_B_TRAY_ITEM_MSTEntity>>().GetList(new { CN_S_TRAY_CODE = model.objectCode });
|
string itemCode = "";
|
if (lstOriginalMST.Count > 0)
|
{
|
itemCode = lstOriginalMST[0].CN_S_ITEM_CODE;
|
}
|
//获取预出库锁定的货位
|
List<TN_WM_LOCATIONCODE_EXT_Entity> locationOutLock = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLockLocationByState(model.stockCode.Trim(), item.areaCode, logicModel.lstLocationCode, Constants.Location_State_OutLock);
|
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "locationOutLock数据:" + JsonConvert.SerializeObject(lstLockLItem));
|
foreach (TN_WM_LOCATIONCODE_EXT_Entity lEntity in locationOutLock)
|
{
|
lstTrueLItem.RemoveAll(o => o.CN_S_ROW == lEntity.CN_S_ROW && o.CN_S_COL == lEntity.CN_S_COL);
|
}
|
|
List<TN_WM_LOCATIONCODE_EXT_Entity> locationCheckLock = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLockLocationByState(model.stockCode.Trim(), item.areaCode, null, Constants.Location_Check_Lock);
|
Log.AlgorInfo("OutAssign-FlatAreaOutLocation", "locationCheckLock数据:" + JsonConvert.SerializeObject(locationCheckLock));
|
foreach (TN_WM_LOCATIONCODE_EXT_Entity lEntity in locationCheckLock)
|
{
|
lstTrueLItem.RemoveAll(o => o.CN_S_ROW == lEntity.CN_S_ROW && o.CN_S_COL == lEntity.CN_S_COL);
|
}
|
List<TN_WM_LOCATIONCODE_EXT_Entity> locationCarryLock = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLockLocationByState(model.stockCode.Trim(), item.areaCode, null, Constants.Location_Carry_Lock);
|
Log.AlgorInfo("OutAssign-FlatAreaOutLocation", "locationCarryLock数据:" + JsonConvert.SerializeObject(locationCarryLock));
|
foreach (TN_WM_LOCATIONCODE_EXT_Entity lEntity in locationCarryLock)
|
{
|
lstTrueLItem.RemoveAll(o => o.CN_S_ROW == lEntity.CN_S_ROW && o.CN_S_COL == lEntity.CN_S_COL);
|
}
|
List<AutoBomLocationAbbreEntity> lstLocationHasItem = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLocationByItemCode("", "", item.areaCode);
|
List<AutoBomLocationAbbreEntity> lstLocationHasItemOrder = new List<AutoBomLocationAbbreEntity>();
|
List<AutoBomLocationAbbreEntity> lstLocationRowCols = new List<AutoBomLocationAbbreEntity>();
|
List<AutoBomLocationAbbreEntity> lstItemCols = lstLocationHasItem.GroupBy(a => new
|
{
|
a.CN_S_ROW,
|
a.CN_S_COL
|
}).Select(o => new AutoBomLocationAbbreEntity
|
{
|
CN_S_ROW = o.Key.CN_S_ROW,
|
CN_S_COL = o.Key.CN_S_COL
|
}).ToList();
|
foreach (AutoBomLocationAbbreEntity itemC in lstItemCols)
|
{
|
lstLocationHasItemOrder = lstLocationHasItem.Where(o => o.CN_S_ROW == itemC.CN_S_ROW && o.CN_S_COL == itemC.CN_S_COL).OrderByDescending(a => int.Parse(a.CN_S_FLOOR)).ToList();
|
lstTrueLItem.RemoveAll(o => o.CN_S_ROW == itemC.CN_S_ROW && o.CN_S_COL == itemC.CN_S_COL && int.Parse(o.CN_S_FLOOR) < int.Parse(lstLocationHasItemOrder[0].CN_S_FLOOR));
|
}
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "去除阻挡后的lstTrueLItem数据:" + JsonConvert.SerializeObject(lstTrueLItem));
|
//查找该库区中已存放该物料的货位
|
List<AutoBomLocationAbbreEntity> lstLocationSameItem = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLocationByItemCode(itemCode, item.areaCode);
|
//查找该库区中即将要存放该物料的货位
|
List<AutoBomLocationAbbreEntity> lstTaskSameItem = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetInTaskLocationByItemCode(itemCode, item.areaCode);
|
if (lstTaskSameItem.Count > 0)
|
{
|
lstLocationSameItem.AddRange(lstTaskSameItem);
|
}
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "lstLocationSameItem数据:" + JsonConvert.SerializeObject(lstLocationSameItem));
|
List<AutoBomLocationAbbreEntity> tmpTrueItem = new List<AutoBomLocationAbbreEntity>();
|
lstItemCols = lstLocationSameItem.GroupBy(a => new
|
{
|
a.CN_S_ROW,
|
a.CN_S_COL
|
}).Select(o => new AutoBomLocationAbbreEntity
|
{
|
CN_S_ROW = o.Key.CN_S_ROW,
|
CN_S_COL = o.Key.CN_S_COL
|
}).ToList();
|
|
foreach (AutoBomLocationAbbreEntity lEntity in lstItemCols)
|
{
|
tmpTrueItem.AddRange(lstTrueLItem.Where(o => o.CN_S_COL == lEntity.CN_S_COL && o.CN_S_ROW == lEntity.CN_S_ROW).ToList());
|
}
|
if (tmpTrueItem.Count > 0)
|
{
|
lstTrueLItem = tmpTrueItem;
|
}
|
else
|
{
|
//判断库区中是否有未使用的空列
|
List<AutoBomLocationAbbreEntity> lstEmptyCol = lstTrueLItem.GroupBy(a => new
|
{
|
a.CN_S_ROW,
|
a.CN_S_COL
|
}).Select(o => new AutoBomLocationAbbreEntity
|
{
|
CN_S_ROW = o.Key.CN_S_ROW,
|
CN_S_COL = o.Key.CN_S_COL
|
}).ToList();
|
foreach (AutoBomLocationAbbreEntity aEntity in lstEmptyCol)
|
{
|
if (lstTrueLItem.Where(o => o.CN_S_ROW == aEntity.CN_S_ROW && o.CN_S_COL == aEntity.CN_S_COL).Count() == lstLocation.Where(o => o.CN_S_ROW == aEntity.CN_S_ROW && o.CN_S_COL == aEntity.CN_S_COL).Count())
|
{
|
tmpTrueItem.AddRange(lstTrueLItem.Where(o => o.CN_S_ROW == aEntity.CN_S_ROW && o.CN_S_COL == aEntity.CN_S_COL).ToList());
|
}
|
}
|
if (tmpTrueItem.Count > 0)
|
{
|
lstTrueLItem = tmpTrueItem;
|
}
|
}
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "lstTrueLItem数据:" + JsonConvert.SerializeObject(lstTrueLItem));
|
#endregion
|
}
|
if (model.projectCode == "masym")
|
{
|
#region 马鞍山粤美算法定制代码
|
List<STRATEGYALGOREntity> lstStrategy = CreateDAL<TN_WM_B_STRATEGYDAL>().GetStrateListByAreaOrStock("", resultEntity.areaCode, "入库");
|
//获取预出库锁定的货位
|
if (lstStrategy.Select(o => o.CN_S_CODE).ToList().Contains("FirstInLastOut"))
|
{
|
List<TN_WM_LOCATIONCODE_EXT_Entity> locationOutLock = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLockLocationByState(model.stockCode.Trim(), item.areaCode, logicModel.lstLocationCode, Constants.Location_State_OutLock);
|
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "locationOutLock数据:" + JsonConvert.SerializeObject(lstLockLItem));
|
|
List<TN_WM_LOCATIONCODE_EXT_Entity> lstOutLockRows = locationOutLock.GroupBy(a => new
|
{
|
a.CN_S_ROW
|
}).Select(o => new TN_WM_LOCATIONCODE_EXT_Entity
|
{
|
CN_S_ROW = o.Key.CN_S_ROW
|
}).ToList();
|
foreach (TN_WM_LOCATIONCODE_EXT_Entity lEntity in lstOutLockRows)
|
{
|
lstTrueLItem.RemoveAll(o => o.CN_S_ROW == lEntity.CN_S_ROW);
|
}
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "去除预出库锁定后的lstTrueLItem数据:" + JsonConvert.SerializeObject(lstTrueLItem));
|
|
List<AutoBomLocationAbbreEntity> lstLocationHasItem = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLocationByItemCode("", "", item.areaCode);
|
List<AutoBomLocationAbbreEntity> lstLocationInlock = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLocationByInLockYM("", "", item.areaCode);
|
if (lstLocationInlock.Count > 0)
|
{
|
lstLocationHasItem.AddRange(lstLocationInlock);
|
}
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "lstLocationHasItem数据:" + JsonConvert.SerializeObject(lstLocationHasItem));
|
List<AutoBomLocationAbbreEntity> lstLocationHasItemOrder = new List<AutoBomLocationAbbreEntity>();
|
List<string> lstItemRows = lstLocationHasItem.GroupBy(a => new
|
{
|
a.CN_S_ROW
|
}).Select(o => o.Key.CN_S_ROW
|
).ToList();
|
foreach (string itemC in lstItemRows)
|
{
|
lstLocationHasItemOrder = lstLocationHasItem.Where(o => o.CN_S_ROW == itemC).OrderByDescending(a => int.Parse(a.CN_S_COL)).ToList();
|
lstTrueLItem.RemoveAll(o => o.CN_S_ROW == itemC && int.Parse(o.CN_S_COL) < int.Parse(lstLocationHasItemOrder[0].CN_S_COL));
|
}
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "去除阻挡后的lstTrueLItem数据:" + JsonConvert.SerializeObject(lstTrueLItem));
|
}
|
#endregion
|
}
|
else if (model.projectCode == "ntsd")
|
{
|
#region 南通定制算法代码
|
List<STRATEGYALGOREntity> lstStrategy = new List<STRATEGYALGOREntity>();
|
lstStrategy = CreateDAL<TN_WM_B_STRATEGYDAL>().GetStrateListByAreaOrStock("", resultEntity.areaCode, "入库");
|
if (lstStrategy.Select(o => o.CN_S_CODE).ToList().Contains("FirstInLastOut"))
|
{
|
//获取该托盘中的物料信息
|
List<TN_WM_B_TRAY_ITEM_MSTEntity> lstOriginalMST = BLLCreator.Create<DapperBLL<TN_WM_B_TRAY_ITEM_MSTEntity>>().GetList(new { CN_S_TRAY_CODE = model.objectCode });
|
string itemCode = "";
|
if (lstOriginalMST.Count > 0)
|
{
|
itemCode = lstOriginalMST[0].CN_S_ITEM_CODE;
|
}
|
//获取预出库锁定的货位,预出库锁定货位所在列的其他货位(同层)还可以使用
|
//List<TN_WM_LOCATIONCODE_EXT_Entity> locationOutLock = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLockLocationByState(model.stockCode.Trim(), item.areaCode, logicModel.lstLocationCode, Constants.Location_State_OutLock);
|
|
//Log.AlgorInfo("InAssign-FlatAreaGetLocation", "locationOutLock数据:" + JsonConvert.SerializeObject(lstLockLItem));
|
//foreach (TN_WM_LOCATIONCODE_EXT_Entity lEntity in locationOutLock)
|
//{
|
// lstTrueLItem.RemoveAll(o => o.CN_S_ROW == lEntity.CN_S_ROW && o.CN_S_COL != lEntity.CN_S_COL);
|
//}
|
//获取预出库锁定的货位,预出库锁定货位所在排不能入
|
List<TN_WM_LOCATIONCODE_EXT_Entity> locationOutLock = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLockLocationByState(model.stockCode.Trim(), item.areaCode, logicModel.lstLocationCode, Constants.Location_State_OutLock);
|
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "locationOutLock数据:" + JsonConvert.SerializeObject(lstLockLItem));
|
foreach (TN_WM_LOCATIONCODE_EXT_Entity lEntity in locationOutLock)
|
{
|
lstTrueLItem.RemoveAll(o => o.CN_S_ROW == lEntity.CN_S_ROW);
|
}
|
//获取预入库锁定的货位,预入库锁定货位所在列的其他货位(同层)还可以使用
|
List<TN_WM_LOCATIONCODE_EXT_Entity> locationInLock = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLockLocationByState(model.stockCode.Trim(), item.areaCode, logicModel.lstLocationCode, Constants.Location_State_InLock);
|
|
//Log.AlgorInfo("InAssign-FlatAreaGetLocation", "locationInLock数据:" + JsonConvert.SerializeObject(locationInLock));
|
//foreach (TN_WM_LOCATIONCODE_EXT_Entity lEntity in locationInLock)
|
//{
|
// lstTrueLItem.RemoveAll(o => o.CN_S_ROW == lEntity.CN_S_ROW && o.CN_S_COL != lEntity.CN_S_COL);
|
//}
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "去除锁定数据后stTrueLItem:" + JsonConvert.SerializeObject(lstTrueLItem));
|
|
//查找该库区中已存放该物料的货位
|
List<AutoBomLocationAbbreEntity> lstLocationSameItem = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLocationByItemCode(itemCode, item.areaCode);
|
//查找该库区中即将要存放该物料的货位
|
List<AutoBomLocationAbbreEntity> lstTaskSameItem = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetInTaskLocationByItemCode(itemCode, item.areaCode);
|
if (lstTaskSameItem.Count > 0)
|
{
|
lstLocationSameItem.AddRange(lstTaskSameItem);
|
}
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "lstLocationSameItem数据:" + JsonConvert.SerializeObject(lstLocationSameItem));
|
//获取该库区中已存放该物料或即将存放该物料的排
|
//List<string> lstSameItemRow = lstLocationSameItem.Select(o => o.CN_S_ROW).Distinct().ToList();
|
|
List<string> lstEmptyRow = lstTrueLItem.Select(o => o.CN_S_ROW).Distinct().ToList();
|
//获取符合条件的排lstSameItemRow中任务最少的一个排并且该排中有位置可以放
|
List<rowTaskNT> lstRowTask = new List<rowTaskNT>();
|
foreach (string sRow in lstEmptyRow)
|
{
|
rowTaskNT rowT = new rowTaskNT();
|
rowT.row = sRow;
|
rowT.taskNum = locationInLock.Where(o => o.CN_S_ROW == sRow).Count() + locationOutLock.Where(o => o.CN_S_ROW == sRow).Count();
|
rowT.GoodLocationNum = lstLocationSameItem.Where(o => o.CN_S_ROW == sRow).Count();
|
lstRowTask.Add(rowT);
|
}
|
lstRowTask = lstRowTask.OrderBy(o => o.taskNum).ThenBy(a => a.GoodLocationNum).ToList();
|
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "lstRowTask数据:" + JsonConvert.SerializeObject(lstRowTask));
|
if (lstRowTask.Count > 0)
|
{
|
lstTrueLItem = lstTrueLItem.Where(a => a.CN_S_ROW == lstRowTask.FirstOrDefault().row).ToList();
|
}
|
else
|
{
|
lstTrueLItem.Clear();
|
}
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "lstTrueLItem数据:" + JsonConvert.SerializeObject(lstTrueLItem));
|
}
|
#endregion
|
}
|
else if (model.projectCode == "tzlj")
|
{
|
#region 泰州隆基定制算法代码
|
List<STRATEGYALGOREntity> lstStrategy = new List<STRATEGYALGOREntity>();
|
lstStrategy = CreateDAL<TN_WM_B_STRATEGYDAL>().GetStrateListByAreaOrStock("", resultEntity.areaCode, "入库");
|
List<TN_WM_LOCATIONCODE_EXT_Entity> locationOutLock = new List<TN_WM_LOCATIONCODE_EXT_Entity>();
|
List<TN_WM_LOCATIONCODE_EXT_Entity> locationInLock = new List<TN_WM_LOCATIONCODE_EXT_Entity>();
|
|
|
if (lstStrategy.Select(o => o.CN_S_CODE).ToList().Contains("FirstInLastOutLj"))
|
{
|
//获取预出库锁定的货位,预出库锁定货位所在排不能入
|
locationOutLock = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLockLocationByState(model.stockCode.Trim(), item.areaCode, logicModel.lstLocationCode, Constants.Location_State_OutLock);
|
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "locationOutLock数据:" + JsonConvert.SerializeObject(locationOutLock));
|
foreach (TN_WM_LOCATIONCODE_EXT_Entity lEntity in locationOutLock)
|
{
|
lstTrueLItem.RemoveAll(o => o.CN_S_COL == lEntity.CN_S_COL);
|
}
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "去除锁定数据后stTrueLItem:" + JsonConvert.SerializeObject(lstTrueLItem));
|
//获取预入库锁定的货位
|
locationInLock = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLockLocationByState(model.stockCode.Trim(), item.areaCode, logicModel.lstLocationCode, Constants.Location_State_InLock);
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "locationInLock数据:" + JsonConvert.SerializeObject(locationInLock));
|
}
|
if (lstStrategy.Select(o => o.CN_S_CODE).ToList().Contains("AdjoinColNoTask"))
|
{
|
foreach (TN_WM_LOCATIONCODE_EXT_Entity lEntity in locationOutLock)
|
{
|
lstTrueLItem.RemoveAll(o => int.Parse(o.CN_S_COL) == int.Parse(lEntity.CN_S_COL) + 1);
|
lstTrueLItem.RemoveAll(o => int.Parse(o.CN_S_COL) == int.Parse(lEntity.CN_S_COL) - 1);
|
}
|
foreach (TN_WM_LOCATIONCODE_EXT_Entity lEntity in locationInLock)
|
{
|
lstTrueLItem.RemoveAll(o => int.Parse(o.CN_S_COL) == int.Parse(lEntity.CN_S_COL) + 1);
|
lstTrueLItem.RemoveAll(o => int.Parse(o.CN_S_COL) == int.Parse(lEntity.CN_S_COL) - 1);
|
}
|
}
|
if (lstStrategy.Select(o => o.CN_S_CODE).ToList().Contains("FirstInLastOutLj"))
|
{
|
//查找该库区中已存放该物料的货位
|
List<AutoBomLocationAbbreEntity> lstLocationSameItem = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLocationByItemCode(model.itemCode, item.areaCode);
|
////查找该库区中即将要存放该物料的货位
|
//List<AutoBomLocationAbbreEntity> lstTaskSameItem = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetInTaskLocationByItemCode(itemCode, item.areaCode);
|
//if (lstTaskSameItem.Count > 0)
|
//{
|
// lstLocationSameItem.AddRange(lstTaskSameItem);
|
//}
|
//Log.AlgorInfo("InAssign-FlatAreaGetLocation", "lstLocationSameItem数据:" + JsonConvert.SerializeObject(lstLocationSameItem));
|
//获取该库区中已存放该物料或即将存放该物料的排
|
// List<string> lstSameItemRow = lstLocationSameItem.Select(o => o.CN_S_ROW).Distinct().ToList();
|
//List<AutoBomLocationAbbreEntity> tmpTrueItem = new List<AutoBomLocationAbbreEntity>();
|
List<string> lstEmptyCol = lstTrueLItem.Select(o => o.CN_S_COL).Distinct().ToList();
|
//获取符合条件的排lstSameItemRow中任务最少的一个列并且该排中有位置可以放
|
List<rowTaskNT> lstColTask = new List<rowTaskNT>();
|
foreach (string sCol in lstEmptyCol)
|
{
|
rowTaskNT rowT = new rowTaskNT();
|
rowT.row = sCol;
|
rowT.taskNum = locationInLock.Where(o => o.CN_S_COL == sCol).Count();
|
rowT.GoodLocationNum = lstLocationSameItem.Where(o => o.CN_S_COL == sCol).Count();
|
lstColTask.Add(rowT);
|
}
|
lstColTask = lstColTask.OrderBy(o => o.taskNum).ThenBy(a => a.GoodLocationNum).ToList();
|
//获取符合条件的排lstSameItemRow中任务最少的一个排并且该排中有位置可以放
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "lstRowTask数据:" + JsonConvert.SerializeObject(lstColTask));
|
if (lstColTask.Count > 0)
|
{
|
lstTrueLItem = lstTrueLItem.Where(a => a.CN_S_COL == lstColTask.FirstOrDefault().row).ToList();
|
}
|
else
|
{
|
lstTrueLItem.Clear();
|
}
|
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "lstTrueLItem数据:" + JsonConvert.SerializeObject(lstTrueLItem));
|
}
|
#endregion
|
}
|
else if (model.projectCode == "hcbh")
|
{
|
#region 杭叉钣焊算法定制代码
|
|
//获取预出库锁定的货位
|
List<TN_WM_LOCATIONCODE_EXT_Entity> locationOutLock = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLockLocationByState(model.stockCode.Trim(), item.areaCode, logicModel.lstLocationCode, Constants.Location_State_OutLock);
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "locationOutLock数据:" + JsonConvert.SerializeObject(locationOutLock));
|
List<string> lstOutLockRow = locationOutLock.Select(o => o.CN_S_ROW).Distinct().ToList();
|
lstTrueLItem.RemoveAll(o => lstOutLockRow.Contains(o.CN_S_ROW));
|
//获取预出库锁定的货位
|
List<TN_WM_LOCATIONCODE_EXT_Entity> locationInLock = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLockLocationByState(model.stockCode.Trim(), item.areaCode, logicModel.lstLocationCode, Constants.Location_State_InLock);
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "locationInLock数据:" + JsonConvert.SerializeObject(locationOutLock));
|
List<string> lstInLockRow = locationInLock.Select(o => o.CN_S_ROW).Distinct().ToList();
|
List<TN_WM_LOCATIONCODE_EXT_Entity> lstLocationLock = new List<TN_WM_LOCATIONCODE_EXT_Entity>();
|
foreach (string sRow in lstInLockRow)
|
{
|
lstLocationLock = locationInLock.Where(o => o.CN_S_ROW == sRow).OrderByDescending(a => int.Parse(a.CN_S_COL)).ToList();
|
// tmpGreaterItem = lstTrueLItem.Where(o => o.CN_S_ROW == sRow && int.Parse(o.CN_S_COL) > int.Parse(lstLocationRowCols[0].CN_S_COL)).ToList();
|
lstTrueLItem.RemoveAll(o => o.CN_S_ROW == sRow && int.Parse(o.CN_S_COL) < int.Parse(lstLocationLock[0].CN_S_COL));
|
}
|
|
|
//去除因被阻挡而不能入的货位
|
List<AutoBomLocationAbbreEntity> lstLocationHasItem = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLocationByItemCode("", "", item.areaCode);
|
List<AutoBomLocationAbbreEntity> lstLocationRowCols = new List<AutoBomLocationAbbreEntity>();
|
List<string> lstRows = lstLocationHasItem.Select(o => o.CN_S_ROW).Distinct().ToList();
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "lstLocationSameItem数据:" + JsonConvert.SerializeObject(lstLocationHasItem));
|
// List<AutoBomLocationAbbreEntity> tmpTrueItem = new List<AutoBomLocationAbbreEntity>();
|
// List<AutoBomLocationAbbreEntity> tmpGreaterItem = new List<AutoBomLocationAbbreEntity>();
|
foreach (string sRow in lstRows)
|
{
|
lstLocationRowCols = lstLocationHasItem.Where(o => o.CN_S_ROW == sRow).OrderByDescending(a => int.Parse(a.CN_S_COL)).ToList();
|
//tmpGreaterItem = lstTrueLItem.Where(o => o.CN_S_ROW == sRow && int.Parse(o.CN_S_COL) > int.Parse(lstLocationRowCols[0].CN_S_COL)).ToList();
|
lstTrueLItem.RemoveAll(o => o.CN_S_ROW == sRow && int.Parse(o.CN_S_COL) < int.Parse(lstLocationRowCols[0].CN_S_COL));
|
//if (tmpGreaterItem.Count > 0)
|
//{
|
// tmpTrueItem.AddRange(tmpGreaterItem);
|
//}
|
}
|
//if (tmpTrueItem.Count > 0)
|
//{
|
// lstTrueLItem = tmpTrueItem;
|
//}
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "lstTrueLItem数据:" + JsonConvert.SerializeObject(lstTrueLItem));
|
|
#endregion
|
}
|
if (lstTrueLItem.Count > 0)
|
{
|
if (resultEntity.isControlQty == "N")
|
{
|
//该库区中的货位如果为不管控数量,则对所有货位平均分配入库任务
|
resultEntity = AverageLocation(lstTrueLItem, model.lockLocation, resultEntity.isControlQty);
|
}
|
else
|
{
|
//根据入库策略计算货位
|
resultEntity = CalLocationByStraty(resultEntity, lstDevice, lstTrueLItem, lstLocation, lstLockLItem, model.lockLocation);
|
}
|
}
|
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;
|
}
|
|
/// <summary>
|
/// 获取平库立库货架中最近的一个可用货位
|
/// </summary>
|
/// <param name="trayCode"></param>
|
/// <param name="lstDevice"></param>
|
/// <param name="lstTrueLocation"></param>
|
/// <returns></returns>
|
private InAssignResultEntity CalLocationByStraty(InAssignResultEntity resultEntity, List<Device> lstDevice, List<AutoBomLocationAbbreEntity> lstTrueLocation, List<AutoBomLocationAbbreEntity> lstAllLocation, List<AutoBomLocationAbbreEntity> lstLockLItem, bool lockLocation)
|
{
|
List<AutoBomLocationAbbreEntity> lstTmp_Location = new List<AutoBomLocationAbbreEntity>();
|
string deviceCode = string.Empty;
|
#region 查询该库区配置的入库策略及优先级
|
List<STRATEGYALGOREntity> lstStrategy = new List<STRATEGYALGOREntity>();
|
lstStrategy = CreateDAL<TN_WM_B_STRATEGYDAL>().GetStrateListByAreaOrStock("", resultEntity.areaCode, "入库");
|
List<string> lstStrate = lstStrategy.OrderByDescending(a => a.CN_N_PRIORITY).Select(o => o.CN_S_CODE).ToList();
|
#endregion
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "循环前lstTmp_Location数据:" + JsonConvert.SerializeObject(lstTmp_Location));
|
lstTmp_Location = CalculateLocByStegy(ref lstDevice, lstTrueLocation, lstAllLocation, lstLockLItem, lstStrate, out deviceCode);
|
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "循环后lstTmp_Location数据:" + JsonConvert.SerializeObject(lstTmp_Location));
|
if (lstTmp_Location == null || lstTmp_Location.Count == 0)
|
{
|
resultEntity.Success = false;
|
resultEntity.errCode = "8";
|
resultEntity.Msg = "库区有空货位但启用算法策略后计算出货位不足";
|
return resultEntity;
|
}
|
AutoBomLocationAbbreEntity at_l_Entity = lstTmp_Location[0];
|
if (lockLocation)
|
{
|
#region 锁定入库货位
|
SqlExecuteResult result = CreateDAL<TN_WM_LOCATION_EXTDAL>().UpdateLocationState(at_l_Entity.CN_S_LOCATION_CODE, Constants.Location_State_InLock, "入库", null);
|
Log.AlgorInfo("InAssign-CalLocationByStraty", at_l_Entity.CN_S_LOCATION_CODE + "货位更改为预入库锁定,锁定结果:" + result.Success + result.Row);
|
if (result.Success && result.Row > 0)
|
{
|
resultEntity.Success = true;
|
resultEntity.Msg = "";
|
resultEntity.locationCode = at_l_Entity.CN_S_LOCATION_CODE;
|
resultEntity.stockCode = at_l_Entity.CN_S_STOCK_CODE;
|
if (!string.IsNullOrEmpty(deviceCode))
|
{
|
//增加设备任务数
|
lstDevice = lstDevice.Select(o =>
|
{
|
o.taskNum = o.deviceCode == deviceCode ? o.taskNum + 1 : o.taskNum;
|
return o;
|
}).ToList();
|
}
|
}
|
else
|
{
|
resultEntity.Success = false;
|
resultEntity.errCode = "5";
|
resultEntity.Msg = "锁定货位状态失败";
|
}
|
#endregion
|
}
|
else
|
{
|
resultEntity.Success = true;
|
resultEntity.Msg = "";
|
resultEntity.locationCode = at_l_Entity.CN_S_LOCATION_CODE;
|
resultEntity.stockCode = at_l_Entity.CN_S_STOCK_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<AutoBomLocationAbbreEntity> CalculateLocByStegy(ref List<Device> lstDevice, List<AutoBomLocationAbbreEntity> lstLocation, List<AutoBomLocationAbbreEntity> lstAllLocation, List<AutoBomLocationAbbreEntity> lstLockLItem, List<string> lstStrate, out string deviceCode)
|
{
|
List<AutoBomLocationAbbreEntity> lstFilterLoc = lstLocation;
|
List<AutoBomLocationAbbreEntity> lstTmp = new List<AutoBomLocationAbbreEntity>();
|
deviceCode = string.Empty;
|
AlgorTacticsCommon Trctics = new AlgorTacticsCommon();
|
foreach (string stegy in lstStrate)
|
{
|
//逐个策略进行计算
|
switch (stegy)
|
{
|
case "EquipmentBalance": //设备均衡
|
lstFilterLoc = Trctics.EquipmentBalance(lstDevice, lstFilterLoc, out deviceCode);
|
break;
|
case "RoadWayBalance": //巷道均衡
|
lstFilterLoc = Trctics.RoadWayBalance(lstFilterLoc);
|
break;
|
case "NearByRoadWay": //巷道由近及远
|
lstFilterLoc = Trctics.RoadWayBalance(lstFilterLoc);
|
break;
|
case "NearbyBalance": //就近原则
|
lstFilterLoc = Trctics.NearbyBalance(lstFilterLoc);
|
break;
|
case "NearbyBalanceRow": //就近原则
|
lstFilterLoc = Trctics.NearbyBalanceRow(lstFilterLoc);
|
break;
|
case "FirstInLastOut": //宇寿 南通 巨星 先进后出
|
lstFilterLoc = Trctics.FirstInLastOut(lstFilterLoc, lstAllLocation, lstLockLItem, lstStrate);
|
break;
|
case "FirstInLastOutLj": //隆基先进后出
|
lstFilterLoc = Trctics.FirstInLastOutLj(lstFilterLoc, lstAllLocation, lstLockLItem, lstStrate);
|
break;
|
case "SyncEmptyFirst": //隆基 优先计算先被同步为空的货位
|
List<TN_WM_LOCATION_EXTEntity> lstTrueLocations = CreateDAL<TN_WM_LOCATION_EXTDAL>().GetLocationCreateTime(lstFilterLoc.Select(o => o.CN_S_LOCATION_CODE).ToList());
|
lstFilterLoc = lstFilterLoc.Join(lstTrueLocations, u => u.CN_S_LOCATION_CODE, d => d.CN_S_LOCATION_CODE, (u, d) => new { u, d })
|
.Select(o => new AutoBomLocationAbbreEntity
|
{
|
CN_S_LOCATION_CODE = o.u.CN_S_LOCATION_CODE,
|
CN_S_STOCK_CODE = o.u.CN_S_STOCK_CODE,
|
CN_T_CREATE = o.d.CN_T_CREATE
|
}).ToList();
|
lstFilterLoc = lstLocation.OrderBy(o => o.CN_T_CREATE).ToList(); ;
|
break;
|
|
}
|
|
}
|
return lstFilterLoc;
|
}
|
|
/// <summary>
|
/// 根据平均入库策略获取可用货位
|
/// </summary>
|
/// <param name="trayCode"></param>
|
/// <param name="lstDevice"></param>
|
/// <param name="lstTrueLocation"></param>
|
/// <returns></returns>
|
private InAssignResultEntity AverageLocation(List<AutoBomLocationAbbreEntity> lstTrueLocation, bool lockLocation, string isControlQty)
|
{
|
InAssignResultEntity resultEntity = new InAssignResultEntity();
|
//策略实体
|
AlgorTacticsCommon Trctics = new AlgorTacticsCommon();
|
AutoBomLocationAbbreEntity at_l_Entity = Trctics.AverageBalance(lstTrueLocation);
|
bool result = CreateDAL<TN_WMS_LOCATIONDAL>().UpdateLocationTaskQty(at_l_Entity.CN_S_LOCATION_CODE, at_l_Entity.CN_N_INTASK_QTY + 1);
|
if (result)
|
{
|
resultEntity.Success = true;
|
resultEntity.Msg = "";
|
resultEntity.locationCode = at_l_Entity.CN_S_LOCATION_CODE;
|
resultEntity.stockCode = at_l_Entity.CN_S_STOCK_CODE;
|
}
|
else
|
{
|
resultEntity.Success = false;
|
resultEntity.Msg = "计算货位失败-更新入库任务数失败";
|
}
|
return resultEntity;
|
}
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
}
|
}
|