diff --git a/TransactionProcessor.Mobile.BusinessLogic.Tests/TestData.cs b/TransactionProcessor.Mobile.BusinessLogic.Tests/TestData.cs index cac53a499..049408256 100644 --- a/TransactionProcessor.Mobile.BusinessLogic.Tests/TestData.cs +++ b/TransactionProcessor.Mobile.BusinessLogic.Tests/TestData.cs @@ -154,6 +154,11 @@ public static class TestData TestData.Operator3Product_200KES }; + public static List ContractOperatorList = new List + { + ContractOperatorModel + }; + public static List ContractProductListEmpty = new List(); public static ContractOperatorModel ContractOperatorModel = new ContractOperatorModel diff --git a/TransactionProcessor.Mobile.BusinessLogic.Tests/ViewModelTests/Transactions/BillPayment/BillPaymentSelectOperatorPageViewModelTests.cs b/TransactionProcessor.Mobile.BusinessLogic.Tests/ViewModelTests/Transactions/BillPayment/BillPaymentSelectOperatorPageViewModelTests.cs index 3d31b7272..f569d2a94 100644 --- a/TransactionProcessor.Mobile.BusinessLogic.Tests/ViewModelTests/Transactions/BillPayment/BillPaymentSelectOperatorPageViewModelTests.cs +++ b/TransactionProcessor.Mobile.BusinessLogic.Tests/ViewModelTests/Transactions/BillPayment/BillPaymentSelectOperatorPageViewModelTests.cs @@ -47,26 +47,26 @@ public BillPaymentSelectOperatorPageViewModelTests() { [Fact] public async Task BillPaymentSelectOperatorPageViewModel_Initialise_IsInitialised() { - this.Mediator.Setup(m => m.Send(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.ContractProductList)); + this.Mediator.Setup(m => m.Send(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.ContractOperatorList)); await this.ViewModel.Initialise(CancellationToken.None); - this.Mediator.Verify(x => x.Send(It.IsAny(), It.IsAny()), Times.Once); + this.Mediator.Verify(x => x.Send(It.IsAny(), It.IsAny()), Times.Once); - this.ViewModel.Operators.Count.ShouldBe(3); + this.ViewModel.Operators.Count.ShouldBe(1); } [Fact] public async Task BillPaymentSelectOperatorPageViewModel_OperatorSelectedCommand_Execute_IsExecuted() { - this.Mediator.Setup(m => m.Send(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.ContractProductList)); + this.Mediator.Setup(m => m.Send(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.ContractOperatorList)); await this.ViewModel.Initialise(CancellationToken.None); - this.ViewModel.Operators.Count.ShouldBe(3); + this.ViewModel.Operators.Count.ShouldBe(1); ItemSelected selectedContractOperator = new ItemSelected { - SelectedItemIndex = 1, + SelectedItemIndex = 0, SelectedItem = TestData.ContractOperatorModel }; diff --git a/TransactionProcessor.Mobile.BusinessLogic.Tests/ViewModelTests/Transactions/MobileTopup/MobileTopupSelectOperatorPageViewModelTests.cs b/TransactionProcessor.Mobile.BusinessLogic.Tests/ViewModelTests/Transactions/MobileTopup/MobileTopupSelectOperatorPageViewModelTests.cs index 27a8de8e1..630faf627 100644 --- a/TransactionProcessor.Mobile.BusinessLogic.Tests/ViewModelTests/Transactions/MobileTopup/MobileTopupSelectOperatorPageViewModelTests.cs +++ b/TransactionProcessor.Mobile.BusinessLogic.Tests/ViewModelTests/Transactions/MobileTopup/MobileTopupSelectOperatorPageViewModelTests.cs @@ -46,22 +46,22 @@ public MobileTopupSelectOperatorPageViewModelTests() { [Fact] public async Task MobileTopupSelectOperatorPageViewModel_Initialise_IsInitialised() { - this.Mediator.Setup(m => m.Send(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.ContractProductList)); - + this.Mediator.Setup(m => m.Send(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.ContractOperatorList)); + await this.ViewModel.Initialise(CancellationToken.None); - this.Mediator.Verify(x => x.Send(It.IsAny(), It.IsAny()), Times.Once); + this.Mediator.Verify(x => x.Send(It.IsAny(), It.IsAny()), Times.Once); - this.ViewModel.Operators.Count.ShouldBe(3); + this.ViewModel.Operators.Count.ShouldBe(1); } [Fact] public async Task MobileTopupSelectOperatorPageViewModel_OperatorSelectedCommand_Execute_IsExecuted() { - this.Mediator.Setup(m => m.Send(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.ContractProductList)); - + this.Mediator.Setup(m => m.Send(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.ContractOperatorList)); + await this.ViewModel.Initialise(CancellationToken.None); - this.ViewModel.Operators.Count.ShouldBe(3); + this.ViewModel.Operators.Count.ShouldBe(1); ItemSelected selectedContractOperator = new ItemSelected { diff --git a/TransactionProcessor.Mobile.BusinessLogic.Tests/ViewModelTests/Transactions/Voucher/VoucherSelectOperatorPageViewModelTests.cs b/TransactionProcessor.Mobile.BusinessLogic.Tests/ViewModelTests/Transactions/Voucher/VoucherSelectOperatorPageViewModelTests.cs index 55ec48575..b87b13409 100644 --- a/TransactionProcessor.Mobile.BusinessLogic.Tests/ViewModelTests/Transactions/Voucher/VoucherSelectOperatorPageViewModelTests.cs +++ b/TransactionProcessor.Mobile.BusinessLogic.Tests/ViewModelTests/Transactions/Voucher/VoucherSelectOperatorPageViewModelTests.cs @@ -42,23 +42,22 @@ public VoucherSelectOperatorPageViewModelTests() { [Fact] public async Task VoucherSelectOperatorPageViewModel_Initialise_IsInitialised() { - this.Mediator.Setup(m => m.Send(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.ContractProductList)); - + this.Mediator.Setup(m => m.Send(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.ContractOperatorList)); await this.ViewModel.Initialise(CancellationToken.None); - this.Mediator.Verify(x => x.Send(It.IsAny(), It.IsAny()), Times.Once); + this.Mediator.Verify(x => x.Send(It.IsAny(), It.IsAny()), Times.Once); - this.ViewModel.Operators.Count.ShouldBe(3); + this.ViewModel.Operators.Count.ShouldBe(1); } [Fact] public async Task VoucherSelectOperatorPageViewModel_OperatorSelectedCommand_Execute_IsExecuted() { - this.Mediator.Setup(m => m.Send(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.ContractProductList)); - + this.Mediator.Setup(m => m.Send(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.ContractOperatorList)); + await this.ViewModel.Initialise(CancellationToken.None); - this.ViewModel.Operators.Count.ShouldBe(3); + this.ViewModel.Operators.Count.ShouldBe(1); ItemSelected selectedContractOperator = new ItemSelected { diff --git a/TransactionProcessor.Mobile.BusinessLogic/RequestHandlers/MerchantRequestHandler.cs b/TransactionProcessor.Mobile.BusinessLogic/RequestHandlers/MerchantRequestHandler.cs index 93cac5586..7ac171b24 100644 --- a/TransactionProcessor.Mobile.BusinessLogic/RequestHandlers/MerchantRequestHandler.cs +++ b/TransactionProcessor.Mobile.BusinessLogic/RequestHandlers/MerchantRequestHandler.cs @@ -1,4 +1,5 @@ using MediatR; +using Shared.Results; using SimpleResults; using TransactionProcessor.Mobile.BusinessLogic.Models; using TransactionProcessor.Mobile.BusinessLogic.Requests; @@ -8,7 +9,8 @@ namespace TransactionProcessor.Mobile.BusinessLogic.RequestHandlers; public class MerchantRequestHandler : IRequestHandler>>, IRequestHandler>, - IRequestHandler> + IRequestHandler>, + IRequestHandler>> { #region Fields @@ -74,4 +76,42 @@ public async Task> Handle(GetMerchantDetailsRequest } #endregion + + public async Task>> Handle(GetProductOperators request, + CancellationToken cancellationToken) { + List products = this.ApplicationCache.GetContractProducts(); + + Boolean useTrainingMode = this.ApplicationCache.GetUseTrainingMode(); + IMerchantService merchantService = this.MerchantServiceResolver(useTrainingMode); + + if (products == null || products.Any() == false) + { + Result> getProductsResult = await merchantService.GetContractProducts(cancellationToken); + if (getProductsResult.IsFailed) { + return ResultHelpers.CreateFailure(getProductsResult); + } + + products = getProductsResult.Data; + + if (request.ProductType.HasValue) + { + products = products.Where(p => p.ProductType == request.ProductType).ToList(); + } + } + + List operators = products.GroupBy(c => new + { + c.OperatorName, + c.OperatorId, + c.OperatorIdentfier + }).Select(g => new ContractOperatorModel + { + OperatorId = g.Key.OperatorId, + OperatorName = g.Key.OperatorName, + OperatorIdentfier = g.Key.OperatorIdentfier + }).ToList(); + + return Result.Success(operators); + + } } \ No newline at end of file diff --git a/TransactionProcessor.Mobile.BusinessLogic/Requests/GetContractProductsRequest.cs b/TransactionProcessor.Mobile.BusinessLogic/Requests/GetContractProductsRequest.cs index 6fc33a285..efaa2eab5 100644 --- a/TransactionProcessor.Mobile.BusinessLogic/Requests/GetContractProductsRequest.cs +++ b/TransactionProcessor.Mobile.BusinessLogic/Requests/GetContractProductsRequest.cs @@ -27,4 +27,6 @@ public static GetContractProductsRequest Create(ProductType? productType =null) } #endregion -} \ No newline at end of file +} + +public record GetProductOperators(ProductType? ProductType) : IRequest>>; \ No newline at end of file diff --git a/TransactionProcessor.Mobile.BusinessLogic/ViewModels/Transactions/BillPaymentSelectOperatorPageViewModel.cs b/TransactionProcessor.Mobile.BusinessLogic/ViewModels/Transactions/BillPaymentSelectOperatorPageViewModel.cs index 8a84dcb3f..c7529f586 100644 --- a/TransactionProcessor.Mobile.BusinessLogic/ViewModels/Transactions/BillPaymentSelectOperatorPageViewModel.cs +++ b/TransactionProcessor.Mobile.BusinessLogic/ViewModels/Transactions/BillPaymentSelectOperatorPageViewModel.cs @@ -45,26 +45,14 @@ public BillPaymentSelectOperatorPageViewModel(IMediator mediator, INavigationSer public async Task Initialise(CancellationToken cancellationToken) { - GetContractProductsRequest request = GetContractProductsRequest.Create(ProductType.BillPayment); - - Result> productsresult = await this.Mediator.Send(request, cancellationToken); - // TODO: Handle the failure result - List products = productsresult.Data; - - // TODO: Should this logic live in the Reqest handler ??? - List operators = products.GroupBy(c => new - { - c.OperatorName, - c.OperatorId, - c.OperatorIdentfier - }).Select(g => new ContractOperatorModel - { - OperatorId = g.Key.OperatorId, - OperatorName = g.Key.OperatorName, - OperatorIdentfier = g.Key.OperatorIdentfier - }).ToList(); - - this.Operators = operators; + GetProductOperators request = new GetProductOperators(ProductType.BillPayment); + Result> operatorsResult = await this.Mediator.Send(request, cancellationToken); + if (operatorsResult.IsFailed) + { + await this.DialogService.ShowWarningToast("Unable to load operators. Please try again later.", cancellationToken: cancellationToken); + return; + } + this.Operators = operatorsResult.Data; } [RelayCommand] diff --git a/TransactionProcessor.Mobile.BusinessLogic/ViewModels/Transactions/MobileTopupSelectOperatorPageViewModel.cs b/TransactionProcessor.Mobile.BusinessLogic/ViewModels/Transactions/MobileTopupSelectOperatorPageViewModel.cs index 83cecad5f..7681c303a 100644 --- a/TransactionProcessor.Mobile.BusinessLogic/ViewModels/Transactions/MobileTopupSelectOperatorPageViewModel.cs +++ b/TransactionProcessor.Mobile.BusinessLogic/ViewModels/Transactions/MobileTopupSelectOperatorPageViewModel.cs @@ -43,25 +43,14 @@ public MobileTopupSelectOperatorPageViewModel(IMediator mediator, INavigationSer public async Task Initialise(CancellationToken cancellationToken) { - GetContractProductsRequest request = GetContractProductsRequest.Create(ProductType.MobileTopup); - - Result> productsresult = await this.Mediator.Send(request, cancellationToken); - List products = productsresult.Data; - - // TODO: Should this logic live in the Request handler ??? - List operators = products.GroupBy(c => new - { - c.OperatorName, - c.OperatorId, - c.OperatorIdentfier - }).Select(g => new ContractOperatorModel - { - OperatorId = g.Key.OperatorId, - OperatorName = g.Key.OperatorName, - OperatorIdentfier = g.Key.OperatorIdentfier - }).ToList(); - - this.Operators = operators; + GetProductOperators request = new GetProductOperators(ProductType.MobileTopup); + Result> operatorsResult = await this.Mediator.Send(request, cancellationToken); + if (operatorsResult.IsFailed) + { + await this.DialogService.ShowWarningToast("Unable to load operators. Please try again later.", cancellationToken: cancellationToken); + return; + } + this.Operators = operatorsResult.Data; } [RelayCommand] diff --git a/TransactionProcessor.Mobile.BusinessLogic/ViewModels/Transactions/VoucherSelectOperatorPageViewModel.cs b/TransactionProcessor.Mobile.BusinessLogic/ViewModels/Transactions/VoucherSelectOperatorPageViewModel.cs index 49ed0a747..8f41eef47 100644 --- a/TransactionProcessor.Mobile.BusinessLogic/ViewModels/Transactions/VoucherSelectOperatorPageViewModel.cs +++ b/TransactionProcessor.Mobile.BusinessLogic/ViewModels/Transactions/VoucherSelectOperatorPageViewModel.cs @@ -1,7 +1,8 @@ -using System.Windows.Input; -using CommunityToolkit.Mvvm.Input; +using CommunityToolkit.Mvvm.Input; using MediatR; using MvvmHelpers.Commands; +using SimpleResults; +using System.Windows.Input; using TransactionProcessor.Mobile.BusinessLogic.Common; using TransactionProcessor.Mobile.BusinessLogic.Logging; using TransactionProcessor.Mobile.BusinessLogic.Models; @@ -43,25 +44,14 @@ public VoucherSelectOperatorPageViewModel(IMediator mediator, INavigationService public async Task Initialise(CancellationToken cancellationToken) { - GetContractProductsRequest request = GetContractProductsRequest.Create(ProductType.Voucher); - - var productsresult = await this.Mediator.Send(request, cancellationToken); - List products = productsresult.Data; - - // TODO: Should this logic live in the Reqest handler ??? - List operators = products.GroupBy(c => new - { - c.OperatorName, - c.OperatorId, - c.OperatorIdentfier - }).Select(g => new ContractOperatorModel - { - OperatorId = g.Key.OperatorId, - OperatorName = g.Key.OperatorName, - OperatorIdentfier = g.Key.OperatorIdentfier - }).ToList(); - - this.Operators = operators; + GetProductOperators request = new GetProductOperators(ProductType.Voucher); + Result> operatorsResult = await this.Mediator.Send(request, cancellationToken); + if (operatorsResult.IsFailed) + { + await this.DialogService.ShowWarningToast("Unable to load operators. Please try again later.", cancellationToken: cancellationToken); + return; + } + this.Operators = operatorsResult.Data; } [RelayCommand] diff --git a/TransactionProcessor.Mobile/Extensions/MauiAppBuilderExtensions.cs b/TransactionProcessor.Mobile/Extensions/MauiAppBuilderExtensions.cs index 19bdaa195..e3e6f94f5 100644 --- a/TransactionProcessor.Mobile/Extensions/MauiAppBuilderExtensions.cs +++ b/TransactionProcessor.Mobile/Extensions/MauiAppBuilderExtensions.cs @@ -183,29 +183,31 @@ public static MauiAppBuilder ConfigureUIServices(this MauiAppBuilder builder) { } public static MauiAppBuilder ConfigureRequestHandlers(this MauiAppBuilder builder) { - builder.Services.AddSingleton(); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(); - builder.Services.AddSingleton>, LoginRequestHandler>(); - builder.Services.AddSingleton>, LoginRequestHandler>(); - builder.Services.AddSingleton>, LoginRequestHandler>(); - - builder.Services.AddSingleton>>, MerchantRequestHandler>(); - builder.Services.AddSingleton>, MerchantRequestHandler>(); - builder.Services.AddSingleton>, MerchantRequestHandler>(); - - builder.Services.AddSingleton>, TransactionRequestHandler>(); - builder.Services.AddSingleton>, TransactionRequestHandler>(); - builder.Services.AddSingleton>, TransactionRequestHandler>(); - builder.Services.AddSingleton>, TransactionRequestHandler>(); - builder.Services.AddSingleton>, TransactionRequestHandler>(); - builder.Services.AddSingleton>, TransactionRequestHandler>(); - builder.Services.AddSingleton>, TransactionRequestHandler>(); - builder.Services.AddSingleton>, TransactionRequestHandler>(); - - builder.Services.AddSingleton, SupportRequestHandler>(); - builder.Services.AddSingleton>, SupportRequestHandler>(); + //builder.Services.AddSingleton(); + //builder.Services.AddSingleton(); + //builder.Services.AddSingleton(); + //builder.Services.AddSingleton(); + builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(typeof(LoginRequestHandler).Assembly)); + //builder.Services.AddSingleton>, LoginRequestHandler>(); + //builder.Services.AddSingleton>, LoginRequestHandler>(); + //builder.Services.AddSingleton>, LoginRequestHandler>(); + + //builder.Services.AddSingleton>>, MerchantRequestHandler>(); + //builder.Services.AddSingleton>>, MerchantRequestHandler>(); + //builder.Services.AddSingleton>, MerchantRequestHandler>(); + //builder.Services.AddSingleton>, MerchantRequestHandler>(); + + //builder.Services.AddSingleton>, TransactionRequestHandler>(); + //builder.Services.AddSingleton>, TransactionRequestHandler>(); + //builder.Services.AddSingleton>, TransactionRequestHandler>(); + //builder.Services.AddSingleton>, TransactionRequestHandler>(); + //builder.Services.AddSingleton>, TransactionRequestHandler>(); + //builder.Services.AddSingleton>, TransactionRequestHandler>(); + //builder.Services.AddSingleton>, TransactionRequestHandler>(); + //builder.Services.AddSingleton>, TransactionRequestHandler>(); + + //builder.Services.AddSingleton, SupportRequestHandler>(); + //builder.Services.AddSingleton>, SupportRequestHandler>(); return builder; }