From 3766e5cffad23ba4f4f1a56baf9c4a4b7ee12e0d Mon Sep 17 00:00:00 2001 From: Stuart Ferguson Date: Wed, 9 Feb 2022 14:39:55 +0000 Subject: [PATCH] Initial mobile topup flow --- .../Models/ContractProductModel.cs | 140 ++++++++++++++++++ .../Models/PerformLogonRequestModel.cs | 16 ++ .../Models/PerformMobileTopupRequestModel.cs | 31 ++++ .../RequestHandlers/LoginRequestHandler.cs | 4 +- .../RequestHandlers/MerchantRequestHandler.cs | 39 +++++ .../TransactionRequestHandler.cs | 68 +++++++++ .../Requests/GetContractProductsRequest.cs | 41 +++++ .../Requests/GetMerchantBalanceRequest.cs | 40 +++++ .../Requests/LoginRequest.cs | 25 +++- .../Requests/LogonTransactionRequest.cs | 31 ++++ .../Requests/PerformMobileTopupRequest.cs | 80 ++++++++++ .../Services/DummyMerchantService.cs | 71 +++++++++ .../Services/IMerchantService.cs | 20 +++ .../Services/ITransactionService.cs | 47 ++++++ TransactionMobile.Maui/App.xaml.cs | 22 ++- .../Extensions/MauiAppBuilderExtensions.cs | 25 +++- TransactionMobile.Maui/MauiProgram.cs | 5 + .../Pages/AppHome/HomePage.xaml | 2 +- .../Pages/AppHome/HomePage.xaml.cs | 2 + TransactionMobile.Maui/Pages/LoginPage.xaml | 2 +- .../Pages/LoginPage.xaml.cs | 6 +- .../{MyAccount.xaml => MyAccountPage.xaml} | 2 +- ...yAccount.xaml.cs => MyAccountPage.xaml.cs} | 0 .../{Reports.xaml => ReportsPage.xaml} | 0 .../{Reports.xaml.cs => ReportsPage.xaml.cs} | 0 .../MobileTopup/MobileTopupFailedPage.xaml | 27 ++++ .../MobileTopup/MobileTopupFailedPage.xaml.cs | 14 ++ .../MobileTopupPerformTopupPage.xaml | 51 +++++++ .../MobileTopupPerformTopupPage.xaml.cs | 45 ++++++ .../MobileTopupSelectOperatorPage.xaml | 13 ++ .../MobileTopupSelectOperatorPage.xaml.cs | 69 +++++++++ .../MobileTopupSelectProductPage.xaml | 13 ++ .../MobileTopupSelectProductPage.xaml.cs | 65 ++++++++ .../MobileTopup/MobileTopupSuccessPage.xaml | 31 ++++ .../MobileTopupSuccessPage.xaml.cs | 14 ++ .../Pages/Transactions/Transactions.xaml | 13 -- .../Pages/Transactions/Transactions.xaml.cs | 9 -- .../Pages/Transactions/TransactionsPage.xaml | 28 ++++ .../Transactions/TransactionsPage.xaml.cs | 19 +++ .../TransactionMobile.Maui.csproj | 45 +++++- .../UIServices/DialogService.cs | 63 ++++++++ .../ViewModels/LoginViewModel.cs | 38 +++-- .../MobileTopupFailedPageViewModel.cs | 32 ++++ .../MobileTopupPerformTopupPageViewModel.cs | 127 ++++++++++++++++ .../MobileTopupSelectOperatorPageViewModel.cs | 68 +++++++++ .../MobileTopupSelectProductPageViewModel.cs | 61 ++++++++ .../MobileTopupSuccessPageViewModel.cs | 34 +++++ .../Transactions/TransactionsPageViewModel.cs | 62 ++++++++ 48 files changed, 1607 insertions(+), 53 deletions(-) create mode 100644 TransactionMobile.Maui.BusinessLogic/Models/ContractProductModel.cs create mode 100644 TransactionMobile.Maui.BusinessLogic/Models/PerformLogonRequestModel.cs create mode 100644 TransactionMobile.Maui.BusinessLogic/Models/PerformMobileTopupRequestModel.cs create mode 100644 TransactionMobile.Maui.BusinessLogic/RequestHandlers/MerchantRequestHandler.cs create mode 100644 TransactionMobile.Maui.BusinessLogic/RequestHandlers/TransactionRequestHandler.cs create mode 100644 TransactionMobile.Maui.BusinessLogic/Requests/GetContractProductsRequest.cs create mode 100644 TransactionMobile.Maui.BusinessLogic/Requests/GetMerchantBalanceRequest.cs create mode 100644 TransactionMobile.Maui.BusinessLogic/Requests/LogonTransactionRequest.cs create mode 100644 TransactionMobile.Maui.BusinessLogic/Requests/PerformMobileTopupRequest.cs create mode 100644 TransactionMobile.Maui.BusinessLogic/Services/DummyMerchantService.cs create mode 100644 TransactionMobile.Maui.BusinessLogic/Services/IMerchantService.cs create mode 100644 TransactionMobile.Maui.BusinessLogic/Services/ITransactionService.cs rename TransactionMobile.Maui/Pages/MyAccount/{MyAccount.xaml => MyAccountPage.xaml} (94%) rename TransactionMobile.Maui/Pages/MyAccount/{MyAccount.xaml.cs => MyAccountPage.xaml.cs} (100%) rename TransactionMobile.Maui/Pages/Reports/{Reports.xaml => ReportsPage.xaml} (100%) rename TransactionMobile.Maui/Pages/Reports/{Reports.xaml.cs => ReportsPage.xaml.cs} (100%) create mode 100644 TransactionMobile.Maui/Pages/Transactions/MobileTopup/MobileTopupFailedPage.xaml create mode 100644 TransactionMobile.Maui/Pages/Transactions/MobileTopup/MobileTopupFailedPage.xaml.cs create mode 100644 TransactionMobile.Maui/Pages/Transactions/MobileTopup/MobileTopupPerformTopupPage.xaml create mode 100644 TransactionMobile.Maui/Pages/Transactions/MobileTopup/MobileTopupPerformTopupPage.xaml.cs create mode 100644 TransactionMobile.Maui/Pages/Transactions/MobileTopup/MobileTopupSelectOperatorPage.xaml create mode 100644 TransactionMobile.Maui/Pages/Transactions/MobileTopup/MobileTopupSelectOperatorPage.xaml.cs create mode 100644 TransactionMobile.Maui/Pages/Transactions/MobileTopup/MobileTopupSelectProductPage.xaml create mode 100644 TransactionMobile.Maui/Pages/Transactions/MobileTopup/MobileTopupSelectProductPage.xaml.cs create mode 100644 TransactionMobile.Maui/Pages/Transactions/MobileTopup/MobileTopupSuccessPage.xaml create mode 100644 TransactionMobile.Maui/Pages/Transactions/MobileTopup/MobileTopupSuccessPage.xaml.cs delete mode 100644 TransactionMobile.Maui/Pages/Transactions/Transactions.xaml delete mode 100644 TransactionMobile.Maui/Pages/Transactions/Transactions.xaml.cs create mode 100644 TransactionMobile.Maui/Pages/Transactions/TransactionsPage.xaml create mode 100644 TransactionMobile.Maui/Pages/Transactions/TransactionsPage.xaml.cs create mode 100644 TransactionMobile.Maui/UIServices/DialogService.cs create mode 100644 TransactionMobile.Maui/ViewModels/Transactions/MobileTopupFailedPageViewModel.cs create mode 100644 TransactionMobile.Maui/ViewModels/Transactions/MobileTopupPerformTopupPageViewModel.cs create mode 100644 TransactionMobile.Maui/ViewModels/Transactions/MobileTopupSelectOperatorPageViewModel.cs create mode 100644 TransactionMobile.Maui/ViewModels/Transactions/MobileTopupSelectProductPageViewModel.cs create mode 100644 TransactionMobile.Maui/ViewModels/Transactions/MobileTopupSuccessPageViewModel.cs create mode 100644 TransactionMobile.Maui/ViewModels/Transactions/TransactionsPageViewModel.cs diff --git a/TransactionMobile.Maui.BusinessLogic/Models/ContractProductModel.cs b/TransactionMobile.Maui.BusinessLogic/Models/ContractProductModel.cs new file mode 100644 index 00000000..9b2d5066 --- /dev/null +++ b/TransactionMobile.Maui.BusinessLogic/Models/ContractProductModel.cs @@ -0,0 +1,140 @@ +namespace TransactionMobile.Maui.BusinessLogic.Models +{ + public class ContractOperatorModel + { + #region Properties + + /// + /// Gets or sets the operator identifier. + /// + /// + /// The operator identifier. + /// + public Guid OperatorId { get; set; } + + /// + /// Gets or sets the operator identfier. + /// + /// + /// The operator identfier. + /// + public String OperatorIdentfier { get; set; } + + /// + /// Gets or sets the name of the operator. + /// + /// + /// The name of the operator. + /// + public String OperatorName { get; set; } + + #endregion + } + + public class ContractProductModel + { + #region Properties + + /// + /// Gets or sets the contract identifier. + /// + /// + /// The contract identifier. + /// + public Guid ContractId { get; set; } + + /// + /// Gets or sets a value indicating whether this instance is fixed value. + /// + /// + /// true if this instance is fixed value; otherwise, false. + /// + public Boolean IsFixedValue { get; set; } + + /// + /// Gets or sets the operator identifier. + /// + /// + /// The operator identifier. + /// + public Guid OperatorId { get; set; } + + /// + /// Gets or sets the operator identfier. + /// + /// + /// The operator identfier. + /// + public String OperatorIdentfier { get; set; } + + /// + /// Gets or sets the name of the operator. + /// + /// + /// The name of the operator. + /// + public String OperatorName { get; set; } + + /// + /// Gets or sets the product display text. + /// + /// + /// The product display text. + /// + public String ProductDisplayText { get; set; } + + /// + /// Gets or sets the product identifier. + /// + /// + /// The product identifier. + /// + public Guid ProductId { get; set; } + + /// + /// Gets or sets the type of the product. + /// + /// + /// The type of the product. + /// + public ProductType ProductType { get; set; } + + /// + /// Gets or sets the value. + /// + /// + /// The value. + /// + public Decimal Value { get; set; } + + #endregion + } + + public enum ProductType + { + /// + /// The not set + /// + NotSet = 0, + + /// + /// The mobile topup + /// + MobileTopup, + + /// + /// The mobile wallet + /// + MobileWallet, + + /// + /// The bill payment + /// + BillPayment, + + /// + /// The voucher + /// + Voucher + } +} \ No newline at end of file diff --git a/TransactionMobile.Maui.BusinessLogic/Models/PerformLogonRequestModel.cs b/TransactionMobile.Maui.BusinessLogic/Models/PerformLogonRequestModel.cs new file mode 100644 index 00000000..810d30c3 --- /dev/null +++ b/TransactionMobile.Maui.BusinessLogic/Models/PerformLogonRequestModel.cs @@ -0,0 +1,16 @@ +namespace TransactionMobile.Maui.BusinessLogic.Models; + +public class PerformLogonRequestModel +{ + #region Properties + + public String ApplicationVersion { get; set; } + + public String DeviceIdentifier { get; set; } + + public DateTime TransactionDateTime { get; set; } + + public String TransactionNumber { get; set; } + + #endregion +} \ No newline at end of file diff --git a/TransactionMobile.Maui.BusinessLogic/Models/PerformMobileTopupRequestModel.cs b/TransactionMobile.Maui.BusinessLogic/Models/PerformMobileTopupRequestModel.cs new file mode 100644 index 00000000..b432ec12 --- /dev/null +++ b/TransactionMobile.Maui.BusinessLogic/Models/PerformMobileTopupRequestModel.cs @@ -0,0 +1,31 @@ +namespace TransactionMobile.Maui.BusinessLogic.Models +{ + public class PerformMobileTopupRequestModel + { + // TODO: should we have a base transaction request model ? + + #region Properties + + public String ApplicationVersion { get; set; } + + public Guid ContractId { get; set; } + + public String CustomerAccountNumber { get; set; } + + public String CustomerEmailAddress { get; set; } + + public String DeviceIdentifier { get; set; } + + public String OperatorIdentifier { get; set; } + + public Guid ProductId { get; set; } + + public Decimal TopupAmount { get; set; } + + public DateTime TransactionDateTime { get; set; } + + public String TransactionNumber { get; set; } + + #endregion + } +} \ No newline at end of file diff --git a/TransactionMobile.Maui.BusinessLogic/RequestHandlers/LoginRequestHandler.cs b/TransactionMobile.Maui.BusinessLogic/RequestHandlers/LoginRequestHandler.cs index 49510bb2..6cf8f59c 100644 --- a/TransactionMobile.Maui.BusinessLogic/RequestHandlers/LoginRequestHandler.cs +++ b/TransactionMobile.Maui.BusinessLogic/RequestHandlers/LoginRequestHandler.cs @@ -7,9 +7,9 @@ public class LoginRequestHandler : IRequestHandler { #region Constructors - public LoginRequestHandler(IAuthenticationService authenticationService) { + this.AuthenticationService = authenticationService; } @@ -32,5 +32,7 @@ public async Task Handle(LoginRequest request, } #endregion + + } } \ No newline at end of file diff --git a/TransactionMobile.Maui.BusinessLogic/RequestHandlers/MerchantRequestHandler.cs b/TransactionMobile.Maui.BusinessLogic/RequestHandlers/MerchantRequestHandler.cs new file mode 100644 index 00000000..d6a0595f --- /dev/null +++ b/TransactionMobile.Maui.BusinessLogic/RequestHandlers/MerchantRequestHandler.cs @@ -0,0 +1,39 @@ +namespace TransactionMobile.Maui.BusinessLogic.RequestHandlers; + +using MediatR; +using Models; +using Requests; +using Services; + +public class MerchantRequestHandler : IRequestHandler>, IRequestHandler +{ + #region Fields + + private readonly IMerchantService MerchantService; + + #endregion + + #region Constructors + public MerchantRequestHandler(IMerchantService merchantService) + { + this.MerchantService = merchantService; + } + + #endregion + + #region Methods + + public async Task> Handle(GetContractProductsRequest request, + CancellationToken cancellationToken) + { + return await this.MerchantService.GetContractProducts(request.AccessToken, request.EstateId, request.MerchantId, cancellationToken); + } + + public async Task Handle(GetMerchantBalanceRequest request, + CancellationToken cancellationToken) + { + return await this.MerchantService.GetMerchantBalance(request.AccessToken, request.EstateId, request.MerchantId, cancellationToken); + } + + #endregion +} \ No newline at end of file diff --git a/TransactionMobile.Maui.BusinessLogic/RequestHandlers/TransactionRequestHandler.cs b/TransactionMobile.Maui.BusinessLogic/RequestHandlers/TransactionRequestHandler.cs new file mode 100644 index 00000000..92e167e3 --- /dev/null +++ b/TransactionMobile.Maui.BusinessLogic/RequestHandlers/TransactionRequestHandler.cs @@ -0,0 +1,68 @@ +namespace TransactionMobile.Maui.BusinessLogic.RequestHandlers; + +using MediatR; +using Models; +using Requests; +using Services; + +public class TransactionRequestHandler : IRequestHandler, IRequestHandler +{ + #region Fields + + private readonly ITransactionService TransactionService; + + #endregion + + #region Constructors + + public TransactionRequestHandler(ITransactionService transactionService) + { + this.TransactionService = transactionService; + } + + #endregion + + #region Methods + + public async Task Handle(PerformMobileTopupRequest request, + CancellationToken cancellationToken) + { + // TODO: Factory + PerformMobileTopupRequestModel model = new PerformMobileTopupRequestModel + { + ApplicationVersion = request.ApplicationVersion, + ContractId = request.ContractId, + CustomerAccountNumber = request.CustomerAccountNumber, + CustomerEmailAddress = request.CustomerEmailAddress, + DeviceIdentifier = request.DeviceIdentifier, + OperatorIdentifier = request.OperatorIdentifier, + ProductId = request.ProductId, + TopupAmount = request.TopupAmount, + TransactionDateTime = request.TransactionDateTime, + TransactionNumber = request.TransactionNumber + }; + + Boolean result = await this.TransactionService.PerformMobileTopup(model, cancellationToken); + + return result; + } + + public async Task Handle(LogonTransactionRequest request, + CancellationToken cancellationToken) + { + // TODO: Factory + PerformLogonRequestModel model = new PerformLogonRequestModel + { + ApplicationVersion = request.ApplicationVersion, + DeviceIdentifier = request.DeviceIdentifier, + TransactionDateTime = request.TransactionDateTime, + TransactionNumber = request.TransactionNumber + }; + + Boolean result = await this.TransactionService.PerformLogon(model, cancellationToken); + + return result; + } + + #endregion +} \ No newline at end of file diff --git a/TransactionMobile.Maui.BusinessLogic/Requests/GetContractProductsRequest.cs b/TransactionMobile.Maui.BusinessLogic/Requests/GetContractProductsRequest.cs new file mode 100644 index 00000000..40b8e43d --- /dev/null +++ b/TransactionMobile.Maui.BusinessLogic/Requests/GetContractProductsRequest.cs @@ -0,0 +1,41 @@ +namespace TransactionMobile.Maui.BusinessLogic.Requests; + +using MediatR; +using Models; + +public class GetContractProductsRequest : IRequest> +{ + #region Constructors + + private GetContractProductsRequest(String accessToken, + Guid estateId, + Guid merchantId) + { + this.AccessToken = accessToken; + this.EstateId = estateId; + this.MerchantId = merchantId; + } + + #endregion + + #region Properties + + public String AccessToken { get; } + + public Guid EstateId { get; } + + public Guid MerchantId { get; } + + #endregion + + #region Methods + + public static GetContractProductsRequest Create(String accessToken, + Guid estateId, + Guid merchantId) + { + return new GetContractProductsRequest(accessToken, estateId, merchantId); + } + + #endregion +} \ No newline at end of file diff --git a/TransactionMobile.Maui.BusinessLogic/Requests/GetMerchantBalanceRequest.cs b/TransactionMobile.Maui.BusinessLogic/Requests/GetMerchantBalanceRequest.cs new file mode 100644 index 00000000..8d6470c7 --- /dev/null +++ b/TransactionMobile.Maui.BusinessLogic/Requests/GetMerchantBalanceRequest.cs @@ -0,0 +1,40 @@ +namespace TransactionMobile.Maui.BusinessLogic.Requests; + +using MediatR; + +public class GetMerchantBalanceRequest : IRequest +{ + #region Constructors + + private GetMerchantBalanceRequest(String accessToken, + Guid estateId, + Guid merchantId) + { + this.AccessToken = accessToken; + this.EstateId = estateId; + this.MerchantId = merchantId; + } + + #endregion + + #region Properties + + public String AccessToken { get; } + + public Guid EstateId { get; } + + public Guid MerchantId { get; } + + #endregion + + #region Methods + + public static GetMerchantBalanceRequest Create(String accessToken, + Guid estateId, + Guid merchantId) + { + return new GetMerchantBalanceRequest(accessToken, estateId, merchantId); + } + + #endregion +} \ No newline at end of file diff --git a/TransactionMobile.Maui.BusinessLogic/Requests/LoginRequest.cs b/TransactionMobile.Maui.BusinessLogic/Requests/LoginRequest.cs index 9eea359d..1e8a99b1 100644 --- a/TransactionMobile.Maui.BusinessLogic/Requests/LoginRequest.cs +++ b/TransactionMobile.Maui.BusinessLogic/Requests/LoginRequest.cs @@ -4,11 +4,32 @@ public class LoginRequest : IRequest { + #region Constructors + + private LoginRequest(String username, + String password) + { + this.UserName = username; + this.Password = password; + } + + #endregion + #region Properties - public String Password { get; set; } + public String Password { get; } + + public String UserName { get; } + + #endregion + + #region Methods - public String UserName { get; set; } + public static LoginRequest Create(String username, + String password) + { + return new LoginRequest(username, password); + } #endregion } diff --git a/TransactionMobile.Maui.BusinessLogic/Requests/LogonTransactionRequest.cs b/TransactionMobile.Maui.BusinessLogic/Requests/LogonTransactionRequest.cs new file mode 100644 index 00000000..963c015b --- /dev/null +++ b/TransactionMobile.Maui.BusinessLogic/Requests/LogonTransactionRequest.cs @@ -0,0 +1,31 @@ +namespace TransactionMobile.Maui.BusinessLogic.Requests; + +using MediatR; + +public class LogonTransactionRequest : IRequest +{ + public String DeviceIdentifier { get; private set; } + public DateTime TransactionDateTime { get; private set; } + public String TransactionNumber { get; private set; } + public String ApplicationVersion { get; private set; } + + private LogonTransactionRequest(DateTime transactionDateTime, + String transactionNumber, + String deviceIdentifier, + String applicationVersion) + { + this.ApplicationVersion=applicationVersion; + this.DeviceIdentifier=deviceIdentifier; + this.TransactionDateTime=transactionDateTime; + this.TransactionNumber=transactionNumber; + } + + public static LogonTransactionRequest Create(DateTime transactionDateTime, + String transactionNumber, + String deviceIdentifier, + String applicationVersion) + { + return new LogonTransactionRequest(transactionDateTime, transactionNumber, deviceIdentifier, applicationVersion); + } + +} \ No newline at end of file diff --git a/TransactionMobile.Maui.BusinessLogic/Requests/PerformMobileTopupRequest.cs b/TransactionMobile.Maui.BusinessLogic/Requests/PerformMobileTopupRequest.cs new file mode 100644 index 00000000..63f1c6fe --- /dev/null +++ b/TransactionMobile.Maui.BusinessLogic/Requests/PerformMobileTopupRequest.cs @@ -0,0 +1,80 @@ +namespace TransactionMobile.Maui.BusinessLogic.Requests; + +using MediatR; + +public class PerformMobileTopupRequest : IRequest +{ + #region Constructors + + private PerformMobileTopupRequest(DateTime transactionDateTime, + String transactionNumber, + String deviceIdentifier, + String applicationVersion, + Guid contractId, + Guid productId, + String operatorIdentifier, + String customerAccountNumber, + Decimal topupAmount, + String customerEmailAddress) + { + this.ApplicationVersion = applicationVersion; + this.DeviceIdentifier = deviceIdentifier; + this.TransactionDateTime = transactionDateTime; + this.TransactionNumber = transactionNumber; + this.ContractId = contractId; + this.ProductId = productId; + this.OperatorIdentifier = operatorIdentifier; + this.CustomerAccountNumber = customerAccountNumber; + this.TopupAmount = topupAmount; + this.CustomerEmailAddress = customerEmailAddress; + } + + #endregion + + public static PerformMobileTopupRequest Create(DateTime transactionDateTime, + String transactionNumber, + String deviceIdentifier, + String applicationVersion, + Guid contractId, + Guid productId, + String operatorIdentifier, + String customerAccountNumber, + Decimal topupAmount, + String customerEmailAddress) + { + return new PerformMobileTopupRequest(transactionDateTime, + transactionNumber, + deviceIdentifier, + applicationVersion, + contractId, + productId, + operatorIdentifier, + customerAccountNumber, + topupAmount, + customerEmailAddress); + } + + #region Properties + + public String ApplicationVersion { get; } + + public Guid ContractId { get; } + + public String CustomerAccountNumber { get; } + + public String CustomerEmailAddress { get; } + + public String DeviceIdentifier { get; } + + public String OperatorIdentifier { get; } + + public Guid ProductId { get; } + + public Decimal TopupAmount { get; } + + public DateTime TransactionDateTime { get; } + + public String TransactionNumber { get; } + + #endregion +} \ No newline at end of file diff --git a/TransactionMobile.Maui.BusinessLogic/Services/DummyMerchantService.cs b/TransactionMobile.Maui.BusinessLogic/Services/DummyMerchantService.cs new file mode 100644 index 00000000..768de82c --- /dev/null +++ b/TransactionMobile.Maui.BusinessLogic/Services/DummyMerchantService.cs @@ -0,0 +1,71 @@ +namespace TransactionMobile.Maui.BusinessLogic.Services; + +using Models; + +public class DummyMerchantService : IMerchantService +{ + public async Task> GetContractProducts(String accessToken, + Guid estateId, + Guid merchantId, + CancellationToken cancellationToken) + { + return new List + { + new ContractProductModel + { + ContractId = Guid.Parse("D57DAC9B-4039-4120-B5A8-F7FDF1D3A3C2"), + IsFixedValue = true, + OperatorId = Guid.Parse("2CA5F4C7-34EC-425B-BB53-7EEDF48D9967"), + OperatorIdentfier = "Safaricom", + OperatorName = "Safaricom", + ProductDisplayText = "100 KES", + ProductId = Guid.Parse("48D96AE5-A829-498B-8C0D-D7107610EBDC"), + ProductType = ProductType.MobileTopup, + Value = 100 + }, + new ContractProductModel + { + ContractId = Guid.Parse("D57DAC9B-4039-4120-B5A8-F7FDF1D3A3C2"), + IsFixedValue = true, + OperatorId = Guid.Parse("2CA5F4C7-34EC-425B-BB53-7EEDF48D9967"), + OperatorIdentfier = "Safaricom", + OperatorName = "Safaricom", + ProductDisplayText = "200 KES", + ProductId = Guid.Parse("63821A48-D35E-451D-9E88-C8DCB548E7ED"), + ProductType = ProductType.MobileTopup, + Value = 200 + }, + new ContractProductModel + { + ContractId = Guid.Parse("D57DAC9B-4039-4120-B5A8-F7FDF1D3A3C2"), + IsFixedValue = false, + OperatorId = Guid.Parse("2CA5F4C7-34EC-425B-BB53-7EEDF48D9967"), + OperatorIdentfier = "Safaricom", + OperatorName = "Safaricom", + ProductDisplayText = "Custom", + ProductId = Guid.Parse("63821A48-D35E-451D-9E88-C8DCB548E7ED"), + ProductType = ProductType.MobileTopup + } + , + new ContractProductModel + { + ContractId = Guid.Parse("D57DAC9B-4039-4120-B5A8-F7FDF1D3A3C2"), + IsFixedValue = false, + OperatorId = Guid.Parse("1CA5F4C7-34EC-425B-BB53-7EEDF48D9968"), + OperatorIdentfier = "Safaricom1", + OperatorName = "Safaricom1", + ProductDisplayText = "Custom", + ProductId = Guid.Parse("63821A48-D35E-451D-9E88-C8DCB548E7ED"), + ProductType = ProductType.MobileTopup + } + }; + } + + public async Task GetMerchantBalance(String accessToken, + Guid estateId, + Guid merchantId, + CancellationToken cancellationToken) + { + return 100; + } +} \ No newline at end of file diff --git a/TransactionMobile.Maui.BusinessLogic/Services/IMerchantService.cs b/TransactionMobile.Maui.BusinessLogic/Services/IMerchantService.cs new file mode 100644 index 00000000..fbd1614b --- /dev/null +++ b/TransactionMobile.Maui.BusinessLogic/Services/IMerchantService.cs @@ -0,0 +1,20 @@ +namespace TransactionMobile.Maui.BusinessLogic.Services; + +using Models; + +public interface IMerchantService +{ + #region Methods + + Task> GetContractProducts(String accessToken, + Guid estateId, + Guid merchantId, + CancellationToken cancellationToken); + + Task GetMerchantBalance(String accessToken, + Guid estateId, + Guid merchantId, + CancellationToken cancellationToken); + + #endregion +} \ No newline at end of file diff --git a/TransactionMobile.Maui.BusinessLogic/Services/ITransactionService.cs b/TransactionMobile.Maui.BusinessLogic/Services/ITransactionService.cs new file mode 100644 index 00000000..07b53665 --- /dev/null +++ b/TransactionMobile.Maui.BusinessLogic/Services/ITransactionService.cs @@ -0,0 +1,47 @@ +namespace TransactionMobile.Maui.BusinessLogic.Services +{ + using Models; + + public interface ITransactionService + { + #region Methods + + Task PerformLogon(PerformLogonRequestModel model, CancellationToken cancellationToken); + + Task PerformMobileTopup(PerformMobileTopupRequestModel model, CancellationToken cancellationToken); + + Task PerformReconciliation(CancellationToken cancellationToken); + + Task PerformVoucherIssue(CancellationToken cancellationToken); + + #endregion + } + + public class DummyTransactionService : ITransactionService + { + public async Task PerformLogon(PerformLogonRequestModel model, CancellationToken cancellationToken) + { + return true; + } + + public async Task PerformMobileTopup(PerformMobileTopupRequestModel model, CancellationToken cancellationToken) + { + if (model.TopupAmount == 100) + { + return false; + } + + return true; + } + + public async Task PerformReconciliation(CancellationToken cancellationToken) + { + return true; + } + + public async Task PerformVoucherIssue(CancellationToken cancellationToken) + { + return true; + } + } +} \ No newline at end of file diff --git a/TransactionMobile.Maui/App.xaml.cs b/TransactionMobile.Maui/App.xaml.cs index 4ca6041b..3ff57d98 100644 --- a/TransactionMobile.Maui/App.xaml.cs +++ b/TransactionMobile.Maui/App.xaml.cs @@ -3,12 +3,30 @@ namespace TransactionMobile.Maui; +using Pages.AppHome; + public partial class App : Application { + /// + /// The estate identifier + /// + public static Guid EstateId; + + /// + /// The merchant identifier + /// + public static Guid MerchantId; + public App() { InitializeComponent(); - MainPage = new AppShell(); - } + MainPage = new AppShell(); + + Routing.RegisterRoute(nameof(MobileTopupSelectOperatorPage), typeof(MobileTopupSelectOperatorPage)); + Routing.RegisterRoute(nameof(MobileTopupSelectProductPage), typeof(MobileTopupSelectProductPage)); + Routing.RegisterRoute(nameof(MobileTopupPerformTopupPage), typeof(MobileTopupPerformTopupPage)); + Routing.RegisterRoute(nameof(MobileTopupSuccessPage), typeof(MobileTopupSuccessPage)); + Routing.RegisterRoute(nameof(MobileTopupFailedPage), typeof(MobileTopupFailedPage)); + } } diff --git a/TransactionMobile.Maui/Extensions/MauiAppBuilderExtensions.cs b/TransactionMobile.Maui/Extensions/MauiAppBuilderExtensions.cs index d3d70934..dcce8b61 100644 --- a/TransactionMobile.Maui/Extensions/MauiAppBuilderExtensions.cs +++ b/TransactionMobile.Maui/Extensions/MauiAppBuilderExtensions.cs @@ -1,10 +1,13 @@ namespace TransactionMobile.Maui.Extensions { + using BusinessLogic.Models; using BusinessLogic.RequestHandlers; using BusinessLogic.Requests; using BusinessLogic.Services; using MediatR; + using UIServices; using ViewModels; + using ViewModels.Transactions; public static class MauiAppBuilderExtensions { @@ -13,14 +16,27 @@ public static class MauiAppBuilderExtensions public static MauiAppBuilder ConfigureAppServices(this MauiAppBuilder builder) { builder.Services.AddSingleton(); + builder.Services.AddSingleton(); + builder.Services.AddSingleton(); return builder; } + //public static MauiAppBuilder ConfigureUIServices(this MauiAppBuilder builder) + //{ + // builder.Services.AddSingleton(); + + // return builder; + //} + public static MauiAppBuilder ConfigureRequestHandlers(this MauiAppBuilder builder) { builder.Services.AddSingleton(); builder.Services.AddSingleton, LoginRequestHandler>(); + builder.Services.AddSingleton>, MerchantRequestHandler>(); + builder.Services.AddSingleton, MerchantRequestHandler>(); + builder.Services.AddSingleton, TransactionRequestHandler>(); + builder.Services.AddSingleton, TransactionRequestHandler>(); builder.Services.AddSingleton(ctx => { return t => ctx.GetService(t); }); return builder; @@ -28,7 +44,14 @@ public static MauiAppBuilder ConfigureRequestHandlers(this MauiAppBuilder builde public static MauiAppBuilder ConfigureViewModels(this MauiAppBuilder builder) { - builder.Services.AddTransient(); + builder.Services.AddTransient(); + builder.Services.AddTransient(); + builder.Services.AddTransient(); + builder.Services.AddTransient(); + builder.Services.AddTransient(); + builder.Services.AddTransient(); + builder.Services.AddTransient(); + return builder; } diff --git a/TransactionMobile.Maui/MauiProgram.cs b/TransactionMobile.Maui/MauiProgram.cs index eb22bf54..c299b00a 100644 --- a/TransactionMobile.Maui/MauiProgram.cs +++ b/TransactionMobile.Maui/MauiProgram.cs @@ -2,6 +2,8 @@ namespace TransactionMobile.Maui; +using CommunityToolkit.Maui; + public static class MauiProgram { public static MauiApp Container; @@ -12,6 +14,9 @@ public static MauiApp CreateMauiApp() .UseMauiApp() .ConfigureRequestHandlers() .ConfigureViewModels() + .ConfigureAppServices() + //.ConfigureUIServices() + .UseMauiCommunityToolkit() .ConfigureFonts(fonts => { fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); diff --git a/TransactionMobile.Maui/Pages/AppHome/HomePage.xaml b/TransactionMobile.Maui/Pages/AppHome/HomePage.xaml index 78e710e3..60d4623b 100644 --- a/TransactionMobile.Maui/Pages/AppHome/HomePage.xaml +++ b/TransactionMobile.Maui/Pages/AppHome/HomePage.xaml @@ -2,7 +2,7 @@