using HH.WMS.BLL.Algorithm; using HH.WMS.BLL.Basic; using HH.WMS.BLL.External; using HH.WMS.BLL.Interface; using HH.WMS.Common; using HH.WMS.Common.Algorithm; using HH.WMS.DAL; using HH.WMS.DAL.Basic; using HH.WMS.DAL.InStock; using HH.WMS.DAL.OutStock; using HH.WMS.Entitys; using HH.WMS.Entitys.Basic; using HH.WMS.Entitys.Common; using HH.WMS.Entitys.Dto; using HH.WMS.Entitys.Entitys; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; namespace HH.WMS.BLL.OutStock { public class OutStockBLL : DapperBaseBLL { #region 发货通知单主表-分页 /// /// 发货通知单主表-分页 /// /// /// /// public DataTable GetOutList(OutSearchDto param, out long total) { return CreateDAL().GetOutList(param, out total); } #endregion #region 获取出库主子表 /// /// 获取出库主子表 /// /// /// public TN_WM_OUT_MSTEntity GetOutMstAndDtl(string CN_S_OP_NO) { TN_WM_OUT_MSTEntity outMst = CreateDapperDAL().GetSingleEntity(new { CN_S_OP_NO = CN_S_OP_NO }); List outDtlList = CreateDapperDAL().GetList(new { CN_S_OP_NO = CN_S_OP_NO }); outMst.OutDtlList = outDtlList; return outMst; } #endregion #region 根据出库单上升仓库量表分配量 /// /// 根据出库单上升仓库量表分配量 /// /// /// public List AddOrDropStockAllocQtyByOut(TN_WM_OUT_MSTEntity outMst, BatchType batchType) { if (outMst.OutDtlList == null || !outMst.OutDtlList.Any()) throw new Exception("批分物料行不可为空"); var stockQty = CreateDapperDAL().GetList(new { CN_S_ITEM_CODE = outMst.OutDtlList.Select(s => s.CN_S_ITEM_CODE).ToList() }); if (!stockQty.Any()) throw new Exception("仓库中未找到单据:" + outMst.CN_S_OP_NO + "的物料"); foreach (var dtl in outMst.OutDtlList) { var qty = dtl.CN_F_QUANTITY; var currentItemQty = stockQty.FindAll(f => f.CN_S_ITEM_CODE == dtl.CN_S_ITEM_CODE); switch (batchType) { case BatchType.Add: #region 上升分配量 foreach (var stock in currentItemQty) { var sQty = stock.CN_F_QUANTITY - stock.CN_F_EDITING_QTY - stock.CN_F_ALLOC_QTY; if (sQty == 0) continue; if (qty == 0) break; if (sQty >= qty) { stock.Update = true; stock.CN_F_ALLOC_QTY += qty; qty = 0; } else { stock.Update = true; stock.CN_F_ALLOC_QTY += sQty; qty -= sQty; } } if (qty > 0) { throw new Exception("仓库中物料:" + dtl.CN_S_ITEM_CODE + "库存量不足"); } #endregion break; case BatchType.Drop: #region 下降分配量 foreach (var stock in currentItemQty) { var aQty = stock.CN_F_ALLOC_QTY; if (aQty == 0) continue; if (qty == 0) break; if (aQty >= qty) { stock.Update = true; stock.CN_F_ALLOC_QTY -= qty; qty = 0; } else { stock.Update = true; stock.CN_F_ALLOC_QTY -= aQty; qty -= aQty; } } if (qty > 0) { throw new Exception("仓库中物料:" + dtl.CN_S_ITEM_CODE + "分配量不足"); } #endregion break; default: throw new Exception("批分参数错误"); } } return stockQty.FindAll(f => f.Update); } #endregion #region 根据分拣单明细上升仓库量表分配量 /// /// 根据出库单上升仓库量表分配量 /// /// /// public List AddOrDropStockAllocQtyBySorting(List sortingLocations, BatchType batchType) { if (sortingLocations == null || !sortingLocations.Any()) throw new Exception("AddOrDropStockAllocQtyBySorting 批分物料不可为空"); //仓库物料,批次空的放前面 var stockQty = CreateDapperDAL().GetList(new { CN_S_ITEM_CODE = sortingLocations.Select(s => s.CN_S_ITEM_CODE).ToList() }).Select(x => new { index = string.IsNullOrEmpty(x.CN_S_PRODUCTION_BATCH) ? 0 : 1, x }).OrderBy(o => o.index).Select(m => m.x).ToList(); if (!stockQty.Any()) throw new Exception("仓库中未找到物料:" + string.Join(",", sortingLocations.Select(s => s.CN_S_ITEM_CODE))); sortingLocations = sortingLocations.GroupBy(g => new { g.CN_S_ITEM_CODE, g.CN_S_PRODUCTION_BATCH }).Select(s => new TN_WM_SORTING_LOCATIONEntity() { CN_S_ITEM_CODE = s.Key.CN_S_ITEM_CODE, CN_S_PRODUCTION_BATCH = s.Key.CN_S_PRODUCTION_BATCH, CN_F_QUANTITY = s.Sum(m => m.CN_F_QUANTITY) }).ToList(); foreach (var dtl in sortingLocations) { var qty = dtl.CN_F_QUANTITY; var currentItemQty = stockQty.FindAll(f => f.CN_S_ITEM_CODE == dtl.CN_S_ITEM_CODE && (string.IsNullOrEmpty(dtl.CN_S_PRODUCTION_BATCH) || dtl.CN_S_PRODUCTION_BATCH == f.CN_S_PRODUCTION_BATCH)); switch (batchType) { case BatchType.Add: #region 上升分配量 foreach (var stock in currentItemQty) { var sQty = stock.CN_F_QUANTITY - stock.CN_F_EDITING_QTY - stock.CN_F_ALLOC_QTY; if (sQty == 0) continue; if (qty == 0) break; if (sQty >= qty) { stock.Update = true; stock.CN_F_ALLOC_QTY += qty; qty = 0; } else { stock.Update = true; stock.CN_F_ALLOC_QTY += sQty; qty -= sQty; } } if (qty > 0) { throw new Exception("仓库中物料:" + dtl.CN_S_ITEM_CODE + "库存量不足"); } #endregion break; case BatchType.Drop: #region 下降分配量 foreach (var stock in currentItemQty) { var aQty = stock.CN_F_ALLOC_QTY; if (aQty == 0) continue; if (qty == 0) break; if (aQty >= qty) { stock.Update = true; stock.CN_F_ALLOC_QTY -= qty; stock.CN_F_QUANTITY -= qty; qty = 0; } else { stock.Update = true; stock.CN_F_ALLOC_QTY -= aQty; stock.CN_F_QUANTITY -= aQty; qty -= aQty; } } if (qty > 0) { throw new Exception("仓库中物料:" + dtl.CN_S_ITEM_CODE + "分配量不足"); } #endregion break; default: throw new Exception("批分参数错误"); } } return stockQty.FindAll(f => f.Update); } #endregion #region 根据分拣单明细上升库区量表分配量 /// /// 根据出库单上升仓库量表分配量 /// /// /// public List AddOrDropAreaAllocQtyBySorting(List sortingLocations, BatchType batchType) { if (sortingLocations == null || !sortingLocations.Any()) throw new Exception("AddOrDropAreaAllocQtyBySorting 批分物料不可为空"); //仓库物料,批次空的放前面 var areaQty = CreateDapperDAL().GetList(new { CN_S_STOCK_AREA = sortingLocations.Select(s => s.CN_S_AREA_CODE).ToList(), CN_S_ITEM_CODE = sortingLocations.Select(s => s.CN_S_ITEM_CODE).ToList() }).Select(x => new { index = string.IsNullOrEmpty(x.CN_S_PRODUCTION_BATCH) ? 0 : 1, x }).OrderBy(o => o.index).Select(m => m.x).ToList(); if (!areaQty.Any()) throw new Exception("库区中未找到物料:" + string.Join(",", sortingLocations.Select(s => s.CN_S_ITEM_CODE))); sortingLocations = sortingLocations.GroupBy(g => new { g.CN_S_ITEM_CODE, g.CN_S_AREA_CODE, g.CN_S_PRODUCTION_BATCH }).Select(s => new TN_WM_SORTING_LOCATIONEntity() { CN_S_AREA_CODE = s.Key.CN_S_AREA_CODE, CN_S_ITEM_CODE = s.Key.CN_S_ITEM_CODE, CN_S_PRODUCTION_BATCH = s.Key.CN_S_PRODUCTION_BATCH, CN_F_QUANTITY = s.Sum(m => m.CN_F_QUANTITY) }).ToList(); foreach (var dtl in sortingLocations) { var qty = dtl.CN_F_QUANTITY; var currentItemQty = areaQty.FindAll(f => f.CN_S_ITEM_CODE == dtl.CN_S_ITEM_CODE && dtl.CN_S_AREA_CODE == f.CN_S_STOCK_AREA && (string.IsNullOrEmpty(dtl.CN_S_PRODUCTION_BATCH) || dtl.CN_S_PRODUCTION_BATCH == f.CN_S_PRODUCTION_BATCH)); switch (batchType) { case BatchType.Add: #region 上升分配量 foreach (var stock in currentItemQty) { var sQty = stock.CN_F_QUANTITY - stock.CN_F_ALLOC_QTY; if (sQty == 0) continue; if (qty == 0) break; if (sQty >= qty) { stock.Update = true; stock.CN_F_ALLOC_QTY += qty; qty = 0; } else { stock.Update = true; stock.CN_F_ALLOC_QTY += sQty; qty -= sQty; } } if (qty > 0) { throw new Exception("库区中物料:" + dtl.CN_S_ITEM_CODE + "库存量不足"); } #endregion break; case BatchType.Drop: #region 下降分配量 foreach (var stock in currentItemQty) { var aQty = stock.CN_F_ALLOC_QTY; if (aQty == 0) continue; if (qty == 0) break; if (aQty >= qty) { stock.Update = true; stock.CN_F_ALLOC_QTY -= qty; stock.CN_F_QUANTITY -= qty; qty = 0; } else { stock.Update = true; stock.CN_F_ALLOC_QTY -= aQty; stock.CN_F_QUANTITY -= aQty; qty -= aQty; } } if (qty > 0) { throw new Exception("库区中物料:" + dtl.CN_S_ITEM_CODE + "分配量不足"); } #endregion break; default: throw new Exception("批分参数错误"); } } return areaQty.FindAll(f => f.Update); } #endregion #region 下架记录 /// /// 下架记录 /// /// /// /// private TN_WM_DOWN_HISTORYEntity GetDownHistory(TN_WM_SORTING_LOCATIONEntity sl, decimal qty) { return new TN_WM_DOWN_HISTORYEntity { CN_GUID = Guid.NewGuid().ToString(), CN_S_LOCATION_CODE = sl.CN_S_LOCATION_CODE, CN_S_ITEM_STATE = sl.CN_S_ITEM_STATE, CN_S_TRAY_CODE = sl.CN_S_TRAY_CODE, CN_S_TRAY_GRID = sl.CN_S_TRAY_GRID, CN_S_ITEM_CODE = sl.CN_S_ITEM_CODE, CN_S_ITEM_NAME = sl.CN_S_ITEM_NAME, CN_S_PRODUCTION_BATCH = sl.CN_S_LOT_NO, CN_F_QUANTITY = qty, CN_S_MODEL = sl.CN_S_MODEL, CN_S_STOCK_AREA = sl.CN_S_AREA_CODE, CN_S_STOCK_CODE = sl.CN_S_STOCK_CODE, CN_T_CREATE = DateTime.Now, CN_T_MODIFY = DateTime.Now, CN_S_OWNER = "", CN_S_MEASURE_UNIT = "", CN_S_CREATOR = userInfo.CN_S_LOGIN, CN_S_CREATOR_BY = userInfo.CN_S_NAME, CN_S_MODIFY = "", CN_S_MODIFY_BY = "", CN_S_OP_FROM = "分拣完成-" + sl.CN_S_SORTING_NO, //CN_S_EXT1 = uniqueCode //executeStatePara.uniqueCodes }; } #endregion #region 根据分拣单明细上升托盘物料关联表分配量 /// /// 根据分拣单明细上升托盘物料关联表分配量 /// /// /// /// public List AddOrDropTrayAllocQtyBySorting(List sortingLocations, BatchType batchType) { if (sortingLocations == null || !sortingLocations.Any()) throw new Exception("AddOrDropTrayAllocQtyBySorting 批分物料不可为空"); //仓库物料,批次空的放前面 var trayQty = CreateDapperDAL().GetList(new { CN_S_ITEM_CODE = sortingLocations.Select(s => s.CN_S_ITEM_CODE).ToList() }).Select(x => new { index = string.IsNullOrEmpty(x.CN_S_PRODUCTION_BATCH) ? 0 : 1, x }).OrderBy(o => o.index).Select(m => m.x).ToList(); if (!trayQty.Any()) throw new Exception("托盘中未找到物料:" + string.Join(",", sortingLocations.Select(s => s.CN_S_ITEM_CODE))); //sortingLocations = sortingLocations.GroupBy(g => new //{ // g.CN_S_ITEM_CODE, // g.CN_S_TRAY_CODE, // g.CN_S_PRODUCTION_BATCH //}).Select(s => new TN_WM_SORTING_LOCATIONEntity() //{ // CN_S_ITEM_CODE = s.Key.CN_S_ITEM_CODE, // CN_S_TRAY_CODE = s.Key.CN_S_TRAY_CODE, // CN_S_PRODUCTION_BATCH = s.Key.CN_S_PRODUCTION_BATCH, // CN_F_QUANTITY = s.Sum(m => m.CN_F_QUANTITY) //}).ToList(); foreach (var dtl in sortingLocations) { var qty = dtl.CN_F_QUANTITY; var currentItemQty = trayQty.FindAll(f => f.CN_S_ITEM_CODE == dtl.CN_S_ITEM_CODE && f.CN_S_TRAY_CODE == dtl.CN_S_TRAY_CODE); switch (batchType) { case BatchType.Add: #region 上升分配量 foreach (var stock in currentItemQty) { var sQty = stock.CN_F_QUANTITY - stock.CN_F_ALLOC_QTY; if (sQty == 0) continue; if (qty == 0) break; if (sQty >= qty) { stock.Update = true; stock.CN_F_ALLOC_QTY += qty; qty = 0; } else { stock.Update = true; stock.CN_F_ALLOC_QTY += sQty; qty -= sQty; } } if (qty > 0) { throw new Exception("托盘中物料:" + dtl.CN_S_ITEM_CODE + "库存量不足"); } #endregion break; case BatchType.Drop: #region 下降分配量 foreach (var stock in currentItemQty) { var aQty = stock.CN_F_ALLOC_QTY; if (aQty == 0) continue; if (qty == 0) break; if (aQty >= qty) { stock.Update = true; stock.CN_F_ALLOC_QTY -= qty; stock.CN_F_QUANTITY -= qty; qty = 0; } else { stock.Update = true; stock.CN_F_ALLOC_QTY -= aQty; stock.CN_F_QUANTITY -= aQty; qty -= aQty; } } if (qty > 0) { throw new Exception("托盘中物料:" + dtl.CN_S_ITEM_CODE + "分配量不足"); } #endregion break; default: throw new Exception("批分参数错误"); } } return trayQty.FindAll(f => f.Update); } #endregion #region 出库订单新增 /// /// 出库订单新增 /// /// /// public OperateResult AddOut(TN_WM_OUT_MSTEntity outMst) { return UseTransaction(trans => { //新增主表 CreateDapperDAL().Add(outMst, trans); //新增子表 CreateDapperDAL().AddRange(outMst.OutDtlList, trans); //升仓库分配量 }); } #endregion #region 出库订单修改 /// /// 出库订单修改 /// /// /// public OperateResult UpdateOut(TN_WM_OUT_MSTEntity outMst) { return UseTransaction(trans => { //修改主表 CreateDapperDAL().Update(outMst, new { CN_S_OP_NO = outMst.CN_S_OP_NO }, trans); //删除子表 CreateDapperDAL().Delete(new { CN_S_OP_NO = outMst.CN_S_OP_NO }, trans); //新增子表 CreateDapperDAL().AddRange(outMst.OutDtlList, trans); }); } #endregion #region 删除出库订单 /// /// 删除出库订单 /// /// /// public OperateResult DeleteOut(string opNo) { return UseTransaction(trans => { //删除出库订单主表 CreateDapperDAL().Delete(new { CN_S_OP_NO = opNo }, trans); //删除出库订单子表 CreateDapperDAL().Delete(new { CN_S_OP_NO = opNo }, trans); }); } #endregion #region 提交出库订单 /// /// 提交出库订单 /// /// /// /// public OperateResult SubmitOut(TN_WM_OUT_MSTEntity outMst, TN_WM_SORTING_LISTEntity sortingEntity) { #region 上升仓库、库区、托盘 分配量 var sortingLocations = sortingEntity.SortingLocationList; //上升仓库量表分配量 var addStockAlloc = AddOrDropStockAllocQtyBySorting(sortingLocations, BatchType.Add); //上升库区量表分配量 var addAreaAlloc = AddOrDropAreaAllocQtyBySorting(sortingLocations, BatchType.Add); //上升托盘关联表分配量 var addTrayAlloc = AddOrDropTrayAllocQtyBySorting(sortingLocations, BatchType.Add); #endregion return UseTransaction(trans => { //分拣单主表 CreateDapperDAL().Add(sortingEntity, trans); //分拣单子表 CreateDapperDAL().AddRange(sortingEntity.SortingDtlList, trans); //分拣明细表 CreateDapperDAL().AddRange(sortingEntity.SortingLocationList, trans); //锁货位 预出库锁定 sortingEntity.SortingLocationList.ForEach(m => { CreateDapperDAL().Update(new { CN_S_LOCATION_STATE = Constants.Location_State_OutLock }, new { CN_S_LOCATION_CODE = m.CN_S_LOCATION_CODE }, trans); }); //修改出库单表属性 CreateDapperDAL().Update(new { CN_S_STATE = "待分拣", CN_T_MODIFY = DateTime.Now, }, new { CN_S_OP_NO = outMst.CN_S_OP_NO }, trans); //升仓库分配量 addStockAlloc.ForEach(e => { if (CreateDAL().UpdateStockAllocQty(e, trans).AffectedRows == 0) throw new Exception("时间戳被更新,修改仓库分配量失败"); }); //升库区分配量 addAreaAlloc.ForEach(e => { if (CreateDAL().UpdateAreaAlloc(e, trans).AffectedRows == 0) throw new Exception("时间戳被更新,修改库区分配量失败"); }); //升托盘物料关联表分配量 addTrayAlloc.ForEach(e => { if (CreateDAL().UpdateTrayItemAllocQty(e, trans).AffectedRows == 0) throw new Exception("时间戳被更新,修改托盘物料关联表分配量失败"); }); }); } #endregion #region 获取波次实体 /// /// 获取波次实体 /// /// /// /// /// private TN_WM_WAVE_MSTEntity GetWaveEntity(TN_WM_OUT_MSTEntity outMst) { var user = userInfo; TN_WM_WAVE_MSTEntity waveMstEntity = new TN_WM_WAVE_MSTEntity() { CN_S_CREATE_TYPE = Constants.CreateType_Manual, CN_S_WAVE_NO = outMst.CN_S_WAVE_CODE, CN_S_FROM = "WMS", CN_GUID = Guid.NewGuid().ToString(), CN_S_STATE = Constants.Sorting_Stay, CN_T_CREATE = DateTime.Now, CN_T_MODIFY = DateTime.Now, CN_T_OPERATE = DateTime.Now, CN_S_CREATOR = user.CN_S_NAME, CN_S_CREATOR_BY = user.CN_S_LOGIN, CN_S_MODIFY = user.CN_S_NAME, CN_S_MODIFY_BY = user.CN_S_LOGIN, CN_C_NEED_SEEDING = Constants.Y, CN_S_STATUS = Constants.State_New, CN_S_SEEDING_MODE = "", CN_S_STOCK_CODE = outMst.CN_S_STOCK_CODE }; waveMstEntity.WaveDtlList = new List(); int index = 1; TN_WM_WAVE_DTLEntity waveDtlEntity = new TN_WM_WAVE_DTLEntity() { CN_GUID = Guid.NewGuid().ToString(), CN_S_WAVE_NO = outMst.CN_S_WAVE_CODE, CN_S_ORDER_NO = outMst.CN_S_OP_NO, CN_S_STATE = Constants.State_New, CN_T_CREATE = DateTime.Now, CN_T_MODIFY = DateTime.Now, CN_S_CREATOR = user.CN_S_NAME, CN_S_CREATOR_BY = user.CN_S_LOGIN, CN_S_MODIFY = user.CN_S_NAME, CN_S_MODIFY_BY = user.CN_S_LOGIN, CN_S_MSTGUID = waveMstEntity.CN_GUID, CN_N_ORDER = index++ }; waveMstEntity.WaveDtlList.Add(waveDtlEntity); return waveMstEntity; } #endregion #region 取货位分拣中的物料 /// /// 取货位分拣中的物料 /// /// /// public List GetSortingLocation(string locationCode) { return CreateDAL().GetSortingLocation(locationCode); } #endregion #region 分拣货位生成任务 /// /// 分拣货位生成任务 /// /// /// public OperateResult ExecuteSortingTask(List sortingLocations) { //所有库区 var allArea = BLLCreator.Create().GetArea(4, sortingLocations[0].CN_S_STOCK_CODE); //生成出库任务号 UserRuleEntity user = new UserRuleEntity() { RuleCode = Constants.TaskNo_Out }; //生成出库任务 var tasks = new List(); foreach (var s in sortingLocations) { var startArea = allArea.Find(f => f.CN_S_AREA_CODE == Util.ToString(s.CN_S_AREA_CODE).Trim()); if (startArea == null) return OperateResult.Error("mongo未找到库区:" + s.CN_S_AREA_CODE); var endArea = allArea.Find(f => f.CN_S_AREA_CODE == Util.ToString(s.EndArea).Trim()); if (endArea == null) return OperateResult.Error("mongo未找到库区:" + s.EndArea); string taskNo = user.GenerateNo(); if (string.IsNullOrEmpty(taskNo)) throw new Exception("生成出库任务号失败"); var task = new TN_WM_TASKEntity { CN_S_TASK_NO = taskNo, CN_S_TRAY_CODE = s.CN_S_TRAY_CODE, CN_S_START_BIT = s.CN_S_LOCATION_CODE, CN_S_END_BIT = s.EndBit, CN_S_STATE = Constants.TaskState_NoExecuted, CN_S_STOCK_CODE = s.CN_S_STOCK_CODE, CN_S_START_AREA = s.CN_S_AREA_CODE, CN_S_END_AREA = s.EndArea, CN_N_PRIORITY = 1, CN_S_CREATOR = "sys", CN_S_CREATOR_BY = "sys", CN_T_CREATE = DateTime.Now, CN_T_MODIFY = DateTime.Now, CN_S_REMARK = "", CN_S_TASK_TYPE = Constants.TaskType_SortingOut, CN_C_START_IS_CONTROL_QTY = startArea.CN_C_IS_CONTROL_QTY, CN_C_END_IS_CONTROL_QTY = endArea.CN_C_IS_CONTROL_QTY, CN_S_START_CONTROL_INV = startArea.CN_C_IS_INVENTORY, CN_S_END_CONTROL_INV = endArea.CN_C_IS_INVENTORY, CN_S_START_AREA_TYPE = startArea.CN_S_AREA_CLASS, CN_S_END_AREA_TYPE = endArea.CN_S_AREA_CLASS, CN_S_FROM_OP = Constants.Rule_SortingNo }; tasks.Add(task); } return UseTransaction(trans => { sortingLocations.ForEach(e => { CreateDapperDAL().Update(new { CN_B_SEND = true }, new { CN_S_SORTING_NO = e.CN_S_SORTING_NO, CN_S_LOCATION_CODE = e.CN_S_LOCATION_CODE }, trans); }); tasks.ForEach(taskEntity => { //锁货位,发任务 LockLocationAndSendAms(taskEntity, trans); }); }); } #endregion #region 保存分拣 /// /// 保存分拣 /// /// /// public OperateResult SaveSortingLocation(string startLocationCode, List sortingLocations) { #region 装载分拣数据 //分拣单 string sortingNo = sortingLocations[0].CN_S_SORTING_NO; //分拣单实体 var sortingEntity = BLLCreator.CreateDapper().GetSingleEntity(new { CN_S_SORTING_NO = sortingNo }); if (sortingEntity == null) return OperateResult.Error("未找到分拣单:" + sortingNo); //该分拣单的所有分拣明细 var all = BLLCreator.CreateDapper().GetList(new { CN_S_SORTING_NO = sortingNo }); //不包括本次的分拣明细 var other = all.FindAll(f => !sortingLocations.Select(ss => ss.CN_GUID).Contains(f.CN_GUID)); #endregion var taskEntity = new TN_WM_TASKEntity(); if (sortingLocations[0].CN_S_NEED_SORT == Constants.Y) { #region 生成入库任务 //调用算法计算终点货位 string endLocationCode = string.Empty; //调用入库算法,获取空货位 InAlgorEnitty iAe = new InAlgorEnitty() { stockAreaCode = sortingLocations[0].CN_S_AREA_CODE, logicCode = "", locationQty = 1, trayCode = sortingLocations[0].CN_S_TRAY_CODE, itemCode = "", lockLocation = false//是否需要锁定货位 }; iAe.lstDevice = null; InResultEntity irEresult = BLLCreator.Create().In(iAe); if (!irEresult.Success) { return OperateResult.Error(irEresult.Msg);//货位获取失败! } else { endLocationCode = irEresult.lstLocation[0].locationCode.ToString(); } var startLocation = BLLCreator.CreateDapper().GetSingleEntity(new { CN_S_LOCATION_CODE = startLocationCode }); if (startLocation == null) return OperateResult.Error("未找到货位:" + startLocationCode); //所有库区 var allArea = BLLCreator.Create().GetArea(4, sortingEntity.CN_S_STOCK_CODE); var startArea = allArea.Find(f => f.CN_S_AREA_CODE == Util.ToString(startLocation.CN_S_AREA_CODE).Trim()); if (startArea == null) return OperateResult.Error("mongo未找到库区:" + startLocation.CN_S_AREA_CODE); var endArea = allArea.Find(f => f.CN_S_AREA_CODE == Util.ToString(sortingLocations[0].CN_S_AREA_CODE).Trim()); if (endArea == null) return OperateResult.Error("mongo未找到库区:" + sortingLocations[0].CN_S_AREA_CODE); //生成入库任务号 UserRuleEntity user = new UserRuleEntity() { RuleCode = Constants.TaskNo_In }; string taskNo = user.GenerateNo(); if (string.IsNullOrEmpty(taskNo)) throw new Exception("生产入库任务号失败"); var s = sortingLocations[0]; taskEntity = new TN_WM_TASKEntity { CN_S_TASK_NO = taskNo, CN_S_TRAY_CODE = s.CN_S_TRAY_CODE, CN_S_START_BIT = startLocation.CN_S_LOCATION_CODE, CN_S_END_BIT = endLocationCode, CN_S_STATE = Constants.TaskState_NoExecuted, CN_S_STOCK_CODE = sortingEntity.CN_S_STOCK_CODE, CN_S_START_AREA = startLocation.CN_S_AREA_CODE, CN_S_END_AREA = sortingLocations[0].CN_S_AREA_CODE, CN_N_PRIORITY = 1, CN_S_CREATOR = userInfo.CN_S_LOGIN, CN_S_CREATOR_BY = userInfo.CN_S_NAME, CN_T_CREATE = DateTime.Now, CN_T_MODIFY = DateTime.Now, CN_S_REMARK = "", CN_S_TASK_TYPE = Constants.TaskType_SortingIn, CN_C_START_IS_CONTROL_QTY = startArea.CN_C_IS_CONTROL_QTY, CN_C_END_IS_CONTROL_QTY = endArea.CN_C_IS_CONTROL_QTY, CN_S_START_CONTROL_INV = startArea.CN_C_IS_INVENTORY, CN_S_END_CONTROL_INV = endArea.CN_C_IS_INVENTORY, CN_S_START_AREA_TYPE = startArea.CN_S_AREA_CLASS, CN_S_END_AREA_TYPE = endArea.CN_S_AREA_CLASS, CN_S_FROM_OP = Constants.Rule_SortingNo }; #endregion } //下降托盘关联表分配量 var dropTrayAlloc = AddOrDropTrayAllocQtyBySorting(sortingLocations, BatchType.Drop); //下架记录 var downHistory = sortingLocations.Select(sl => new TN_WM_DOWN_HISTORYEntity { CN_GUID = Guid.NewGuid().ToString(), CN_S_LOCATION_CODE = sl.CN_S_LOCATION_CODE, CN_S_ITEM_STATE = sl.CN_S_ITEM_STATE, CN_S_TRAY_CODE = sl.CN_S_TRAY_CODE, CN_S_TRAY_GRID = sl.CN_S_TRAY_GRID, CN_S_ITEM_CODE = sl.CN_S_ITEM_CODE, CN_S_ITEM_NAME = sl.CN_S_ITEM_NAME, CN_S_PRODUCTION_BATCH = sl.CN_S_PRODUCTION_BATCH, CN_F_QUANTITY = sl.CN_F_QUANTITY, CN_S_MODEL = sl.CN_S_MODEL, CN_S_STOCK_AREA = sl.CN_S_AREA_CODE, CN_S_STOCK_CODE = sortingEntity.CN_S_STOCK_CODE, CN_T_CREATE = DateTime.Now, CN_T_MODIFY = DateTime.Now, CN_S_OWNER = "", CN_S_MEASURE_UNIT = sl.CN_S_MEASURE_UNIT, CN_S_CREATOR = userInfo.CN_S_LOGIN, CN_S_CREATOR_BY = userInfo.CN_S_NAME, CN_S_MODIFY = "", CN_S_MODIFY_BY = "", CN_S_OP_FROM = "分拣完成-" + sl.CN_S_SORTING_NO, //CN_S_EXT1 = uniqueCode //executeStatePara.uniqueCodes }).ToList(); var dropStockAlloc = new List(); var dropAreaAlloc = new List(); if (!other.Exists(e => e.CN_F_PICKED_QTY == 0)) { //下降仓库量表分配量 dropStockAlloc = AddOrDropStockAllocQtyBySorting(all, BatchType.Drop); //下降库区量表分配量 dropAreaAlloc = AddOrDropAreaAllocQtyBySorting(all, BatchType.Drop); } return UseTransaction(trans => { sortingLocations.ForEach(e => { CreateDapperDAL().Update(new { CN_F_PICKED_QTY = e.CN_F_QUANTITY }, new { CN_GUID = e.CN_GUID }, trans); }); //降托盘物料关联表分配量 dropTrayAlloc.ForEach(e => { if (CreateDAL().UpdateTrayItemAllocQty(e, trans).AffectedRows == 0) throw new Exception("时间戳被更新,修改托盘物料关联表分配量失败"); }); //下架记录 CreateDapperDAL().AddRange(downHistory, trans); //已分拣完 if (!other.Exists(e => e.CN_F_PICKED_QTY == 0)) { //出库单置为已完成 CreateDapperDAL().Update(new { CN_S_STATE = Constants.State_Completed }, new { CN_S_OP_NO = sortingEntity.CN_S_FROM_NO }, trans); //分拣单置为已分拣 CreateDapperDAL().Update(new { CN_S_STATE = Constants.Sorting_Sorted }, new { CN_S_SORTING_NO = sortingNo }, trans); //降仓库分配量 dropStockAlloc.ForEach(e => { if (CreateDAL().UpdateStockAllocQty(e, trans).AffectedRows == 0) throw new Exception("时间戳被更新,修改仓库分配量失败"); }); //降库区分配量 dropAreaAlloc.ForEach(e => { if (CreateDAL().UpdateAreaAlloc(e, trans).AffectedRows == 0) throw new Exception("时间戳被更新,修改库区分配量失败"); }); } if (sortingLocations[0].CN_S_NEED_SORT == Constants.Y) { //锁货位,发任务 LockLocationAndSendAms(taskEntity, trans, true); } else { CreateDapperDAL().Delete(new { CN_S_LOCATION_CODE = startLocationCode }, trans); CreateDapperDAL().Update(new { CN_S_LOCATION_STATE = Constants.Location_State_Normal, CN_S_USE_STATE = Constants.Use_State_Empty }, new { CN_S_LOCATION_CODE = startLocationCode }); } }); } #endregion #region 锁货位,发任务 /// /// 锁货位,发任务 /// /// /// private void LockLocationAndSendAms(TN_WM_TASKEntity taskEntity, IDbTransaction trans, bool lockStart = false) { string taskNo = taskEntity.CN_S_TASK_NO; OperateResult re = CreateDAL>().Add(taskEntity, trans); //锁定目的位置货位-预入库锁定 if ("Y".Equals(taskEntity.CN_C_END_IS_CONTROL_QTY)) { var operateResult = CreateDAL().UpdateLocationExtStateLock(taskEntity.CN_S_END_BIT, Constants.Location_State_InLock, Constants.Location_State_Normal, "", taskNo, trans); if (operateResult.AffectedRows == 0) { throw new Exception("更新目的货位状态并发冲突,该货位状态可能已经发生变化"); } BLLCreator.Create().AddStateChange(taskEntity.CN_S_START_BIT, "正常", "预入库锁定", "分拣出生成任务锁定终点货位", "服务", "sys", taskNo, taskEntity.CN_S_STOCK_CODE, taskEntity.CN_S_END_AREA, trans); } if ("Y".Equals(taskEntity.CN_C_START_IS_CONTROL_QTY) && lockStart) { //锁定起始位置货位-预出库锁定 var operateResult = CreateDAL().UpdateLocationExtStateLock(taskEntity.CN_S_START_BIT, Constants.Location_State_OutLock, Constants.Location_State_Normal, "", taskNo, trans); if (operateResult.AffectedRows == 0) { throw new Exception("更新起点货位状态并发冲突,该货位状态可能已经发生变化"); } BLLCreator.Create().AddStateChange(taskEntity.CN_S_START_BIT, "正常", "预出库锁定", "分拣出生成任务锁定起点货位", "服务", "sys", taskNo, taskEntity.CN_S_STOCK_CODE, taskEntity.CN_S_START_AREA, trans); } var amsRes = BLLCreator.Create().SendAmsCreateTaskHK(taskEntity); if (!amsRes.Success) throw new Exception("SendAmsCreateTaskHK 异常:" + amsRes.Msg); } #endregion } }