Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@ public record TransactionQueries {
public record TodaysSalesQuery(Guid EstateId, Int32 MerchantReportingId, Int32 OperatorReportingId, DateTime ComparisonDate) : IRequest<Result<TodaysSales>>;
public record TodaysFailedSales(Guid EstateId, DateTime ComparisonDate, String ResponseCode) : IRequest<Result<TodaysSales>>;
public record TransactionDetailReportQuery(Guid EstateId, TransactionDetailReportRequest Request) : IRequest<Result<TransactionDetailReportResponse>>;

public record TransactionSummaryByMerchantQuery(Guid EstateId, TransactionSummaryByMerchantRequest Request) : IRequest<Result<TransactionSummaryByMerchantResponse>>;

}
116 changes: 114 additions & 2 deletions EstateReportingAPI.BusinessLogic/ReportingManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using System.ClientModel.Primitives;
using System.Linq;
using System.Threading;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
using Calendar = Models.Calendar;
using Merchant = Models.Merchant;

Expand All @@ -41,9 +42,10 @@
Task<Result<List<MerchantContract>>> GetMerchantContracts(MerchantQueries.GetMerchantContractsQuery request, CancellationToken cancellationToken);
Task<Result<List<MerchantDevice>>> GetMerchantDevices(MerchantQueries.GetMerchantDevicesQuery request, CancellationToken cancellationToken);
Task<Result<Operator>> GetOperator(OperatorQueries.GetOperatorQuery request, CancellationToken cancellationToken);

Task<Result<TransactionDetailReportResponse>> GetTransactionDetailReport(TransactionQueries.TransactionDetailReportQuery request,
CancellationToken cancellationToken);
Task<Result<TransactionSummaryByMerchantResponse>> GetTransactionSummaryByMerchantReport(TransactionQueries.TransactionSummaryByMerchantQuery request,
CancellationToken cancellationToken);

#endregion
}
Expand Down Expand Up @@ -817,7 +819,7 @@
query = query.Where(q => request.Request.Operators.Contains(q.OperatorReportingId));
}

var queryResult = await ExecuteQuerySafeToList(query, cancellationToken, "Error retrieving transaction details resport");
var queryResult = await ExecuteQuerySafeToList(query, cancellationToken, "Error retrieving transaction details report");

if (queryResult.IsFailed)
return ResultHelpers.CreateFailure(queryResult);
Expand Down Expand Up @@ -859,6 +861,116 @@
}
};

return Result.Success(response);
}

public async Task<Result<TransactionSummaryByMerchantResponse>> GetTransactionSummaryByMerchantReport(TransactionQueries.TransactionSummaryByMerchantQuery request,

Check warning on line 867 in EstateReportingAPI.BusinessLogic/ReportingManager.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

EstateReportingAPI.BusinessLogic/ReportingManager.cs#L867

Method ReportingManager::GetTransactionSummaryByMerchantReport has 96 lines of code (limit is 50)

Check warning on line 867 in EstateReportingAPI.BusinessLogic/ReportingManager.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

EstateReportingAPI.BusinessLogic/ReportingManager.cs#L867

Method ReportingManager::GetTransactionSummaryByMerchantReport has a cyclomatic complexity of 14 (limit is 8)
CancellationToken cancellationToken) {

TransactionSummaryByMerchantResponse response = null;
using ResolvedDbContext<EstateManagementContext>? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, request.EstateId.ToString());
await using EstateManagementContext context = resolvedContext.Context;

var query =
from t in context.Transactions
join m in context.Merchants on t.MerchantId equals m.MerchantId
join o in context.Operators on t.OperatorId equals o.OperatorId
where t.TransactionType == "Sale"
&& t.TransactionDate >= request.Request.StartDate
&& t.TransactionDate <= request.Request.EndDate
group t by new
{
t.MerchantId,
m.MerchantReportingId,
MerchantName = m.Name,
t.OperatorId,
o.OperatorReportingId
}
into g
select new
{
g.Key.MerchantId,
g.Key.MerchantReportingId,
g.Key.MerchantName,
g.Key.OperatorId,
g.Key.OperatorReportingId,
TotalCount = g.Count(),
TotalValue = g.Sum(x => x.TransactionAmount),
AuthorisedCount = g.Sum(x => x.IsAuthorised ? 1 : 0),
DeclinedCount = g.Sum(x => x.IsAuthorised ? 0 : 1)
};

// 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.Operators != null && request.Request.Operators.Any())
{
query = query.Where(q => request.Request.Operators.Contains(q.OperatorReportingId));
}

var finalQuery = from x in query
group x by new
{
x.MerchantId,
x.MerchantReportingId,
MerchantName = x.MerchantName,
}
into g
select new
{
g.Key.MerchantId,
g.Key.MerchantReportingId,
g.Key.MerchantName,
TotalCount = g.Sum(x => x.TotalCount),
TotalValue = g.Sum(x => x.TotalValue),
AverageValue = g.Count() > 0 ? g.Sum(x => x.TotalValue) / g.Count() : 0m,
AuthorisedCount = g.Sum(x => x.AuthorisedCount),
DeclinedCount = g.Sum(x => x.DeclinedCount),
AuthorisedPercentage = g.Sum(x => x.TotalCount) > 0 ? (decimal)g.Sum(x => x.AuthorisedCount) / (decimal)g.Sum(x => x.TotalCount) : 0m
};

var queryResult = await ExecuteQuerySafeToList(finalQuery, cancellationToken, "Error retrieving transaction summary by merchant report");

if (queryResult.IsFailed)
return ResultHelpers.CreateFailure(queryResult);

// Ok now enumerate the results
var queryResults = queryResult.Data;

if (queryResults.Any() == false)
return new TransactionSummaryByMerchantResponse
{
Summary = new MerchantDetailSummary(),
Merchants= new List<MerchantDetail>()
};

// Now to translate the results
response = new TransactionSummaryByMerchantResponse
{
Merchants = queryResults.Select(q => new MerchantDetail
{
MerchantId = q.MerchantId,
MerchantReportingId = q.MerchantReportingId,
MerchantName = q.MerchantName,
AuthorisedCount = q.AuthorisedCount,
AuthorisedPercentage = q.AuthorisedPercentage,
AverageValue = q.AverageValue,
DeclinedCount = q.DeclinedCount,
TotalCount = q.TotalCount,
TotalValue = q.TotalValue
}).ToList(),
Summary = new MerchantDetailSummary
{
TotalCount = queryResults.Sum(q => q.TotalCount),
TotalValue = queryResults.Sum(q => q.TotalValue),
AverageValue = this.SafeDivide(queryResults.Sum(q => q.TotalValue)
,queryResults.Sum(q => q.TotalCount)),
TotalMerchants = queryResults.Count()
}
};

return response;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ namespace EstateReportingAPI.BusinessLogic.RequestHandlers;

public class TransactionRequestHandler : IRequestHandler<TransactionQueries.TodaysFailedSales, Result<TodaysSales>>,
IRequestHandler<TransactionQueries.TodaysSalesQuery, Result<TodaysSales>>,
IRequestHandler<TransactionQueries.TransactionDetailReportQuery, Result<TransactionDetailReportResponse>> {
IRequestHandler<TransactionQueries.TransactionDetailReportQuery, Result<TransactionDetailReportResponse>>,
IRequestHandler<TransactionQueries.TransactionSummaryByMerchantQuery, Result<TransactionSummaryByMerchantResponse>>
{
private readonly IReportingManager Manager;

public TransactionRequestHandler(IReportingManager manager) {
Expand All @@ -28,4 +30,10 @@ public async Task<Result<TransactionDetailReportResponse>> Handle(TransactionQue
CancellationToken cancellationToken) {
return await this.Manager.GetTransactionDetailReport(request, cancellationToken);
}

public async Task<Result<TransactionSummaryByMerchantResponse>> Handle(TransactionQueries.TransactionSummaryByMerchantQuery request,
CancellationToken cancellationToken)
{
return await this.Manager.GetTransactionSummaryByMerchantReport(request, cancellationToken);
}
}
7 changes: 7 additions & 0 deletions EstateReportingAPI.DataTrasferObjects/GroupByOption.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace EstateReportingAPI.DataTransferObjects;

public enum GroupByOption{
Operator,
Merchant,
Product
}
7 changes: 7 additions & 0 deletions EstateReportingAPI.DataTrasferObjects/SortDirection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace EstateReportingAPI.DataTransferObjects;

public enum SortDirection{
Ascending,

Descending,
}
9 changes: 9 additions & 0 deletions EstateReportingAPI.DataTrasferObjects/SortField.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace EstateReportingAPI.DataTransferObjects;

public enum SortField{
TransactionAmount = 1,

MerchantName = 2,

OperatorName = 3
}
40 changes: 40 additions & 0 deletions EstateReportingAPI.DataTrasferObjects/TransactionDetail.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System;
using Newtonsoft.Json;

namespace EstateReportingAPI.DataTransferObjects;

public class TransactionDetail
{
[JsonProperty("id")]
public Guid Id { get; set; }
[JsonProperty("date_time")]
public DateTime DateTime { get; set; }
[JsonProperty("merchant")]
public String Merchant { get; set; }
[JsonProperty("merchant_id")]
public Guid MerchantId { get; set; }
[JsonProperty("merchant_reporting_id")]
public Int32 MerchantReportingId { get; set; }
[JsonProperty("operator")]
public String Operator { get; set; }
[JsonProperty("operator_id")]
public Guid OperatorId { get; set; }
[JsonProperty("operator_reporting_id")]
public Int32 OperatorReportingId { get; set; }
[JsonProperty("product")]
public String Product { get; set; }
[JsonProperty("product_id")]
public Guid ProductId { get; set; }
[JsonProperty("product_reporting_id")]
public Int32 ProductReportingId { get; set; }
[JsonProperty("type")]
public String Type { get; set; }
[JsonProperty("status")]
public String Status { get; set; }
[JsonProperty("value")]
public Decimal Value { get; set; }
[JsonProperty("total_fees")]
public Decimal TotalFees { get; set; }
[JsonProperty("settlement_reference")]
public String SettlementReference { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;

namespace EstateReportingAPI.DataTransferObjects;

public class TransactionDetailReportRequest
{
[JsonProperty("operators")]
public List<Int32>? Operators { get; set; }
[JsonProperty("merchants")]
public List<Int32>? Merchants { get; set; }
[JsonProperty("products")]
public List<Int32>? Products { get; set; }
[JsonProperty("start_date")]
public DateTime StartDate { get; set; }
[JsonProperty("end_date")]
public DateTime EndDate { get; set; }
}

public class TransactionSummaryByMerchantRequest
{
[JsonProperty("operators")]
public List<Int32>? Operators { get; set; }
[JsonProperty("merchants")]
public List<Int32>? Merchants { get; set; }
[JsonProperty("start_date")]
public DateTime StartDate { get; set; }
[JsonProperty("end_date")]
public DateTime EndDate { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;

namespace EstateReportingAPI.DataTransferObjects;

public class TransactionDetailReportResponse
{
[JsonProperty("transactions")]
public List<TransactionDetail> Transactions { get; set; }
[JsonProperty("summary")]
public TransactionDetailSummary Summary { get; set; }
}

public class TransactionSummaryByMerchantResponse
{
[JsonProperty("merchants")]
public List<MerchantDetail> Merchants { get; set; }
[JsonProperty("summary")]
public MerchantDetailSummary Summary { get; set; }
}

public class MerchantDetail {
[JsonProperty("merchant_id")]
public Guid MerchantId { get; set; }
[JsonProperty("merchant_reporting_id")]
public Int32 MerchantReportingId { get; set; }
[JsonProperty("merchant_name")]
public string MerchantName { get; set; }
[JsonProperty("total_count")]
public Int32 TotalCount { get; set; }
[JsonProperty("total_value")]
public Decimal TotalValue { get; set; }
[JsonProperty("average_value")]
public Decimal AverageValue { get; set; }
[JsonProperty("authorised_count")]
public Int32 AuthorisedCount { get; set; }
[JsonProperty("declined_count")]
public Int32 DeclinedCount { get; set; }
[JsonProperty("authorised_percentage")]
public Decimal AuthorisedPercentage { get; set; }
}

public class MerchantDetailSummary {
[JsonProperty("total_merchants")]
public Int32 TotalMerchants { get; set; }
[JsonProperty("total_count")]
public Int32 TotalCount { get; set; }
[JsonProperty("total_value")]
public Decimal TotalValue { get; set; }
[JsonProperty("average_value")]
public Decimal AverageValue { get; set; }
}
14 changes: 14 additions & 0 deletions EstateReportingAPI.DataTrasferObjects/TransactionDetailSummary.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using Newtonsoft.Json;

namespace EstateReportingAPI.DataTransferObjects;

public class TransactionDetailSummary
{
[JsonProperty("total_value")]
public Decimal TotalValue { get; set; }
[JsonProperty("total_fees")]
public Decimal TotalFees { get; set; }
[JsonProperty("transaction_count")]
public Int32 TransactionCount { get; set; }
}
Loading
Loading