diff --git a/EstateManagementUI.BlazorServer.Tests/Pages/Estate/EstateIndexPageTests.cs b/EstateManagementUI.BlazorServer.Tests/Pages/Estate/EstateIndexPageTests.cs index 5c152d5e..44f25ed0 100644 --- a/EstateManagementUI.BlazorServer.Tests/Pages/Estate/EstateIndexPageTests.cs +++ b/EstateManagementUI.BlazorServer.Tests/Pages/Estate/EstateIndexPageTests.cs @@ -33,7 +33,9 @@ public void EstateIndex_RendersCorrectly() .ReturnsAsync(Result.Success(new List())); _mockMediator.Setup(x => x.Send(It.IsAny(), default)) .ReturnsAsync(Result.Success(new List())); - + _mockMediator.Setup(x => x.Send(It.IsAny(), default)) + .ReturnsAsync(Result.Success(new List())); + // Act var cut = RenderComponent(); @@ -59,6 +61,8 @@ public void EstateIndex_DisplaysEstateDetails() .ReturnsAsync(Result.Success(new List())); _mockMediator.Setup(x => x.Send(It.IsAny(), default)) .ReturnsAsync(Result.Success(new List())); + _mockMediator.Setup(x => x.Send(It.IsAny(), default)) + .ReturnsAsync(Result.Success(new List())); // Act var cut = RenderComponent(); @@ -77,6 +81,8 @@ public void EstateIndex_HasCorrectPageTitle() .ReturnsAsync(Result.Success(new List())); _mockMediator.Setup(x => x.Send(It.IsAny(), default)) .ReturnsAsync(Result.Success(new List())); + _mockMediator.Setup(x => x.Send(It.IsAny(), default)) + .ReturnsAsync(Result.Success(new List())); // Act var cut = RenderComponent(); diff --git a/EstateManagementUI.BlazorServer/Components/Pages/Estate/Index.razor.cs b/EstateManagementUI.BlazorServer/Components/Pages/Estate/Index.razor.cs index 2cb040dc..1441e33d 100644 --- a/EstateManagementUI.BlazorServer/Components/Pages/Estate/Index.razor.cs +++ b/EstateManagementUI.BlazorServer/Components/Pages/Estate/Index.razor.cs @@ -60,8 +60,6 @@ private async Task LoadEstateData(CorrelationId correlationId, Guid esta if (merchantResult.IsFailed) return ResultHelpers.CreateFailure(merchantResult); - // Note: API returns merchants in creation order (newest first) - // If ordering is incorrect, would need CreatedDate field in the model this.merchants = ModelFactory.ConvertFrom(merchantResult.Data); Result> contractResult = await Mediator.Send(new Queries.GetRecentContractsQuery(correlationId, estateId)); @@ -69,10 +67,15 @@ private async Task LoadEstateData(CorrelationId correlationId, Guid esta if (contractResult.IsFailed) return ResultHelpers.CreateFailure(contractResult); - // Note: API returns merchants in creation order (newest first) - // If ordering is incorrect, would need CreatedDate field in the model this.contracts = ModelFactory.ConvertFrom(contractResult.Data); + Result> assignedOperatorsResult = await Mediator.Send(new Queries.GetAssignedOperatorsQuery(correlationId, estateId)); + + if (assignedOperatorsResult.IsFailed) + return ResultHelpers.CreateFailure(assignedOperatorsResult); + + this.assignedOperators = ModelFactory.ConvertFrom(assignedOperatorsResult.Data); + return Result.Success(); } diff --git a/EstateManagementUI.BlazorServer/Factories/ModelFactory.cs b/EstateManagementUI.BlazorServer/Factories/ModelFactory.cs index 1b594588..39f3c3b3 100644 --- a/EstateManagementUI.BlazorServer/Factories/ModelFactory.cs +++ b/EstateManagementUI.BlazorServer/Factories/ModelFactory.cs @@ -62,6 +62,13 @@ public static MerchantModel ConvertFrom(BusinessLogic.Models.MerchantModel model }; } + public static List ConvertFrom(List models) + { + List result = new List(); + models.ForEach(m => result.Add(ConvertFrom(m))); + return result; + } + public static OperatorModel ConvertFrom(BusinessLogic.Models.OperatorModel model) { return new OperatorModel() { OperatorId = model.OperatorId, Name = model.Name, RequireCustomMerchantNumber = model.RequireCustomMerchantNumber, RequireCustomTerminalNumber = model.RequireCustomTerminalNumber }; } @@ -220,11 +227,7 @@ public static ProductPerformanceModel ConvertFrom(BusinessLogic.Models.ProductPe return new ProductPerformanceModel() { PercentageContribution = model.PercentageContribution, ProductName = model.ProductName, TransactionCount = model.TransactionCount, TransactionValue = model.TransactionValue }; } - public static List ConvertFrom(List models) { - List result = new List(); - models.ForEach(m => result.Add(ConvertFrom(m))); - return result; - } + public static List ConvertFrom(List models) { List result = new List(); @@ -355,7 +358,7 @@ public static List ConvertFrom(List result.Add(ConvertFrom(m))); return result; } - + private static RecentContractModel ConvertFrom(BusinessLogic.Models.RecentContractModel model) { return new RecentContractModel { OperatorName = model.OperatorName, Description = model.Description, ContractId = model.ContractId }; } diff --git a/EstateManagmentUI.BusinessLogic/BackendAPI/IEstateReportingApiClient.cs b/EstateManagmentUI.BusinessLogic/BackendAPI/IEstateReportingApiClient.cs index ab8e117b..862aa26f 100644 --- a/EstateManagmentUI.BusinessLogic/BackendAPI/IEstateReportingApiClient.cs +++ b/EstateManagmentUI.BusinessLogic/BackendAPI/IEstateReportingApiClient.cs @@ -11,6 +11,9 @@ public interface IEstateReportingApiClient { Task> GetEstate(String accessToken, Guid estateId, CancellationToken cancellationToken); + Task>> GetEstateAssignedOperators(String accessToken, + Guid estateId, + CancellationToken cancellationToken); Task>> GetComparisonDates(String accessToken, Guid estateId, CancellationToken cancellationToken); Task> GetMerchantKpi(String accessToken, Guid estateId, CancellationToken cancellationToken); @@ -66,6 +69,34 @@ public async Task> GetEstate(String accessToken, } } + public async Task>> GetEstateAssignedOperators(String accessToken, + Guid estateId, + CancellationToken cancellationToken) + { + String requestUri = this.BuildRequestUrl("/api/estates/operators"); + + try + { + List<(String headerName, String headerValue)> additionalHeaders = [ + (EstateIdHeaderName, estateId.ToString()) + ]; + + Result> result = await this.SendHttpGetRequest>(requestUri, accessToken, additionalHeaders, cancellationToken); + + if (result.IsFailed) + return ResultHelpers.CreateFailure(result); + + return result; + } + catch (Exception ex) + { + // An exception has occurred, add some additional information to the message + Exception exception = new Exception($"Error getting estate assigned operators {estateId}.", ex); + + return Result.Failure(exception.Message); + } + } + public async Task>> GetComparisonDates(String accessToken, Guid estateId, CancellationToken cancellationToken) { diff --git a/EstateManagmentUI.BusinessLogic/Client/APIModelFactory.cs b/EstateManagmentUI.BusinessLogic/Client/APIModelFactory.cs index f4c185ec..b5de4c11 100644 --- a/EstateManagmentUI.BusinessLogic/Client/APIModelFactory.cs +++ b/EstateManagmentUI.BusinessLogic/Client/APIModelFactory.cs @@ -133,4 +133,17 @@ public static List ConvertFrom(List apiResultData return contracts; } + + public static List ConvertFrom(List apiResultData) { + List operators = new(); + foreach (EstateOperator estateOperator in apiResultData) { + operators.Add(new OperatorModel() { + Name = estateOperator.Name, + OperatorId = estateOperator.OperatorId, + RequireCustomMerchantNumber = estateOperator.RequireCustomMerchantNumber, + RequireCustomTerminalNumber = estateOperator.RequireCustomTerminalNumber + }); + } + return operators; + } } \ No newline at end of file diff --git a/EstateManagmentUI.BusinessLogic/Client/EstateMethods.cs b/EstateManagmentUI.BusinessLogic/Client/EstateMethods.cs index 8c59f228..850e7016 100644 --- a/EstateManagmentUI.BusinessLogic/Client/EstateMethods.cs +++ b/EstateManagmentUI.BusinessLogic/Client/EstateMethods.cs @@ -13,6 +13,9 @@ namespace EstateManagementUI.BusinessLogic.Client { public partial interface IApiClient { Task> GetEstate(Queries.GetEstateQuery request, CancellationToken cancellationToken); + + Task>> GetEstateAssignedOperators(Queries.GetAssignedOperatorsQuery request, + CancellationToken cancellationToken); } public partial class ApiClient : IApiClient { @@ -32,5 +35,21 @@ public async Task> GetEstate(Queries.GetEstateQuery request, return Result.Success(estate); } + + public async Task>> GetEstateAssignedOperators(Queries.GetAssignedOperatorsQuery request, + CancellationToken cancellationToken) { + // Get a token here + Result token = await this.GetToken(cancellationToken); + if (token.IsFailed) + return ResultHelpers.CreateFailure(token); + + Result>? apiResult = await this.EstateReportingApiClient.GetEstateAssignedOperators(token.Data, request.EstateId, cancellationToken); + if (apiResult.IsFailed) + return ResultHelpers.CreateFailure(apiResult); + + List estateOperators = APIModelFactory.ConvertFrom(apiResult.Data); + + return Result.Success(estateOperators); + } } } diff --git a/EstateManagmentUI.BusinessLogic/RequestHandlers/DateRequestHandler.cs b/EstateManagmentUI.BusinessLogic/RequestHandlers/DateRequestHandler.cs index 94a3abe4..80c44cfe 100644 --- a/EstateManagmentUI.BusinessLogic/RequestHandlers/DateRequestHandler.cs +++ b/EstateManagmentUI.BusinessLogic/RequestHandlers/DateRequestHandler.cs @@ -21,8 +21,8 @@ public async Task>> Handle(Queries.GetCompariso public class EstateRequestHandler : IRequestHandler>, IRequestHandler, - IRequestHandler - { + IRequestHandler, + IRequestHandler>> { private readonly IApiClient ApiClient; public EstateRequestHandler(IApiClient apiClient) { @@ -43,6 +43,11 @@ public async Task Handle(Commands.RemoveOperatorFromEstateCommand reques CancellationToken cancellationToken) { return Result.Success(); } + + public async Task>> Handle(Queries.GetAssignedOperatorsQuery request, + CancellationToken cancellationToken) { + return await this.ApiClient.GetEstateAssignedOperators(request, cancellationToken); + } } public class MerchantRequestHandler : IRequestHandler>>, diff --git a/EstateManagmentUI.BusinessLogic/Requests/Requests.cs b/EstateManagmentUI.BusinessLogic/Requests/Requests.cs index f492da67..cc2a0aad 100644 --- a/EstateManagmentUI.BusinessLogic/Requests/Requests.cs +++ b/EstateManagmentUI.BusinessLogic/Requests/Requests.cs @@ -14,6 +14,7 @@ public static class CorrelationIdHelper public static class Queries { public record GetEstateQuery(CorrelationId CorrelationId, Guid EstateId) : IRequest>; + public record GetAssignedOperatorsQuery(CorrelationId CorrelationId, Guid EstateId) : IRequest>>; public record GetMerchantsQuery(CorrelationId CorrelationId, Guid EstateId) : IRequest>>; public record GetRecentMerchantsQuery(CorrelationId CorrelationId, Guid EstateId) : IRequest>>; public record GetRecentContractsQuery(CorrelationId CorrelationId, Guid EstateId) : IRequest>>;