using Connected.Collections.Queues; using Connected.Middleware; using Logistics.Types.WarehouseLocations; using Microsoft.Extensions.Logging; namespace Logistics.Stock.Services; internal sealed class StockAggregator : MiddlewareComponent, IQueueClient> { public StockAggregator(ILogger logger, IWarehouseLocationService locations, IStockService stock) { Logger = logger; Locations = locations; Stock = stock; } private ILogger Logger { get; } private IWarehouseLocationService Locations { get; } private IStockService Stock { get; } public async Task Invoke(IQueueMessage message, PrimaryKeyQueueArgs args) { if (await Stock.SelectItem(args.Id) is not IStockItem stock) { Logger.LogWarning("IStockItem not found {id}", args.Id); return; } await Calculate(stock, stock.Location); } private async Task Calculate(IStockItem stock, int locationId) { if (await Locations.Select(locationId) is not IWarehouseLocation location) { Logger.LogWarning("IWarehouseLocation not found {id}", locationId); return; } if (location.Parent is null) return; var parent = (int)location.Parent; var sum = (await Stock.QueryItems(new QueryStockItemsArgs { Id = stock.Id, Location = parent, Serial = stock.Serial })).Sum(f => f.Quantity); await Stock.Update(new UpdateStockArgs { Location = parent, Quantity = sum, Serial = stock.Serial }); await Calculate(stock, parent); } }