using CMS.Plugin.HIAWms.Application.Contracts.Dtos.CommonDto;
|
using CMS.Plugin.HIAWms.Domain.WmsMaterials;
|
using CMS.Plugin.HIAWms.Domain.WmsMaterialStocks;
|
using CMS.Plugin.HIAWms.Domain.WmsPlaces;
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Text;
|
using System.Threading.Tasks;
|
using Volo.Abp;
|
|
namespace CMS.Plugin.HIAWms.Application.Implements
|
{
|
/// <summary>
|
/// 公共操作服务
|
/// </summary>
|
public class WmsCommonAppService : CMSPluginAppService
|
{
|
private readonly IWmsMaterialRepository _wmsMaterialRepository;
|
private readonly IWmsPlaceRepository _wmsPlaceRepository;
|
private readonly IWmsMaterialStockRepository _wmsMaterialStockRepository;
|
|
public WmsCommonAppService(IWmsMaterialRepository wmsMaterialRepository,
|
IWmsPlaceRepository wmsPlaceRepository,
|
IWmsMaterialStockRepository wmsMaterialStockRepository
|
)
|
{
|
_wmsMaterialRepository = wmsMaterialRepository;
|
_wmsPlaceRepository = wmsPlaceRepository;
|
_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>
|
/// 查找空库位
|
/// </summary>
|
/// <param name="materialModel"></param>
|
/// <param name="materialNo"></param>
|
/// <param name="requiredNum"></param>
|
/// <returns></returns>
|
/// <exception cref="UserFriendlyException"></exception>
|
public async Task<Dictionary<WmsPlace, int>> FindAvailablePlacesAsync(string materialModel, string materialNo, int requiredNum)
|
{
|
// 1. 获取所有库存和库位信息
|
var stockList = await _wmsMaterialStockRepository.GetListAsync(new WmsMaterialStock());
|
var allPlaceList = await _wmsPlaceRepository.GetListAsync(new WmsPlace());
|
|
// 2. 查找相同物料型号和编号的库存(按库存量降序)
|
var sameModelStocks = stockList
|
.Where(x => x.MaterialModel == materialModel)
|
.WhereIf(!string.IsNullOrEmpty(materialNo), x => x.MaterialNo == materialNo)
|
.OrderByDescending(x => x.StockNumber)
|
.ToList();
|
|
var availablePlaces = new Dictionary<WmsPlace, int>();
|
int remainingNum = requiredNum;
|
|
// 3. 优先检查已有库存的库位是否能存放(相同 MaterialNo)
|
foreach (var stock in sameModelStocks)
|
{
|
if (remainingNum <= 0) break; // 数量已分配完
|
|
var placeInfo = allPlaceList.FirstOrDefault(x => x.PlaceNo == stock.PlaceNo);
|
if (placeInfo == null) continue;
|
|
int availableSpace = placeInfo.MaxStockNumber - stock.StockNumber;
|
if (availableSpace <= 0) continue;
|
|
int allocatedNum = Math.Min(availableSpace, remainingNum);
|
availablePlaces.Add(placeInfo, allocatedNum);
|
remainingNum -= allocatedNum;
|
}
|
|
// 4. 如果仍有剩余,查找空库位
|
if (remainingNum > 0)
|
{
|
var usedPlaceNos = stockList.Select(x => x.PlaceNo).Distinct().ToList();
|
var emptyPlaces = allPlaceList
|
.Where(x => !usedPlaceNos.Contains(x.PlaceNo))
|
.ToList();
|
|
foreach (var place in emptyPlaces)
|
{
|
if (remainingNum <= 0) break;
|
|
int allocatedNum = Math.Min(place.MaxStockNumber, remainingNum);
|
availablePlaces.Add(place, allocatedNum);
|
remainingNum -= allocatedNum;
|
}
|
}
|
|
// 5. 如果仍有剩余,说明库位不足
|
if (remainingNum > 0)
|
{
|
throw new UserFriendlyException($"库位不足,还差 {remainingNum} 个无法存放!");
|
}
|
|
return availablePlaces;
|
}
|
}
|
}
|