From e178c18f80d93d238ff0792df5cf5893cee8ba43 Mon Sep 17 00:00:00 2001 From: Loretta Date: Mon, 8 Dec 2025 15:49:51 +0100 Subject: [PATCH] Add stock-taking enhancements and validation updates Enhanced stock-taking functionality by introducing the `CloseStockTaking` method in `StockTakingDbContext` to manage session closures with validation. Added the `IsReadyForClose` method to `IMgStockTaking` and its implementation in `MgStockTaking`. Integrated `FruitBankDbContext` for stock updates. Improved logging in `StockSignalREndpointServer` and added a new SignalR endpoint for closing stock-taking sessions. Updated `AddStockTaking` to initialize properties for new entries. Simplified loading logic in `OrderItemDtoDbTable` by commenting out unnecessary `.ThenLoad` chains. Enhanced validation in `RefreshStockTakingItemMeasuredValuesFromPallets` and adjusted return statements in `AddOrUpdateMeasuredStockTakingItemPallet` and `UpdateStockTakingItemPallet` to fetch updated entities. These changes improve maintainability, robustness, and functionality across the codebase. --- .../Controllers/StockSignalREndpointServer.cs | 17 ++++++++ .../Domains/DataLayer/OrderItemDtoDbTable.cs | 2 +- .../Domains/DataLayer/StockTakingDbContext.cs | 39 ++++++++++++++++--- 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Controllers/StockSignalREndpointServer.cs b/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Controllers/StockSignalREndpointServer.cs index 82ada7e..4f7040c 100644 --- a/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Controllers/StockSignalREndpointServer.cs +++ b/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Controllers/StockSignalREndpointServer.cs @@ -23,6 +23,7 @@ public class StockSignalREndpointServer(StockTakingDbContext ctx, SignalRSendToC [SignalR(SignalRTags.GetStockTakings)] public async Task> GetStockTakings(bool loadRelations) { + _logger.Debug($"GetStockTakings invoke. loadRelations: {loadRelations}"); return await ctx.StockTakings.GetAll(loadRelations).ToListAsync(); } @@ -31,11 +32,27 @@ public class StockSignalREndpointServer(StockTakingDbContext ctx, SignalRSendToC throw new NotImplementedException(); } + [SignalR(SignalRTags.CloseStockTaking)] + public async Task CloseStockTaking(int stockTakingId) + { + var result = await ctx.TransactionSafeAsync(async _ => + { + await ctx.CloseStockTaking(stockTakingId); + return true; + }); + + if (result) return await ctx.StockTakings.GetByIdAsync(stockTakingId, false); + return null; + } + [SignalR(SignalRTags.AddStockTaking)] public async Task AddStockTaking(StockTaking stockTaking) { var result = await ctx.TransactionSafeAsync(async _ => { + stockTaking.IsClosed = false; + stockTaking.StartDateTime = DateTime.Now; + await ctx.StockTakings.InsertAsync(stockTaking); var productDtos = await ctx.ProductDtos.GetAll(true).ToListAsync(); diff --git a/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/OrderItemDtoDbTable.cs b/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/OrderItemDtoDbTable.cs index dca5e88..1ea4d4c 100644 --- a/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/OrderItemDtoDbTable.cs +++ b/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/OrderItemDtoDbTable.cs @@ -24,7 +24,7 @@ public class OrderItemDtoDbTable : MgDtoDbTableBase .LoadWith(oi => oi.OrderDto).ThenLoad(o => o.Customer) .LoadWith(oi => oi.OrderDto).ThenLoad(o => o.OrderNotes) .LoadWith(oi => oi.OrderDto).ThenLoad(o => o.GenericAttributes) - .LoadWith(oi => oi.OrderItemPallets).ThenLoad(oip => oip.OrderItemDto).ThenLoad(oi => oi.GenericAttributes) + .LoadWith(oi => oi.OrderItemPallets)//.ThenLoad(oip => oip.OrderItemDto).ThenLoad(oi => oi.GenericAttributes) .LoadWith(oi => oi.ProductDto).ThenLoad(prod => prod.GenericAttributes); } diff --git a/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/StockTakingDbContext.cs b/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/StockTakingDbContext.cs index 7cf2de4..a57d217 100644 --- a/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/StockTakingDbContext.cs +++ b/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/StockTakingDbContext.cs @@ -25,6 +25,7 @@ public class StockTakingDbContext : MgDbContextBase, IStockTakingItemDbSet, IStockTakingItemPalletDbSet { + private FruitBankDbContext _fruitBankDbContext; public ProductDtoDbTable ProductDtos { get; set; } public OrderItemDtoDbTable OrderItemDtos { get; set; } @@ -42,7 +43,7 @@ public class StockTakingDbContext : MgDbContextBase, private readonly IStaticCacheManager _staticCacheManager; protected readonly IEventPublisher _eventPublisher; - public StockTakingDbContext(INopDataProvider dataProvider, ILockService lockService, IStoreContext storeContext, + public StockTakingDbContext(INopDataProvider dataProvider, ILockService lockService, IStoreContext storeContext, FruitBankDbContext fruitBankDbContext, ProductDtoDbTable productDtoDbTable, OrderItemDtoDbTable orderItemDtoDbTable, StockQuantityHistoryDtoDbTable stockQuantityHistoryDtos, @@ -64,6 +65,8 @@ public class StockTakingDbContext : MgDbContextBase, _productService = productService; _staticCacheManager = staticCacheManager; + _fruitBankDbContext = fruitBankDbContext; + ProductDtos = productDtoDbTable; OrderItemDtos = orderItemDtoDbTable; @@ -78,6 +81,28 @@ public class StockTakingDbContext : MgDbContextBase, StockTakingItemPallets = stockTakingItemPalletDbTable; } + public async Task CloseStockTaking(int stockTakingId) + { + var stockTaking = await StockTakings.GetByIdAsync(stockTakingId, true); + + if (!stockTaking.IsReadyForClose()) throw new Exception($"Not all IsRequiredForMeasuring items are IsMeasured! IsReadyForClose: false;"); + + var count = 0; + foreach (var stockTakingItem in stockTaking.StockTakingItems!.Where(stockTakingItem => stockTakingItem is { IsMeasured: true, IsInvalid: false })) + { + count++; + + //await _fruitBankDbContext.UpdateStockQuantityAndWeightAsync(stockTakingItem.Product!, stockTakingItem.QuantityDiff, + // $"Leltár által módosítva! stockTakingId: #{stockTaking.Id}, stockTakingItemId: #{stockTakingItem.Id}", + // stockTakingItem.NetWeightDiff); + } + + stockTaking.IsClosed = true; + await StockTakings.UpdateAsync(stockTaking); + + Logger.Info($"StockTaking closed! stockTakingId: {stockTaking.Id}; stockTakingItems count: {count}"); + } + public async Task AddOrUpdateMeasuredStockTakingItemPallet(StockTakingItemPallet stockTakingItemPallet) { if (stockTakingItemPallet.Id == 0) return await AddStockTakingItemPallet(stockTakingItemPallet); @@ -94,7 +119,7 @@ public class StockTakingDbContext : MgDbContextBase, return true; }); - return stockTakingItemPallet; + return await StockTakingItemPallets.GetByIdAsync(stockTakingItemPallet.Id); } public async Task UpdateStockTakingItemPallet(StockTakingItemPallet stockTakingItemPallet) @@ -107,16 +132,20 @@ public class StockTakingDbContext : MgDbContextBase, return true; }); - return stockTakingItemPallet; + return await StockTakingItemPallets.GetByIdAsync(stockTakingItemPallet.Id); } private async Task RefreshStockTakingItemMeasuredValuesFromPallets(int stockTakingItemId) { var stockTakingItem = await StockTakingItems.GetByIdAsync(stockTakingItemId, true)!; - if (stockTakingItem.StockTaking!.IsClosed) throw new Exception($"stockTakingItem.StockTaking!.IsClosed"); + if (stockTakingItem.IsInvalid) throw new Exception($"stockTakingItem.IsInvalid"); + if (stockTakingItem.StockTaking!.IsClosed) throw new Exception($"stockTakingItem.StockTaking.IsClosed"); + if (stockTakingItem.StockTakingItemPallets!.Count == 0) throw new Exception($"stockTakingItem.StockTakingItemPallets.Count == 0"); + if (stockTakingItem.StockTakingItemPallets!.Any(x => !x.IsValidMeasuringValues(stockTakingItem.IsMeasurable))) throw new Exception($"IsValidMeasuringValues == false"); - stockTakingItem.IsMeasured = stockTakingItem.StockTakingItemPallets!.Count > 0; + + stockTakingItem.IsMeasured = true; stockTakingItem.MeasuredStockQuantity = stockTakingItem.StockTakingItemPallets.Sum(x => x.TrayQuantity); if (stockTakingItem.IsMeasurable) stockTakingItem.MeasuredNetWeight = double.Round(stockTakingItem.StockTakingItemPallets.Sum(x => x.NetWeight), 1);