From 7b0ce0ee1fd2176117d51d46c06148b678d45f04 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 27 Feb 2026 19:31:14 +0000 Subject: [PATCH 1/2] Initial plan From 14ec25fde8eb89469138bb43306ec9d02bc06343 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 27 Feb 2026 19:41:58 +0000 Subject: [PATCH 2/2] Refactor GetTransactionDetailReport to reduce method length from 85 to 18 lines Co-authored-by: StuartFerguson <16325469+StuartFerguson@users.noreply.github.com> --- .../ReportingManager.cs | 87 +++++++++++-------- 1 file changed, 53 insertions(+), 34 deletions(-) diff --git a/EstateReportingAPI.BusinessLogic/ReportingManager.cs b/EstateReportingAPI.BusinessLogic/ReportingManager.cs index aaad86e..ab40e61 100644 --- a/EstateReportingAPI.BusinessLogic/ReportingManager.cs +++ b/EstateReportingAPI.BusinessLogic/ReportingManager.cs @@ -665,12 +665,26 @@ public async Task> GetOperator(OperatorQueries.GetOperatorQuery public async Task> GetTransactionDetailReport(TransactionQueries.TransactionDetailReportQuery request, CancellationToken cancellationToken) { - - TransactionDetailReportResponse response = null; using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, request.EstateId.ToString()); await using EstateManagementContext context = resolvedContext.Context; - var query = from t in context.Transactions + var query = ApplyTransactionDetailFilters(BuildTransactionDetailBaseQuery(context, request.Request), request.Request); + var queryResult = await ExecuteQuerySafeToList(query, cancellationToken, "Error retrieving transaction details report"); + + if (queryResult.IsFailed) + return ResultHelpers.CreateFailure(queryResult); + + var queryResults = queryResult.Data; + + if (queryResults.Any() == false) + return new TransactionDetailReportResponse { Summary = new TransactionDetailSummary(), Transactions = new List() }; + + return Result.Success(MapToTransactionDetailResponse(queryResults)); + } + + private static IQueryable BuildTransactionDetailBaseQuery(EstateManagementContext context, + TransactionDetailReportRequest request) { + return from t in context.Transactions join cp in context.ContractProducts on new { t.ContractProductId, t.ContractId } equals new { cp.ContractProductId, cp.ContractId } join m in context.Merchants on t.MerchantId equals m.MerchantId join o in context.Operators on t.OperatorId equals o.OperatorId @@ -679,10 +693,10 @@ from msf in msfJoin.DefaultIfEmpty() // left join Settlements (msf may be null) join s in context.Settlements on msf.SettlementId equals s.SettlementId into sJoin from s in sJoin.DefaultIfEmpty() - where t.TransactionType != "Logon" && t.TransactionDate >= request.Request.StartDate && t.TransactionDate <= request.Request.EndDate - select new { - t.TransactionId, - t.TransactionDateTime, + where t.TransactionType != "Logon" && t.TransactionDate >= request.StartDate && t.TransactionDate <= request.EndDate + select new TransactionDetailQueryResult { + TransactionId = t.TransactionId, + TransactionDateTime = t.TransactionDateTime, MerchantId = m.MerchantId, MerchantReportingId = m.MerchantReportingId, MerchantName = m.Name, @@ -698,33 +712,21 @@ from s in sJoin.DefaultIfEmpty() FeeValue = msf != null ? msf.FeeValue : 0m, SettlementId = s != null ? s.SettlementId : Guid.Empty, }; + } - // Now apply the filters - if (request.Request.Merchants != null && request.Request.Merchants.Any()) { - query = query.Where(q => request.Request.Merchants.Contains(q.MerchantReportingId)); - } - - if (request.Request.Products != null && request.Request.Products.Any()) { - query = query.Where(q => request.Request.Products.Contains(q.ContractProductReportingId)); - } - - if (request.Request.Operators != null && request.Request.Operators.Any()) { - query = query.Where(q => request.Request.Operators.Contains(q.OperatorReportingId)); - } - - var queryResult = await ExecuteQuerySafeToList(query, cancellationToken, "Error retrieving transaction details report"); - - if (queryResult.IsFailed) - return ResultHelpers.CreateFailure(queryResult); - - // Ok now enumerate the results - var queryResults = queryResult.Data; - - if (queryResults.Any() == false) - return new TransactionDetailReportResponse { Summary = new TransactionDetailSummary(), Transactions = new List() }; + private static IQueryable ApplyTransactionDetailFilters(IQueryable query, + TransactionDetailReportRequest request) { + if (request.Merchants != null && request.Merchants.Any()) + query = query.Where(q => request.Merchants.Contains(q.MerchantReportingId)); + if (request.Products != null && request.Products.Any()) + query = query.Where(q => request.Products.Contains(q.ContractProductReportingId)); + if (request.Operators != null && request.Operators.Any()) + query = query.Where(q => request.Operators.Contains(q.OperatorReportingId)); + return query; + } - // Now to translate the results - response = new TransactionDetailReportResponse { + private static TransactionDetailReportResponse MapToTransactionDetailResponse(List queryResults) { + return new TransactionDetailReportResponse { Transactions = queryResults.Select(q => new TransactionDetail { Id = q.TransactionId, DateTime = q.TransactionDateTime, @@ -745,8 +747,6 @@ from s in sJoin.DefaultIfEmpty() }).ToList(), Summary = new TransactionDetailSummary { TransactionCount = queryResults.Count(), TotalValue = queryResults.Sum(q => q.Value), TotalFees = queryResults.Sum(q => q.FeeValue) } }; - - return Result.Success(response); } public async Task> GetTransactionSummaryByMerchantReport(TransactionQueries.TransactionSummaryByMerchantQuery request, @@ -1396,6 +1396,25 @@ private static List BuildContracts(List baseContract }).ToList(); } + private sealed class TransactionDetailQueryResult { + public Guid TransactionId { get; init; } + public DateTime TransactionDateTime { get; init; } + public Guid MerchantId { get; init; } + public int MerchantReportingId { get; init; } + public string? MerchantName { get; init; } + public Guid OperatorId { get; init; } + public int OperatorReportingId { get; init; } + public string? OperatorName { get; init; } + public string? ProductName { get; init; } + public Guid ContractProductId { get; init; } + public int ContractProductReportingId { get; init; } + public string? TransactionType { get; init; } + public string? Status { get; init; } + public decimal Value { get; init; } + public decimal FeeValue { get; init; } + public Guid SettlementId { get; init; } + } + private sealed class ContractBaseData { public Guid ContractId { get; init; } public int ContractReportingId { get; init; }