diff --git a/EstateReportingAPI.BusinessLogic/ReportingManager.cs b/EstateReportingAPI.BusinessLogic/ReportingManager.cs index cb33c62..4f4c6b7 100644 --- a/EstateReportingAPI.BusinessLogic/ReportingManager.cs +++ b/EstateReportingAPI.BusinessLogic/ReportingManager.cs @@ -1140,44 +1140,48 @@ public async Task> GetProductPerformanceRepor using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, request.EstateId.ToString()); await using EstateManagementContext context = resolvedContext.Context; - var grandTotalAmountQuery = (from t in context.Transactions where t.TransactionType == "Sale" && t.TransactionDate >= new DateTime(2025, 12, 21) && t.TransactionDate <= new DateTime(2025, 12, 25) select t.TransactionAmount); + var grandTotalAmountQuery = (from t in context.Transactions where t.TransactionType == "Sale" && t.TransactionDate >= new DateTime(2025, 12, 21) && t.TransactionDate <= new DateTime(2025, 12, 25) select t.TransactionAmount); var grandTotalAmountResult = await ExecuteQuerySafeSum(grandTotalAmountQuery, cancellationToken); if (grandTotalAmountResult.IsFailed) return ResultHelpers.CreateFailure(grandTotalAmountResult); var grandTotalAmount = grandTotalAmountResult.Data; - var query = from t in context.Transactions + var query = BuildProductPerformanceQuery(context, request.StartDate, request.EndDate, grandTotalAmount); + var queryResult = await ExecuteQuerySafeToList(query, cancellationToken); + if (queryResult.IsFailed) + return ResultHelpers.CreateFailure(queryResult); + var queryResults = queryResult.Data; + if (queryResults.Any() == false) + return Result.Success(new ProductPerformanceResponse() { Summary = new ProductPerformanceSummary(), ProductDetails = new List() }); + + return Result.Success(BuildProductPerformanceResponse(queryResults)); + } + + private static IQueryable BuildProductPerformanceQuery(EstateManagementContext context, + DateTime startDate, + DateTime endDate, + decimal grandTotalAmount) { + return from t in context.Transactions join cp in context.ContractProducts on new { t.ContractProductId, t.ContractId } equals new { cp.ContractProductId, cp.ContractId } join c in context.Contracts on t.ContractId equals c.ContractId - where t.TransactionType == "Sale" && t.TransactionDate >= request.StartDate && t.TransactionDate <= request.EndDate - group t by new { - cp.ProductName, - cp.ContractProductId, - cp.ContractProductReportingId, - c.ContractId, - c.ContractReportingId - } + where t.TransactionType == "Sale" && t.TransactionDate >= startDate && t.TransactionDate <= endDate + group t by new { cp.ProductName, cp.ContractProductId, cp.ContractProductReportingId, c.ContractId, c.ContractReportingId } into g - select new { - g.Key.ProductName, - g.Key.ContractProductId, - g.Key.ContractProductReportingId, - g.Key.ContractId, - g.Key.ContractReportingId, + select new ProductPerformanceItemData { + ProductName = g.Key.ProductName, + ContractProductId = g.Key.ContractProductId, + ContractProductReportingId = g.Key.ContractProductReportingId, + ContractId = g.Key.ContractId, + ContractReportingId = g.Key.ContractReportingId, TransactionCount = g.Count(), TotalAmount = g.Sum(x => x.TransactionAmount), PercentOfTotalAmount = grandTotalAmount == 0 ? 0 : 100.0m * g.Sum(x => x.TransactionAmount) / grandTotalAmount }; + } - var queryResult = await ExecuteQuerySafeToList(query, cancellationToken); - if (queryResult.IsFailed) - return ResultHelpers.CreateFailure(queryResult); - var queryResults = queryResult.Data; - if (queryResults.Any() == false) - return Result.Success(new ProductPerformanceResponse() { Summary = new ProductPerformanceSummary(), ProductDetails = new List() }); - - ProductPerformanceResponse response = new ProductPerformanceResponse() { + private ProductPerformanceResponse BuildProductPerformanceResponse(List queryResults) { + return new ProductPerformanceResponse { ProductDetails = queryResults.Select(q => new ProductPerformanceDetail { ProductName = q.ProductName, ProductId = q.ContractProductId, @@ -1190,8 +1194,6 @@ into g }).ToList(), Summary = new ProductPerformanceSummary { TotalCount = queryResults.Sum(q => q.TransactionCount), TotalValue = queryResults.Sum(q => q.TotalAmount), AveragePerProduct = this.SafeDivide(queryResults.Sum(q => q.TotalAmount), queryResults.Count), TotalProducts = queryResults.Count() } }; - - return Result.Success(response); } public async Task>> GetTodaysSalesByHour(TransactionQueries.TodaysSalesByHour request, @@ -1412,6 +1414,17 @@ private sealed class ContractFeeData { public bool IsEnabled { get; init; } } + private sealed class ProductPerformanceItemData { + public string? ProductName { get; init; } + public Guid ContractProductId { get; init; } + public int ContractProductReportingId { get; init; } + public Guid ContractId { get; init; } + public int ContractReportingId { get; init; } + public int TransactionCount { get; init; } + public decimal TotalAmount { get; init; } + public decimal PercentOfTotalAmount { get; init; } + } + #endregion }