1
647556386
2025-11-30 8639f19c82f6e263654db44286256bb8d028d2c2
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_OutboundService/OutStockLockInfoService.cs
@@ -1,17 +1,21 @@
using System;
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
{
@@ -20,9 +24,238 @@
        public IRepository<Dt_OutStockLockInfo> Repository => BaseDal;
        public IUnitOfWorkManage _unitOfWorkManage;
        public OutStockLockInfoService(IRepository<Dt_OutStockLockInfo> BaseDal, IUnitOfWorkManage unitOfWorkManage) : base(BaseDal)
        private readonly IStockService _stockService;
        private readonly IRecordService _recordService;
        public OutStockLockInfoService(IRepository<Dt_OutStockLockInfo> BaseDal, IUnitOfWorkManage unitOfWorkManage, IStockService stockService, IRecordService recordService) : base(BaseDal)
        {
            _unitOfWorkManage = unitOfWorkManage;
            _stockService = stockService;
            _recordService = recordService;
        }
        /// <summary>
        /// åˆ›å»ºå‡ºåº“锁定
        /// </summary>
        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<Dt_OutStockLockInfo> GetOutStockLockInfos(Dt_OutboundOrder outboundOrder, Dt_OutboundOrderDetail outboundOrderDetail, List<Dt_StockInfo> outStocks, int? taskNum = null)
        {
            List<Dt_OutStockLockInfo> outStockLockInfos = new List<Dt_OutStockLockInfo>();
            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;
        }
        /// <summary>
        /// æ ¹æ®è®¢å•明细ID获取出库锁定信息
        /// </summary>
        public async Task<List<Dt_OutStockLockInfo>> GetByOrderDetailId(int orderDetailId)
        {
            return await Db.Queryable<Dt_OutStockLockInfo>()
                .Where(x => x.OrderDetailId == orderDetailId)
                .OrderBy(x => x.Id)
                .ToListAsync();
        }
        public async Task<LockInfoDetailDto> GetLockInfoDetail(int lockInfoId)
        {
            var lockInfo = await Db.Queryable<Dt_OutStockLockInfo>()
                .LeftJoin<Dt_OutboundOrderDetail>((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;
        }
        /// <summary>
        /// æ ¹æ®æ‰˜ç›˜ç¼–号获取出库锁定信息
        /// </summary>
        public async Task<List<Dt_OutStockLockInfo>> GetByPalletCode(string palletCode, int? status = null)
        {
            var query = Db.Queryable<Dt_OutStockLockInfo>()
                .Where(x => x.PalletCode == palletCode);
            if (status.HasValue)
            {
                query = query.Where(x => x.Status == status.Value);
            }
            return await query.OrderBy(x => x.Id).ToListAsync();
        }
        /// <summary>
        /// èŽ·å–æ‰˜ç›˜çš„é”å®šä¿¡æ¯
        /// </summary>
        public async Task<List<Dt_OutStockLockInfo>> GetPalletLockInfos(string palletCode)
        {
            return await Db.Queryable<Dt_OutStockLockInfo>()
                .Where(x => x.PalletCode == palletCode && x.Status == (int)OutLockStockStatusEnum.出库中)
                .ToListAsync();
        }
        /// <summary>
        /// æ›´æ–°å‡ºåº“锁定信息的条码(用于拆包操作)
        /// </summary>
        public async Task<WebResponseContent> UpdateLockInfoBarcode(int lockInfoId, string newBarcode)
        {
            try
            {
                var lockInfo = await Db.Queryable<Dt_OutStockLockInfo>()
                    .Where(x => x.Id == lockInfoId)
                    .FirstAsync();
                if (lockInfo == null)
                    return WebResponseContent.Instance.Error("未找到出库锁定信息");
                // éªŒè¯æ–°æ¡ç æ˜¯å¦å­˜åœ¨
                var stockDetail = await Db.Queryable<Dt_StockInfoDetail>()
                    .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<Dt_OutStockLockInfo> GetByOrderDetailId(int orderDetailId, OutLockStockStatusEnum? outStockStatus)
        {
            return BaseDal.QueryData(x => x.OrderDetailId == orderDetailId );
        }
    }