using Microsoft.AspNetCore.Http; 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_DTO.Outbound; 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, string barcode = null,string outboundBatchNo = "") { // 获取库存明细信息 var stockDetails = outStock.Details .Where(x => x.MaterielCode == outboundOrderDetail.MaterielCode) .ToList(); if (!stockDetails.Any()) { throw new Exception($"未找到物料[{outboundOrderDetail.MaterielCode}]的库存明细"); } // 确定条码 string targetBarcode; var firstAvailableDetail=new Dt_StockInfoDetail(); if (!string.IsNullOrEmpty(barcode)) { // 验证指定的条码是否存在 firstAvailableDetail = stockDetails.FirstOrDefault(x => x.Barcode == barcode); if (firstAvailableDetail == null) { throw new Exception($"指定的条码[{barcode}]在库存中不存在"); } targetBarcode = barcode; } else { // 使用第一个可用条码 firstAvailableDetail = stockDetails .Where(x => x.StockQuantity > x.OutboundQuantity) .OrderBy(x => x.CreateDate) .FirstOrDefault(); if (firstAvailableDetail == null) { throw new Exception($"物料[{outboundOrderDetail.MaterielCode}]没有可用库存"); } targetBarcode = firstAvailableDetail.Barcode; } return new Dt_OutStockLockInfo() { PalletCode = outStock.PalletCode, AssignQuantity = assignQuantity, 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 = (int)OutLockStockStatusEnum.已分配, StockId = outStock.Id, OrderType=outboundOrder.OrderType, SupplyCode = firstAvailableDetail.SupplyCode, WarehouseCode = firstAvailableDetail.WarehouseCode, // 新增字段 CurrentBarcode = targetBarcode, OriginalLockQuantity = assignQuantity, IsSplitted = 0, MaterielCode = outboundOrderDetail.MaterielCode, BatchNo = firstAvailableDetail.BatchNo, Unit = firstAvailableDetail.Unit, BarcodeQty = firstAvailableDetail.BarcodeQty, BarcodeUnit = firstAvailableDetail.BarcodeUnit, FactoryArea = firstAvailableDetail.FactoryArea, lineNo = outboundOrderDetail.lineNo, OutboundBatchNo= outboundBatchNo }; } public List GetOutStockLockInfos(Dt_OutboundOrder outboundOrder, Dt_OutboundOrderDetail outboundOrderDetail, List outStocks, int? taskNum = null) { List outStockLockInfos = new List(); foreach (var item in outStocks) { Dt_OutStockLockInfo outStockLockInfo = new Dt_OutStockLockInfo() { PalletCode = item.PalletCode, AssignQuantity = item.Details.Where(x => x.MaterielCode == outboundOrderDetail.MaterielCode).Sum(x => x.OutboundQuantity), MaterielCode = outboundOrderDetail.MaterielCode, BatchNo = outboundOrderDetail.BatchNo, LocationCode = item.LocationCode, MaterielName = outboundOrderDetail.MaterielName, OrderDetailId = outboundOrderDetail.Id, OrderNo = outboundOrder.OrderNo, OrderType = outboundOrder.OrderType, OriginalQuantity = item.Details.Where(x => x.MaterielCode == outboundOrderDetail.MaterielCode).Sum(x => x.StockQuantity), Status = taskNum == null ? OutLockStockStatusEnum.已分配.ObjToInt() : OutLockStockStatusEnum.出库中.ObjToInt(), StockId = item.Id, TaskNum = taskNum, }; outStockLockInfos.Add(outStockLockInfo); } return outStockLockInfos; } /// /// 根据订单明细ID获取出库锁定信息 /// public async Task> GetByOrderDetailId(int orderDetailId) { return await Db.Queryable() .Where(x => x.OrderDetailId == orderDetailId) .OrderBy(x => x.Id) .ToListAsync(); } public async Task GetLockInfoDetail(int lockInfoId) { var lockInfo = await Db.Queryable() .LeftJoin((lockInfo, detail) => lockInfo.OrderDetailId == detail.Id) .Where((lockInfo, detail) => lockInfo.Id == lockInfoId) .Select((lockInfo, detail) => new LockInfoDetailDto { Id = lockInfo.Id, OrderNo = lockInfo.OrderNo, OrderDetailId = lockInfo.OrderDetailId, BatchNo = lockInfo.BatchNo, MaterielCode = lockInfo.MaterielCode, StockId = lockInfo.StockId, OrderQuantity = lockInfo.OrderQuantity, OriginalQuantity = lockInfo.OriginalQuantity, AssignQuantity = lockInfo.AssignQuantity, PickedQty = lockInfo.PickedQty, LocationCode = lockInfo.LocationCode, PalletCode = lockInfo.PalletCode, Status = lockInfo.Status, IsSplitted = lockInfo.IsSplitted, ParentLockId = lockInfo.ParentLockId, MaterielName = detail.MaterielName, Unit = detail.Unit }) .FirstAsync(); return lockInfo; } /// /// 根据托盘编号获取出库锁定信息 /// 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}"); } } public List GetByOrderDetailId(int orderDetailId, OutLockStockStatusEnum? outStockStatus) { return BaseDal.QueryData(x => x.OrderDetailId == orderDetailId ); } } }