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
{
///
/// 入库算法业务层
///
public class In_AlgorBLL : BaseBLL
{
/**************非作业区入库算法(平库、立库) 开始/**************/
#region 非作业区 入库算法
///
/// 入库算法
///
///
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().GetAreaTypeByCode(model.stockAreaCode);
List 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 非作业区立库入库算法 指定物料(通过库区关联逻辑分区,物料关联逻辑分区)
///
/// 入库 指定物料(通过库区关联逻辑分区,物料关联逻辑分区)
///
/// 物料编码
/// 逻辑分区编码
/// 库区编码
/// 需要货位的数量
/// 设备信息 AMS给出
///
private InResultEntity In_ItemCode(string itemCode, string logicCode, string stockAreaCode, int locationQty, List lstDevice, bool lockLocation)
{
InResultEntity resultEntity = new InResultEntity();
//需要纳入计算的逻辑分区集合
List lstLogic = new List();
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 lstLogics = new List(logicCode.Split(new string[] { ", " }, StringSplitOptions.RemoveEmptyEntries));
//通过逻辑分区编码集合以及库区编码获得逻辑分区仓库/库区/货位关联
List lstLogicEntityByArea = CreateDAL().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 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 非作业区立库入库算法 不指定物料(直接通过库区计算货位)
///
/// 入库 不指定物料(直接通过库区对应逻辑分区计算货位)
///
///
///
///
///
///
private InResultEntity In_TrayCode(string stockAreaCode, string logicCode, int locationQty, List lstDevice, bool lockLocation)
{
//返回类型
InResultEntity resultEntity = new InResultEntity();
//需要纳入计算的逻辑分区集合
List lstLogic = new List();
//如果逻辑分区不为空
if (!string.IsNullOrEmpty(logicCode))
{
List lstLogics = new List(logicCode.Split(new string[] { ", " }, StringSplitOptions.RemoveEmptyEntries));
//通过逻辑分区编码集合以及库区编码获得逻辑分区仓库/库区/货位关联
List lstLogicEntityByArea = CreateDAL().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 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 非作业区立库入库算法 通过逻辑分区计算符合条件的货位信息(指定物料专用)
///
/// 计算 通过逻辑分区计算符合条件的货位信息(指定物料专用)
///
/// 获得空位的数量
/// 设备信息
/// 逻辑分区详细
///
private List AlgorIn(string areaCode, int locationQty, List lstDevice, List lstLogic, bool lockLocation)
{
//货位列表
List lstLocations = new List();
//循环逻辑分区关联的仓库/库区/货位
foreach (LogicTrue logicEntity in lstLogic)
{
//获得真实可用的货位数据
Log.AlgorInfo("In_AlgorBLL-AlgorIn", "logicEntity实体数据" + JsonConvert.SerializeObject(logicEntity));
List 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 非作业区立库入库算法 利用入库策略计算得到货位列表(公用)
///
/// 利用入库策略计算得到货位列表(公用)
///
///
///
///
///
public List GetLocationsByStrategyAlgor(string areaCode, int locationQty, ref List lstDevice, ref List lstTrueLocation, bool lockLocation)
{
#region 查询该库区配置的入库策略及优先级
List lstStrategy = new List();
lstStrategy = CreateDAL().GetStrateListByAreaOrStock("", areaCode, "入库");
List lstStrate = lstStrategy.OrderByDescending(a => a.CN_N_PRIORITY).Select(o => o.CN_S_CODE).ToList();
#endregion
//策略实体
AlgorTacticsCommon Trctics = new AlgorTacticsCommon();
List lstTmp_Location = new List();
//返回货位实体列表
List lstLocations = new List();
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().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 CalculateLocByStegy(ref List lstDevice, List lstLocation, List lstStrate, out string deviceCode)
{
List 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 GetLogicList(string itemCode, string stockAreaCode, out string errMsg)
{
errMsg = "";
#region 通过物料取逻辑分区 逻辑分区关联物料
//需要纳入计算的逻辑分区集合
List lstLogic = new List();
//逻辑分区集合
List lstLogicEntityByItem = CreateDAL().GetPartitionItem(itemCode, 2);
if (lstLogicEntityByItem == null || lstLogicEntityByItem.Count == 0)
{
//根据物料编码获得物料信息
AutoBomItemEntity itemEntity = CreateDAL().GetItemEntity(itemCode);
if (itemEntity != null && !string.IsNullOrEmpty(itemEntity.CN_S_STORE_TYPE))
{
//获得物料类型
string itemType = itemEntity.CN_S_STORE_TYPE;
lstLogicEntityByItem = CreateDAL().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 lstLogicEntityByArea = CreateDAL().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 公用方法 获得真实可用的货位数据(公用)
///
/// 获得真实可用的货位数据 指已在关系型数据库中验证货位状态后的货位集合数据
///
/// 取交集后的逻辑分区列表
///
public List GetLocationByArea_R(LogicTrue model)
{
//用于存储真实可用的数据 注:此列表已在关系型数据库中验证了货位扩展表的状态
//可以用于入库策略计算与生成
List lstTrueLocation = new List();
//根据逻辑分区查询出来可用的货位列表 注:此列表暂未在关系型数据库中货位扩展验证状态
List locationCodes = new List();
List lstLocation = new List();
switch (model.type)
{
case 1://返回仓库对应的货位列表
lstLocation = CreateDAL().GetLocationByStockCode(model.stockCode);
break;
case 2://返回库区对应的货位列表
lstLocation = CreateDAL().GetLocationByAreaCode(model.areaCode);
break;
case 3://直接返回货位编号
locationCodes = new List(model.locationCode.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries));// new List() { model.locationCode };
lstLocation = CreateDAL().GetLocationByLocationCode(locationCodes);
break;
case 4://返回库区对应的货位列表
lstLocation = CreateDAL().GetLocationByAreaCode(model.areaCode);
break;
case 5://返回库区对应的货位列表
locationCodes = new List() { model.locationCode };
lstLocation = CreateDAL().GetLocationByLocationCode(locationCodes);
break;
case 6://返回库区对应的货位列表
lstLocation = CreateDAL().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 locationLog = lstLocation.Select(o => o.CN_S_LOCATION_CODE).ToList();
// Log.Debug("Inasign", "TN_AB_STOCK_LOCATION中货位数据" + string.Join(",", locationLog));
//}
//货位扩展表中可用的货位
//List locationTrueCodes = GetTrueLocationCodes(model.stockCode, locationCodes, model.type);
List locationTrueCodes = GetTrueLocationCodes(model.stockCode.Trim(), model.areaCode, locationCodes, model.type);
if (locationTrueCodes.Count == 0)
{
Log.AlgorInfo("GetLocationByArea_R", "货位扩展表中没有数据");
}
//else
//{
// List 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 locationLog = lstTrueLocation.Select(o => o.CN_S_LOCATION_CODE).ToList();
Log.AlgorInfo("GetLocationByArea_R", "lstTrueLocation中货位数据" + string.Join(",", locationLog));
}
return lstTrueLocation;
}
public List GetLocationByArea_R(LogicTrue model, string locationType)
{
//用于存储真实可用的数据 注:此列表已在关系型数据库中验证了货位扩展表的状态
//可以用于入库策略计算与生成
List lstTrueLocation = new List();
//根据逻辑分区查询出来可用的货位列表 注:此列表暂未在关系型数据库中货位扩展验证状态
List locationCodes = new List();
List lstLocation = new List();
switch (model.type)
{
case 1://返回仓库对应的货位列表
lstLocation = CreateDAL().GetLocationByStockCode(model.stockCode);
break;
case 2://返回库区对应的货位列表
lstLocation = CreateDAL().GetLocationByAreaCode(model.areaCode, locationType);
break;
case 3://直接返回货位编号
locationCodes = new List(model.locationCode.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries));// new List() { model.locationCode };
lstLocation = CreateDAL().GetLocationByLocationCode(locationCodes, locationType);
break;
case 4://返回库区对应的货位列表
lstLocation = CreateDAL().GetLocationByAreaCode(model.areaCode);
break;
case 5://返回库区对应的货位列表
locationCodes = new List() { model.locationCode };
lstLocation = CreateDAL().GetLocationByLocationCode(locationCodes);
break;
case 6://返回库区对应的货位列表
lstLocation = CreateDAL().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 locationLog = lstLocation.Select(o => o.CN_S_LOCATION_CODE).ToList();
// Log.Debug("Inasign", "TN_AB_STOCK_LOCATION中货位数据" + string.Join(",", locationLog));
//}
//货位扩展表中可用的货位
//List locationTrueCodes = GetTrueLocationCodes(model.stockCode, locationCodes, model.type);
List locationTrueCodes = GetTrueLocationCodes(model.stockCode.Trim(), model.areaCode, locationCodes, model.type);
if (locationTrueCodes.Count == 0)
{
Log.AlgorInfo("GetLocationByArea_R", "货位扩展表中没有数据");
}
//else
//{
// List 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 locationLog = lstTrueLocation.Select(o => o.CN_S_LOCATION_CODE).ToList();
// Log.AlgorInfo("GetLocationByArea_R", "lstTrueLocation中货位数据" + string.Join(",", locationLog));
//}
return lstTrueLocation;
}
///
/// 获得货位扩展表中可用的货位
///
///
///
///
private List GetTrueLocationCodes(string stockCode, string areaCode, List locationCodes, int type)
{
List lstTrueLocations = new List();
switch (type)
{
case 1://仓库 只根据仓库编号获得可用货位
lstTrueLocations = CreateDAL().GetLocationCodeExtListBy(stockCode, areaCode, null, "入库");
break;
case 2://库区 根据货位编码集合 in 查询关系型数据库中的扩展货位表数据
lstTrueLocations = CreateDAL().GetLocationCodeExtListBy(stockCode, areaCode, null, "入库");
break;
case 3://货位 根据单个货位编码 = 查询关系型数据库中的扩展货位表数据
lstTrueLocations = CreateDAL().GetLocationCodeExtListBy(stockCode, areaCode, locationCodes, "入库");
break;
case 4://库区(流离式货架) 根据货位编码集合 in 查询关系型数据库中的扩展货位表数据
lstTrueLocations = CreateDAL().GetLocationCodeExtListBy(stockCode, areaCode, null, "入流离库");
break;
case 5://库区(流离式货架) 根据货位编码集合 in 查询关系型数据库中的扩展货位表数据
lstTrueLocations = CreateDAL().GetLocationCodeExtListBy(stockCode, areaCode, locationCodes, "入流离库");
break;
}
return lstTrueLocations;
}
#endregion
#region 作业区(流离式、平库、立库)入库算法入扣
public InAssignResultEntity InAssign(InAssignEntity model)
{
//定义返回实体
InAssignResultEntity resultEntity = new InAssignResultEntity();
resultEntity.Msg = "";
Log.AlgorInfo("InAssign", "入库算法参数:" + JsonConvert.SerializeObject(model));
try
{
#region 传入参数判断
if (model == null)
{
resultEntity.Success = false;
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.Msg = "指定的入作业库库区列表不能为空!";
return resultEntity;
}
#endregion
//(流离式、平库、立库)标准入库算法
string areaType = CreateDAL().GetAreaTypeByCode(model.lstAreaPrior[0].areaCode.ToString());
if (areaType == Constants.Area_Struc_PingStock || areaType == Constants.Area_Struc_LiStock)
{
if (model.projectCode == "jxhn")
{
resultEntity = FlatAreaGetLocationJx(model, model.lstDevice);
}
else
{
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.Msg = "算法异常," + ex.Message + ex.StackTrace;
resultEntity.errCode = "1002";
return resultEntity;
}
}
#endregion
#region 作业区 平库入库算法
public InAssignResultEntity FlatAreaGetLocation(InAssignEntity model, List lstDevice)
{
InAssignResultEntity resultEntity = new InAssignResultEntity();
resultEntity.Success = false;
List lstTrueLocation = new List();
List lstTmpLocation = new List();
List lstALR = null;
List lstLocation = new List();
List lstJuxingLocation = new List();
List lstLockLItem = new List();
List lstEmptyLocation = new List();
List lstTrueLItem = new List();
List lstAreaPrior = model.lstAreaPrior.OrderBy(o => o.Prior).ToList();
StringBuilder sbDetailError = new StringBuilder();
if (model.projectCode == "ntsd")
{
foreach (areaPriorClass item in lstAreaPrior)
{
List lstTask = CreateDAL().GetTaskByAreaCode(item.areaCode);
item.Prior = lstTask.Count;
}
lstAreaPrior = lstAreaPrior.OrderBy(o => o.Prior).ToList();
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "lstAreaPrior数据:" + JsonConvert.SerializeObject(lstAreaPrior));
}
#region 从autobom和货位扩展表中获取可用货位集合
//按优先级循环处理库区获取可用货位集合
foreach (areaPriorClass item in lstAreaPrior)
{
AutoBomStockAreaEntity areaModel = CreateDAL().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().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().AutoBomLocationTrue(logicModel);
// Log.AlgorInfo("InAssign-FlatAreaGetLocation", "lstLocation:" + JsonConvert.SerializeObject(lstLocation));
//获取在货位扩展表中可用的货位的集合(去除锁定的货位)
List locationTrueCodes = BLLCreator.Create().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().GetAreaClassByCode(item.areaCode.ToString());
//控制该库区的任务总数阀值
if (areaClass == "高架库")
{
#region 高架库
//LogicTrue logicT = new LogicTrue();
//logicT.stockCode = "";
//logicT.type = 2;
//logicT.areaCode = item.areaCode;
//lstJuxingLocation = BLLCreator.Create().AutoBomLocationTrue(logicT);
//获取系统配置的巷道最大任务数限制
long maxTaskQty = 0;
List list = BLLCreator.Create>().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 lstTask = CreateDAL().GetTaskByAreaCode(item.areaCode);
List lstRoadTask = new List();
lstRoadTask = lstTrueLItem.GroupBy(o => o.CN_S_ROADWAY).Select(g => (new RoadTask
{
roadWay = g.Key,
taskNum = 0
})).Distinct().ToList();
List lstTmpL = new List();
List lstNewRoadTask = new List();
foreach (RoadTask roadT in lstRoadTask)
{
lstTmpL = lstLocation.Where(o => o.CN_S_ROADWAY == 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).ToList();
lstTmpL = lstNewRoadTask.Where(o => o.taskNum == lstNewRoadTask.FirstOrDefault().taskNum).Select(a => a.roadWay).ToList();
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "lstNewRoadTask:" + JsonConvert.SerializeObject(lstNewRoadTask));
lstTrueLItem = lstTrueLItem.Where(o => lstTmpL.Contains(o.CN_S_ROADWAY)).ToList();
}
else
{
lstTrueLItem.Clear();
}
#endregion
}
else if (areaClass == "缓存区")
{
#region 缓存区
//巷道内有入不能有出 有出不能有入 巷道任务尽量平均分配
// 获取预入库锁定的货位
List locationInLock = CreateDAL().GetLockLocationByState(model.stockCode.Trim(), item.areaCode, null, Constants.Location_State_InLock);
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "locationInLock数据:" + JsonConvert.SerializeObject(locationInLock));
// 获取预出库锁定的货位
List locationOutLock = CreateDAL().GetLockLocationByState(model.stockCode.Trim(), item.areaCode, null, Constants.Location_State_OutLock);
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "locationOutLock数据:" + JsonConvert.SerializeObject(locationOutLock));
List lstOutLockRow = locationOutLock.Select(o => o.CN_S_ROW).Distinct().ToList();
lstTrueLItem.RemoveAll(o => lstOutLockRow.Contains(o.CN_S_ROW));
//获取货位所在行的预入库任务数量
List lstTask = new List();
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 lstLocationHasItem = CreateDAL().GetLocationByItemCode("", "", item.areaCode);
List lstLocationRowCols = new List();
List lstRows = lstLocationHasItem.Select(o => o.CN_S_ROW).Distinct().ToList();
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "lstLocationSameItem数据:" + JsonConvert.SerializeObject(lstLocationHasItem));
List tmpTrueItem = new List();
List tmpGreaterItem = new List();
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 locationInLock = CreateDAL().GetLockLocationByState(model.stockCode.Trim(), item.areaCode, logicModel.lstLocationCode, Constants.Location_State_InLock);
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "去除被(异形件)人工绑定阻挡的货位数据:" + JsonConvert.SerializeObject(locationInLock));
//获取货位所在行的预入库任务数量
List lstTask = new List();
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 (model.projectCode == "ys001")
{
#region 宇寿算法定制代码
//获取该托盘中的物料信息
List lstOriginalMST = BLLCreator.Create>().GetList(new { CN_S_TRAY_CODE = model.objectCode });
string itemCode = "";
if (lstOriginalMST.Count > 0)
{
itemCode = lstOriginalMST[0].CN_S_ITEM_CODE;
}
//获取预出库锁定的货位
List locationOutLock = CreateDAL().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 locationCheckLock = CreateDAL().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 locationCarryLock = CreateDAL().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 lstLocationHasItem = CreateDAL().GetLocationByItemCode("", "", item.areaCode);
List lstLocationHasItemOrder = new List();
List lstLocationRowCols = new List();
List 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 lstLocationSameItem = CreateDAL().GetLocationByItemCode(itemCode, item.areaCode);
//查找该库区中即将要存放该物料的货位
List lstTaskSameItem = CreateDAL().GetInTaskLocationByItemCode(itemCode, item.areaCode);
if (lstTaskSameItem.Count > 0)
{
lstLocationSameItem.AddRange(lstTaskSameItem);
}
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "lstLocationSameItem数据:" + JsonConvert.SerializeObject(lstLocationSameItem));
List tmpTrueItem = new List();
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 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
}
else if (model.projectCode == "qzhk")
{
#region 衢州华凯算法定制代码
string areaClass = CreateDAL().GetAreaClassByCode(item.areaCode.ToString());
if (areaClass == "密集型")
{
string itemCode = model.itemCode;
//获取预出库锁定的货位
List locationOutLock = CreateDAL().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 lstLocationHasItem = CreateDAL().GetLocationByItemCode("", "", item.areaCode);
List lstLocationHasItemOrder = new List();
List lstLocationRowCols = new List();
List lstItemRows = lstLocationHasItem.GroupBy(a => new
{
a.CN_S_ROW,
}).Select(o => new AutoBomLocationAbbreEntity
{
CN_S_ROW = o.Key.CN_S_ROW
}).ToList();
foreach (AutoBomLocationAbbreEntity itemC in lstItemRows)
{
lstLocationHasItemOrder = lstLocationHasItem.Where(o => o.CN_S_ROW == itemC.CN_S_ROW).OrderByDescending(a => int.Parse(a.CN_S_COL)).ToList();
lstTrueLItem.RemoveAll(o => o.CN_S_ROW == itemC.CN_S_ROW && int.Parse(o.CN_S_COL) < int.Parse(lstLocationHasItemOrder[0].CN_S_COL));
}
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "去除阻挡后的lstTrueLItem数据:" + JsonConvert.SerializeObject(lstTrueLItem));
//查找该库区中已存放该物料的货位
List lstLocationSameItem = CreateDAL().GetLocationByItemCodeAndLotNo(model.itemCode, model.lotNo, item.areaCode);
//查找该库区中即将要存放该物料的货位
List lstTaskSameItem = CreateDAL().GetInTaskLocationByItemCodeAndLotNo(model.itemCode, model.lotNo, item.areaCode);
if (lstTaskSameItem.Count > 0)
{
lstLocationSameItem.AddRange(lstTaskSameItem);
}
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "lstLocationSameItem数据:" + JsonConvert.SerializeObject(lstLocationSameItem));
List tmpTrueItem = new List();
lstItemRows = lstLocationSameItem.GroupBy(a => new
{
a.CN_S_ROW
}).Select(o => new AutoBomLocationAbbreEntity
{
CN_S_ROW = o.Key.CN_S_ROW
}).ToList();
foreach (AutoBomLocationAbbreEntity lEntity in lstItemRows)
{
tmpTrueItem.AddRange(lstTrueLItem.Where(o => o.CN_S_ROW == lEntity.CN_S_ROW).ToList());
}
if (tmpTrueItem.Count > 0)
{
lstTrueLItem = tmpTrueItem;
}
else
{
//判断库区中是否有未使用的空列
List lstEmptyCol = lstTrueLItem.GroupBy(a => new
{
a.CN_S_ROW
}).Select(o => new AutoBomLocationAbbreEntity
{
CN_S_ROW = o.Key.CN_S_ROW
}).ToList();
foreach (AutoBomLocationAbbreEntity aEntity in lstEmptyCol)
{
if (lstTrueLItem.Where(o => o.CN_S_ROW == aEntity.CN_S_ROW).Count() == lstLocation.Where(o => o.CN_S_ROW == aEntity.CN_S_ROW).Count())
{
tmpTrueItem.AddRange(lstTrueLItem.Where(o => o.CN_S_ROW == aEntity.CN_S_ROW).ToList());
}
}
if (tmpTrueItem.Count > 0)
{
lstTrueLItem = tmpTrueItem;
}
}
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "lstTrueLItem数据:" + JsonConvert.SerializeObject(lstTrueLItem));
}
#endregion
}
else if (model.projectCode == "masym")
{
#region 马鞍山粤美算法定制代码
List lstStrategy = CreateDAL().GetStrateListByAreaOrStock("", resultEntity.areaCode, "入库");
//获取预出库锁定的货位
if (lstStrategy.Select(o => o.CN_S_CODE).ToList().Contains("FirstInLastOut"))
{
List locationOutLock = CreateDAL().GetLockLocationByState(model.stockCode.Trim(), item.areaCode, logicModel.lstLocationCode, Constants.Location_State_OutLock);
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "locationOutLock数据:" + JsonConvert.SerializeObject(lstLockLItem));
List 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 lstLocationHasItem = CreateDAL().GetLocationByItemCode("", "", item.areaCode);
List lstLocationInlock = CreateDAL().GetLocationByInLockYM("", "", item.areaCode);
if (lstLocationInlock.Count > 0)
{
lstLocationHasItem.AddRange(lstLocationInlock);
}
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "lstLocationHasItem数据:" + JsonConvert.SerializeObject(lstLocationHasItem));
List lstLocationHasItemOrder = new List();
List 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 lstStrategy = new List();
lstStrategy = CreateDAL().GetStrateListByAreaOrStock("", resultEntity.areaCode, "入库");
if (lstStrategy.Select(o => o.CN_S_CODE).ToList().Contains("FirstInLastOut"))
{
//获取该托盘中的物料信息
List lstOriginalMST = BLLCreator.Create>().GetList(new { CN_S_TRAY_CODE = model.objectCode });
string itemCode = "";
if (lstOriginalMST.Count > 0)
{
itemCode = lstOriginalMST[0].CN_S_ITEM_CODE;
}
//获取预出库锁定的货位,预出库锁定货位所在列的其他货位(同层)还可以使用
//List locationOutLock = CreateDAL().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 locationOutLock = CreateDAL().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 locationInLock = CreateDAL().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 lstLocationSameItem = CreateDAL().GetLocationByItemCode(itemCode, item.areaCode);
//查找该库区中即将要存放该物料的货位
List lstTaskSameItem = CreateDAL().GetInTaskLocationByItemCode(itemCode, item.areaCode);
if (lstTaskSameItem.Count > 0)
{
lstLocationSameItem.AddRange(lstTaskSameItem);
}
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "lstLocationSameItem数据:" + JsonConvert.SerializeObject(lstLocationSameItem));
//获取该库区中已存放该物料或即将存放该物料的排
//List lstSameItemRow = lstLocationSameItem.Select(o => o.CN_S_ROW).Distinct().ToList();
List lstEmptyRow = lstTrueLItem.Select(o => o.CN_S_ROW).Distinct().ToList();
//获取符合条件的排lstSameItemRow中任务最少的一个排并且该排中有位置可以放
List lstRowTask = new List();
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 lstStrategy = new List();
lstStrategy = CreateDAL().GetStrateListByAreaOrStock("", resultEntity.areaCode, "入库");
List locationOutLock = new List();
List locationInLock = new List();
if (lstStrategy.Select(o => o.CN_S_CODE).ToList().Contains("FirstInLastOutLj"))
{
//获取预出库锁定的货位,预出库锁定货位所在排不能入
locationOutLock = CreateDAL().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().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 lstLocationSameItem = CreateDAL().GetLocationByItemCode(model.itemCode, item.areaCode);
////查找该库区中即将要存放该物料的货位
//List lstTaskSameItem = CreateDAL().GetInTaskLocationByItemCode(itemCode, item.areaCode);
//if (lstTaskSameItem.Count > 0)
//{
// lstLocationSameItem.AddRange(lstTaskSameItem);
//}
//Log.AlgorInfo("InAssign-FlatAreaGetLocation", "lstLocationSameItem数据:" + JsonConvert.SerializeObject(lstLocationSameItem));
//获取该库区中已存放该物料或即将存放该物料的排
// List lstSameItemRow = lstLocationSameItem.Select(o => o.CN_S_ROW).Distinct().ToList();
//List tmpTrueItem = new List();
List lstEmptyCol = lstTrueLItem.Select(o => o.CN_S_COL).Distinct().ToList();
//获取符合条件的排lstSameItemRow中任务最少的一个列并且该排中有位置可以放
List lstColTask = new List();
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 locationOutLock = CreateDAL().GetLockLocationByState(model.stockCode.Trim(), item.areaCode, logicModel.lstLocationCode, Constants.Location_State_OutLock);
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "locationOutLock数据:" + JsonConvert.SerializeObject(locationOutLock));
List lstOutLockRow = locationOutLock.Select(o => o.CN_S_ROW).Distinct().ToList();
lstTrueLItem.RemoveAll(o => lstOutLockRow.Contains(o.CN_S_ROW));
//获取预出库锁定的货位
List locationInLock = CreateDAL().GetLockLocationByState(model.stockCode.Trim(), item.areaCode, logicModel.lstLocationCode, Constants.Location_State_InLock);
Log.AlgorInfo("InAssign-FlatAreaGetLocation", "locationInLock数据:" + JsonConvert.SerializeObject(locationOutLock));
List lstInLockRow = locationInLock.Select(o => o.CN_S_ROW).Distinct().ToList();
List lstLocationLock = new List