| | |
| | | using CMS.Plugin.HIAWms.Application.Contracts.Dtos.CommonDto; |
| | | using CMS.Plugin.HIAWms.Application.Contracts.Dtos.WmsMaterialStocks; |
| | | using CMS.Plugin.HIAWms.Application.Contracts.Dtos.WmsPlaces; |
| | | using CMS.Plugin.HIAWms.Application.Contracts.Dtos.WmsPlace; |
| | | using CMS.Plugin.HIAWms.Application.Contracts.Services; |
| | | using CMS.Plugin.HIAWms.Domain.Shared.Enums; |
| | | using CMS.Plugin.HIAWms.Domain.WmsInOutStockRecord; |
| | | using CMS.Plugin.HIAWms.Domain.WmsMaterials; |
| | | using CMS.Plugin.HIAWms.Domain.WmsMaterialStocks; |
| | | using CMS.Plugin.HIAWms.Domain.WmsPlaces; |
| | | using CmsQueryExtensions.Extension; |
| | | using Microsoft.Extensions.DependencyInjection; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using Volo.Abp; |
| | | using Volo.Abp.Uow; |
| | | |
| | | namespace CMS.Plugin.HIAWms.Application.Implements |
| | | { |
| | | /// <summary> |
| | | /// 公共操作服务 |
| | | /// </summary> |
| | | public class WmsCommonAppService : CMSPluginAppService,IWmsCommonAppService |
| | | public class WmsCommonAppService : CMSPluginAppService, IWmsCommonAppService |
| | | { |
| | | private readonly IWmsMaterialRepository _wmsMaterialRepository; |
| | | private readonly IWmsPlaceRepository _wmsPlaceRepository; |
| | | private readonly IWmsMaterialStockRepository _wmsMaterialStockRepository; |
| | | private readonly IWmsInOutStockRecordRepository _wmsInOutStockRecordRepository; |
| | | private readonly IServiceProvider _serviceProvider; |
| | | |
| | | public WmsCommonAppService(IWmsMaterialRepository wmsMaterialRepository, |
| | | IWmsPlaceRepository wmsPlaceRepository, |
| | | IWmsMaterialStockRepository wmsMaterialStockRepository |
| | | ) |
| | | , |
| | | IServiceProvider serviceProvider, |
| | | IWmsInOutStockRecordRepository wmsInOutStockRecordRepository) |
| | | { |
| | | _wmsMaterialRepository = wmsMaterialRepository; |
| | | _wmsPlaceRepository = wmsPlaceRepository; |
| | | _wmsMaterialStockRepository = wmsMaterialStockRepository; |
| | | _serviceProvider = serviceProvider; |
| | | _wmsInOutStockRecordRepository = wmsInOutStockRecordRepository; |
| | | } |
| | | |
| | | |
| | |
| | | /// <param name="requiredNum"></param> |
| | | /// <returns></returns> |
| | | /// <exception cref="UserFriendlyException"></exception> |
| | | public async Task<Dictionary<WmsPlaceDto, int>> FindAvailablePlacesAsync(string materialModel,int requiredNum, string materialNo="" ) |
| | | public async Task<Dictionary<WmsPlaceDto, int>> FindAvailablePlacesAsync(string materialModel, int requiredNum, string materialNo = "") |
| | | { |
| | | |
| | | var whereConditions = DynamicGetQueryParams(new GetWmsMaterialStockInput { StorageTypeNo = Domain.Shared.Enums.PlaceTypeEnum.YUANLIAOKUWEI }); |
| | | // 1. 获取所有库存和库位信息 |
| | | var stockList = await _wmsMaterialStockRepository.GetListAsync(whereConditions); |
| | | |
| | | var placeList = await _wmsPlaceRepository.GetListAsync(new WmsPlace { StorageTypeNo = Domain.Shared.Enums.PlaceTypeEnum.YUANLIAOKUWEI}); |
| | | var allPlaceList = ObjectMapper.Map<List<WmsPlace>, List<WmsPlaceDto>>(placeList); |
| | | var placeList = await _wmsPlaceRepository.GetListAsync(new WmsPlace { StorageTypeNo = Domain.Shared.Enums.PlaceTypeEnum.YUANLIAOKUWEI }); |
| | | var allPlaceList = ObjectMapper.Map<List<WmsPlace>, List<WmsPlaceDto>>(placeList.Where(x => !x.IsDisabled).ToList()); |
| | | |
| | | // 2. 查找相同物料型号和编号的库存(按库存量降序) |
| | | var sameModelStocks = stockList |
| | |
| | | /// <param name="requiredNum"></param> |
| | | /// <param name="materialNo"></param> |
| | | /// <returns></returns> |
| | | public async Task<Dictionary<WmsMaterialStockDto, int>> FindStockAsync(string materialModel, int requiredNum, string materialNo = "") |
| | | public async Task<Dictionary<WmsMaterialStockDto, int>> FindStockAsync(string materialModel, int requiredNum, string placeNo = "", PlaceTypeEnum placeType = PlaceTypeEnum.YUANLIAOKUWEI, string materialNo = "") |
| | | { |
| | | var allocation = new Dictionary<WmsMaterialStockDto, int>(); // <库位号, 出库数> |
| | | // 1. 获取所有库存(排除锁定库存) |
| | | var input = new GetWmsMaterialStockInput(); |
| | | var whereConditions = DynamicGetQueryParams(new GetWmsMaterialStockInput()); |
| | | var stockList = (await _wmsMaterialStockRepository.GetListAsync(whereConditions)) |
| | | .Where(x => x.IsLock == Domain.Shared.Enums.YesNoEnum.N) |
| | | .Where(x=>x.StorageTypeNo == Domain.Shared.Enums.PlaceTypeEnum.YUANLIAOKUWEI) |
| | | .Where(x => x.StorageTypeNo == placeType) |
| | | .ToList(); |
| | | |
| | | if (!string.IsNullOrEmpty(placeNo)) |
| | | { |
| | | var stock = stockList.Where(x => x.PlaceNo == placeNo).FirstOrDefault(); |
| | | if (stock.StockNumber < requiredNum) |
| | | { |
| | | throw new UserFriendlyException($"库位{placeNo}库存不足,可用: {stock.StockNumber}, 缺: {requiredNum - stock.StockNumber}"); |
| | | } |
| | | |
| | | allocation.Add(ObjectMapper.Map<WmsMaterialStock, WmsMaterialStockDto>(stock), requiredNum); |
| | | return allocation; |
| | | } |
| | | |
| | | // 2. 筛选匹配物料 |
| | | var availableStocklist = stockList |
| | |
| | | } |
| | | |
| | | // 4. 计算各库位出库数量 |
| | | var allocation = new Dictionary<WmsMaterialStockDto, int>(); // <库位号, 出库数> |
| | | int remaining = requiredNum; |
| | | |
| | | foreach (var stock in availableStocks) |
| | |
| | | |
| | | return whereConditions; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 扣减库存 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public async Task<List<WmsMaterialStockDto>> ReduceMaterialStockAsync(ReduceStockInput input) |
| | | { |
| | | using var scope = _serviceProvider.CreateScope(); |
| | | var unitOfWorkManager = scope.ServiceProvider.GetRequiredService<IUnitOfWorkManager>(); |
| | | using var uow = unitOfWorkManager.Begin(requiresNew: true); |
| | | |
| | | var materialModel = await _wmsMaterialRepository.FindByModelAsync(input.MaterialModel); |
| | | if (materialModel == null) |
| | | { |
| | | throw new UserFriendlyException("物料型号不存在"); |
| | | } |
| | | var placeInfo = await _wmsPlaceRepository.FindByNameAsync(input.PlaceNo); |
| | | if (placeInfo == null) |
| | | { |
| | | throw new UserFriendlyException("库位信息不存在"); |
| | | } |
| | | var stockresult = await FindStockAsync(input.MaterialModel, input.StockNumber, input.PlaceNo, placeInfo.StorageTypeNo); |
| | | if (stockresult == null) |
| | | { |
| | | throw new UserFriendlyException("当前无库存"); |
| | | } |
| | | var recordList = new List<WmsInOutStockRecord>(); |
| | | var delStock = new List<WmsMaterialStock>(); |
| | | foreach (var kvp in stockresult) |
| | | { |
| | | var stock = kvp.Key; // WmsPlace对象 |
| | | var quantity = kvp.Value; // 分配数量 |
| | | |
| | | // 扣减库存 |
| | | var stockList = await _wmsMaterialStockRepository.GetStockListAsync(new WmsMaterialStock { MaterialModel = input.MaterialModel, PlaceNo = stock.PlaceNo }); |
| | | var reduceStockList = stockList.OrderBy(x => x.InStockTime).Take(quantity).ToList(); |
| | | delStock.AddRange(reduceStockList); |
| | | |
| | | // 出入库记录 |
| | | foreach (var item in reduceStockList) |
| | | { |
| | | var record = new WmsInOutStockRecord |
| | | { |
| | | TaskNo = string.IsNullOrEmpty(input.OrderNo) ? "Task_" + DateTime.Now.ToString("yyyyMMddHHmmssfff") : input.OrderNo, |
| | | OrderNo = input.OrderNo, |
| | | StockType = StockTypeEnum.Move, |
| | | ContainerNo = item.ContainerNo, |
| | | MaterialId = item.MaterialId, |
| | | MaterialModel = item.MaterialModel, |
| | | MaterialName = item.MaterialName, |
| | | MaterialNo = item.MaterialNo, |
| | | MaterialBatch = item.MaterialBatch, |
| | | SourcePlace = item.PlaceNo, |
| | | ToPlace = "出库", |
| | | OperateTime = DateTime.Now, |
| | | Remark = "出库扣减", |
| | | }; |
| | | recordList.Add(record); |
| | | } |
| | | } |
| | | await _wmsMaterialStockRepository.DeleteManyAsync(delStock); |
| | | await _wmsInOutStockRecordRepository.InsertManyAsync(recordList); |
| | | |
| | | await uow.SaveChangesAsync(); |
| | | await uow.CompleteAsync(); |
| | | |
| | | var result = ObjectMapper.Map<List<WmsMaterialStock>, List<WmsMaterialStockDto>>(delStock); |
| | | return result; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 库存转移 |
| | | /// </summary> |
| | | /// <param name="input"></param> |
| | | /// <returns></returns> |
| | | public async Task<List<WmsMaterialStockDto>> MoveMaterialStock(MoveStockInput input) |
| | | { |
| | | using var scope = _serviceProvider.CreateScope(); |
| | | var unitOfWorkManager = scope.ServiceProvider.GetRequiredService<IUnitOfWorkManager>(); |
| | | using var uow = unitOfWorkManager.Begin(requiresNew: true); |
| | | |
| | | var materialModel = await _wmsMaterialRepository.FindByModelAsync(input.MaterialModel); |
| | | if (materialModel == null) |
| | | { |
| | | throw new UserFriendlyException("物料型号不存在"); |
| | | } |
| | | |
| | | var placeInfo = await _wmsPlaceRepository.FindByNameAsync(input.SourcePlace); |
| | | if (placeInfo == null) |
| | | { |
| | | throw new UserFriendlyException("来源库位信息不存在"); |
| | | } |
| | | var toPlace = await _wmsPlaceRepository.FindByNameAsync(input.ToPlace); |
| | | if (toPlace == null) |
| | | { |
| | | throw new UserFriendlyException("目标库位信息不存在"); |
| | | } |
| | | var stockresult = await FindStockAsync(input.MaterialModel, input.StockNumber, input.SourcePlace, placeInfo.StorageTypeNo); |
| | | if (stockresult == null) |
| | | { |
| | | throw new UserFriendlyException("当前无库存"); |
| | | } |
| | | |
| | | var recordList = new List<WmsInOutStockRecord>(); |
| | | var result = new List<WmsMaterialStockDto>(); |
| | | foreach (var kvp in stockresult) |
| | | { |
| | | var stock = kvp.Key; // WmsPlace对象 |
| | | var quantity = kvp.Value; // 分配数量 |
| | | |
| | | // 扣减转移 |
| | | var stockList = await _wmsMaterialStockRepository.GetStockListAsync(new WmsMaterialStock { MaterialModel = input.MaterialModel, PlaceNo = stock.PlaceNo }); |
| | | var reduceStockList = stockList.OrderBy(x => x.InStockTime).Take(quantity).ToList(); |
| | | |
| | | // 出入库记录 |
| | | foreach (var item in reduceStockList) |
| | | { |
| | | var record = new WmsInOutStockRecord |
| | | { |
| | | TaskNo = string.IsNullOrEmpty(input.OrderNo) ? "Task_" + DateTime.Now.ToString("yyyyMMddHHmmssfff") : input.OrderNo, |
| | | OrderNo = input.OrderNo, |
| | | StockType = StockTypeEnum.Move, |
| | | ContainerNo = item.ContainerNo, |
| | | MaterialId = item.MaterialId, |
| | | MaterialModel = item.MaterialModel, |
| | | MaterialName = item.MaterialName, |
| | | MaterialNo = item.MaterialNo, |
| | | MaterialBatch = item.MaterialBatch, |
| | | SourcePlace = item.PlaceNo, |
| | | ToPlace = input.ToPlace, |
| | | OperateTime = DateTime.Now, |
| | | Remark = "出库扣减", |
| | | }; |
| | | recordList.Add(record); |
| | | item.PlaceNo = input.ToPlace; |
| | | } |
| | | |
| | | await _wmsMaterialStockRepository.UpdateManyAsync(reduceStockList); |
| | | await _wmsInOutStockRecordRepository.InsertManyAsync(recordList); |
| | | |
| | | result.AddRange(ObjectMapper.Map<List<WmsMaterialStock>, List<WmsMaterialStockDto>>(reduceStockList)); |
| | | } |
| | | |
| | | await uow.SaveChangesAsync(); |
| | | await uow.CompleteAsync(); |
| | | |
| | | return result; |
| | | } |
| | | } |
| | | } |