using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using WIDESEA_Common.StockEnum; using WIDESEA_Common.WareHouseEnum; using WIDESEA_Core; using WIDESEA_Core.BaseRepository; using WIDESEA_Core.BaseServices; using WIDESEA_Core.Enums; using WIDESEA_Core.Helper; using WIDESEA_IRecordService; using WIDESEA_IStockService; using WIDESEA_Model.Models; using WIDESEA_Model.Models.Basic; namespace WIDESEA_IOutboundService { public partial class OutStockLockInfoService : ServiceBase>, IOutStockLockInfoService { public IRepository Repository => BaseDal; public IUnitOfWorkManage _unitOfWorkManage; private readonly IStockService _stockService; private readonly IRecordService _recordService; public OutStockLockInfoService(IRepository BaseDal, IUnitOfWorkManage unitOfWorkManage, IStockService stockService, IRecordService recordService) : base(BaseDal) { _unitOfWorkManage = unitOfWorkManage; _stockService = stockService; _recordService = recordService; } public Dt_OutStockLockInfo GetOutStockLockInfo(Dt_OutboundOrder outboundOrder, Dt_OutboundOrderDetail outboundOrderDetail, Dt_StockInfo outStock, decimal assignQuantity, int? taskNum = null) { Dt_OutStockLockInfo outStockLockInfo = new Dt_OutStockLockInfo() { PalletCode = outStock.PalletCode, AssignQuantity = assignQuantity, MaterielCode = outboundOrderDetail.MaterielCode, BatchNo = outboundOrderDetail.BatchNo ?? outStock.Details.FirstOrDefault()?.BatchNo, LocationCode = outStock.LocationCode, MaterielName = outboundOrderDetail.MaterielName, OrderDetailId = outboundOrderDetail.Id, OrderNo = outboundOrder.OrderNo, OrderType = outboundOrder.OrderType, OriginalQuantity = outStock.Details.Where(x => x.MaterielCode == outboundOrderDetail.MaterielCode).Sum(x => x.StockQuantity), Status = taskNum == null ? OutLockStockStatusEnum.已分配.ObjToInt() : OutLockStockStatusEnum.出库中.ObjToInt(), StockId = outStock.Id, TaskNum = taskNum, OrderQuantity = outboundOrderDetail.OrderQuantity, Unit = outboundOrderDetail.Unit, //ProductionDate = outStock.Details.Where(x => x.MaterielCode == outboundOrderDetail.MaterielCode).FirstOrDefault()?.ProductionDate, //EffectiveDate = outStock.Details.Where(x => x.MaterielCode == outboundOrderDetail.MaterielCode).FirstOrDefault()?.EffectiveDate }; return outStockLockInfo; } /// /// 创建出库锁定信息 /// public Dt_OutStockLockInfo GetOutStockLockInfo(Dt_OutboundOrder outboundOrder, Dt_OutboundOrderDetail outboundOrderDetail, Dt_StockInfo outStock, decimal assignQuantity, string barcode = null, int? taskNum = null) { // 获取库存明细中的条码信息(如果未指定条码,使用第一个可用条码) var stockDetails = outStock.Details.Where(x => x.MaterielCode == outboundOrderDetail.MaterielCode && x.StockQuantity > x.OutboundQuantity) .OrderBy(x => x.ProductionDate).ToList(); if (!stockDetails.Any()) { throw new Exception($"未找到物料[{outboundOrderDetail.MaterielCode}]的可用库存明细"); } // 确定条码(如果未指定,使用最早入库的条码) var targetBarcode = barcode; if (string.IsNullOrEmpty(targetBarcode)) { targetBarcode = stockDetails.First().Barcode; } // 获取该条码的可用数量 var barcodeDetail = stockDetails.FirstOrDefault(x => x.Barcode == targetBarcode); if (barcodeDetail == null) { throw new Exception($"条码[{targetBarcode}]在库存中不存在"); } return new Dt_OutStockLockInfo() { PalletCode = outStock.PalletCode, AssignQuantity = assignQuantity, MaterielCode = outboundOrderDetail.MaterielCode, BatchNo = outboundOrderDetail.BatchNo ?? outStock.Details.FirstOrDefault()?.BatchNo, LocationCode = outStock.LocationCode, MaterielName = outboundOrderDetail.MaterielName, OrderDetailId = outboundOrderDetail.Id, OrderNo = outboundOrder.OrderNo, OrderQuantity = outboundOrderDetail.OrderQuantity, OriginalQuantity = outStock.Details .Where(x => x.MaterielCode == outboundOrderDetail.MaterielCode) .Sum(x => x.StockQuantity), Status = taskNum == null ? (int)OutLockStockStatusEnum.已分配 : (int)OutLockStockStatusEnum.出库中, StockId = outStock.Id, TaskNum = taskNum, Unit = outboundOrderDetail.Unit, // 新增字段赋值 CurrentBarcode = targetBarcode, // 当前分配的条码 OriginalLockQuantity = assignQuantity, // 原始锁定数量 IsSplitted = 0 // 初始未拆包 }; } /// /// 根据订单明细ID获取出库锁定信息 /// public async Task> GetByOrderDetailId(int orderDetailId) { return await Db.Queryable() .Where(x => x.OrderDetailId == orderDetailId) .OrderBy(x => x.Id) .ToListAsync(); } /// /// 根据托盘编号获取出库锁定信息 /// public async Task> GetByPalletCode(string palletCode, int? status = null) { var query = Db.Queryable() .Where(x => x.PalletCode == palletCode); if (status.HasValue) { query = query.Where(x => x.Status == status.Value); } return await query.OrderBy(x => x.Id).ToListAsync(); } /// /// 获取托盘的锁定信息 /// public async Task> GetPalletLockInfos(string palletCode) { return await Db.Queryable() .Where(x => x.PalletCode == palletCode && x.Status == (int)OutLockStockStatusEnum.出库中) .ToListAsync(); } /// /// 更新出库锁定信息的条码(用于拆包操作) /// public async Task UpdateLockInfoBarcode(int lockInfoId, string newBarcode) { try { var lockInfo = await Db.Queryable() .Where(x => x.Id == lockInfoId) .FirstAsync(); if (lockInfo == null) return WebResponseContent.Instance.Error("未找到出库锁定信息"); // 验证新条码是否存在 var stockDetail = await Db.Queryable() .Where(x => x.Barcode == newBarcode && x.StockId == lockInfo.StockId && x.MaterielCode == lockInfo.MaterielCode) .FirstAsync(); if (stockDetail == null) return WebResponseContent.Instance.Error("新条码在库存中不存在"); // 更新条码和拆包状态 lockInfo.CurrentBarcode = newBarcode; lockInfo.IsSplitted = 1; await Db.Updateable(lockInfo).ExecuteCommandAsync(); return WebResponseContent.Instance.OK("更新条码成功"); } catch (Exception ex) { return WebResponseContent.Instance.Error($"更新条码失败: {ex.Message}"); } } } }