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
{
///
/// 公共操作服务
///
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> GetMaterialModeListAsync()
{
var materialList = await _wmsMaterialRepository.GetMaterialListAsync(new WmsMaterial());
if (materialList == null || materialList.Count <= 0) return new List(); ;
return materialList.Select(material => new MaterialModelOutput
{
MaterialModel = material.MaterialModel,
MaterialModelDesc = material.MaterialModel
}).ToList();
}
///
/// 查找空库位
///
///
///
///
///
///
public async Task> 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();
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;
}
}
}