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
2 changes: 2 additions & 0 deletions EstateReportingAPI.BusinessLogic/IReportingManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,7 @@ public interface IReportingManager{
Task<TodaysSales> GetMerchantPerformance(Guid estateId, DateTime comparisonDate, List<Int32> merchantIds,CancellationToken cancellationToken);
Task<TodaysSales> GetProductPerformance(Guid estateId, DateTime comparisonDate, List<Int32> productIds, CancellationToken cancellationToken);

Task<TodaysSales> GetOperatorPerformance(Guid estateId, DateTime comparisonDate, List<String> operatorIds, CancellationToken cancellationToken);

#endregion
}
35 changes: 35 additions & 0 deletions EstateReportingAPI.BusinessLogic/ReportingManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,41 @@ public async Task<TodaysSales> GetProductPerformance(Guid estateId, DateTime com
return response;
}

public async Task<TodaysSales> GetOperatorPerformance(Guid estateId, DateTime comparisonDate, List<String> operatorIds, CancellationToken cancellationToken){
EstateManagementGenericContext? context = await this.ContextFactory.GetContext(estateId, ReportingManager.ConnectionStringIdentifier, cancellationToken);

// First we need to get a value of todays sales
var todaysSalesQuery = (from t in context.Transactions
where t.IsAuthorised && t.TransactionType == "Sale"
&& t.TransactionDate == DateTime.Now.Date
&& t.TransactionTime <= DateTime.Now.TimeOfDay
select t);

var comparisonSalesQuery = (from t in context.Transactions
where t.IsAuthorised && t.TransactionType == "Sale"
&& t.TransactionDate == comparisonDate
&& t.TransactionTime <= DateTime.Now.TimeOfDay
select t);


if (operatorIds.Any())
{
todaysSalesQuery = todaysSalesQuery.Where(t => operatorIds.Contains(t.OperatorIdentifier));
comparisonSalesQuery = comparisonSalesQuery.Where(t => operatorIds.Contains(t.OperatorIdentifier));
}

TodaysSales response = new TodaysSales
{
ComparisonSalesCount = comparisonSalesQuery.Count(),
ComparisonSalesValue = comparisonSalesQuery.Sum(t => t.TransactionAmount),
ComparisonAverageSalesValue = comparisonSalesQuery.Sum(t => t.TransactionAmount) / comparisonSalesQuery.Count(),
TodaysSalesCount = todaysSalesQuery.Count(),
TodaysSalesValue = todaysSalesQuery.Sum(t => t.TransactionAmount),
TodaysAverageSalesValue = todaysSalesQuery.Sum(t => t.TransactionAmount) / todaysSalesQuery.Count()
};
return response;
}

public async Task<List<Merchant>> GetMerchants(Guid estateId, CancellationToken cancellationToken){
EstateManagementGenericContext? context = await this.ContextFactory.GetContext(estateId, ReportingManager.ConnectionStringIdentifier, cancellationToken);

Expand Down
34 changes: 34 additions & 0 deletions EstateReportingAPI.Client/EstateReportingApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,40 @@ public async Task<TodaysSales> GetProductPerformance(String accessToken, Guid es
return response;
}

public async Task<TodaysSales> GetOperatorPerformance(String accessToken, Guid estateId, DateTime comparisonDate, List<String> operatorIds, CancellationToken cancellationToken){
// Serialize the integer array into a comma-separated string
string serializedArray = string.Join(",", operatorIds);

TodaysSales response = null;

String requestUri = this.BuildRequestUrl($"/api/facts/transactions/operators/performance?comparisonDate={comparisonDate.Date:yyyy-MM-dd}&operatorIds={serializedArray}");

try
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUri);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
request.Headers.Add("EstateId", estateId.ToString());

// Make the Http Call here
HttpResponseMessage httpResponse = await this.HttpClient.SendAsync(request, cancellationToken);

// Process the response
String content = await this.HandleResponse(httpResponse, cancellationToken);

// call was successful so now deserialise the body to the response object
response = JsonConvert.DeserializeObject<TodaysSales>(content);
}
catch (Exception ex)
{
// An exception has occurred, add some additional information to the message
Exception exception = new Exception($"Error getting operator performance for estate {estateId}.", ex);

throw exception;
}

return response;
}

public async Task<MerchantKpi> GetMerchantKpi(String accessToken, Guid estateId, CancellationToken cancellationToken){
MerchantKpi response = null;

Expand Down
2 changes: 2 additions & 0 deletions EstateReportingAPI.Client/IEstateReportingApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public interface IEstateReportingApiClient{
Task<TodaysSales> GetMerchantPerformance(String accessToken, Guid estateId, DateTime comparisonDate, List<Int32> merchantIds,CancellationToken cancellationToken);

Task<TodaysSales> GetProductPerformance(String accessToken, Guid estateId, DateTime comparisonDate, List<Int32> productIds, CancellationToken cancellationToken);

Task<TodaysSales> GetOperatorPerformance(String accessToken, Guid estateId, DateTime comparisonDate, List<String> operatorIds, CancellationToken cancellationToken);
#endregion
}
}
149 changes: 149 additions & 0 deletions EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -886,5 +886,154 @@ public async Task FactTransactionsControllerController_ProductPerformance_Multip
todaysSales.ComparisonSalesValue.ShouldBe(comparisonDateTransactions.Where(c => productFilterList.Contains(c.ContractProductReportingId)).Sum(c => c.TransactionAmount));
}

[Fact]
public async Task FactTransactionsControllerController_OperatorPerformance_AllOperators_SalesReturned()
{
EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}"));
var todaysTransactions = new List<Transaction>();
var comparisonDateTransactions = new List<Transaction>();
DatabaseHelper helper = new DatabaseHelper(context);
// TODO: make counts dynamic
DateTime todaysDateTime = DateTime.Now;
DateTime comparisonDate = DateTime.Now.AddDays(-1).AddHours(-1);

List<String> operatorIds = new List<String>{
"Operator1",
"Operator2",
"Operator3"
};

foreach (String operatorId in operatorIds)
{

for (int i = 0; i < 25; i++)
{
Decimal amount = 100 + i;
Transaction transaction = await helper.AddTransaction(todaysDateTime.AddHours(-1), 1, operatorId,1, "0000", amount);
todaysTransactions.Add(transaction);
}

for (int i = 0; i < 21; i++)
{
Decimal amount = 100 + i;
Transaction transaction = await helper.AddTransaction(comparisonDate, 1, operatorId, 1, "0000", amount);
comparisonDateTransactions.Add(transaction);
}
}

HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage($"api/facts/transactions/operators/performance?comparisonDate={comparisonDate.ToString("yyyy-MM-dd")}");

response.IsSuccessStatusCode.ShouldBeTrue();
String content = await response.Content.ReadAsStringAsync(CancellationToken.None);
TodaysSales? todaysSales = JsonConvert.DeserializeObject<TodaysSales>(content);
todaysSales.ComparisonSalesCount.ShouldBe(comparisonDateTransactions.Count);
todaysSales.ComparisonSalesValue.ShouldBe(comparisonDateTransactions.Sum(c => c.TransactionAmount));

todaysSales.TodaysSalesCount.ShouldBe(todaysTransactions.Count);
todaysSales.ComparisonSalesValue.ShouldBe(comparisonDateTransactions.Sum(c => c.TransactionAmount));
}

[Fact]
public async Task FactTransactionsControllerController_OperatorPerformance_SingleOperator_SalesReturned()
{
EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}"));
var todaysTransactions = new List<Transaction>();
var comparisonDateTransactions = new List<Transaction>();
DatabaseHelper helper = new DatabaseHelper(context);
// TODO: make counts dynamic
DateTime todaysDateTime = DateTime.Now;
DateTime comparisonDate = DateTime.Now.AddDays(-1).AddHours(-1);

List<String> operatorIds = new List<String>{
"Operator1",
"Operator2",
"Operator3"
};

foreach (String operatorId in operatorIds)
{

for (int i = 0; i < 25; i++)
{
Decimal amount = 100 + i;
Transaction transaction = await helper.AddTransaction(todaysDateTime.AddHours(-1), 1, operatorId, 1, "0000", amount);
todaysTransactions.Add(transaction);
}

for (int i = 0; i < 21; i++)
{
Decimal amount = 100 + i;
Transaction transaction = await helper.AddTransaction(comparisonDate, 1, operatorId, 1, "0000", amount);
comparisonDateTransactions.Add(transaction);
}
}
List<String> operatorFilterList = new List<String>{
"Operator2"
};
string serializedArray = string.Join(",", operatorFilterList);

HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage($"api/facts/transactions/operators/performance?comparisonDate={comparisonDate.ToString("yyyy-MM-dd")}&operatorIds={serializedArray}");

response.IsSuccessStatusCode.ShouldBeTrue();
String content = await response.Content.ReadAsStringAsync(CancellationToken.None);
TodaysSales? todaysSales = JsonConvert.DeserializeObject<TodaysSales>(content);
todaysSales.ComparisonSalesCount.ShouldBe(comparisonDateTransactions.Count(c => operatorFilterList.Contains(c.OperatorIdentifier)));
todaysSales.ComparisonSalesValue.ShouldBe(comparisonDateTransactions.Where(c => operatorFilterList.Contains(c.OperatorIdentifier)).Sum(c => c.TransactionAmount));

todaysSales.TodaysSalesCount.ShouldBe(todaysTransactions.Count(c => operatorFilterList.Contains(c.OperatorIdentifier)));
todaysSales.ComparisonSalesValue.ShouldBe(comparisonDateTransactions.Where(c => operatorFilterList.Contains(c.OperatorIdentifier)).Sum(c => c.TransactionAmount));
}

[Fact]
public async Task FactTransactionsControllerController_OperatorPerformance_MultipleOperators_SalesReturned()
{
EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}"));
var todaysTransactions = new List<Transaction>();
var comparisonDateTransactions = new List<Transaction>();
DatabaseHelper helper = new DatabaseHelper(context);
// TODO: make counts dynamic
DateTime todaysDateTime = DateTime.Now;
DateTime comparisonDate = DateTime.Now.AddDays(-1).AddHours(-1);

List<String> operatorIds = new List<String>{
"Operator1",
"Operator2",
"Operator3"
};

foreach (String operatorId in operatorIds)
{

for (int i = 0; i < 25; i++)
{
Decimal amount = 100 + i;
Transaction transaction = await helper.AddTransaction(todaysDateTime.AddHours(-1), 1, operatorId, 1, "0000", amount);
todaysTransactions.Add(transaction);
}

for (int i = 0; i < 21; i++)
{
Decimal amount = 100 + i;
Transaction transaction = await helper.AddTransaction(comparisonDate, 1, operatorId, 1, "0000", amount);
comparisonDateTransactions.Add(transaction);
}
}
List<String> operatorFilterList = new List<String>{
"Operator2",
"Operator3"
};
string serializedArray = string.Join(",", operatorFilterList);

HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage($"api/facts/transactions/operators/performance?comparisonDate={comparisonDate.ToString("yyyy-MM-dd")}&operatorIds={serializedArray}");

response.IsSuccessStatusCode.ShouldBeTrue();
String content = await response.Content.ReadAsStringAsync(CancellationToken.None);
TodaysSales? todaysSales = JsonConvert.DeserializeObject<TodaysSales>(content);
todaysSales.ComparisonSalesCount.ShouldBe(comparisonDateTransactions.Count(c => operatorFilterList.Contains(c.OperatorIdentifier)));
todaysSales.ComparisonSalesValue.ShouldBe(comparisonDateTransactions.Where(c => operatorFilterList.Contains(c.OperatorIdentifier)).Sum(c => c.TransactionAmount));

todaysSales.TodaysSalesCount.ShouldBe(todaysTransactions.Count(c => operatorFilterList.Contains(c.OperatorIdentifier)));
todaysSales.ComparisonSalesValue.ShouldBe(comparisonDateTransactions.Where(c => operatorFilterList.Contains(c.OperatorIdentifier)).Sum(c => c.TransactionAmount));
}

}
27 changes: 27 additions & 0 deletions EstateReportingAPI/Controllers/FactTransactionsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,33 @@ public async Task<IActionResult> GetProductPerformance([FromHeader] Guid estateI

return this.Ok(response);
}

[HttpGet]
[Route("operators/performance")]
public async Task<IActionResult> GetOperatorPerformance([FromHeader] Guid estateId, [FromQuery] DateTime comparisonDate, [FromQuery] string? operatorIds, CancellationToken cancellationToken)
{

List<String> operatorIdFilter = new List<String>();
if (String.IsNullOrEmpty(operatorIds) == false)
{
operatorIdFilter = operatorIds.Split(',').ToList();

}

Models.TodaysSales model = await this.ReportingManager.GetOperatorPerformance(estateId, comparisonDate, operatorIdFilter, cancellationToken);

TodaysSales response = new TodaysSales
{
ComparisonSalesCount = model.ComparisonSalesCount,
ComparisonSalesValue = model.ComparisonSalesValue,
TodaysSalesCount = model.TodaysSalesCount,
TodaysSalesValue = model.TodaysSalesValue,
ComparisonAverageSalesValue = model.ComparisonAverageSalesValue,
TodaysAverageSalesValue = model.TodaysAverageSalesValue,
};

return this.Ok(response);
}
}


Expand Down