From 0057ff26d5e835629d9d85d63f4bbe723e5c9e44 Mon Sep 17 00:00:00 2001 From: zs <zhousong@weben-smart.com> Date: 周日, 18 5月 2025 19:47:32 +0800 Subject: [PATCH] 项目 --- HIAWms/server/src/CMS.Plugin.HIAWms.Application/Implements/WmsCommonAppService.cs | 224 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 212 insertions(+), 12 deletions(-) diff --git a/HIAWms/server/src/CMS.Plugin.HIAWms.Application/Implements/WmsCommonAppService.cs b/HIAWms/server/src/CMS.Plugin.HIAWms.Application/Implements/WmsCommonAppService.cs index 63d57b9..dcd579c 100644 --- a/HIAWms/server/src/CMS.Plugin.HIAWms.Application/Implements/WmsCommonAppService.cs +++ b/HIAWms/server/src/CMS.Plugin.HIAWms.Application/Implements/WmsCommonAppService.cs @@ -1,35 +1,48 @@ 锘縰sing CMS.Plugin.HIAWms.Application.Contracts.Dtos.CommonDto; -using CMS.Plugin.HIAWms.Application.Contracts.Dtos.WmsPlaces; +using CMS.Plugin.HIAWms.Application.Contracts.Dtos.WmsMaterialStocks; +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.Linq.Expressions; 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; } @@ -41,12 +54,15 @@ /// <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 = "") { - // 1. 鑾峰彇鎵�鏈夊簱瀛樺拰搴撲綅淇℃伅 - var stockList = await _wmsMaterialStockRepository.GetListAsync(new WmsMaterialStock()); - var allPlaceList = ObjectMapper.Map<List<WmsPlace>, List<WmsPlaceDto>>(await _wmsPlaceRepository.GetListAsync(new WmsPlace())); + 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.Where(x => !x.IsDisabled).ToList()); // 2. 鏌ユ壘鐩稿悓鐗╂枡鍨嬪彿鍜岀紪鍙风殑搴撳瓨锛堟寜搴撳瓨閲忛檷搴忥級 var sameModelStocks = stockList @@ -108,19 +124,37 @@ /// <param name="requiredNum"></param> /// <param name="materialNo"></param> /// <returns></returns> - public async Task<Dictionary<string, 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 stockList = (await _wmsMaterialStockRepository.GetListAsync(new WmsMaterialStock())) + 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 == 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 availableStocks = stockList + var availableStocklist = stockList .Where(x => x.MaterialModel == materialModel) .WhereIf(!string.IsNullOrEmpty(materialNo), x => x.MaterialNo == materialNo) .OrderBy(x => x.StockNumber) // 浼樺厛浠庡簱瀛樺皯鐨勫簱浣嶅嚭 .ToList(); + + var availableStocks = ObjectMapper.Map<List<WmsMaterialStock>, List<WmsMaterialStockDto>>(availableStocklist); // 3. 妫�鏌ユ�诲簱瀛樻槸鍚﹁冻澶� int totalAvailable = availableStocks.Sum(x => x.StockNumber); @@ -131,7 +165,6 @@ } // 4. 璁$畻鍚勫簱浣嶅嚭搴撴暟閲� - var allocation = new Dictionary<string, int>(); // <搴撲綅鍙�, 鍑哄簱鏁�> int remaining = requiredNum; foreach (var stock in availableStocks) @@ -139,11 +172,178 @@ if (remaining <= 0) break; int deductAmount = Math.Min(stock.StockNumber, remaining); - allocation.Add(stock.PlaceNo, deductAmount); + allocation.Add(stock, deductAmount); remaining -= deductAmount; } return allocation; } + + private FunReturnResultModel<Expression<Func<WmsMaterialStock, bool>>> DynamicGetQueryParams(GetWmsMaterialStockInput input) + { + //鍔ㄦ�佹瀯閫犳煡璇㈡潯浠� + var whereConditions = WhereConditionsExtensions.GetWhereConditions<WmsMaterialStock, GetWmsMaterialStockInput>(input); + if (!whereConditions.IsSuccess) + { + throw new Exception("鍔ㄦ�佹瀯閫犳煡璇㈡潯浠跺け璐�:" + whereConditions.ErrMsg); + } + + //涔熷彲鍐嶆鑷畾涔夋瀯寤烘煡璇㈡潯浠� + Expression<Func<WmsMaterialStock, bool>> extendExpression = a => a.IsDeleted == false; + // 浣跨敤 System.Linq.PredicateBuilder 鐨� And + var pres = (System.Linq.Expressions.Expression<Func<WmsMaterialStock, bool>>)(whereConditions.data); + whereConditions.data = System.Linq.PredicateBuilder.And(pres, extendExpression); + + return whereConditions; + } + + + /// <summary> + /// 鎵e噺搴撳瓨 + /// </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; // 鍒嗛厤鏁伴噺 + + // 鎵e噺搴撳瓨 + 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 = "鍑哄簱鎵e噺", + }; + 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; // 鍒嗛厤鏁伴噺 + + // 鎵e噺杞Щ + 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 = "鍑哄簱鎵e噺", + }; + 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; + } } } -- Gitblit v1.9.3