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 } }