zs
2025-05-09 14f9c8378bde7d9a8d8f1fcc393e0e8d49eced82
HIAWms/server/src/CMS.Plugin.HIAWms.Application/Implements/WmsCommonAppService.cs
@@ -1,4 +1,6 @@
using CMS.Plugin.HIAWms.Application.Contracts.Dtos.CommonDto;
using CMS.Plugin.HIAWms.Application.Contracts.Dtos.WmsPlaces;
using CMS.Plugin.HIAWms.Application.Contracts.Services;
using CMS.Plugin.HIAWms.Domain.WmsMaterials;
using CMS.Plugin.HIAWms.Domain.WmsMaterialStocks;
using CMS.Plugin.HIAWms.Domain.WmsPlaces;
@@ -14,7 +16,7 @@
    /// <summary>
    /// 公共操作服务
    /// </summary>
    public class WmsCommonAppService : CMSPluginAppService
    public class WmsCommonAppService : CMSPluginAppService,IWmsCommonAppService
    {
        private readonly IWmsMaterialRepository _wmsMaterialRepository;
        private readonly IWmsPlaceRepository _wmsPlaceRepository;
@@ -30,17 +32,6 @@
            _wmsMaterialStockRepository = wmsMaterialStockRepository;
        }
        public async Task<List<MaterialModelOutput>> GetMaterialModeListAsync()
        {
            var materialList = await _wmsMaterialRepository.GetMaterialListAsync(new WmsMaterial());
            if (materialList == null || materialList.Count <= 0) return new List<MaterialModelOutput>(); ;
            return materialList.Select(material => new MaterialModelOutput
            {
                MaterialModel = material.MaterialModel,
                MaterialModelDesc = material.MaterialModel
            }).ToList();
        }
        /// <summary>
        /// 查找空库位
@@ -50,11 +41,12 @@
        /// <param name="requiredNum"></param>
        /// <returns></returns>
        /// <exception cref="UserFriendlyException"></exception>
        public async Task<Dictionary<WmsPlace, int>> FindAvailablePlacesAsync(string materialModel, string materialNo, int requiredNum)
        public async Task<Dictionary<WmsPlaceDto, int>> FindAvailablePlacesAsync(string materialModel,int requiredNum, string materialNo="" )
        {
            // 1. 获取所有库存和库位信息
            var stockList = await _wmsMaterialStockRepository.GetListAsync(new WmsMaterialStock());
            var allPlaceList = await _wmsPlaceRepository.GetListAsync(new WmsPlace());
            var allPlaceList = ObjectMapper.Map<List<WmsPlace>, List<WmsPlaceDto>>(await _wmsPlaceRepository.GetListAsync(new WmsPlace()));
            // 2. 查找相同物料型号和编号的库存(按库存量降序)
            var sameModelStocks = stockList
@@ -63,7 +55,7 @@
                .OrderByDescending(x => x.StockNumber)
                .ToList();
            var availablePlaces = new Dictionary<WmsPlace, int>();
            var availablePlaces = new Dictionary<WmsPlaceDto, int>();
            int remainingNum = requiredNum;
            // 3. 优先检查已有库存的库位是否能存放(相同 MaterialNo)
@@ -108,5 +100,50 @@
            return availablePlaces;
        }
        /// <summary>
        /// 查找库存
        /// </summary>
        /// <param name="materialModel"></param>
        /// <param name="requiredNum"></param>
        /// <param name="materialNo"></param>
        /// <returns></returns>
        public async Task<Dictionary<string, int>> FindStockAsync(string materialModel, int requiredNum, string materialNo = "")
        {
            // 1. 获取所有库存(排除锁定库存)
            var stockList = (await _wmsMaterialStockRepository.GetListAsync(new WmsMaterialStock()))
                .Where(x => x.IsLock == Domain.Shared.Enums.YesNoEnum.N)
                .ToList();
            // 2. 筛选匹配物料
            var availableStocks = stockList
                .Where(x => x.MaterialModel == materialModel)
                .WhereIf(!string.IsNullOrEmpty(materialNo), x => x.MaterialNo == materialNo)
                .OrderBy(x => x.StockNumber) // 优先从库存少的库位出
                .ToList();
            // 3. 检查总库存是否足够
            int totalAvailable = availableStocks.Sum(x => x.StockNumber);
            if (totalAvailable < requiredNum)
            {
                throw new UserFriendlyException(
                    $"库存不足!需求: {requiredNum}, 可用: {totalAvailable}, 缺: {requiredNum - totalAvailable}");
            }
            // 4. 计算各库位出库数量
            var allocation = new Dictionary<string, int>(); // <库位号, 出库数>
            int remaining = requiredNum;
            foreach (var stock in availableStocks)
            {
                if (remaining <= 0) break;
                int deductAmount = Math.Min(stock.StockNumber, remaining);
                allocation.Add(stock.PlaceNo, deductAmount);
                remaining -= deductAmount;
            }
            return allocation;
        }
    }
}