using HH.WMS.Common;
using HH.WMS.Common.Algorithm;
using HH.WMS.Common.Algorithm.Out;
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 HH.WMS.BLL.Common;
using Newtonsoft.Json;
using HH.WMS.Entitys.Dto;
using HH.WMS.Entitys;
namespace HH.WMS.BLL.Algorithm
{
///
/// 出库算法BLL层
///
public class Out_AlgorBLL : BaseBLL
{
/**************计算 返回物料所在货位的算法开始/**************/
#region 非作业区 出库算法
///
/// 返回物料 先进先出、质保期将近的先出
///
///
///
//public List Out(OutAlgorEnitty model)
//{
// List lstResultEntity = new List();
// Log.AlgorInfo("Out_AlgorBLL—Out", "出库算法开始,传入参数:" + JsonConvert.SerializeObject(model));
// //获取项目策略
// List lstStrategy = new List();
// HH.WMS.Entitys.Basic.AutoBomStockAreaEntity stockEntity = CreateDAL().GetStockAreaEntity(model.lstQueryItem[0].areaCode);
// lstStrategy = CreateDAL().GetStrateListByAreaOrStock(stockEntity.CN_S_STOCK_CODE, "", "");
// List lstStrate = lstStrategy.Select(o => o.CN_S_NAME).ToList();
// //if (lstStrate.Contains("JXXAlgor"))
// //{
// lstResultEntity = OutJxxFlat(model);
// //}
// //if (lstStrate.Contains("SszyAlgor"))
// //{
// // lstResultEntity = OutSszyFlat(model);
// //}
// return lstResultEntity;
//}
#endregion
#region 非作业区 平库立库出库算法,根据物料的数量出库
/////
///// 非作业区 平库立库出库算法,根据物料的数量出库
/////
/////
/////
//public List OutJxxFlat(OutAlgorEnitty model)
//{
// Log.AlgorInfo("Out_AlgorBLL—Out", "OutJxxFlat");
// List lstResultEntity = new List();
// //将传递过来的参数按货主、状态、等查询条件分组
// List lstAreaItemGroup = GroupAreaCode(model.lstQueryItem);
// foreach (Out_AreaItemClass areaItemEntity in lstAreaItemGroup)
// {
// Log.AlgorInfo("Out_AlgorBLL—Out", "循环处理lstAreaItemGroup数据:" + JsonConvert.SerializeObject(areaItemEntity));
// string areaCode = areaItemEntity.areaCode;
// string itemCodes = string.Join(",", areaItemEntity.lstItem.Select(o => o.itemCode)).Replace(",", "','");
// //组合查询条件
// string strWhere = GetPropWhereStr(itemCodes, areaItemEntity.itemState, areaItemEntity.batchCode, areaItemEntity.prodBatchCode, areaItemEntity.ownerName);
// //查询该库区配置的出库策略及优先级(生产日期早先出、先进先出、出库整托优先)
// List lstStrategy = new List();
// lstStrategy = CreateDAL().GetStrateListByAreaOrStock("", areaCode, "出库");
// List lstStrate = lstStrategy.Select(o => o.CN_S_NAME).ToList();
// //获得库区中所有匹配的物料
// List v = CreateDAL().GetItemQtyJxx(strWhere, areaCode);
// Log.AlgorInfo("Out_AlgorBLL—Out", "List数据:" + JsonConvert.SerializeObject(v));
// //循环处理批分分配量
// List lstAllocQty = v.Select(g => new itemQty()
// {
// trayCode = g.trayCode,
// CN_F_ALLOC_QTY = g.CN_F_ALLOC_QTY,
// CN_S_OWNER = g.CN_S_OWNER,
// CN_S_ITEM_STATE = g.CN_S_ITEM_STATE,
// itemCode = g.itemCode,
// }).Distinct().ToList();
// int tmpAllocQty = 0;
// foreach (itemQty item in v)
// {
// //循环托盘物料详细数据,按生产批次早、入库批次早批分分配量
// tmpAllocQty = lstAllocQty.Where(o => (o.trayCode == item.trayCode && o.CN_S_OWNER == item.CN_S_OWNER && o.CN_S_ITEM_STATE == item.CN_S_ITEM_STATE && o.itemCode == item.itemCode)).FirstOrDefault().CN_F_ALLOC_QTY;
// if (tmpAllocQty > 0)
// {
// item.Qty = item.Qty - tmpAllocQty;
// lstAllocQty.Where(o => (o.trayCode == item.trayCode && o.CN_S_OWNER == item.CN_S_OWNER && o.CN_S_ITEM_STATE == item.CN_S_ITEM_STATE && o.itemCode == item.itemCode)).FirstOrDefault().CN_F_ALLOC_QTY = item.Qty - tmpAllocQty;
// }
// }
// v.RemoveAll(o => o.Qty <= 0);
// Log.AlgorInfo("Out_AlgorBLL—Out", "获得库区中所有匹配的物料:lstItemQty:" + JsonConvert.SerializeObject(v));
// List lstCodes = v.GroupBy(a => a.locationCode).Select(o => o.Key).ToList();
// //到mongodb中查询每个货位的基本信息排除货位被报废的数据
// List lstFalseLocation = CreateDAL().GetScrapLocationCode(lstCodes);
// lstCodes = lstFalseLocation.Select(a => a.CN_S_LOCATION_CODE).ToList();
// v.RemoveAll(o => lstCodes.Contains(o.locationCode));
// //循环前端物料列表
// foreach (itemInClass item in areaItemEntity.lstItem)
// {
// //定义返回值
// OutResultEntity resultEntity = new OutResultEntity();
// //验证过的物料货位集合
// List lstTrueItem = new List();
// //判断是否合法
// MsgEntity msgEntity = IsPassItem(item, v, out lstTrueItem);
// if (!msgEntity.Success)//不合法
// {
// resultEntity.Success = false;
// resultEntity.Msg = msgEntity.Msg;
// resultEntity.itemCode = item.itemCode;
// }
// else //合法
// {
// resultEntity.Success = true;
// resultEntity.itemCode = item.itemCode;
// /*返回时加入条件*/
// resultEntity.areaCode = areaItemEntity.areaCode;
// resultEntity.batchCode = areaItemEntity.batchCode;
// resultEntity.prodBatchCode = areaItemEntity.prodBatchCode;
// resultEntity.itemState = areaItemEntity.itemState;
// resultEntity.ownerName = areaItemEntity.ownerName;
// /*条件结束*/
// List lstResult = GetJXXTrayLocation(lstStrate, item, model.lstDevice, lstTrueItem, model.lockLocation);
// resultEntity.itemLocations = lstResult.GroupBy(a => new
// {
// a.agvLocationCode,
// a.locationCode,
// a.trayCode,
// a.trayGrid
// }).Select(g => new itemTrayLocation()
// {
// itemQty = g.Sum(s => s.itemQty),
// agvLocationCode = g.Key.agvLocationCode,
// locationCode = g.Key.locationCode,
// trayCode = g.Key.trayCode,
// trayGrid = g.Key.trayGrid
// }).ToList();
// }
// lstResultEntity.Add(resultEntity);
// }
// }
// return lstResultEntity;
//}
#endregion
public OutResultEntityNew OutNew(OutAlgorEnitty model)
{
OutResultEntityNew resultE = new OutResultEntityNew();
Log.AlgorInfo("Out_AlgorBLL—Out", "出库算法开始,传入参数:" + JsonConvert.SerializeObject(model));
resultE = OutCommonFlat(model);
return resultE;
}
#region 非作业区 平库立库出库算法,根据物料的数量出库
///
/// 非作业区 平库立库出库算法,根据物料的数量出库
///
///
///
public OutResultEntityNew OutCommonFlat(OutAlgorEnitty model)
{
OutResultEntityNew resultEntity = new OutResultEntityNew();
resultEntity.Success = true;
resultEntity.Msg = "";
try
{
#region 定义变量
Log.AlgorInfo("Out_AlgorBLL—Out", "OutCommonFlat");
StringBuilder sbWhere = new StringBuilder();
List lstAllIQ = new List();
List lstTray = new List();
resultEntity.lstItemNotEnough = new List();
#endregion
#region 查询该库区配置的出库策略及优先级
List lstStrategy = new List();
lstStrategy = CreateDAL().GetStrateListByAreaOrStock("", model.lstQueryItem[0].areaCode, "出库");
List lstStrate = lstStrategy.OrderByDescending(a => a.CN_N_PRIORITY).Select(o => o.CN_S_CODE).ToList();
#endregion
#region 缓存记录托盘、货主、物料、状态对应的待分配量,循环itemQueryClass时根据结果实时更新
//List lstWaitAlloc = new List();
//List lstForAlloc = new List();
//foreach (itemQueryClass itemQuery in model.lstQueryItem)
//{
// lstForAlloc = CreateDAL().GetOutItemAllocQty(itemQuery.itemCode, itemQuery.itemState, itemQuery.ownerName, itemQuery.areaCode);
// if (lstForAlloc != null && lstForAlloc.Count > 0)
// {
// lstWaitAlloc.AddRange(lstForAlloc);
// }
//}
//lstWaitAlloc = lstWaitAlloc.Distinct().ToList();
//if (lstWaitAlloc.Count == 0)
//{
// //如果从库区中查找不到符合出库条件的托盘,则将传入物料记录到物料不足列表中反馈
// resultEntity.lstItemNotEnough.AddRange(model.lstQueryItem);
// return resultEntity;
//}
#endregion
foreach (itemQueryClass itemQuery in model.lstQueryItem)
{
Log.AlgorInfo("Out_AlgorBLL—Out", "循环处理lstQueryItem数据:" + JsonConvert.SerializeObject(itemQuery));
#region 循环处理批分分配量
//获得库区中所有匹配的待出库的物料库存数据
List lstIQ = CreateDAL().GetOutItemQty(itemQuery.itemCode, itemQuery.itemState, itemQuery.prodBatchCode, itemQuery.batchCode, itemQuery.ownerName, itemQuery.areaCode);
if (lstIQ.Count == 0)
{
resultEntity.lstItemNotEnough.Add(itemQuery);
continue;
}
//Log.AlgorInfo("Out_AlgorBLL—Out", "批分前库区中所有匹配的物料数据:" + JsonConvert.SerializeObject(lstIQ));
////过滤lstWaitAlloc中不在lstIQ中的托盘,因为这些托盘的待分配量不需要处理
//List lstTrayCode = lstIQ.Select(o => o.trayCode).Distinct().ToList();
//List lstAllocQty = lstWaitAlloc.Where(o => o.CN_F_ALLOC_QTY > 0 && lstTrayCode.Contains(o.trayCode) && o.itemCode == itemQuery.itemCode && o.CN_S_OWNER == itemQuery.ownerName && o.CN_S_ITEM_STATE == itemQuery.itemState).Select(g => new itemQty()
//{
// trayCode = g.trayCode,
// CN_F_ALLOC_QTY = g.CN_F_ALLOC_QTY,
// CN_S_OWNER = g.CN_S_OWNER,
// CN_S_ITEM_STATE = g.CN_S_ITEM_STATE,
// itemCode = g.itemCode
//}).Distinct().ToList();
//decimal alloc_qty = 0;
//foreach (itemQty iQty in lstAllocQty)
//{
// alloc_qty = iQty.CN_F_ALLOC_QTY;
// //递归批分处理货位托盘中的待分配量,去除lstIQ中已经被批分的数据(已被其他分拣单占用的数据)
// DivideAllocQty(ref lstIQ, iQty, ref alloc_qty, lstStrate);
//}
//Log.AlgorInfo("Out_AlgorBLL—Out", "批分后库区中所有匹配的物料数据:" + JsonConvert.SerializeObject(lstIQ));
#endregion
#region 到mongodb中查询每个货位的基本信息,排除货位被报废的数据
List lstCodes = lstIQ.GroupBy(a => a.locationCode).Select(o => o.Key).ToList();
List lstFalseLocation = CreateDAL().GetScrapLocationCode(lstCodes);
lstCodes = lstFalseLocation.Select(a => a.CN_S_LOCATION_CODE).ToList();
//此时的lstIQ是去除批分量、货位无故障的可出库物料数据
lstIQ.RemoveAll(o => lstCodes.Contains(o.locationCode));
#endregion
#region 处理不满足出库数量的物料并计算可出库货位
//按照库区等查询条件分组
var lstItemGroup = lstIQ.GroupBy(a => new
{
a.itemCode
}).Select(g => (new
{
itemCode = g.Key.itemCode,
itemQty = g.Sum(p => p.Qty)
}));
var equalItem = lstItemGroup.Where(o => o.itemCode == itemQuery.itemCode).FirstOrDefault();
if (equalItem == null || equalItem.itemQty < itemQuery.itemQty)
{
//记录不满足出库条件的物料
itemQuery.itemQty = itemQuery.itemQty - equalItem.itemQty;
resultEntity.lstItemNotEnough.Add(itemQuery);
}
else
{
Log.AlgorInfo("Out_AlgorBLL—Out", "计算具体出库货位开始:");
decimal needOutQty = itemQuery.itemQty;
lstTray.AddRange(CalculateOutLocation(itemQuery, ref needOutQty, ref lstIQ, lstStrate));
//增加缓存批分量
//foreach (trayOutItem toItem in lstTray)
//{
// tmpItemQty = lstWaitAlloc.Where(o => o.trayCode == toItem.trayCode && o.itemCode == toItem.itemCode && o.CN_S_OWNER == toItem.ownerName && o.CN_S_ITEM_STATE == toItem.itemState).FirstOrDefault();
// if (tmpItemQty != null)
// {
// tmpItemQty.CN_F_ALLOC_QTY = tmpItemQty.CN_F_ALLOC_QTY + toItem.itemQty;
// }
//}
List needLock = lstTray.Select(o => o.locationCode).Distinct().ToList();
foreach (string itemLoc in needLock)
{
//更新货位状态
if (model.lockLocation)
{
SqlExecuteResult result = CreateDAL().UpdateLocationState(itemLoc, Constants.Location_State_OutLock, "出库", null);
Log.AlgorInfo("Out_AlgorBLL", "货位" + itemLoc + "更改为预出库锁定,执行结果为:" + result.Success.ToString() + result.Row.ToString());
}
}
}
#endregion
}
resultEntity.itemLocations = lstTray;
}
catch (Exception ex)
{
resultEntity.Success = false;
resultEntity.Msg = ex.Message;
}
Log.AlgorInfo("Out_AlgorBLL—Out", "返回计算结果:" + JsonConvert.SerializeObject(resultEntity));
return resultEntity;
}
public List CalculateOutLocation(itemQueryClass itemQC, ref decimal needOutQty, ref List lstAllIQ, List lstStrate)
{
bool isNoDivide = false;
bool forceDivide = false;
List lstFilterItem = CalculateItemByStegy(needOutQty, lstAllIQ, lstStrate, out isNoDivide, out forceDivide);
List lstTray = new List();
decimal tmpQty = 0;
List lstNeedRemove = new List();
#region 不可拆包,优先拣包装数量较大的
foreach (itemQty item in lstFilterItem)
{
Log.AlgorInfo("Out_AlgorBLL—Out", "循环lstFilterItem物料数据:" + JsonConvert.SerializeObject(item));
trayOutItem trayItem = new trayOutItem();
trayItem.itemCode = item.itemCode;
trayItem.itemState = item.CN_S_ITEM_STATE;
trayItem.ownerName = item.CN_S_OWNER;
trayItem.batchCode = item.lotNo;
trayItem.prodBatchCode = item.prodBatchCode;
trayItem.trayCode = item.trayCode;
trayItem.trayGrid = item.trayGrid;
trayItem.locationCode = item.locationCode;
trayItem.areaCode = itemQC.areaCode;
trayItem.CN_S_TIMESTAMP = item.CN_S_TIMESTAMP;
trayItem.packUnit = item.packUnit;
trayItem.packQty = item.PAKQty;
Log.AlgorInfo("Out_AlgorBLL—Out", "needOutQty < item.Qty:" + needOutQty.ToString() + "," + item.Qty.ToString());
if (needOutQty < item.Qty)
{
Log.AlgorInfo("Out_AlgorBLL—Out", "needOutQty < item.PAKQty:" + needOutQty.ToString() + "," + item.PAKQty.ToString());
//待出库量比该托盘中物料数量小
if (needOutQty >= item.PAKQty)
{
trayItem.itemQty = needOutQty - needOutQty % item.PAKQty;
if (item.Qty - trayItem.itemQty >= 0)
{
//降低该记录的可出库量,
lstAllIQ.Find(O => O.ID == item.ID).Qty = item.Qty - trayItem.itemQty;
}
else
{
lstNeedRemove.Add(item.ID);
}
needOutQty = needOutQty % item.PAKQty;
lstTray.Add(trayItem);
Log.AlgorInfo("Out_AlgorBLL—Out", "needOutQty >= item.PAKQty,trayItem:" + JsonConvert.SerializeObject(trayItem));
}
else
{
Log.AlgorInfo("Out_AlgorBLL—Out", "forceDivide:" + forceDivide.ToString());
if (forceDivide)
{
//库区中无不拆包可出库数据,强制拆包
trayItem.itemQty = needOutQty;
lstAllIQ.Find(O => O.ID == item.ID).Qty = item.Qty - needOutQty;
needOutQty = 0;
lstTray.Add(trayItem);
Log.AlgorInfo("Out_AlgorBLL—Out", "forceDivide,trayItem:" + JsonConvert.SerializeObject(trayItem));
}
else
{
//待出库量比该托盘中该单位的包装数量小,则跳出循环,寻找比该包装规格小的物料数据
break;
}
}
}
else
{
//待出库量比该托盘中物料数量大,将该托盘中物料全出
trayItem.itemQty = item.Qty;
lstNeedRemove.Add(item.ID);
needOutQty = needOutQty - item.Qty;
lstTray.Add(trayItem);
Log.AlgorInfo("Out_AlgorBLL—Out", "待出库量比该托盘中物料数量大,trayItem:" + JsonConvert.SerializeObject(trayItem));
}
if (needOutQty < item.PAKQty)
{
//待出库量小于规格数量则结束循环
break;
}
}
#endregion
lstAllIQ.RemoveAll(o => lstNeedRemove.Contains(o.ID));
if (needOutQty > 0 && lstAllIQ.Count > 0)
{
//如果未分配完则递归循环
lstTray.AddRange(CalculateOutLocation(itemQC, ref needOutQty, ref lstAllIQ, lstStrate));
}
return lstTray;
}
///
/// 将货位中的物料数据按照策略排序
///
///
///
///
public List CalculateItemByStegy(decimal needOutQty, List lstIQ, List lstStrate, out bool isNoDivide, out bool forceDivide)
{
List lstFilterItem = lstIQ;
List lstEmptyPBC;
List lstTpm;
List lstTpm1;
bool IsIntegerOut = false;
isNoDivide = false;
forceDivide = false;
foreach (string stegy in lstStrate)
{
//逐个策略进行计算
switch (stegy)
{
case "RowOutFirst":
lstFilterItem = lstFilterItem.OrderBy(o => o.CN_S_ROW).ThenBy(o => o.CN_S_COL).ToList();
lstFilterItem = lstFilterItem.Where(o => o.CN_S_ROW == lstFilterItem.FirstOrDefault().CN_S_ROW && o.CN_S_COL == lstFilterItem.FirstOrDefault().CN_S_COL).ToList();
break;
case "ProductTimeOutFirst":
lstFilterItem = lstFilterItem.OrderBy(o => o.productDate).ToList();
lstFilterItem = lstFilterItem.Where(o => o.productDate == lstFilterItem.FirstOrDefault().productDate).ToList();
break;
case "FirstWarrantFirstOut":
lstEmptyPBC = lstFilterItem.Where(o => string.IsNullOrEmpty(o.prodBatchCode)).ToList();
lstFilterItem = lstFilterItem.Where(o => !string.IsNullOrEmpty(o.prodBatchCode)).OrderBy(o => o.prodBatchCode).ToList();
lstFilterItem.AddRange(lstEmptyPBC);
lstFilterItem = lstFilterItem.Where(o => o.prodBatchCode == lstFilterItem.FirstOrDefault().prodBatchCode).ToList();
break;
case "IntegerTrayFirstOut":
IsIntegerOut = true;
lstTpm = lstFilterItem.GroupBy(a => new { a.trayCode }).Select(g => new itemQty()
{
Qty = g.Sum(s => s.Qty),
trayCode = g.Key.trayCode
}).ToList();
lstTpm = lstTpm.OrderByDescending(o => o.Qty).ToList();
lstTpm1 = lstTpm.Where(o => o.Qty >= needOutQty).ToList();
if (lstTpm1 == null || lstTpm1.Count == 0)
{
//该托盘中总数量不满足出库需求,则找最大数量的托盘
lstFilterItem = lstFilterItem.Where(o => o.trayCode == lstTpm.FirstOrDefault().trayCode).ToList();
}
else
{
//该托盘中总数量满足出库需求
lstTpm1 = lstTpm1.OrderBy(o => o.Qty).ToList();
lstFilterItem = lstFilterItem.Where(o => o.trayCode == lstTpm1.FirstOrDefault().trayCode).ToList();
}
break;
case "NoDivideFirstOut":
IsIntegerOut = true;
isNoDivide = true;
lstFilterItem = lstFilterItem.OrderByDescending(o => o.PAKQty).ToList();
Log.AlgorInfo("Out_AlgorBLL—Out", "NoDivideFirstOut前lstFilterItem物料数据:" + JsonConvert.SerializeObject(lstFilterItem));
lstTpm1 = lstFilterItem.Where(o => o.PAKQty <= needOutQty).ToList();
if (lstTpm1.Count == 0)
{
//货位中物料匹配数据中无包装单位比待出库数量小的数据,只有拆包
forceDivide = true;
lstTpm1 = lstFilterItem.OrderBy(o => o.PAKQty).ToList();
//寻找最接近出库数量的包装拆包
lstFilterItem = lstFilterItem.Where(o => o.Qty == lstTpm1.FirstOrDefault().Qty).ToList();
}
else
{
//货位中物料匹配数据中存在包装单位比带出库数量小的数据,先计算大包装的
lstFilterItem = lstFilterItem.Where(o => o.PAKQty == lstTpm1.FirstOrDefault().PAKQty).ToList();
}
Log.AlgorInfo("Out_AlgorBLL—Out", "NoDivideFirstOut后lstFilterItem物料数据:" + JsonConvert.SerializeObject(lstFilterItem));
break;
}
if (IsIntegerOut)
{
break;
}
}
return lstFilterItem;
}
///
/// 降低货位库存分配量
///
///
///
///
///
public void DivideAllocQty(ref List lstIQ, itemQty allocItem, ref decimal needDivideQty, List lstStrate)
{
List lstFilterItem = FilterItemByStegy(lstIQ.Where(o => o.trayCode == allocItem.trayCode && o.itemCode == allocItem.itemCode && o.CN_S_OWNER == allocItem.CN_S_OWNER && o.CN_S_ITEM_STATE == allocItem.CN_S_ITEM_STATE).ToList(), lstStrate);
decimal tmpQty = 0;
List lstNeedRemove = new List();
foreach (itemQty item in lstFilterItem)
{
tmpQty = needDivideQty - item.Qty;
if (tmpQty < 0)
{
//降低该记录的可出库量,并跳出循环
lstIQ.Find(O => O.ID == item.ID).Qty = item.Qty - needDivideQty;
needDivideQty = tmpQty;
break;
}
else
{
needDivideQty = tmpQty;
//删除该记录
lstNeedRemove.Add(item.ID);
}
}
lstIQ.RemoveAll(o => lstNeedRemove.Contains(o.ID));
if (needDivideQty > 0 && lstIQ.Count > 0)
{
//如果未分配完则递归循环
DivideAllocQty(ref lstIQ, allocItem, ref needDivideQty, lstStrate);
}
}
///
/// 将货位中的物料数据按照策略排序
///
///
///
///
public List FilterItemByStegy(List lstIQ, List lstStrate)
{
List lstFilterItem = lstIQ;
List lstEmptyPBC;
foreach (string stegy in lstStrate)
{
//逐个策略进行计算
switch (stegy)
{
case "FirstInFirstOut":
lstFilterItem = lstFilterItem.OrderBy(o => o.lotNo).ToList();
lstFilterItem = lstFilterItem.Where(o => o.lotNo == lstFilterItem.FirstOrDefault().lotNo).ToList();
break;
case "FirstWarrantFirstOut":
lstEmptyPBC = lstFilterItem.Where(o => string.IsNullOrEmpty(o.prodBatchCode)).ToList();
lstFilterItem = lstFilterItem.Where(o => !string.IsNullOrEmpty(o.prodBatchCode)).OrderBy(o => o.prodBatchCode).ToList();
lstFilterItem.AddRange(lstEmptyPBC);
lstFilterItem = lstFilterItem.Where(o => o.prodBatchCode == lstFilterItem.FirstOrDefault().prodBatchCode).ToList();
break;
}
}
return lstFilterItem;
}
#endregion
#region 生成查询条件
///
/// 生成查询条件
///
///
///
///
///
///
public string GetPropWhereStr1(string itemCodes, string itemState, string batchCode, string prodBatchCode, string ownerName)
{
StringBuilder strWhere = new StringBuilder();
// strWhere.Append(" 1=1 ");
//物料编码
if (!string.IsNullOrEmpty(itemCodes))
{
strWhere.AppendLine(" AND CN_S_ITEM_CODE IN ('" + itemCodes + "') ");
}
//物料状态
if (!string.IsNullOrEmpty(itemState))
{
strWhere.AppendLine(" AND CN_S_ITEM_STATE = '" + itemState + "' ");
}
//批次号
if (!string.IsNullOrEmpty(batchCode))
{
strWhere.AppendLine(" AND CN_S_LOT_NO = '" + batchCode + "' ");
}
//生产批次号
if (!string.IsNullOrEmpty(prodBatchCode))
{
strWhere.AppendLine(" AND CN_S_PRODUCTION_BATCH = '" + prodBatchCode + "' ");
}
//货主
if (!string.IsNullOrEmpty(ownerName))
{
strWhere.AppendLine(" AND CN_S_OWNER = '" + ownerName + "' ");
}
return strWhere.ToString();
}
#endregion
#region 出库调用的方法 将传递过来的请求出库的物料进行分组
///
/// 将传递过来的请求出库的物料进行分组 保证算法的执行速度
///
///
///
private List GroupAreaCode(List lstQueryItem)
{
//定义分组后的物料数据
List lstAreaItemGroup = new List();
if (lstQueryItem == null || lstQueryItem.Count == 0)
{
return lstAreaItemGroup;
}
//按照库区等查询条件分组
var v_AreaGroup = lstQueryItem.GroupBy(a => new
{
//追加条件后 需要在此处加入分组条件定义 &&&&
a.stockCode,
a.areaCode,
a.ownerName,
a.batchCode,
a.prodBatchCode,
a.itemState,
a.itemCode
}).Select(g => (new
{
//追加条件后 需要在此处加入分组条件定义 &&&&
stockCode = g.Key.stockCode,
areaCode = g.Key.areaCode,
ownerName = g.Key.ownerName,
batchCode = g.Key.batchCode,
prodBatchCode = g.Key.prodBatchCode,
itemState = g.Key.itemState,
itemCode = g.Key.itemCode,
itemQty = g.Sum(p => p.itemQty)
}));
Out_AreaItemClass areaItemEntity = new Out_AreaItemClass();
//循环传递的实体参数数量
foreach (var areaItem in v_AreaGroup)
{
//则将物料列表信息传递给分组后的列表
areaItemEntity.areaCode = areaItem.areaCode;
areaItemEntity.stockCode = areaItem.stockCode;
areaItemEntity.ownerName = areaItem.ownerName;
areaItemEntity.batchCode = areaItem.batchCode;
areaItemEntity.prodBatchCode = areaItem.prodBatchCode;
areaItemEntity.itemState = areaItem.itemState;
areaItemEntity.itemCode = areaItem.itemCode;
areaItemEntity.itemQty = decimal.Parse(areaItem.itemQty.ToString());
lstAreaItemGroup.Add(areaItemEntity);
}
return lstAreaItemGroup;
}
#endregion
/**************计算 返回物料所在货位的算法结束/**************/
/*****************计算 返回库区的算法开始/*****************/
#region 非作业区平库立库 返回库区对应出库物料的算法,该算法只算到库区可出库数量
///
/// 出库 返回库区对应出库物料的算法,该算法只算到库区,不到货位
///
/// 返回库区算法传递的类
///
public OutAreaResultAllEntity OutArea(List lstQueryOut, List lstAreaPrior)
{
Log.AlgorInfo("Out_AlgorBLL—OutArea", "算法开始,传入参数lstQueryOut:" + JsonConvert.SerializeObject(lstQueryOut) + ",lstAreaPrior:" + JsonConvert.SerializeObject(lstAreaPrior));
//返回数据的实体集合
OutAreaResultAllEntity outAreaResult = new OutAreaResultAllEntity();
//存放计算物料库存结果
List lstOutResultEntity = new List();
bool checkEnough = true;
//将传递过来的参数按货主、批次号、物料状态分组后再按物料分组
List lstAreaItemGroup = GroupAreaCode(lstQueryOut);
//循环处理
foreach (var i_Group in lstAreaItemGroup)
{
Log.AlgorInfo("Out_AlgorBLL—OutArea", "循环处理lstAreaItemGroup:" + i_Group.areaCode + "," + i_Group.batchCode + "," + i_Group.itemState + "," + i_Group.ownerName);
string stockCode = i_Group.stockCode;
#region 判断库存是否足够
//获得所有物料
string itemCodes = i_Group.itemCode;
//获得查询条件
string strWhere = GetPropWhereStr1(itemCodes, i_Group.itemState, i_Group.batchCode, i_Group.prodBatchCode, i_Group.ownerName);
//获得物料在仓库中的数量
List lstAreaItemQty = null;
lstAreaItemQty = CreateDAL().GetAreaQty(strWhere, stockCode);
lstAreaItemQty.ForEach(x => x.areaCode = x.areaCode.Trim());
lstAreaItemQty.RemoveAll(o => o.Qty <= 0);
lstAreaItemQty = lstAreaItemQty.Join(lstAreaPrior, u => u.areaCode, d => d.areaCode, (u, d) => new { u, d })
.Select(o => new OutAreaItemQty
{
areaCode = o.u.areaCode,
itemCode = o.u.itemCode,
Qty = o.u.Qty,
Prior = o.d.Prior
}
).OrderBy(p => p.Prior).ToList();
var lstStockItemQty = lstAreaItemQty.GroupBy(a => a.itemCode).Select(g => new
{
itemCode = g.Key,
stockNum = g.Sum(p => p.Qty)
});
List lstFalseItem = new List();
#region 循环处理查询不满足出库数量的物料
itemOutClass outClassEntity = new itemOutClass();
var itemEntity = lstStockItemQty.Where(o => o.itemCode == i_Group.itemCode).SingleOrDefault();
if (itemEntity != null)
{
//获得仓库内该物料的数量
decimal qty = (decimal)i_Group.itemQty;
if (qty < (decimal)i_Group.itemQty)
{
outClassEntity.Success = false;
outClassEntity.Msg = "当前仓库中该物料的数量不满足需要出库的数量";
outClassEntity.itemCode = i_Group.itemCode;
outClassEntity.itemQty = qty;
lstFalseItem.Add(outClassEntity);
}
}
else
{
outClassEntity.Success = false;
outClassEntity.Msg = "在仓库中未找到该物料对应的库存数量信息";
outClassEntity.itemCode = i_Group.itemCode;
outClassEntity.itemQty = 0;
lstFalseItem.Add(outClassEntity);
}
#endregion
if (lstFalseItem != null && lstFalseItem.Count > 0)
{
checkEnough = false;
}
lstOutResultEntity.AddRange(GetOutAreaList(stockCode, lstAreaItemQty, i_Group, lstAreaPrior));
#endregion
}
if (!checkEnough)
{
outAreaResult.Success = false;
outAreaResult.Msg = "物料库存不足";
}
else
{
outAreaResult.Success = true;
outAreaResult.Msg = "";
}
outAreaResult.itemOutAreaResult = lstOutResultEntity;
Log.AlgorInfo("Out_AlgorBLL—OutArea", "计算结果outAreaResult:" + JsonConvert.SerializeObject(outAreaResult));
return outAreaResult;
}
#endregion
#region 用于计算返回库区的算法
///
/// 用于计算返回库区的算法
///
///
/// 每个库区对应的物料数量
///
///
private List GetOutAreaList(string stockCode, List lstAreaOutItemQty, Out_AreaItemClass outAreaItem, List lstAreaPrior)
{
List lstOutResultEntity = new List();
List lstArea = lstAreaPrior.OrderByDescending(o => o.Prior).Select(p => p.areaCode).ToList();
Out_AreaItemClass divideItemEntity = new Out_AreaItemClass();
//则将物料列表信息传递给分组后的列表
decimal remainder = 0;
Out_AreaItemClass itemRemaind = null;
if (outAreaItem.itemQty >= 12)
{
remainder = outAreaItem.itemQty % 12;
outAreaItem.itemQty = outAreaItem.itemQty - remainder;
if (remainder != 0)
{
itemRemaind = new Out_AreaItemClass();
itemRemaind.areaCode = outAreaItem.areaCode;
itemRemaind.stockCode = outAreaItem.stockCode;
itemRemaind.ownerName = outAreaItem.ownerName;
itemRemaind.batchCode = outAreaItem.batchCode;
itemRemaind.prodBatchCode = outAreaItem.prodBatchCode;
itemRemaind.itemState = outAreaItem.itemState;
itemRemaind.itemCode = outAreaItem.itemCode;
itemRemaind.itemQty = remainder;
}
}
else
{
lstArea = lstAreaPrior.OrderBy(o => o.Prior).Select(p => p.areaCode).ToList();
}
//循环所有库区
List LstItemOut = new List();
for (int i = 0; i < lstArea.Count; i++)
{
#region 循环库区获取可出库物料
if (outAreaItem.itemQty == 0)
{
break;
}
//找到该库区下的物料
List lst_item_Area = lstAreaOutItemQty.Where(o => o.areaCode == lstArea[i] && o.itemCode == outAreaItem.itemCode).ToList();
if (lst_item_Area.Count > 0)
{
foreach (OutAreaItemQty item_Area in lst_item_Area)
{
OutAreaResultEntity resultEntity = new OutAreaResultEntity();
resultEntity.stockCode = stockCode;
resultEntity.areaCode = lstArea[i];
resultEntity.ownerName = outAreaItem.ownerName;
resultEntity.batchCode = outAreaItem.batchCode;
resultEntity.prodBatchCode = outAreaItem.prodBatchCode;
resultEntity.itemState = outAreaItem.itemState;
//获取当前库区下可分配的物料列表
if (outAreaItem.itemQty > 0)
{
itemOutClass outEntity = new itemOutClass();
if (outAreaItem.itemQty <= item_Area.Qty)
{
//表示需求物料数量在该库区中满足要求
outAreaItem.itemQty = 0;
outEntity.itemCode = outAreaItem.itemCode;
outEntity.itemQty = outAreaItem.itemQty;
}
else
{
//等于该库区中的数量
outAreaItem.itemQty = outAreaItem.itemQty - item_Area.Qty;
outEntity.itemCode = outAreaItem.itemCode;
outEntity.itemQty = item_Area.Qty;
}
LstItemOut.Add(outEntity);
resultEntity.lstItem = LstItemOut;
lstOutResultEntity.Add(resultEntity);
}
else
{
break;
}
}
}
#endregion
}
//循环所有库区
List LstItemOutRemaind = new List();
if (itemRemaind != null)
{
lstArea = lstAreaPrior.OrderBy(o => o.Prior).Select(p => p.areaCode).ToList();
for (int i = 0; i < lstArea.Count; i++)
{
#region 循环库区获取可出库物料
if (itemRemaind.itemQty == 0)
{
break;
}
//找到该库区下的物料
List lst_item_Area = lstAreaOutItemQty.Where(o => o.areaCode == lstArea[i] && o.itemCode == itemRemaind.itemCode).ToList();
if (lst_item_Area.Count > 0)
{
foreach (OutAreaItemQty item_Area in lst_item_Area)
{
OutAreaResultEntity resultEntity = new OutAreaResultEntity();
resultEntity.stockCode = stockCode;
resultEntity.areaCode = lstArea[i];
resultEntity.ownerName = itemRemaind.ownerName;
resultEntity.batchCode = itemRemaind.batchCode;
resultEntity.prodBatchCode = itemRemaind.prodBatchCode;
resultEntity.itemState = itemRemaind.itemState;
//获取当前库区下可分配的物料列表
if (itemRemaind.itemQty > 0)
{
itemOutClass outEntity = new itemOutClass();
if (itemRemaind.itemQty <= item_Area.Qty)
{
//表示需求物料数量在该库区中满足要求
itemRemaind.itemQty = 0;
outEntity.itemCode = itemRemaind.itemCode;
outEntity.itemQty = itemRemaind.itemQty;
}
else
{
//等于该库区中的数量
itemRemaind.itemQty = itemRemaind.itemQty - item_Area.Qty;
outEntity.itemCode = itemRemaind.itemCode;
outEntity.itemQty = item_Area.Qty;
}
LstItemOutRemaind.Add(outEntity);
resultEntity.lstItem = LstItemOutRemaind;
lstOutResultEntity.Add(resultEntity);
}
else
{
break;
}
}
}
#endregion
}
}
return lstOutResultEntity;
}
#endregion
//*****************计算 返回库区的算法结束/*****************/
#region 作业区出库算法入口
public OutAssignResultEntity OutAssign(OutAssignEnitty model)
{
Log.AlgorInfo("OutAssign", "出库算法参数:" + JsonConvert.SerializeObject(model));
OutAssignResultEntity outResult = new OutAssignResultEntity();
try
{
//标准出库算法
string areaType = CreateDAL().GetAreaTypeByCode(model.lstAreaPrior[0].areaCode.ToString());
if (areaType == Constants.Area_Struc_PingStock || areaType == Constants.Area_Struc_LiStock)
{
outResult = FlatAreaOutLocation(model);
}
else if (areaType == Constants.Area_Struc_LiuLiStock)
{
}
outResult.areaType = areaType;
Log.AlgorInfo("OutAssign", "出库返回结果:" + JsonConvert.SerializeObject(outResult));
return outResult;
}
catch (Exception ex)
{
Log.AlgorInfo("OutAssign", "异常:" + ex.Message + ex.StackTrace);
outResult.Msg = "算法异常," + ex.Message + ex.StackTrace;
return outResult;
}
}
#endregion
#region 平库出库算法
public OutAssignResultEntity FlatAreaOutLocation(OutAssignEnitty model)
{
OutAssignResultEntity outResult = new OutAssignResultEntity();
#region 传入参数判断
if (model == null)
{
outResult.Success = false;
outResult.Msg = "参数实体不能为 null !";
return outResult;
}
//判断指定的入作业库对象类型不能为空
if (string.IsNullOrEmpty(model.stockCode.ToString()))
{
outResult.Success = false;
outResult.Msg = "指定的出库仓库编号不能为空!";
return outResult;
}
//判断传入库区列表不能为空
if (model.lstAreaPrior == null || model.lstAreaPrior.Count == 0)
{
outResult.Success = false;
outResult.Msg = "指定的出作业库库区列表不能为空!";
return outResult;
}
#endregion
List lstStrategy = CreateDAL().GetStrateListByAreaOrStock(model.stockCode, "", "出库");
List lstStrate = lstStrategy.Select(o => o.CN_S_NAME).ToList();
if (lstStrate.Count > 0)
{
//如果仓库配置策略(如生产日期早先出等),则优先响应仓库策略
outResult = OutStockPrior(model, lstStrate);
}
else
{
//如果仓库没有配置策略则优先响应库区优先策略
outResult = OutAreaPrior(model);
}
return outResult;
}
///
/// 作业区出库算法 优先仓库策略
///
///
///
///
private OutAssignResultEntity OutStockPrior(OutAssignEnitty model, List lstStrategy)
{
//返回实体集合
OutAssignResultEntity outResult = new OutAssignResultEntity();
outResult.Success = false;
if (string.IsNullOrEmpty(model.itemCode))
{
outResult.Msg = "库区中无该规格的空托";
}
else
{
outResult.Msg = "库存不足";
}
SqlExecuteResult result = null;
List lstDevice = model.lstDevice;
string deviceCode = string.Empty;
AutoBomLocationAbbreEntity at_l_Entity = null;
List lstTmp_Location = new List();
List lstTrueLocation = new List();
string isControlQty = CreateDAL().GetIsControlQtyByCode(model.lstAreaPrior[0].areaCode.ToString());
model.lockLocation = isControlQty.Equals("Y") ? true : false;//不管控数量时,不锁定起点货位
outResult.isControlQty = isControlQty;
string areaCodes = string.Join("','", model.lstAreaPrior.Select(o => o.areaCode));
//获得作业区中所有匹配条件(物料等)的货位
List lstCanOutL = CreateDAL().GetAssignFlatItemQty(model.itemCode, areaCodes);
if (lstCanOutL.Count == 0)
{
return outResult;
}
if (lstStrategy.Contains("ProductTimeOutFirst"))
{
lstCanOutL = lstCanOutL.OrderBy(o => o.productDate).ToList();
at_l_Entity = CreateDAL().GetLocationByLocationCodeAbbre(lstCanOutL[0].ToString());
}
else if (lstStrategy.Contains("InStockTimeOutFirst"))
{
lstCanOutL = lstCanOutL.OrderBy(o => o.opTime).ToList();
at_l_Entity = CreateDAL().GetLocationByLocationCodeAbbre(lstCanOutL[0].ToString());
}
if (at_l_Entity == null)
{
return outResult;
}
else
{
//更新货位状态
if (model.lockLocation)
{
result = CreateDAL().UpdateLocationState(at_l_Entity.CN_S_LOCATION_CODE, Constants.Location_State_OutLock, "出库", null);
if (result != null)
{
if (result.Success && result.Row > 0)
{
outResult.Success = true;
outResult.Msg = "";
outResult.locationCode = at_l_Entity.CN_S_LOCATION_CODE;
outResult.trayCode = lstCanOutL.Where(o => o.locationCode == at_l_Entity.CN_S_LOCATION_CODE).FirstOrDefault().trayCode;
}
else
{
outResult.Success = false;
outResult.Msg = "锁定出库货位失败";
}
}
}
else
{
outResult.Success = true;
outResult.Msg = "";
outResult.locationCode = at_l_Entity.CN_S_LOCATION_CODE;
outResult.trayCode = lstCanOutL.Where(o => o.locationCode == at_l_Entity.CN_S_LOCATION_CODE).FirstOrDefault().trayCode;
}
}
return outResult;
}
///
/// 作业区出库算法 优先库区
///
///
///
private OutAssignResultEntity OutAreaPrior(OutAssignEnitty model)
{
//返回实体集合
OutAssignResultEntity outResult = new OutAssignResultEntity();
outResult.Success = false;
if (string.IsNullOrEmpty(model.itemCode))
{
if (model.projectCode == "ys001")
{
outResult.Msg = "库区中无该规格的空托";
}
else if (model.projectCode == "hcbh")
{
outResult.Msg = "库区中无可出托盘";
}
else
{
outResult.Msg = "库区中无空托";
}
}
else
{
outResult.Msg = "库存不足";
}
List lstStrategy = null;
List lstCanOutL = null;
List lstDevice = model.lstDevice;
string deviceCode = string.Empty;
List lstStrate = null;
SqlExecuteResult result = null;
outAssignLocation at_l_Entity = null;
List lstTmp_Location = new List();
List lstTrueLocation = new List();
List lstAllLocation = new List();
//被锁定的货位
List lstLockLItem = new List();
List lstLocation = new List();
string isControlQty = string.Empty;
string isControlInv = string.Empty;
decimal needOutWeight = 0;
AutoBomItemEntity autoBomE = null;
if (model.projectCode == "ys001")
{
if (!string.IsNullOrEmpty(model.itemCode))
{
autoBomE = CreateDAL().GetItemEntity(model.itemCode);
}
}
//将传递过来的库区列表按库区出库优先级排序
List lstAreaPrior = model.lstAreaPrior.OrderBy(o => o.Prior).ToList();
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));
}
foreach (areaPriorClass item in lstAreaPrior)
{
AutoBomStockAreaEntity areaModel = CreateDAL().GetModel(item.areaCode.ToString());
isControlQty = areaModel.CN_C_IS_CONTROL_QTY;
isControlInv = areaModel.CN_C_IS_INVENTORY;
if (model.needCalLock)
{
model.lockLocation = isControlQty.Equals("Y") ? true : false;//不管控数量时,不锁定目的货位
}
lstStrategy = CreateDAL().GetStrateListByAreaOrStock("", item.areaCode, "出库");
lstStrate = lstStrategy.Select(o => o.CN_S_CODE).ToList();
if (string.IsNullOrEmpty(model.itemCode))
{
if (model.projectCode == "hcbh")
{
#region 托盘出库,忽略托盘中物料
lstCanOutL = CreateDAL().GetAssignFlatEmptySpecTrayBH(model.traySpec, item.areaCode);
if (lstCanOutL.Count == 0)
{
continue;
}
else
{
lstTrueLocation = CreateDAL().GetLocationByLocationCode(lstCanOutL.Select(o => o.locationCode).ToList());
lstCanOutL = lstCanOutL.Join(lstTrueLocation, u => u.locationCode, d => d.CN_S_LOCATION_CODE, (u, d) => new { u, d }).Select(o => new outAssignLocation
{
trayCode = o.u.trayCode,
locationCode = o.u.locationCode,
stockAreaCode = o.u.stockAreaCode,
useState = o.u.useState,
opTime = o.u.opTime,
productDate = o.u.productDate,
lotNo = o.u.lotNo,
CN_S_STOCK_CODE = o.d.CN_S_STOCK_CODE,
CN_S_ROADWAY = o.d.CN_S_ROADWAY,
CN_S_ROW = o.d.CN_S_ROW,
CN_S_COL = o.d.CN_S_COL,
CN_S_FLOOR = o.d.CN_S_FLOOR,
CN_S_LOCATION_STATE = o.d.CN_S_LOCATION_STATE
}).ToList();
//获取该终点对应的出库的排
var rowMapStr = JsonHelper.GetValue("rowMapping");
var rowMaps = JsonConvert.DeserializeObject>(rowMapStr);
RowMapDto rMap = rowMaps.Where(o => o.endBit == model.endBit).FirstOrDefault();
if (rMap != null)
{
lstCanOutL = lstCanOutL.Where(o => o.CN_S_ROW == rMap.startRow).ToList();
}
List locationInLock = CreateDAL().GetLockLocationByState(model.stockCode.Trim(), item.areaCode, null, Constants.Location_State_InLock);
Log.AlgorInfo("OutAssign-FlatAreaOutLocation", "locationInLock数据:" + JsonConvert.SerializeObject(locationInLock));
foreach (TN_WM_LOCATIONCODE_EXT_Entity lEntity in locationInLock)
{
lstCanOutL.RemoveAll(o => o.CN_S_ROW == lEntity.CN_S_ROW);
}
lstTmp_Location = CalculateLocByStegy(ref lstDevice, lstCanOutL, lstStrate, out deviceCode);
if (lstTmp_Location.Count > 0)
{
at_l_Entity = lstTmp_Location[0];
#region 锁定待出库货位
if (at_l_Entity != null)
{
if (model.lockLocation)
{
result = CreateDAL().UpdateLocationState(at_l_Entity.locationCode, Constants.Location_State_OutLock, "出库", null);
if (result != null)
{
if (result.Success && result.Row > 0)
{
outResult.Success = true;
outResult.Msg = "";
outResult.locationCode = at_l_Entity.locationCode;
outResult.trayCode = lstCanOutL.Where(o => o.locationCode == at_l_Entity.locationCode).FirstOrDefault().trayCode;
outResult.areaCode = item.areaCode;
outResult.isControlQty = isControlQty;
outResult.isControlInv = isControlInv;
break;
}
}
}
else
{
outResult.Success = true;
outResult.Msg = "";
outResult.locationCode = at_l_Entity.locationCode;
outResult.trayCode = lstCanOutL.Where(o => o.locationCode == at_l_Entity.locationCode).FirstOrDefault().trayCode;
outResult.areaCode = item.areaCode;
outResult.isControlQty = isControlQty;
outResult.isControlInv = isControlInv;
break;
}
}
#endregion
break;
}
}
#endregion
}
else if (model.projectCode == "tzlj")
{
#region 泰州隆基空托盘出库
lstCanOutL = CreateDAL().GetAssignFlatEmptySpecTrayLJ(model.traySpec, item.areaCode);
if (lstCanOutL.Count == 0)
{
continue;
}
else
{
lstTrueLocation = CreateDAL().GetLocationByLocationCode(lstCanOutL.Select(o => o.locationCode).ToList());
lstCanOutL = lstCanOutL.Join(lstTrueLocation, u => u.locationCode, d => d.CN_S_LOCATION_CODE, (u, d) => new { u, d }).Select(o => new outAssignLocation
{
trayCode = o.u.trayCode,
locationCode = o.u.locationCode,
stockAreaCode = o.u.stockAreaCode,
useState = o.u.useState,
opTime = o.u.opTime,
productDate = o.u.productDate,
lotNo = o.u.lotNo,
CN_S_STOCK_CODE = o.d.CN_S_STOCK_CODE,
CN_S_ROADWAY = o.d.CN_S_ROADWAY,
CN_S_ROW = o.d.CN_S_ROW,
CN_S_COL = o.d.CN_S_COL,
CN_S_FLOOR = o.d.CN_S_FLOOR,
CN_S_LOCATION_STATE = o.d.CN_S_LOCATION_STATE
}).ToList();
lstTmp_Location = CalculateLocByStegy(ref lstDevice, lstCanOutL, lstStrate, out deviceCode);
if (lstTmp_Location.Count > 0)
{
at_l_Entity = lstTmp_Location[0];
#region 锁定待出库货位
if (at_l_Entity != null)
{
if (model.lockLocation)
{
result = CreateDAL().UpdateLocationState(at_l_Entity.locationCode, Constants.Location_State_OutLock, "出库", null);
if (result != null)
{
if (result.Success && result.Row > 0)
{
outResult.Success = true;
outResult.Msg = "";
outResult.locationCode = at_l_Entity.locationCode;
outResult.trayCode = lstCanOutL.Where(o => o.locationCode == at_l_Entity.locationCode).FirstOrDefault().trayCode;
outResult.areaCode = item.areaCode;
outResult.isControlQty = isControlQty;
outResult.isControlInv = isControlInv;
break;
}
}
}
else
{
outResult.Success = true;
outResult.Msg = "";
outResult.locationCode = at_l_Entity.locationCode;
outResult.trayCode = lstCanOutL.Where(o => o.locationCode == at_l_Entity.locationCode).FirstOrDefault().trayCode;
outResult.areaCode = item.areaCode;
outResult.isControlQty = isControlQty;
outResult.isControlInv = isControlInv;
break;
}
}
#endregion
break;
}
}
#endregion
}
else if (model.projectCode == "masym")
{
#region 马鞍山粤美空托盘出库
lstCanOutL = CreateDAL().GetAssignFlatEmptySpecTrayYM(model.traySpec, item.areaCode);
if (lstCanOutL.Count == 0)
{
continue;
}
else
{
lstTrueLocation = CreateDAL().GetLocationByLocationCode(lstCanOutL.Select(o => o.locationCode).ToList());
lstCanOutL = lstCanOutL.Join(lstTrueLocation, u => u.locationCode, d => d.CN_S_LOCATION_CODE, (u, d) => new { u, d }).Select(o => new outAssignLocation
{
trayCode = o.u.trayCode,
locationCode = o.u.locationCode,
stockAreaCode = o.u.stockAreaCode,
useState = o.u.useState,
opTime = o.u.opTime,
productDate = o.u.productDate,
lotNo = o.u.lotNo,
CN_S_STOCK_CODE = o.d.CN_S_STOCK_CODE,
CN_S_ROADWAY = o.d.CN_S_ROADWAY,
CN_S_ROW = o.d.CN_S_ROW,
CN_S_COL = o.d.CN_S_COL,
CN_S_FLOOR = o.d.CN_S_FLOOR,
CN_S_LOCATION_STATE = o.d.CN_S_LOCATION_STATE
}).ToList();
lstTmp_Location = CalculateLocByStegy(ref lstDevice, lstCanOutL, lstStrate, out deviceCode);
if (lstTmp_Location.Count > 0)
{
at_l_Entity = lstTmp_Location[0];
#region 锁定待出库货位
if (at_l_Entity != null)
{
if (model.lockLocation)
{
result = CreateDAL().UpdateLocationState(at_l_Entity.locationCode, Constants.Location_State_OutLock, "出库", null);
if (result != null)
{
if (result.Success && result.Row > 0)
{
outResult.Success = true;
outResult.Msg = "";
outResult.locationCode = at_l_Entity.locationCode;
outResult.trayCode = lstCanOutL.Where(o => o.locationCode == at_l_Entity.locationCode).FirstOrDefault().trayCode;
outResult.areaCode = item.areaCode;
outResult.isControlQty = isControlQty;
outResult.isControlInv = isControlInv;
break;
}
}
}
else
{
outResult.Success = true;
outResult.Msg = "";
outResult.locationCode = at_l_Entity.locationCode;
outResult.trayCode = lstCanOutL.Where(o => o.locationCode == at_l_Entity.locationCode).FirstOrDefault().trayCode;
outResult.areaCode = item.areaCode;
outResult.isControlQty = isControlQty;
outResult.isControlInv = isControlInv;
break;
}
}
#endregion
break;
}
}
#endregion
}
else
{
#region 空托盘出库
//空托盘出库,add by ly 20190102 增加根据托盘类型出库
lstCanOutL = CreateDAL().GetAssignFlatEmptySpecTray(model.traySpec, item.areaCode);
if (lstCanOutL.Count == 0)
{
continue;
}
else
{
lstTrueLocation = CreateDAL().GetLocationByLocationCode(lstCanOutL.Select(o => o.locationCode).ToList());
lstCanOutL = lstCanOutL.Join(lstTrueLocation, u => u.locationCode, d => d.CN_S_LOCATION_CODE, (u, d) => new { u, d }).Select(o => new outAssignLocation
{
trayCode = o.u.trayCode,
locationCode = o.u.locationCode,
stockAreaCode = o.u.stockAreaCode,
useState = o.u.useState,
opTime = o.u.opTime,
productDate = o.u.productDate,
lotNo = o.u.lotNo,
CN_S_STOCK_CODE = o.d.CN_S_STOCK_CODE,
CN_S_ROADWAY = o.d.CN_S_ROADWAY,
CN_S_ROW = o.d.CN_S_ROW,
CN_S_COL = o.d.CN_S_COL,
CN_S_FLOOR = o.d.CN_S_FLOOR,
CN_S_LOCATION_STATE = o.d.CN_S_LOCATION_STATE
}).ToList();
lstTmp_Location = CalculateLocByStegy(ref lstDevice, lstCanOutL, lstStrate, out deviceCode);
if (lstTmp_Location.Count > 0)
{
at_l_Entity = lstTmp_Location[0];
#region 锁定待出库货位
if (at_l_Entity != null)
{
if (model.lockLocation)
{
result = CreateDAL().UpdateLocationState(at_l_Entity.locationCode, Constants.Location_State_OutLock, "出库", null);
if (result != null)
{
if (result.Success && result.Row > 0)
{
outResult.Success = true;
outResult.Msg = "";
outResult.locationCode = at_l_Entity.locationCode;
outResult.trayCode = lstCanOutL.Where(o => o.locationCode == at_l_Entity.locationCode).FirstOrDefault().trayCode;
outResult.areaCode = item.areaCode;
outResult.isControlQty = isControlQty;
outResult.isControlInv = isControlInv;
break;
}
}
}
else
{
outResult.Success = true;
outResult.Msg = "";
outResult.locationCode = at_l_Entity.locationCode;
outResult.trayCode = lstCanOutL.Where(o => o.locationCode == at_l_Entity.locationCode).FirstOrDefault().trayCode;
outResult.areaCode = item.areaCode;
outResult.isControlQty = isControlQty;
outResult.isControlInv = isControlInv;
break;
}
}
#endregion
break;
}
}
#endregion
}
}
else
{
#region 满托盘出库
if (model.projectCode == "ys001")
{
#region 宇寿满托盘出库
// needOutWeight = autoBomE.CN_F_NW * model.itemQty;
needOutWeight = model.itemQty;
lstCanOutL = CreateDAL().GetAssignFlatItemQtyYS(model.itemCode, model.lotNo, item.areaCode);
lstTrueLocation = CreateDAL().GetLocationByLocationCode(lstCanOutL.Select(o => o.locationCode).ToList());
lstCanOutL = lstCanOutL.Join(lstTrueLocation, u => u.locationCode, d => d.CN_S_LOCATION_CODE, (u, d) => new { u, d }).Select(o => new outAssignLocation
{
trayCode = o.u.trayCode,
locationCode = o.u.locationCode,
stockAreaCode = o.u.stockAreaCode,
useState = o.u.useState,
opTime = o.u.opTime,
productDate = o.u.productDate,
lotNo = o.u.lotNo,
CN_S_STOCK_CODE = o.d.CN_S_STOCK_CODE,
CN_S_ROADWAY = o.d.CN_S_ROADWAY,
CN_S_ROW = o.d.CN_S_ROW,
CN_S_COL = o.d.CN_S_COL,
CN_S_FLOOR = o.d.CN_S_FLOOR,
CN_S_LOCATION_STATE = o.d.CN_S_LOCATION_STATE,
needWeight = needOutWeight,
totalWeight = o.u.totalWeight
}).ToList();
List locationInLock = CreateDAL().GetLockLocationByState(model.stockCode.Trim(), item.areaCode, null, Constants.Location_State_InLock);
Log.AlgorInfo("OutAssign-FlatAreaOutLocation", "locationInLock数据:" + JsonConvert.SerializeObject(locationInLock));
foreach (TN_WM_LOCATIONCODE_EXT_Entity lEntity in locationInLock)
{
lstCanOutL.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)
{
lstCanOutL.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)
{
lstCanOutL.RemoveAll(o => o.CN_S_ROW == lEntity.CN_S_ROW && o.CN_S_COL == lEntity.CN_S_COL);
}
locationInLock = CreateDAL().GetLockLocationByState(model.stockCode.Trim(), item.areaCode, null, Constants.Location_State_OutLock);
Log.AlgorInfo("OutAssign-FlatAreaOutLocation", "locationOutLock数据:" + JsonConvert.SerializeObject(locationInLock));
foreach (TN_WM_LOCATIONCODE_EXT_Entity lEntity in locationInLock)
{
lstCanOutL.RemoveAll(o => o.CN_S_ROW == lEntity.CN_S_ROW && o.CN_S_COL == lEntity.CN_S_COL && int.Parse(o.CN_S_FLOOR) > int.Parse(lEntity.CN_S_FLOOR));
}
List lstLocationItem = CreateDAL().GetLocationByItemCode("", item.areaCode);
foreach (outAssignLocation outL in lstCanOutL)
{
//计算出该物料需要移动多少托盘
outL.moveStep = lstLocationItem.Where(o => o.CN_S_ROW == outL.CN_S_ROW && o.CN_S_COL == outL.CN_S_COL && int.Parse(o.CN_S_FLOOR) > int.Parse(outL.CN_S_FLOOR)).Count();
}
#endregion
}
else if (model.projectCode == "tzlj")
{
#region 隆基满托盘出库
List locationInLock = new List();
List locationOutLock = new List();
if (lstStrategy.Select(o => o.CN_S_CODE).ToList().Contains("FirstInLastOutLj"))
{
lstCanOutL = CreateDAL().GetAssignFlatItemQty(model.itemCode, item.areaCode);
lstTrueLocation = CreateDAL().GetLocationByLocationCode(lstCanOutL.Select(o => o.locationCode).ToList());
lstCanOutL = lstCanOutL.Join(lstTrueLocation, u => u.locationCode, d => d.CN_S_LOCATION_CODE, (u, d) => new { u, d }).Select(o => new outAssignLocation
{
trayCode = o.u.trayCode,
locationCode = o.u.locationCode,
stockAreaCode = o.u.stockAreaCode,
useState = o.u.useState,
opTime = o.u.opTime,
productDate = o.u.productDate,
lotNo = o.u.lotNo,
CN_S_STOCK_CODE = o.d.CN_S_STOCK_CODE,
CN_S_ROADWAY = o.d.CN_S_ROADWAY,
CN_S_ROW = o.d.CN_S_ROW,
CN_S_COL = o.d.CN_S_COL,
CN_S_FLOOR = o.d.CN_S_FLOOR,
CN_S_LOCATION_STATE = o.d.CN_S_LOCATION_STATE
}).ToList();
Log.AlgorInfo("OutAssign-FlatAreaOutLocation", "lstCanOutL数据:" + JsonConvert.SerializeObject(lstCanOutL));
locationInLock = CreateDAL().GetLockLocationByState(model.stockCode.Trim(), item.areaCode, null, Constants.Location_State_InLock);
Log.AlgorInfo("OutAssign-FlatAreaOutLocation", "locationInLock数据:" + JsonConvert.SerializeObject(locationInLock));
//控制有入的不能出
foreach (TN_WM_LOCATIONCODE_EXT_Entity lEntity in locationInLock)
{
lstCanOutL.RemoveAll(o => o.CN_S_COL == lEntity.CN_S_COL);
}
locationOutLock = CreateDAL().GetLockLocationByState(model.stockCode.Trim(), item.areaCode, null, Constants.Location_State_OutLock);
Log.AlgorInfo("OutAssign-FlatAreaOutLocation", "locationOutLock数据:" + JsonConvert.SerializeObject(locationOutLock));
}
if (lstStrategy.Select(o => o.CN_S_CODE).ToList().Contains("AdjoinColNoTask"))
{
foreach (TN_WM_LOCATIONCODE_EXT_Entity lEntity in locationOutLock)
{
lstCanOutL.RemoveAll(o => int.Parse(o.CN_S_COL) == int.Parse(lEntity.CN_S_COL) + 1);
lstCanOutL.RemoveAll(o => int.Parse(o.CN_S_COL) == int.Parse(lEntity.CN_S_COL) - 1);
}
foreach (TN_WM_LOCATIONCODE_EXT_Entity lEntity in locationInLock)
{
lstCanOutL.RemoveAll(o => int.Parse(o.CN_S_COL) == int.Parse(lEntity.CN_S_COL) + 1);
lstCanOutL.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 lstSameItemRow = lstCanOutL.Select(o => o.CN_S_COL).Distinct().ToList();
List lstRowTask = new List();
foreach (string sRow in lstSameItemRow)
{
Log.AlgorInfo("OutAssign-FlatAreaOutLocation", "sRow数据:" + sRow.ToString());
rowTaskNT rowT = new rowTaskNT();
rowT.row = sRow;
rowT.taskNum = locationOutLock.Where(o => o.CN_S_COL == sRow).Count();
rowT.canOutLocation = lstCanOutL.Where(o => o.CN_S_COL == sRow).Count();
Log.AlgorInfo("OutAssign-FlatAreaOutLocation", "rowTaskNT数据:" + JsonConvert.SerializeObject(rowT));
if (rowT.canOutLocation > 0)
{
lstRowTask.Add(rowT);
}
}
Log.AlgorInfo("OutAssign-FlatAreaOutLocation", "lstRowTask数据:" + JsonConvert.SerializeObject(lstRowTask));
if (lstRowTask.Count > 0)
{
lstCanOutL = lstCanOutL.Where(a => a.CN_S_COL == lstRowTask.OrderBy(o => o.taskNum).ThenByDescending(b => b.canOutLocation).FirstOrDefault().row).ToList();
}
else
{
lstCanOutL.Clear();
}
}
else
{
lstCanOutL = CreateDAL().GetAssignFlatItemQty(model.itemCode, item.areaCode);
lstTrueLocation = CreateDAL().GetLocationByLocationCode(lstCanOutL.Select(o => o.locationCode).ToList());
lstCanOutL = lstCanOutL.Join(lstTrueLocation, u => u.locationCode, d => d.CN_S_LOCATION_CODE, (u, d) => new { u, d }).Select(o => new outAssignLocation
{
trayCode = o.u.trayCode,
locationCode = o.u.locationCode,
stockAreaCode = o.u.stockAreaCode,
useState = o.u.useState,
opTime = o.u.opTime,
productDate = o.u.productDate,
lotNo = o.u.lotNo,
CN_S_STOCK_CODE = o.d.CN_S_STOCK_CODE,
CN_S_ROADWAY = o.d.CN_S_ROADWAY,
CN_S_ROW = o.d.CN_S_ROW,
CN_S_COL = o.d.CN_S_COL,
CN_S_FLOOR = o.d.CN_S_FLOOR,
CN_S_LOCATION_STATE = o.d.CN_S_LOCATION_STATE
}).ToList();
}
#endregion
}
else
{
lstCanOutL = CreateDAL().GetAssignFlatItemQty(model.itemCode, item.areaCode);
lstTrueLocation = CreateDAL().GetLocationByLocationCode(lstCanOutL.Select(o => o.locationCode).ToList());
lstCanOutL = lstCanOutL.Join(lstTrueLocation, u => u.locationCode, d => d.CN_S_LOCATION_CODE, (u, d) => new { u, d }).Select(o => new outAssignLocation
{
trayCode = o.u.trayCode,
locationCode = o.u.locationCode,
stockAreaCode = o.u.stockAreaCode,
useState = o.u.useState,
opTime = o.u.opTime,
productDate = o.u.productDate,
lotNo = o.u.lotNo,
CN_S_STOCK_CODE = o.d.CN_S_STOCK_CODE,
CN_S_ROADWAY = o.d.CN_S_ROADWAY,
CN_S_ROW = o.d.CN_S_ROW,
CN_S_COL = o.d.CN_S_COL,
CN_S_FLOOR = o.d.CN_S_FLOOR,
CN_S_LOCATION_STATE = o.d.CN_S_LOCATION_STATE
}).ToList();
}
Log.AlgorInfo("OutAssign-GetAssignFlatItemQty结果", JsonConvert.SerializeObject(lstCanOutL));
if (lstCanOutL.Count > 0)
{
//获取该库区中可用货位的信息
Log.AlgorInfo("OutAssign-lstStrate", JsonConvert.SerializeObject(lstStrate));
lstTmp_Location = CalculateLocByStegy(ref lstDevice, lstCanOutL, lstStrate, out deviceCode);
if (lstTmp_Location.Count > 0)
{
at_l_Entity = lstTmp_Location[0];
#region 锁定待出库货位
if (at_l_Entity != null)
{
if (model.lockLocation)
{
result = CreateDAL().UpdateLocationState(at_l_Entity.locationCode, Constants.Location_State_OutLock, "出库", null);
if (result != null)
{
if (result.Success && result.Row > 0)
{
outResult.Success = true;
if (model.projectCode == "ys001")
{
if (at_l_Entity.needWeight > at_l_Entity.totalWeight)
{
int itemQty = Decimal.ToInt32(Math.Round(at_l_Entity.totalWeight, 0));
outResult.Msg = "该托盘大约有该物料" + itemQty.ToString() + autoBomE.CN_S_MEASURE_UNIT + ",不满足出库数量要求,还差" + Decimal.ToInt32(model.itemQty - itemQty).ToString() + autoBomE.CN_S_MEASURE_UNIT;
}
else
{
outResult.Msg = "";
}
}
else if (model.projectCode == "ntsd")
{
if (at_l_Entity.needQty > at_l_Entity.totalQty)
{
outResult.Msg = "该托盘有该物料" + at_l_Entity.totalQty.ToString() + ",不满足出库数量要求,还差" + Decimal.ToInt32(at_l_Entity.needQty - at_l_Entity.totalQty).ToString();
}
else
{
outResult.Msg = "";
}
}
outResult.locationCode = at_l_Entity.locationCode;
outResult.trayCode = lstCanOutL.Where(o => o.locationCode == at_l_Entity.locationCode).FirstOrDefault().trayCode;
outResult.areaCode = item.areaCode;
outResult.isControlQty = isControlQty;
outResult.isControlInv = isControlInv;
break;
}
}
}
else
{
outResult.Success = true;
if (model.projectCode == "ys001")
{
if (at_l_Entity.needWeight > at_l_Entity.totalWeight)
{
int itemQty = Decimal.ToInt32(at_l_Entity.totalWeight);
outResult.Msg = "该托盘大约有该物料" + itemQty.ToString() + autoBomE.CN_S_MEASURE_UNIT + ",不满足出库数量要求,还差" + Decimal.ToInt32(model.itemQty - itemQty).ToString() + autoBomE.CN_S_MEASURE_UNIT;
}
else
{
outResult.Msg = "";
}
}
else if (model.projectCode == "ntsd")
{
if (at_l_Entity.needQty > at_l_Entity.totalQty)
{
outResult.Msg = "该托盘有该物料" + at_l_Entity.totalQty.ToString() + ",不满足出库数量要求,还差" + Decimal.ToInt32(at_l_Entity.needQty - at_l_Entity.totalQty).ToString();
}
else
{
outResult.Msg = "";
}
}
else
{
outResult.Msg = "";
}
outResult.locationCode = at_l_Entity.locationCode;
outResult.trayCode = lstCanOutL.Where(o => o.locationCode == at_l_Entity.locationCode).FirstOrDefault().trayCode;
outResult.areaCode = item.areaCode;
outResult.isControlQty = isControlQty;
outResult.isControlInv = isControlInv;
break;
}
}
#endregion
break;
}
}
#endregion
}
}
return outResult;
}
///
/// 根据入库策略筛选符合条件的货位
///
///
///
///
///
///
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.EquipmentBalanceOut(lstDevice, lstFilterLoc, out deviceCode);
break;
case "RoadWayBalance": //巷道均衡
lstFilterLoc = Trctics.RoadWayBalanceOut(lstFilterLoc); ;
break;
case "NearbyBalance": //就近原则
lstFilterLoc = Trctics.NearbyBalanceOut(lstFilterLoc); ;
break;
case "ProductTimeOutFirst": //生产日期早先出
lstFilterLoc = lstFilterLoc.OrderBy(o => o.productDate).ToList();
lstFilterLoc = lstFilterLoc.Where(o => o.productDate == lstFilterLoc.FirstOrDefault().productDate).ToList();
break;
case "InStockTimeOutFirst": //入库时间早先出
lstFilterLoc = lstFilterLoc.OrderBy(o => o.opTime).ToList();
lstFilterLoc = lstFilterLoc.Where(o => o.opTime == lstFilterLoc.FirstOrDefault().opTime).ToList();
break;
case "SatisfyWeightFirst": //满足重量托盘先出
lstFilterLoc = lstFilterLoc.OrderByDescending(o => o.totalWeight).ToList();
if (lstFilterLoc[0].totalWeight >= lstFilterLoc[0].needWeight)
{
lstFilterLoc = lstFilterLoc.Where(o => o.totalWeight >= lstFilterLoc[0].needWeight).ToList();
}
else
{
lstFilterLoc = lstFilterLoc.Where(o => o.totalWeight == lstFilterLoc[0].totalWeight).ToList();
}
break;
case "MinMoveTray": //移动托盘小列先出
lstFilterLoc = lstFilterLoc.OrderBy(o => o.moveStep).ToList();
lstFilterLoc = lstFilterLoc.Where(o => o.moveStep == lstFilterLoc[0].moveStep).ToList();
break;
case "FirstInLastOut": //先进后出
Log.AlgorInfo("OutAssign-CalculateLocByStegy", "FirstInLastOut");
if (lstStrate.Contains("OutBigToSmall"))
{
Log.AlgorInfo("OutAssign-OutBigToSmall", "OutBigToSmall");
lstFilterLoc = lstFilterLoc.OrderBy(o => int.Parse(o.CN_S_ROW)).ThenByDescending(o => int.Parse(o.CN_S_COL)).ThenByDescending(b => int.Parse(b.CN_S_FLOOR)).ToList();
}
else if (lstStrate.Contains("OutSmallToBig"))
{
Log.AlgorInfo("OutAssign-OutSmallToBig", "OutSmallToBig");
lstFilterLoc = lstFilterLoc.OrderBy(o => int.Parse(o.CN_S_ROW)).ThenBy(o => int.Parse(o.CN_S_COL)).ThenByDescending(b => int.Parse(b.CN_S_FLOOR)).ToList();
}
else
{
lstFilterLoc = lstFilterLoc.OrderByDescending(o => int.Parse(o.CN_S_COL)).ThenBy(b => int.Parse(b.CN_S_FLOOR)).ToList();
}
Log.AlgorInfo("OutAssign-lstFilterLoc", JsonConvert.SerializeObject(lstFilterLoc));
lstFilterLoc = lstFilterLoc.Where(o => o.CN_S_COL == lstFilterLoc.FirstOrDefault().CN_S_COL && o.CN_S_FLOOR == lstFilterLoc.FirstOrDefault().CN_S_FLOOR).ToList();
break;
case "FirstInLastOutLj": //先进后出
Log.AlgorInfo("OutAssign-CalculateLocByStegy", "FirstInLastOut");
if (lstStrate.Contains("OutBigToSmall"))
{
Log.AlgorInfo("OutAssign-OutBigToSmall", "OutBigToSmall");
lstFilterLoc = lstFilterLoc.OrderBy(o => int.Parse(o.CN_S_ROW)).ThenByDescending(o => int.Parse(o.CN_S_COL)).ThenByDescending(b => int.Parse(b.CN_S_FLOOR)).ToList();
}
else if (lstStrate.Contains("OutSmallToBig"))
{
Log.AlgorInfo("OutAssign-OutSmallToBig", "OutSmallToBig");
lstFilterLoc = lstFilterLoc.OrderBy(o => int.Parse(o.CN_S_ROW)).ThenBy(o => int.Parse(o.CN_S_COL)).ThenByDescending(b => int.Parse(b.CN_S_FLOOR)).ToList();
}
else
{
lstFilterLoc = lstFilterLoc.OrderByDescending(o => o.CN_S_ROW).ThenBy(b => int.Parse(b.CN_S_FLOOR)).ToList();
}
Log.AlgorInfo("OutAssign-lstFilterLoc", JsonConvert.SerializeObject(lstFilterLoc));
lstFilterLoc = lstFilterLoc.Where(o => o.CN_S_ROW == lstFilterLoc.FirstOrDefault().CN_S_ROW && o.CN_S_FLOOR == lstFilterLoc.FirstOrDefault().CN_S_FLOOR).ToList();
break;
}
}
return lstFilterLoc;
}
///
/// 根据入库策略筛选符合条件的货位
///
///
///
///
///
///
public List CalculateCanOutByStegy(List lstCanOutL, List lstStrate, decimal needOutWeight)
{
List lstFilterLoc = lstCanOutL;
foreach (string stegy in lstStrate)
{
//逐个策略进行计算
switch (stegy)
{
case "ProductTimeOutFirst": //生产日期早先出
lstFilterLoc = lstFilterLoc.OrderBy(o => o.productDate).ToList();
lstFilterLoc = lstFilterLoc.Where(o => o.productDate == lstFilterLoc.FirstOrDefault().productDate).ToList();
break;
case "InStockTimeOutFirst": //入库时间早先出
lstFilterLoc = lstFilterLoc.OrderBy(o => o.opTime).ToList();
lstFilterLoc = lstFilterLoc.Where(o => o.opTime == lstFilterLoc.FirstOrDefault().opTime).ToList();
break;
}
}
return lstFilterLoc;
}
#endregion
}
}