From 74896ad48c512f92f52f8617c7401672bc2f8d49 Mon Sep 17 00:00:00 2001 From: Stuart Ferguson Date: Fri, 11 Mar 2022 08:01:06 +0000 Subject: [PATCH] Added reconciliation transaction --- .../TransactionRequestHandlerTests.cs | 38 ++++++++ .../RequestTests/RequestTests.cs | 13 +++ .../TestData.cs | 24 +++++ .../ViewModelTests/AdminPageViewModelTests.cs | 40 ++++++++ .../TransactionsPageViewModelTests.cs | 2 +- .../Models/OperatorTotalModel.cs | 9 ++ .../Models/ReconciliationRequestModel.cs | 11 +++ .../TransactionRequestHandler.cs | 95 +++++++++++++++---- .../Requests/PerformReconciliationRequest.cs | 34 +++++++ .../DummyServices/DummyTransactionService.cs | 2 +- .../Services/ITransactionService.cs | 3 +- .../UIServices/INavigationService.cs | 2 + .../ViewModels/Admin/AdminPageViewModel.cs | 67 +++++++++++++ .../Transactions/TransactionsPageViewModel.cs | 2 +- .../IDatabaseContext.cs | 6 ++ TransactionMobile.Maui/App.xaml.cs | 7 +- .../Extensions/MauiAppBuilderExtensions.cs | 6 +- .../Pages/Transactions/Admin/AdminPage.xaml | 18 ++++ .../Transactions/Admin/AdminPage.xaml.cs | 19 ++++ .../MobileTopup/MobileTopupFailedPage.xaml | 2 +- .../MobileTopup/MobileTopupFailedPage.xaml.cs | 2 +- .../MobileTopupPerformTopupPage.xaml | 2 +- .../MobileTopupPerformTopupPage.xaml.cs | 2 +- .../MobileTopupSelectOperatorPage.xaml | 2 +- .../MobileTopupSelectOperatorPage.xaml.cs | 2 +- .../MobileTopupSelectProductPage.xaml | 2 +- .../MobileTopupSelectProductPage.xaml.cs | 2 +- .../MobileTopup/MobileTopupSuccessPage.xaml | 2 +- .../MobileTopupSuccessPage.xaml.cs | 2 +- .../Voucher/VoucherIssueFailedPage.xaml | 2 +- .../Voucher/VoucherIssueFailedPage.xaml.cs | 2 +- .../Voucher/VoucherIssueSuccessPage.xaml | 2 +- .../Voucher/VoucherIssueSuccessPage.xaml.cs | 2 +- .../Voucher/VoucherPerformIssuePage.xaml | 2 +- .../Voucher/VoucherPerformIssuePage.xaml.cs | 2 +- .../Voucher/VoucherSelectOperatorPage.xaml | 2 +- .../Voucher/VoucherSelectOperatorPage.xaml.cs | 2 +- .../Voucher/VoucherSelectProductPage.xaml | 2 +- .../Voucher/VoucherSelectProductPage.xaml.cs | 2 +- .../TransactionMobile.Maui.csproj | 6 ++ .../UIServices/ShellNavigationService.cs | 9 +- 41 files changed, 407 insertions(+), 46 deletions(-) create mode 100644 TransactionMobile.Maui.BusinessLogic.Tests/ViewModelTests/AdminPageViewModelTests.cs create mode 100644 TransactionMobile.Maui.BusinessLogic/Models/OperatorTotalModel.cs create mode 100644 TransactionMobile.Maui.BusinessLogic/Models/ReconciliationRequestModel.cs create mode 100644 TransactionMobile.Maui.BusinessLogic/Requests/PerformReconciliationRequest.cs create mode 100644 TransactionMobile.Maui.BusinessLogic/ViewModels/Admin/AdminPageViewModel.cs create mode 100644 TransactionMobile.Maui/Pages/Transactions/Admin/AdminPage.xaml create mode 100644 TransactionMobile.Maui/Pages/Transactions/Admin/AdminPage.xaml.cs diff --git a/TransactionMobile.Maui.BusinessLogic.Tests/RequestHandlerTests/TransactionRequestHandlerTests.cs b/TransactionMobile.Maui.BusinessLogic.Tests/RequestHandlerTests/TransactionRequestHandlerTests.cs index bd2adaaa..3602fc27 100644 --- a/TransactionMobile.Maui.BusinessLogic.Tests/RequestHandlerTests/TransactionRequestHandlerTests.cs +++ b/TransactionMobile.Maui.BusinessLogic.Tests/RequestHandlerTests/TransactionRequestHandlerTests.cs @@ -1,6 +1,7 @@ namespace TransactionMobile.Maui.BusinessLogic.Tests.RequestHandlerTests; using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Database; @@ -80,4 +81,41 @@ public async Task TransactionRequestHandler_PerformVoucherIssueRequest_Handle_Is response.ShouldBeTrue(); } + + [Fact] + public async Task TransactionRequestHandler_PerformReconciliationRequest_NoTransactions_Handle_IsHandled() + { + Mock transactionService = new Mock(); + Mock databaseContext = new Mock(); + transactionService.Setup(t => t.PerformReconciliation(It.IsAny(), It.IsAny())).ReturnsAsync(true); + databaseContext.Setup(d => d.GetTransactions()).ReturnsAsync(new List()); + TransactionRequestHandler handler = new TransactionRequestHandler(transactionService.Object, databaseContext.Object); + + PerformReconciliationRequest request = PerformReconciliationRequest.Create(TestData.TransactionDateTime, + TestData.DeviceIdentifier, + TestData.ApplicationVersion); + + Boolean response = await handler.Handle(request, CancellationToken.None); + + response.ShouldBeTrue(); + } + + [Fact] + public async Task TransactionRequestHandler_PerformReconciliationRequest_TransactionsStored_Handle_IsHandled() + { + Mock transactionService = new Mock(); + Mock databaseContext = new Mock(); + transactionService.Setup(t => t.PerformReconciliation(It.IsAny(), It.IsAny())).ReturnsAsync(true); + + databaseContext.Setup(d => d.GetTransactions()).ReturnsAsync(TestData.StoredTransactions); + TransactionRequestHandler handler = new TransactionRequestHandler(transactionService.Object, databaseContext.Object); + + PerformReconciliationRequest request = PerformReconciliationRequest.Create(TestData.TransactionDateTime, + TestData.DeviceIdentifier, + TestData.ApplicationVersion); + + Boolean response = await handler.Handle(request, CancellationToken.None); + + response.ShouldBeTrue(); + } } \ No newline at end of file diff --git a/TransactionMobile.Maui.BusinessLogic.Tests/RequestTests/RequestTests.cs b/TransactionMobile.Maui.BusinessLogic.Tests/RequestTests/RequestTests.cs index d9424338..2febcc4e 100644 --- a/TransactionMobile.Maui.BusinessLogic.Tests/RequestTests/RequestTests.cs +++ b/TransactionMobile.Maui.BusinessLogic.Tests/RequestTests/RequestTests.cs @@ -129,4 +129,17 @@ public void PerformVoucherIssueRequest_Create_IsCreated() request.VoucherAmount.ShouldBe(TestData.Operator3Product_200KES.Value); request.CustomerEmailAddress.ShouldBe(TestData.CustomerEmailAddress); } + + [Fact] + public void PerformReconciliationRequest_Create_IsCreated() + { + PerformReconciliationRequest request = PerformReconciliationRequest.Create(TestData.TransactionDateTime,TestData.DeviceIdentifier, + TestData.ApplicationVersion); + + request.ShouldNotBeNull(); + request.TransactionDateTime.ShouldBe(TestData.TransactionDateTime); + request.DeviceIdentifier.ShouldBe(TestData.DeviceIdentifier); + request.ApplicationVersion.ShouldBe(TestData.ApplicationVersion); + + } } \ No newline at end of file diff --git a/TransactionMobile.Maui.BusinessLogic.Tests/TestData.cs b/TransactionMobile.Maui.BusinessLogic.Tests/TestData.cs index 29875ef7..6b4635e3 100644 --- a/TransactionMobile.Maui.BusinessLogic.Tests/TestData.cs +++ b/TransactionMobile.Maui.BusinessLogic.Tests/TestData.cs @@ -6,6 +6,7 @@ namespace TransactionMobile.Maui.BusinessLogic.Tests { + using Database; using Microsoft.Win32.SafeHandles; using Models; @@ -141,6 +142,29 @@ public static class TestData public static Decimal MerchantBalance = 199.99m; + public static List StoredTransactions => + new List + { + new TransactionRecord + { + Amount = TestData.Operator1Product_100KES.Value, + ContractId = TestData.Operator1Product_100KES.ContractId, + OperatorIdentifier = TestData.Operator1Product_100KES.OperatorIdentfier + }, + new TransactionRecord + { + Amount = TestData.Operator1Product_100KES.Value, + ContractId = TestData.Operator1Product_100KES.ContractId, + OperatorIdentifier = TestData.Operator1Product_100KES.OperatorIdentfier + }, + new TransactionRecord + { + Amount = TestData.Operator1Product_100KES.Value, + ContractId = TestData.Operator1Product_100KES.ContractId, + OperatorIdentifier = TestData.Operator1Product_100KES.OperatorIdentfier + } + }; + public static PerformLogonResponseModel PerformLogonResponseModel => new PerformLogonResponseModel { diff --git a/TransactionMobile.Maui.BusinessLogic.Tests/ViewModelTests/AdminPageViewModelTests.cs b/TransactionMobile.Maui.BusinessLogic.Tests/ViewModelTests/AdminPageViewModelTests.cs new file mode 100644 index 00000000..9f51c7e0 --- /dev/null +++ b/TransactionMobile.Maui.BusinessLogic.Tests/ViewModelTests/AdminPageViewModelTests.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TransactionMobile.Maui.BusinessLogic.Tests.ViewModelTests +{ + using Maui.UIServices; + using MediatR; + using Microsoft.Extensions.Caching.Memory; + using Moq; + using UIServices; + using ViewModels.Admin; + using ViewModels.Transactions; + using Xunit; + + public class AdminPageViewModelTests + { + [Fact] + public void TransactionsPageViewModel_AdminCommand_Execute_IsExecuted() + { + Mock navigationService = new Mock(); + Mock mediator = new Mock(); + Mock userDetailsCache = new Mock(); + Mock configurationCache = new Mock(); + Mock deviceService = new Mock(); + Mock applicationInfoService = new Mock(); + AdminPageViewModel viewModel = new AdminPageViewModel(mediator.Object, + navigationService.Object, + userDetailsCache.Object, + configurationCache.Object, + deviceService.Object, + applicationInfoService.Object); + + viewModel.ReconciliationCommand.Execute(null); + navigationService.Verify(n => n.GoToHome(), Times.Once); + } + } +} diff --git a/TransactionMobile.Maui.BusinessLogic.Tests/ViewModelTests/TransactionsPageViewModelTests.cs b/TransactionMobile.Maui.BusinessLogic.Tests/ViewModelTests/TransactionsPageViewModelTests.cs index dfa82bd1..c2430d6c 100644 --- a/TransactionMobile.Maui.BusinessLogic.Tests/ViewModelTests/TransactionsPageViewModelTests.cs +++ b/TransactionMobile.Maui.BusinessLogic.Tests/ViewModelTests/TransactionsPageViewModelTests.cs @@ -15,7 +15,7 @@ public void TransactionsPageViewModel_AdminCommand_Execute_IsExecuted() TransactionsPageViewModel viewModel = new TransactionsPageViewModel(navigationService.Object); viewModel.AdminCommand.Execute(null); - navigationService.Verify(n => n.GoToHome(), Times.Once); + navigationService.Verify(n => n.GoToAdminPage(), Times.Once); } [Fact] diff --git a/TransactionMobile.Maui.BusinessLogic/Models/OperatorTotalModel.cs b/TransactionMobile.Maui.BusinessLogic/Models/OperatorTotalModel.cs new file mode 100644 index 00000000..1b9a63c6 --- /dev/null +++ b/TransactionMobile.Maui.BusinessLogic/Models/OperatorTotalModel.cs @@ -0,0 +1,9 @@ +namespace TransactionMobile.Maui.BusinessLogic.Models; + +public class OperatorTotalModel +{ + public Guid ContractId { get; set; } + public String OperatorIdentifier { get; set; } + public Decimal TransactionValue { get; set; } + public Int32 TransactionCount { get; set; } +} \ No newline at end of file diff --git a/TransactionMobile.Maui.BusinessLogic/Models/ReconciliationRequestModel.cs b/TransactionMobile.Maui.BusinessLogic/Models/ReconciliationRequestModel.cs new file mode 100644 index 00000000..0c0e9e08 --- /dev/null +++ b/TransactionMobile.Maui.BusinessLogic/Models/ReconciliationRequestModel.cs @@ -0,0 +1,11 @@ +namespace TransactionMobile.Maui.BusinessLogic.Models; + +public class PerformReconciliationRequestModel +{ + public List OperatorTotals { get; set; } + public Decimal TransactionValue { get; set; } + public Int32 TransactionCount { get; set; } + public String DeviceIdentifier { get; set; } + public DateTime TransactionDateTime { get; set; } + public String ApplicationVersion { get; set; } +} \ No newline at end of file diff --git a/TransactionMobile.Maui.BusinessLogic/RequestHandlers/TransactionRequestHandler.cs b/TransactionMobile.Maui.BusinessLogic/RequestHandlers/TransactionRequestHandler.cs index 1efeb345..406f9a4e 100644 --- a/TransactionMobile.Maui.BusinessLogic/RequestHandlers/TransactionRequestHandler.cs +++ b/TransactionMobile.Maui.BusinessLogic/RequestHandlers/TransactionRequestHandler.cs @@ -6,9 +6,10 @@ using Requests; using Services; -public class TransactionRequestHandler : IRequestHandler, +public class TransactionRequestHandler : IRequestHandler, IRequestHandler, - IRequestHandler + IRequestHandler, + IRequestHandler { #region Fields @@ -20,7 +21,8 @@ public class TransactionRequestHandler : IRequestHandler Handle(LogonTransactionRequest requ DeviceIdentifier = request.DeviceIdentifier, TransactionDateTime = request.TransactionDateTime, TransactionNumber = transaction.transactionNumber.ToString() - }; - + }; + PerformLogonResponseModel result = await this.TransactionService.PerformLogon(model, cancellationToken); await this.UpdateTransactionRecord(transaction.transactionRecord, result, cancellationToken); @@ -165,19 +167,19 @@ public async Task Handle(PerformVoucherIssueRequest request, (TransactionRecord transactionRecord, Int64 transactionNumber) transaction = await this.CreateTransactionRecord(request, cancellationToken); // TODO: Factory PerformVoucherIssueRequestModel model = new PerformVoucherIssueRequestModel - { - ApplicationVersion = request.ApplicationVersion, - ContractId = request.ContractId, - RecipientEmailAddress = request.RecipientEmailAddress, - RecipientMobileNumber = request.RecipientMobileNumber, - CustomerEmailAddress = request.CustomerEmailAddress, - DeviceIdentifier = request.DeviceIdentifier, - OperatorIdentifier = request.OperatorIdentifier, - ProductId = request.ProductId, - VoucherAmount = request.VoucherAmount, - TransactionDateTime = request.TransactionDateTime, - TransactionNumber = transaction.transactionNumber.ToString() - }; + { + ApplicationVersion = request.ApplicationVersion, + ContractId = request.ContractId, + RecipientEmailAddress = request.RecipientEmailAddress, + RecipientMobileNumber = request.RecipientMobileNumber, + CustomerEmailAddress = request.CustomerEmailAddress, + DeviceIdentifier = request.DeviceIdentifier, + OperatorIdentifier = request.OperatorIdentifier, + ProductId = request.ProductId, + VoucherAmount = request.VoucherAmount, + TransactionDateTime = request.TransactionDateTime, + TransactionNumber = transaction.transactionNumber.ToString() + }; Boolean result = await this.TransactionService.PerformVoucherIssue(model, cancellationToken); @@ -185,4 +187,59 @@ public async Task Handle(PerformVoucherIssueRequest request, return result; } + + public async Task Handle(PerformReconciliationRequest request, + CancellationToken cancellationToken) + { + List storedTransactions = await this.DatabaseContext.GetTransactions(); + + if (storedTransactions.Any() == false) + { + return true; + } + + // TODO: convert these to operator totals + List operatorTotals = (from t in storedTransactions + where t.IsSuccessful = true && + t.TransactionType != 1 // Filter out logons + group t by new + { + t.ContractId, + t.OperatorIdentifier + } + into tempOperatorTotals + select new OperatorTotalModel + { + ContractId = tempOperatorTotals.Key.ContractId, + OperatorIdentifier = tempOperatorTotals.Key.OperatorIdentifier, + TransactionValue = tempOperatorTotals.Sum(t => t.Amount), + TransactionCount = tempOperatorTotals.Count() + }).ToList(); + + var grandTotals = new + { + TransactionValue = operatorTotals.Sum(t => t.TransactionValue), + TransactionCount = operatorTotals.Sum(t => t.TransactionCount) + }; + + PerformReconciliationRequestModel model = new PerformReconciliationRequestModel + { + ApplicationVersion = request.ApplicationVersion, + DeviceIdentifier = request.DeviceIdentifier, + TransactionDateTime = request.TransactionDateTime, + TransactionValue = grandTotals.TransactionValue, + TransactionCount = grandTotals.TransactionCount, + OperatorTotals = operatorTotals + }; + // Send to the host + Boolean result = await this.TransactionService.PerformReconciliation(model, cancellationToken); + + // Clear store (if successful) + if (result) + { + await this.DatabaseContext.ClearStoredTransactions(); + } + + return result; + } } \ No newline at end of file diff --git a/TransactionMobile.Maui.BusinessLogic/Requests/PerformReconciliationRequest.cs b/TransactionMobile.Maui.BusinessLogic/Requests/PerformReconciliationRequest.cs new file mode 100644 index 00000000..ca336692 --- /dev/null +++ b/TransactionMobile.Maui.BusinessLogic/Requests/PerformReconciliationRequest.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TransactionMobile.Maui.BusinessLogic.Requests +{ + using MediatR; + + public class PerformReconciliationRequest : IRequest + { + public String DeviceIdentifier { get; private set; } + public DateTime TransactionDateTime { get; private set; } + public String ApplicationVersion { get; private set; } + + + private PerformReconciliationRequest(DateTime transactionDateTime, + String deviceIdentifier, + String applicationVersion) + { + this.TransactionDateTime = transactionDateTime; + this.DeviceIdentifier = deviceIdentifier; + this.ApplicationVersion = applicationVersion; + } + + public static PerformReconciliationRequest Create(DateTime transactionDateTime, + String deviceIdentifier, + String applicationVersion) + { + return new PerformReconciliationRequest(transactionDateTime, deviceIdentifier, applicationVersion); + } + } +} diff --git a/TransactionMobile.Maui.BusinessLogic/Services/DummyServices/DummyTransactionService.cs b/TransactionMobile.Maui.BusinessLogic/Services/DummyServices/DummyTransactionService.cs index 710d4b63..8be50259 100644 --- a/TransactionMobile.Maui.BusinessLogic/Services/DummyServices/DummyTransactionService.cs +++ b/TransactionMobile.Maui.BusinessLogic/Services/DummyServices/DummyTransactionService.cs @@ -30,7 +30,7 @@ public async Task PerformMobileTopup(PerformMobileTopupRequestModel mod return true; } - public async Task PerformReconciliation(CancellationToken cancellationToken) + public async Task PerformReconciliation(PerformReconciliationRequestModel model,CancellationToken cancellationToken) { return true; } diff --git a/TransactionMobile.Maui.BusinessLogic/Services/ITransactionService.cs b/TransactionMobile.Maui.BusinessLogic/Services/ITransactionService.cs index b9df649b..7ad60700 100644 --- a/TransactionMobile.Maui.BusinessLogic/Services/ITransactionService.cs +++ b/TransactionMobile.Maui.BusinessLogic/Services/ITransactionService.cs @@ -1,6 +1,7 @@ namespace TransactionMobile.Maui.BusinessLogic.Services { using Models; + using RequestHandlers; public interface ITransactionService { @@ -10,7 +11,7 @@ public interface ITransactionService Task PerformMobileTopup(PerformMobileTopupRequestModel model, CancellationToken cancellationToken); - Task PerformReconciliation(CancellationToken cancellationToken); + Task PerformReconciliation(PerformReconciliationRequestModel model, CancellationToken cancellationToken); Task PerformVoucherIssue(PerformVoucherIssueRequestModel model, CancellationToken cancellationToken); diff --git a/TransactionMobile.Maui.BusinessLogic/UIServices/INavigationService.cs b/TransactionMobile.Maui.BusinessLogic/UIServices/INavigationService.cs index a1e1c796..515bd74f 100644 --- a/TransactionMobile.Maui.BusinessLogic/UIServices/INavigationService.cs +++ b/TransactionMobile.Maui.BusinessLogic/UIServices/INavigationService.cs @@ -15,6 +15,8 @@ Task GoToMobileTopupPerformTopupPage(String operatorIdentifier, Task GoToMobileTopupSelectOperatorPage(); + Task GoToAdminPage(); + Task GoToMobileTopupSelectProductPage(String operatorIdentifier); Task GoToMobileTopupSuccessPage(); diff --git a/TransactionMobile.Maui.BusinessLogic/ViewModels/Admin/AdminPageViewModel.cs b/TransactionMobile.Maui.BusinessLogic/ViewModels/Admin/AdminPageViewModel.cs new file mode 100644 index 00000000..47eccba3 --- /dev/null +++ b/TransactionMobile.Maui.BusinessLogic/ViewModels/Admin/AdminPageViewModel.cs @@ -0,0 +1,67 @@ +namespace TransactionMobile.Maui.BusinessLogic.ViewModels.Admin +{ + using System.Windows.Input; + using Maui.UIServices; + using MediatR; + using Microsoft.Extensions.Caching.Memory; + using MvvmHelpers; + using MvvmHelpers.Commands; + using Requests; + using UIServices; + + public class AdminPageViewModel : BaseViewModel + { + private readonly IMediator Mediator; + + private readonly INavigationService NavigationService; + + private readonly IMemoryCache UserDetailsCache; + + private readonly IMemoryCache ConfigurationCache; + + private readonly IDeviceService DeviceService; + + private readonly IApplicationInfoService ApplicationInfoService; + + #region Constructors + + public AdminPageViewModel(IMediator mediator, INavigationService navigationService, + IMemoryCache userDetailsCache, IMemoryCache configurationCache, + IDeviceService deviceService, IApplicationInfoService applicationInfoService) + { + this.Mediator = mediator; + this.NavigationService = navigationService; + this.UserDetailsCache = userDetailsCache; + this.ConfigurationCache = configurationCache; + this.DeviceService = deviceService; + this.ApplicationInfoService = applicationInfoService; + this.ReconciliationCommand = new AsyncCommand(this.ReconciliationCommandExecute); + this.Title = "Select Admin Transaction Type"; + } + + #endregion + + #region Properties + + public ICommand ReconciliationCommand { get; set; } + + #endregion + + #region Methods + + private async Task ReconciliationCommandExecute() + { + PerformReconciliationRequest request = + PerformReconciliationRequest.Create(DateTime.Now, this.DeviceService.GetIdentifier(), this.ApplicationInfoService.VersionString); + + Boolean response = await this.Mediator.Send(request); + + // TODO: Act on the response (display message or something)... + await this.NavigationService.GoToHome(); + } + + + + #endregion + } +} \ No newline at end of file diff --git a/TransactionMobile.Maui.BusinessLogic/ViewModels/Transactions/TransactionsPageViewModel.cs b/TransactionMobile.Maui.BusinessLogic/ViewModels/Transactions/TransactionsPageViewModel.cs index b76b7ae1..b2462706 100644 --- a/TransactionMobile.Maui.BusinessLogic/ViewModels/Transactions/TransactionsPageViewModel.cs +++ b/TransactionMobile.Maui.BusinessLogic/ViewModels/Transactions/TransactionsPageViewModel.cs @@ -43,7 +43,7 @@ public TransactionsPageViewModel(INavigationService navigationService) private async Task AdminCommandExecute() { - await this.NavigationService.GoToHome(); + await this.NavigationService.GoToAdminPage(); } private async Task BillPaymentCommandExecute() diff --git a/TransactionMobile.Maui.Database/IDatabaseContext.cs b/TransactionMobile.Maui.Database/IDatabaseContext.cs index f0c7aec2..6685a08f 100644 --- a/TransactionMobile.Maui.Database/IDatabaseContext.cs +++ b/TransactionMobile.Maui.Database/IDatabaseContext.cs @@ -17,6 +17,7 @@ public interface IDatabaseContext Task UpdateTransaction(TransactionRecord transactionRecord); Task> GetTransactions(); + Task ClearStoredTransactions(); } public class DatabaseContext : IDatabaseContext @@ -49,6 +50,11 @@ public async Task> GetTransactions() { return this.Connection.Table().ToList(); } + + public async Task ClearStoredTransactions() + { + this.Connection.DeleteAll(); + } } public class TransactionRecord diff --git a/TransactionMobile.Maui/App.xaml.cs b/TransactionMobile.Maui/App.xaml.cs index 1e80caa2..9c061d08 100644 --- a/TransactionMobile.Maui/App.xaml.cs +++ b/TransactionMobile.Maui/App.xaml.cs @@ -1,9 +1,11 @@ using TransactionMobile.Maui.Pages.Reports; -using TransactionMobile.Maui.Pages.Transactions; +using TransactionMobile.Maui.Pages.Transactions.MobileTopup; +using TransactionMobile.Maui.Pages.Transactions.Voucher; namespace TransactionMobile.Maui; using Pages.AppHome; +using Pages.Transactions.Admin; public partial class App : Application { @@ -18,10 +20,13 @@ public App() Routing.RegisterRoute(nameof(MobileTopupPerformTopupPage), typeof(MobileTopupPerformTopupPage)); Routing.RegisterRoute(nameof(MobileTopupSuccessPage), typeof(MobileTopupSuccessPage)); Routing.RegisterRoute(nameof(MobileTopupFailedPage), typeof(MobileTopupFailedPage)); + Routing.RegisterRoute(nameof(VoucherSelectOperatorPage), typeof(VoucherSelectOperatorPage)); Routing.RegisterRoute(nameof(VoucherSelectProductPage), typeof(VoucherSelectProductPage)); Routing.RegisterRoute(nameof(VoucherPerformIssuePage), typeof(VoucherPerformIssuePage)); Routing.RegisterRoute(nameof(VoucherIssueSuccessPage), typeof(VoucherIssueSuccessPage)); Routing.RegisterRoute(nameof(VoucherIssueFailedPage), typeof(VoucherIssueFailedPage)); + + Routing.RegisterRoute(nameof(AdminPage), typeof(AdminPage)); } } diff --git a/TransactionMobile.Maui/Extensions/MauiAppBuilderExtensions.cs b/TransactionMobile.Maui/Extensions/MauiAppBuilderExtensions.cs index 7c5163fd..59f6a3be 100644 --- a/TransactionMobile.Maui/Extensions/MauiAppBuilderExtensions.cs +++ b/TransactionMobile.Maui/Extensions/MauiAppBuilderExtensions.cs @@ -8,6 +8,7 @@ using BusinessLogic.Services.DummyServices; using BusinessLogic.UIServices; using BusinessLogic.ViewModels; + using BusinessLogic.ViewModels.Admin; using BusinessLogic.ViewModels.Support; using BusinessLogic.ViewModels.Transactions; using Database; @@ -59,7 +60,8 @@ public static MauiAppBuilder ConfigureRequestHandlers(this MauiAppBuilder builde builder.Services.AddSingleton, TransactionRequestHandler>(); builder.Services.AddSingleton, TransactionRequestHandler>(); builder.Services.AddSingleton, TransactionRequestHandler>(); - + builder.Services.AddSingleton, TransactionRequestHandler>(); + builder.Services.AddSingleton(ctx => { return t => ctx.GetService(t); }); return builder; @@ -82,6 +84,8 @@ public static MauiAppBuilder ConfigureViewModels(this MauiAppBuilder builder) builder.Services.AddTransient(); builder.Services.AddTransient(); + builder.Services.AddTransient(); + builder.Services.AddTransient(); diff --git a/TransactionMobile.Maui/Pages/Transactions/Admin/AdminPage.xaml b/TransactionMobile.Maui/Pages/Transactions/Admin/AdminPage.xaml new file mode 100644 index 00000000..eba0837f --- /dev/null +++ b/TransactionMobile.Maui/Pages/Transactions/Admin/AdminPage.xaml @@ -0,0 +1,18 @@ + + + + +