namespace WIDESEA_StorageOutBasicServices; public class Dt_BillGroupStockService : ServiceBase, IDt_BillGroupStockService { private readonly IUnitOfWorkManage _unitOfWorkManage; private readonly IDt_OutOrderService _outOrderService; private readonly IDt_TaskService _taskService; private readonly IDt_OutOrderAndStockRepository _OutOrderAndStockRepository; private readonly IDt_OutOrderAndStock_HtyService _OutOrderAndStock_HtyService; private readonly IDt_Task_HtyService _Task_HtyService; private readonly IMapper _mapper; public Dt_BillGroupStockService(IDt_BillGroupStockRepository baseDal, IUnitOfWorkManage unitOfWorkManage, IDt_OutOrderService outOrderService, IDt_TaskService taskService, IDt_OutOrderAndStockRepository outOrderAndStockRepository, IMapper mapper, IDt_OutOrderAndStock_HtyService outOrderAndStock_HtyService, IDt_Task_HtyService task_HtyService) : base(baseDal) { _unitOfWorkManage = unitOfWorkManage; _outOrderService = outOrderService; _taskService = taskService; _OutOrderAndStockRepository = outOrderAndStockRepository; _mapper = mapper; _OutOrderAndStock_HtyService = outOrderAndStock_HtyService; _Task_HtyService = task_HtyService; } #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.StockDetailList) .FirstAsync(); } /// /// 获取所有可出库库存,不包括已经出库的或已经分配的。 /// /// 出库库存列表 public async Task GetOutboundStock() { WebResponseContent content = new WebResponseContent(); try { #region 前期没数据临时开发使用,后期更换根据订单进行筛选库存 // 获取所有可出库库存 var stocks = BaseDal.GetOutboundStockList(); // 获取订单 var order = GetOrder("2"); // 检查订单是否获取成功 if (order == null) { return content.Error("获取订单失败"); } // 获取订单中的第一个物料号 var materialNo = order.OrderDetailList.MaterialId; // 筛选并排序库存 var filteredStocks = stocks.Where(x => x.MaterialNo == materialNo.ToString()) .OrderBy(x => x.CreateDate) .ToList(); #endregion 前期没数据临时开发使用,后期更换根据订单进行筛选库存 // 创建任务列表 var (tasks, updateOrder) = CreateTasks(order, filteredStocks); // 更新库存状态 var stockList = UpdateStocks(filteredStocks, updateOrder); // 创建订单库存列表 var orderStocks = CreateOrderStock(filteredStocks, updateOrder, tasks); // 开始事务 _unitOfWorkManage.BeginTran(); // 更新库存 var isStockUpdated = BaseDal.UpdateNavStock(stockList); // 更新订单 var isOrderUpdated = await _outOrderService.OutOrderUpdated(updateOrder); //添加订单库存 var isOrderStockCread = _OutOrderAndStockRepository.AddData(orderStocks) > 0; // 创建任务 var isTaskCreated = await _taskService.Create(tasks); // 提交或回滚事务 if (isStockUpdated && isTaskCreated && isOrderUpdated && isOrderStockCread) { _unitOfWorkManage.CommitTran(); } else { _unitOfWorkManage.RollbackTran(); } return content.OK(data: stocks); } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); return content.Error(ex.Message); } } #endregion 外部接口 #region 内部调用方法 /// /// 更新库存集合 /// /// 库存集合 /// 成功/失败 public bool UpdateNavStock(List stocks) { return BaseDal.UpdateNavStock(stocks); } /// /// 更新单个库存 /// /// 库存 /// 成功/失败 public bool UpdateNavStock(Dt_BillGroupStock stocks) { return BaseDal.UpdateNavStock(stocks); } #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, Dt_OutOrder orderDetail) CreateTasks(Dt_OutOrder order, List filteredStocks) { var tasks = new List(); foreach (var stock in filteredStocks) { // 如果已分配数量达到出库数量,停止分配 if (order.OrderDetailList.AllocatedQuantity >= order.OrderDetailList.OutboundQuantity) break; // 如果托盘任务已存在,跳过 if (_taskService.IsExist(stock.PalletCode)) continue; // 创建任务 tasks.Add(new Dt_Task { CreateDate = DateTime.Now, // 创建时间 Creater = "System", // 创建人 CurrentAddress = stock.LocationCode, //当前位置 Dispatchertime = DateTime.Now, //调度时间(任务下发时间) Grade = 1, // 等级 InboundNo = stock.InboundNo, //单据编号 MaterialNo = stock.MaterialNo, // 物料号 NextAddress = stock.LocationCode, // 下一位置 PalletCode = stock.PalletCode, //托盘号 Remark = stock.Remark, //备注 Roadway = stock.Remark, //巷道 SourceAddress = stock.LocationCode, //来源位置 TargetAddress = order.OrderDetailList.Remarks, //目标地址 TaskNum = 1001, //任务号 TaskState = TaskStateConst.PendingDispatch.ToString(), //任务状态 TaskType = TaskTypeConst.WholeOutbound.ToString(), //任务类型 }); // 更新已分配数量 order.OrderDetailList.AllocatedQuantity++; } return (tasks, order); } /// /// 更新库存状态 /// /// 筛选后的库存列表 /// 订单对象 /// 更新后的库存列表 private List UpdateStocks(List filteredStocks, Dt_OutOrder order) { var updatedStocks = new List(); var orderDetail = order.OrderDetailList; int index = 0; foreach (var stock in filteredStocks) { // 如果已分配数量达到出库数量,停止分配 if (index >= orderDetail.OutboundQuantity) { break; } // 更新库存状态 stock.LocationInfo.IsLocked = true; stock.LocationInfo.Status = 0; stock.State = "3"; updatedStocks.Add(stock); } return updatedStocks; } /// /// 创建订单库存列表 /// /// 筛选后的库存列表 /// 订单对象 /// 任务列表 /// 订单库存列表 private List CreateOrderStock(List stock, Dt_OutOrder order, List task) { var orderStocks = new List(); for (int i = 0; i < task.Count; i++) { orderStocks.Add(new Dt_OutOrderAndStock() { AllocatedQuantity = order.OrderDetailList.AllocatedQuantity, MaterialNo = stock[i].MaterialNo, MaterialName = order.OrderDetailList.MaterialName, OrderNumber = order.OrderNumber, OutboundQuantity = order.OrderDetailList.OutboundQuantity, PalletCode = stock[i].PalletCode, PalletQuantity = stock[i].StockDetailList.PalletQuantity, State = stock[i].State, BatchNumber = order.OrderDetailList.BatchNumber, CompletedQuantity = order.OrderDetailList.CompletedQuantity, Creater = "System", CreateDate = DateTime.Now, GroupId = stock[i].GroupId, GroupDetailId = stock[i].StockDetailList.GroupDetailId, LocationCode = stock[i].LocationInfo.LocationID, OutOrderDetailId = order.OrderDetailList.Id, OutOrderId = order.Id, }); } return orderStocks; } #endregion private内部方法 }