pan
2025-11-06 42429ae61571ff9563c9e987cd52be2132e77775
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs
@@ -2,6 +2,7 @@
using WIDESEA_Common.StockEnum;
using WIDESEA_Core.BaseRepository;
using WIDESEA_Core.BaseServices;
using WIDESEA_IBasicService;
using WIDESEA_IRecordService;
using WIDESEA_IStockService;
using WIDESEA_Model.Models;
@@ -15,11 +16,14 @@
        private readonly IRecordService _recordService;
        public IRepository<Dt_StockInfo> Repository => BaseDal;
        private readonly IRepository<Dt_StockInfoDetail> _stockInfoDetailRepository;
        public StockInfoService(IRepository<Dt_StockInfo> BaseDal, IMapper mapper, IRepository<Dt_StockInfoDetail> stockInfoDetailRepository, IRecordService recordService) : base(BaseDal)
        private readonly ILocationInfoService _locationInfoService;
        public StockInfoService(IRepository<Dt_StockInfo> BaseDal, IMapper mapper, IRepository<Dt_StockInfoDetail> stockInfoDetailRepository, IRecordService recordService, ILocationInfoService locationInfoService) : base(BaseDal)
        {
            _mapper = mapper;
            _stockInfoDetailRepository = stockInfoDetailRepository;
            _recordService = recordService;
            _locationInfoService = locationInfoService;
        }
        /// <summary>
@@ -72,5 +76,102 @@
            _recordService.StockQuantityChangeRecordService.AddStockChangeRecord(stockInfo, stockInfo.Details, beforeQuantity, stockInfo.Details.Sum(x => x.StockQuantity) + beforeQuantity, WIDESEA_Common.StockEnum.StockChangeType.MaterielGroup);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="stockInfos"></param>
        /// <param name="materielCode"></param>
        /// <param name="needQuantity"></param>
        /// <param name="residueQuantity"></param>
        /// <returns></returns>
        public List<Dt_StockInfo> GetOutboundStocks(List<Dt_StockInfo> stockInfos, string materielCode, decimal needQuantity, out decimal residueQuantity)
        {
            List<Dt_StockInfo> outStocks = new List<Dt_StockInfo>();
            var stockTotalQuantity = stockInfos.Select(x => x.Details.Sum(v => v.StockQuantity - v.OutboundQuantity)).Sum(x => x);
            //stockInfos = stockInfos.OrderBy(x => x.Id).ToList();
            if (stockTotalQuantity >= needQuantity)//库存够
            {
                int index = 0;
                while (needQuantity > 0)
                {
                    Dt_StockInfo stockInfo = stockInfos[index];
                    // è®¡ç®—可用库存时转换为decimal
                    decimal useableStockQuantity = stockInfo.Details
                        .Where(x => x.MaterielCode == materielCode)
                        .Sum(x => (decimal)x.StockQuantity - (decimal)x.OutboundQuantity);
                    // å°†needQuantity转换为decimal进行比较
                    if (useableStockQuantity < (decimal)needQuantity && useableStockQuantity > 0)
                    {
                        stockInfo.Details.ForEach(x =>
                            x.OutboundQuantity = x.StockQuantity);
                        // ä½¿ç”¨decimal进行计算后再转回float
                        needQuantity =   needQuantity - useableStockQuantity;
                    }
                    else
                    {
                        stockInfo.Details.ForEach(x =>
                        {
                            if (x.StockQuantity > x.OutboundQuantity && x.MaterielCode == materielCode)
                            {
                                // å°†ç›¸å…³å€¼è½¬æ¢ä¸ºdecimal进行精确计算
                                decimal currentStock = (decimal)x.StockQuantity;
                                decimal currentOutbound = (decimal)x.OutboundQuantity;
                                decimal currentNeed = (decimal)needQuantity;
                                decimal available = currentStock - currentOutbound;
                                if (available >= currentNeed)
                                {
                                    x.OutboundQuantity = currentOutbound + currentNeed;
                                    needQuantity = 0;
                                }
                                else
                                {
                                    needQuantity =currentNeed - available;
                                    x.OutboundQuantity = x.StockQuantity;
                                }
                            }
                        });
                    }
                    outStocks.Add(stockInfo);
                    index++;
                }
            }
            else
            {
                throw new Exception("库存不足");
            }
            residueQuantity = needQuantity;
            return outStocks;
        }
        public List<Dt_StockInfo> GetStockInfos(string materielCode, string lotNo, List<string> locationCodes)
        {
            List<Dt_StockInfo> stockInfos = null;
            if (!string.IsNullOrEmpty(lotNo))
            {
                var stockSort = Db.Queryable<Dt_StockInfo>().Where(x => locationCodes.Contains(x.LocationCode)).Includes(x => x.Details).Where(x => x.Details.Any(v => v.MaterielCode == materielCode && v.BatchNo == lotNo)).ToList();
                stockInfos = stockSort.OrderBy(x => x.Details.FirstOrDefault()?.EffectiveDate).ThenBy(x => x.Details.Sum(v => v.StockQuantity)).ToList();
            }
            else
            {
                var stockSort = Db.Queryable<Dt_StockInfo>().Where(x => locationCodes.Contains(x.LocationCode)).Includes(x => x.Details).Where(x => x.Details.Any(v => v.MaterielCode == materielCode)).ToList();
                stockInfos = stockSort.OrderBy(x => x.Details.FirstOrDefault()?.EffectiveDate).ThenBy(x => x.Details.Sum(v => v.StockQuantity)).ToList();
            }
            return stockInfos;
            //ISugarQueryable<Dt_LocationInfo> sugarQueryable = Db.Queryable<Dt_LocationInfo>().Where(x => locationCodes.Contains(x.LocationCode));
            //ISugarQueryable<Dt_StockInfo> sugarQueryable1 = Db.Queryable<Dt_StockInfo>().Includes(x => x.Details).Where(x => x.Details.Any(v => v.MaterielCode == materielCode));
            //return sugarQueryable.InnerJoin(sugarQueryable1, (a, b) => a.LocationCode == b.LocationCode).Select((a, b) => b).OrderBy(a => a.CreateDate).Includes(a => a.Details).ToList();
        }
        public List<Dt_StockInfo> GetUseableStocks(string materielCode, string batchNo)
        {
            List<string> locationCodes = _locationInfoService.GetCanOutLocationCodes();
            return GetStockInfos(materielCode, batchNo, locationCodes);
        }
    }
}