namespace WIDESEA_StorageBasicServices; public class Dt_BillGroupStockService : ServiceBase, IDt_BillGroupStockService { private readonly IUnitOfWorkManage _unitOfWorkManage; private readonly IDt_OutOrderService _outOrderService; private readonly IDt_OutOrderAndStockRepository _OutOrderAndStockRepository; private readonly IDt_OutOrderAndStock_HtyService _OutOrderAndStock_HtyService; private readonly IMapper _mapper; private readonly IDt_BillGroupStockDetailRepository _dt_BillGroupStockDetailRepository; private readonly IDt_InboundOrderDetailRepository _dt_InboundOrderDetailRepository; private readonly IDt_MaterielInfoRepository _dt_MaterielInfoRepository; private readonly IDt_InboundOrderRepository _dt_InboundOrderRepository; private readonly IDt_BillGroupStock_HtyRepository _dt_BillGroupStock_HtyRepository; private readonly IDt_BillGroupStockDetail_HtyRepository _dt_BillGroupStockDetail_HtyRepository; public Dt_BillGroupStockService(IDt_BillGroupStockRepository baseDal, IUnitOfWorkManage unitOfWorkManage, IDt_OutOrderService outOrderService, IDt_OutOrderAndStockRepository outOrderAndStockRepository, IMapper mapper, IDt_OutOrderAndStock_HtyService outOrderAndStock_HtyService, IDt_BillGroupStockDetailRepository dt_BillGroupStockDetailRepository, IDt_InboundOrderDetailRepository dt_InboundOrderDetailRepository, IDt_MaterielInfoRepository dt_MaterielInfoRepository, IDt_InboundOrderRepository dt_InboundOrderRepository, IDt_BillGroupStock_HtyRepository dt_BillGroupStock_HtyRepository, IDt_BillGroupStockDetail_HtyRepository dt_BillGroupStockDetail_HtyRepository) : base(baseDal) { _unitOfWorkManage = unitOfWorkManage; _outOrderService = outOrderService; _OutOrderAndStockRepository = outOrderAndStockRepository; _mapper = mapper; _OutOrderAndStock_HtyService = outOrderAndStock_HtyService; _dt_BillGroupStockDetailRepository = dt_BillGroupStockDetailRepository; _dt_InboundOrderDetailRepository = dt_InboundOrderDetailRepository; _dt_MaterielInfoRepository = dt_MaterielInfoRepository; _dt_InboundOrderRepository = dt_InboundOrderRepository; _dt_BillGroupStock_HtyRepository = dt_BillGroupStock_HtyRepository; _dt_BillGroupStockDetail_HtyRepository = dt_BillGroupStockDetail_HtyRepository; } #region 外部接口 /// /// 根据特定条件获取库存 /// /// 托盘号 /// 货位ID /// 物料编号 /// 特定库存 public async Task GetStocks(string palletCode = null, string locationID = null, string materialNo = null) { return await Db.Queryable() .WhereIF(palletCode != null, x => x.PalletCode == palletCode) .WhereIF(locationID != null, x => x.LocationCode == locationID) .WhereIF(materialNo != null, x => x.MaterialNo == materialNo) .Includes(x => x.LocationInfo) .Includes(x => x.Dt_BillGroupStockDetailList) .FirstAsync(); } #endregion 外部接口 #region 内部调用方法 /// /// 更新库存集合 /// /// 库存集合 /// 成功/失败 public bool UpdateNavStock(List stocks) { return BaseDal.UpdateNavStock(stocks); } /// /// 更新单个库存 /// /// 库存 /// 成功/失败 public bool UpdateNavStock(Dt_BillGroupStock stocks) { return BaseDal.UpdateNavStock(stocks); } public List GetOutboundStockList(string materialCode) { return BaseDal.GetOutboundStockList(materialCode); } #endregion 内部调用方法 #region private内部方法 /// /// 根据订单号获取订单 /// /// 订单号 /// 订单对象 private Dt_OutOrder GetOrder(string orderNumber) { // 获取订单信息 var content = _outOrderService.GetOutOrderByNumber(orderNumber); // 检查订单是否获取成功 if (!content.Status) { return null; } // 反序列化订单对象 return (Dt_OutOrder)content.Data; } /// /// 更新库存状态 /// /// 筛选后的库存列表 /// 更新后的库存列表 private List UpdateStocks(List filteredStocks) { var updatedStocks = new List(); foreach (var stock in filteredStocks) { // 更新库存状态 stock.LocationInfo.IsLocked = true; stock.LocationInfo.Status = 0; stock.State = 5; updatedStocks.Add(stock); } return updatedStocks; } /// /// 创建订单库存列表 /// /// 筛选后的库存列表 /// 订单对象 /// 订单库存列表 private List CreateOrderStock(List stock, Dt_OutOrder order) { var orderStocks = new List(); foreach (var item in stock) { orderStocks.Add(new Dt_OutOrderAndStock() { AllocatedQuantity = order.OrderDetailList.AllocatedQuantity, MaterialNo = item.MaterialNo, MaterialName = order.OrderDetailList.MaterialName, OrderNumber = order.OrderNumber, OutboundQuantity = order.OrderDetailList.OutboundQuantity, PalletCode = item.PalletCode, PalletQuantity = item.Dt_BillGroupStockDetailList.Sum(x => x.PalletQuantity), State = item.State, BatchNumber = order.OrderDetailList.BatchNumber, CompletedQuantity = order.OrderDetailList.CompletedQuantity, Creater = "System", CreateDate = DateTime.Now, GroupId = item.GroupId, LocationCode = item.LocationInfo.LocationCode, OutOrderId = order.Id, }); } return orderStocks; } #endregion private内部方法 #region PDA组盘 /// /// PDA组盘前校验 /// PDA组盘确认保存组盘信息 /// /// 组盘信息 /// public WebResponseContent PDAGroupPlateConfirm(Dt_BillGroupStock dt_BillGroupStock) { WebResponseContent content = new WebResponseContent(); try { string requeststr = JsonConvert.SerializeObject(dt_BillGroupStock); new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "PDA组盘-PDAGroupPlate", "请求", requeststr); //是否新增 bool isAdd = true; #region 组盘前校验 //查询入库确认和入库完成状态的库存是否存在,不允计组盘 List billGrouplist = BaseDal.QueryData(x => x.PalletCode == dt_BillGroupStock.PalletCode && (x.State == (int)StockStateEmun.入库确认 || x.State == (int)StockStateEmun.入库完成)); if (billGrouplist != null && billGrouplist.Count > 0) { return content.Error("当前托盘已存在组盘信息,库存状态为已确认入库或者入库完成!"); } //1,判断托盘号是否重复(一次组盘重复时不允计组盘,多次组盘重复时可以组盘) List billGroups = BaseDal.QueryData(x => x.PalletCode == dt_BillGroupStock.PalletCode && (x.State == (int)StockStateEmun.组盘暂存)); if (billGroups != null && billGroups.Count == 1) { if (dt_BillGroupStock.Dt_BillGroupStockDetailList.Count == 0) { return content.Error("组盘明细列表不能为空!"); } isAdd = false; Dt_BillGroupStock billGroupStock = billGroups[0]; //如果是多次组盘,托盘号重复可以继续组盘 if (dt_BillGroupStock.GroupType == (int)GroupTypeEmun.多次组盘) { if (Convert.ToBoolean(billGroupStock.IsFull))//如果已满盘,不能多次组盘 { new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "PDA组盘-PDAGroupPlate", "响应", "已满盘不能进行多次组盘!"); return content.Error("已满盘不能进行多次组盘!"); } } else { new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "PDA组盘-PDAGroupPlate", "响应", "当前托盘已组盘,不允计重复组盘!"); return content.Error("当前托盘号重复,不允计组盘!"); } } else if (billGroups != null && billGroups.Count > 1) { new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "PDA组盘-PDAGroupPlate", "响应", "当前托盘已存在组盘信息!"); return content.Error("当前托盘已存在组盘信息!"); } else { isAdd = true; } List billGroupStockDetails = new List(); billGroupStockDetails = dt_BillGroupStock.Dt_BillGroupStockDetailList; foreach (var item in billGroupStockDetails) { int count = _dt_MaterielInfoRepository.QueryData(x => x.MaterielCode == item.MaterialNo).Count();//在物料信息表中查询物料是否存在 if (count == 0)//物料不存在 { new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "PDA组盘-PDAGroupPlate", "响应", $"该物料信息不存在:{item.MaterialName}+{item.MaterialNo}"); return content.Error($"该物料信息不存在:{item.MaterialName}+{item.MaterialNo},请维护物料基本信息!"); } } var groupDetailsByOrderDetailId = billGroupStockDetails.GroupBy(x => x.OrderDetailId).ToList(); foreach (var item in groupDetailsByOrderDetailId) { //查询入库单明细预计入库数量 decimal PreInboundQuantity = _dt_InboundOrderDetailRepository.QueryData(x => x.OrderDetailId == item.Key).Sum(x => Convert.ToDecimal(x.PreInboundQuantity)); //根据入库单明细ID,获取已组盘数量 decimal PalletQuantity = Convert.ToDecimal(Db.Queryable().InnerJoin((s, sd) => s.GroupId == sd.GroupId && sd.GroupDetailId == item.Key && s.State != (int)StockStateEmun.组盘撤销).Select((s, sd) => sd).ToList().Sum(x => x.PalletQuantity)); decimal currentPalletQuantity = Convert.ToDecimal(billGroupStockDetails.Sum(x => x.PalletQuantity)); if (currentPalletQuantity > PreInboundQuantity - PalletQuantity)//如果当前组盘数量比未组盘数量多,需重新调整物料数量 { new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "PDA组盘-PDAGroupPlate", "响应", $"当前组盘物料数量大于单据明细物料数量,需重新调整物料数量!明细ID{item.Key}"); return content.Error($"当前组盘物料数量大于单据明细物料数量,需重新调整物料数量!明细ID{item.Key}"); } } #endregion 组盘前校验 #region 保存组盘信息 try { dt_BillGroupStock.State = (int)StockStateEmun.组盘暂存; //开启事物 _unitOfWorkManage.BeginTran(); //todo:加个判断是新增还是修改(已处理) if (isAdd)//一次组盘-需新增表头 { BaseDal.AddData(dt_BillGroupStock); } else //多次组盘-只需修改表头 { BaseDal.UpdateData(dt_BillGroupStock); } //查询组盘主表获取主表主键ID,用于更新明细 Dt_BillGroupStock billGroupStock = BaseDal.QueryFirst(x => x.PalletCode == dt_BillGroupStock.PalletCode); dt_BillGroupStock.Dt_BillGroupStockDetailList?.ForEach(x => x.GroupId = billGroupStock.GroupId); //添加组盘明细 _dt_BillGroupStockDetailRepository.AddData(dt_BillGroupStock.Dt_BillGroupStockDetailList); //提交事务 _unitOfWorkManage.CommitTran(); content.OK("组盘成功!", dt_BillGroupStock); } catch { _unitOfWorkManage.RollbackTran(); throw; } #endregion 保存组盘信息 } catch (Exception ex) { new LogLibrary.Log.LogFactory().GetLog("接口").ErrorFormat(true, "PDA组盘-PDAGroupPlate", "响应", $"托盘号:{dt_BillGroupStock.PalletCode}组盘异常:{ex.Message}"); content.Error($"托盘号:{dt_BillGroupStock.PalletCode} 组盘异常:{ex.Message}"); } return content; } /// /// PDA组盘撤销确认,解绑托盘码和物料码 /// 1,根据托盘码查询状态为“组盘暂存”组盘信息 2,修改库存状态为"组盘撤销", /// /// 托盘号 /// public WebResponseContent PDAGroupPlateRevoke(string plateCode) { WebResponseContent content = new WebResponseContent(); try { new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "PDA撤销组盘-PDAGroupPlateRevoke", "请求", plateCode); Dt_BillGroupStock_Hty billGroupStockHty = new Dt_BillGroupStock_Hty(); List billGroupStockDetailHtys = new List(); List details = new List(); //1,根据托盘码查询状态为“组盘暂存”组盘信息 List billGroupStockList = BaseDal.QueryData(x => x.PalletCode == plateCode && x.State == (int)StockStateEmun.组盘暂存); if (billGroupStockList != null && billGroupStockList.Count > 0) { Dt_BillGroupStock billGroupStock = billGroupStockList[0]; #region 组盘历史表 billGroupStockHty.PalletCode = plateCode; billGroupStockHty.OrderNo = billGroupStock.OrderNo; billGroupStockHty.OrderType = billGroupStock.OrderType; billGroupStockHty.MaterialNo = billGroupStock.MaterialNo; billGroupStockHty.BatchNo = billGroupStock.BatchNo; billGroupStockHty.GroupType = billGroupStock.OrderType; billGroupStockHty.GroupWay = billGroupStock.GroupWay; billGroupStockHty.IsFull = billGroupStock.IsFull; billGroupStockHty.LocationCode = billGroupStock.LocationCode; billGroupStockHty.State = (int)StockStateEmun.组盘撤销; //2,修改库存状态为"组盘撤销,并移到组盘历史记录表中 billGroupStockHty.Remark = billGroupStock.Remark; billGroupStockHty.Creater = billGroupStock.Creater; billGroupStockHty.CreateDate = billGroupStock.CreateDate; billGroupStockHty.StockDetailList = new List(); details = _dt_BillGroupStockDetailRepository.QueryData(x => x.GroupId == billGroupStock.GroupId); foreach (var item in details) { Dt_BillGroupStockDetail_Hty billGroupStockDetailHty = new Dt_BillGroupStockDetail_Hty(); billGroupStockDetailHty.GroupId = item.GroupId; billGroupStockDetailHty.PalletCode = item.PalletCode; billGroupStockDetailHty.OrderNo = item.OrderNo; billGroupStockDetailHty.OrderDate = item.OrderDate; billGroupStockDetailHty.OrderDetailId = item.OrderDetailId; billGroupStockDetailHty.BatchNo = item.BatchNo; billGroupStockDetailHty.MaterialNo = item.MaterialNo; billGroupStockDetailHty.MaterialName = item.MaterialName; billGroupStockDetailHty.OutBoxCode = item.OutBoxCode; billGroupStockDetailHty.InBoxCode = item.InBoxCode; billGroupStockDetailHty.EmptyPalletCode = item.EmptyPalletCode; billGroupStockDetailHty.PalletUnit = item.PalletUnit; billGroupStockDetailHty.PalletQuantity = item.PalletQuantity; billGroupStockDetailHty.BasicUnit = item.BasicUnit; billGroupStockDetailHty.BasicQuantity = item.BasicQuantity; billGroupStockDetailHty.Creater = item.Creater; billGroupStockDetailHty.CreateDate = item.CreateDate; billGroupStockDetailHtys.Add(billGroupStockDetailHty); } #endregion 组盘历史表 try { //开启事物 _unitOfWorkManage.BeginTran(); _dt_BillGroupStock_HtyRepository.AddData(billGroupStockHty); _dt_BillGroupStockDetail_HtyRepository.AddData(billGroupStockDetailHtys); BaseDal.DeleteData(billGroupStockList[0]); _dt_BillGroupStockDetailRepository.DeleteData(details); //提交事务 _unitOfWorkManage.CommitTran(); new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "PDA撤销组盘-PDAGroupPlateRevoke", "响应", $"撤销组盘成功"); content.OK("撤销组盘成功"); } catch (Exception) { _unitOfWorkManage.RollbackTran(); throw; } } else { new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "PDA撤销组盘-PDAGroupPlate", "响应", $"撤销组盘失败,未查询到可以撤销的组盘"); content.OK("撤销组盘失败,未查询到可以撤销的组盘"); } } catch (Exception ex) { new LogLibrary.Log.LogFactory().GetLog("接口").ErrorFormat(true, "PDA撤销组盘-PDAGroupPlate", "响应", $"托盘号:{plateCode}组盘异常:{ex.Message}"); content.Error($"托盘号:{plateCode} 撤销组盘异常:{ex.Message}"); } return content; } #endregion PDA组盘 }