diff --git a/EstateReportingAPI.BusinessLogic/ReportingManager.cs b/EstateReportingAPI.BusinessLogic/ReportingManager.cs index 52a6c06..8884e14 100644 --- a/EstateReportingAPI.BusinessLogic/ReportingManager.cs +++ b/EstateReportingAPI.BusinessLogic/ReportingManager.cs @@ -469,89 +469,6 @@ group f by f.IsSettled into grouped return response; } - public async Task> GetTopBottomData(Guid estateId, TopBottom direction, Int32 resultCount, Dimension dimension, CancellationToken cancellationToken){ - using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, estateId.ToString()); - await using EstateManagementContext context = resolvedContext.Context; - - IQueryable mainQuery = context.TodayTransactions - .Where(joined => joined.IsAuthorised == true - && joined.TransactionType == "Sale" - && joined.TransactionDate == DateTime.Now.Date); - - IQueryable queryable = null; - if (dimension == Dimension.Product) - { - // Products - queryable = mainQuery - .Join(context.ContractProducts, - t => t.ContractProductReportingId, - contractProduct => contractProduct.ContractProductReportingId, - (t, contractProduct) => new - { - Transaction = t, - ContractProduct = contractProduct - }) - .GroupBy(joined => joined.ContractProduct.ProductName) - .Select(g => new TopBottomData - { - DimensionName = g.Key, - SalesValue = g.Sum(t => t.Transaction.TransactionAmount) - }); - } - else if (dimension == Dimension.Operator) - { - // Operators - queryable = mainQuery - .Join(context.Operators, - t => t.OperatorReportingId, - o => o.OperatorReportingId, - (t, o) => new - { - Transaction = t, - Operator = o - }) - .GroupBy(joined => joined.Operator.Name) - .Select(g => new TopBottomData - { - DimensionName = g.Key, - SalesValue = g.Sum(t => t.Transaction.TransactionAmount) - }); - } - else if (dimension == Dimension.Merchant) - { - // Operators - queryable = mainQuery - .Join(context.Merchants, - t => t.MerchantReportingId, - merchant => merchant.MerchantReportingId, - (t, merchant) => new - { - Transaction = t, - Merchant = merchant - }) - .GroupBy(joined => joined.Merchant.Name) - .Select(g => new TopBottomData - { - DimensionName = g.Key, - SalesValue = g.Sum(t => t.Transaction.TransactionAmount) - }); - } - - if (direction == TopBottom.Top) - { - // Top X - queryable = queryable.OrderByDescending(g => g.SalesValue); - } - else if (direction == TopBottom.Bottom) - { - // Bottom X - queryable = queryable.OrderBy(g => g.SalesValue); - } - - // TODO: bad request?? - return await queryable.Take(resultCount).ToListAsync(cancellationToken); - } - private Int32 SafeDivide(Int32 number, Int32 divisor) { if (divisor == 0) diff --git a/EstateReportingAPI.BusinessLogic/ReportingManagerExtensions.cs b/EstateReportingAPI.BusinessLogic/ReportingManagerExtensions.cs index 3dc58a4..f91123a 100644 --- a/EstateReportingAPI.BusinessLogic/ReportingManagerExtensions.cs +++ b/EstateReportingAPI.BusinessLogic/ReportingManagerExtensions.cs @@ -111,6 +111,64 @@ join op in context.Operators on c.OperatorId equals op.OperatorId }; } + public static IQueryable ApplyMerchantGrouping(this IQueryable transactions, + EstateManagementContext context) + { + return transactions.Join(context.Merchants, + t => t.MerchantReportingId, + merchant => merchant.MerchantReportingId, + (t, merchant) => new + { + Transaction = t, + Merchant = merchant + }) + .GroupBy(joined => joined.Merchant.Name) + .Select(g => new TopBottomData + { + DimensionName = g.Key, + SalesValue = g.Sum(t => t.Transaction.TransactionAmount) + }); + } + + public static IQueryable ApplyOperatorGrouping(this IQueryable transactions, + EstateManagementContext context) + { + return transactions.Join(context.Operators, + t => t.OperatorReportingId, + o => o.OperatorReportingId, + (t, o) => new + { + Transaction = t, + Operator = o + }) + .GroupBy(joined => joined.Operator.Name) + .Select(g => new TopBottomData + { + DimensionName = g.Key, + SalesValue = g.Sum(t => t.Transaction.TransactionAmount) + }); + } + + public static IQueryable ApplyProductGrouping(this IQueryable transactions, + EstateManagementContext context) + { + return transactions + .Join(context.ContractProducts, + t => t.ContractProductReportingId, + contractProduct => contractProduct.ContractProductReportingId, + (t, contractProduct) => new + { + Transaction = t, + ContractProduct = contractProduct + }) + .GroupBy(joined => joined.ContractProduct.ProductName) + .Select(g => new TopBottomData + { + DimensionName = g.Key, + SalesValue = g.Sum(t => t.Transaction.TransactionAmount) + }); + } + public static IQueryable ApplyMerchantGrouping(this IQueryable fees, EstateManagementContext context) { diff --git a/EstateReportingAPI.BusinessLogic/ReportingManagerRefactored.cs b/EstateReportingAPI.BusinessLogic/ReportingManagerRefactored.cs index 6d85045..fda822d 100644 --- a/EstateReportingAPI.BusinessLogic/ReportingManagerRefactored.cs +++ b/EstateReportingAPI.BusinessLogic/ReportingManagerRefactored.cs @@ -196,6 +196,31 @@ public async Task GetOperatorPerformance(Guid estateId, DateTime co return response; } + public async Task> GetTopBottomData(Guid estateId, + TopBottom direction, + Int32 resultCount, + Dimension dimension, + CancellationToken cancellationToken) { + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, estateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; + + IQueryable mainQuery = BuildTodaySalesQuery(context); + + IQueryable topBottomData = dimension switch + { + Dimension.Merchant => mainQuery.ApplyMerchantGrouping(context), + Dimension.Operator => mainQuery.ApplyOperatorGrouping(context), + Dimension.Product => mainQuery.ApplyProductGrouping(context), + }; + + topBottomData = direction switch { + TopBottom.Top => topBottomData.OrderByDescending(g => g.SalesValue), + _ => topBottomData.OrderBy(g => g.SalesValue) + }; + + return await topBottomData.Take(resultCount).ToListAsync(cancellationToken); + } + } public class DatabaseProjections { @@ -211,5 +236,11 @@ public class TransactionSearchProjection { public Merchant Merchant { get; set; } public ContractProduct Product { get; set; } } + + public class TopBottomData + { + public String DimensionName { get; set; } + public Decimal SalesValue { get; set; } + } } }