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
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Database;
using Models;
using Moq;
using RequestHandlers;
Expand All @@ -17,8 +18,9 @@ public class TransactionRequestHandlerTests
public async Task TransactionRequestHandler_LogonTransactionRequest_Handle_IsHandled()
{
Mock<ITransactionService> transactionService = new Mock<ITransactionService>();
Mock<IDatabaseContext> databaseContext = new Mock<IDatabaseContext>();
transactionService.Setup(t => t.PerformLogon(It.IsAny<PerformLogonRequestModel>(), It.IsAny<CancellationToken>())).ReturnsAsync(TestData.PerformLogonResponseModel);
TransactionRequestHandler handler = new TransactionRequestHandler(transactionService.Object);
TransactionRequestHandler handler = new TransactionRequestHandler(transactionService.Object, databaseContext.Object);

LogonTransactionRequest request = LogonTransactionRequest.Create(TestData.TransactionDateTime,
TestData.TransactionNumber,
Expand All @@ -34,8 +36,9 @@ public async Task TransactionRequestHandler_LogonTransactionRequest_Handle_IsHan
public async Task TransactionRequestHandler_PerformMobileTopupRequest_Handle_IsHandled()
{
Mock<ITransactionService> transactionService = new Mock<ITransactionService>();
Mock<IDatabaseContext> databaseContext = new Mock<IDatabaseContext>();
transactionService.Setup(t => t.PerformMobileTopup(It.IsAny<PerformMobileTopupRequestModel>(), It.IsAny<CancellationToken>())).ReturnsAsync(true);
TransactionRequestHandler handler = new TransactionRequestHandler(transactionService.Object);
TransactionRequestHandler handler = new TransactionRequestHandler(transactionService.Object,databaseContext.Object);

PerformMobileTopupRequest request = PerformMobileTopupRequest.Create(TestData.TransactionDateTime,
TestData.TransactionNumber,
Expand All @@ -57,8 +60,9 @@ public async Task TransactionRequestHandler_PerformMobileTopupRequest_Handle_IsH
public async Task TransactionRequestHandler_PerformVoucherIssueRequest_Handle_IsHandled()
{
Mock<ITransactionService> transactionService = new Mock<ITransactionService>();
Mock<IDatabaseContext> databaseContext = new Mock<IDatabaseContext>();
transactionService.Setup(t => t.PerformVoucherIssue(It.IsAny<PerformVoucherIssueRequestModel>(), It.IsAny<CancellationToken>())).ReturnsAsync(true);
TransactionRequestHandler handler = new TransactionRequestHandler(transactionService.Object);
TransactionRequestHandler handler = new TransactionRequestHandler(transactionService.Object,databaseContext.Object);

PerformVoucherIssueRequest request = PerformVoucherIssueRequest.Create(TestData.TransactionDateTime,
TestData.TransactionNumber,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace TransactionMobile.Maui.BusinessLogic.RequestHandlers;

using Database;
using MediatR;
using Models;
using Requests;
Expand All @@ -13,13 +14,16 @@ public class TransactionRequestHandler : IRequestHandler<PerformMobileTopupReque

private readonly ITransactionService TransactionService;

private readonly IDatabaseContext DatabaseContext;

#endregion

#region Constructors

public TransactionRequestHandler(ITransactionService transactionService)
public TransactionRequestHandler(ITransactionService transactionService, IDatabaseContext databaseContext)
{
this.TransactionService = transactionService;
this.DatabaseContext = databaseContext;
}

#endregion
Expand All @@ -29,6 +33,8 @@ public TransactionRequestHandler(ITransactionService transactionService)
public async Task<Boolean> Handle(PerformMobileTopupRequest request,
CancellationToken cancellationToken)
{
(TransactionRecord transactionRecord, Int64 transactionNumber) transaction = await this.CreateTransactionRecord(request, cancellationToken);

// TODO: Factory
PerformMobileTopupRequestModel model = new PerformMobileTopupRequestModel
{
Expand All @@ -46,23 +52,108 @@ public async Task<Boolean> Handle(PerformMobileTopupRequest request,

Boolean result = await this.TransactionService.PerformMobileTopup(model, cancellationToken);

await this.UpdateTransactionRecord(transaction.transactionRecord, result, cancellationToken);

return result;
}

private async Task<(TransactionRecord transactionRecord, Int64 transactionNumber)> CreateTransactionRecord(LogonTransactionRequest request,
CancellationToken cancellationToken)
{
TransactionRecord transactionRecord = new TransactionRecord
{
ApplicationVersion = request.ApplicationVersion,
DeviceIdentifier = request.DeviceIdentifier,
TransactionDateTime = request.TransactionDateTime,
TransactionType = 1
};
Int64 transactionNumber = await this.DatabaseContext.CreateTransaction(transactionRecord);

return (transactionRecord, transactionNumber);
}

private async Task<(TransactionRecord transactionRecord, Int64 transactionNumber)> CreateTransactionRecord(PerformMobileTopupRequest request,
CancellationToken cancellationToken)
{
TransactionRecord transactionRecord = new TransactionRecord
{
ApplicationVersion = request.ApplicationVersion,
DeviceIdentifier = request.DeviceIdentifier,
TransactionDateTime = request.TransactionDateTime,
TransactionType = 2,
Amount = request.TopupAmount,
ProductId = request.ProductId,
ContractId = request.ContractId,
CustomerAccountNumber = request.CustomerAccountNumber,
CustomerEmailAddress = request.CustomerEmailAddress,
OperatorIdentifier = request.OperatorIdentifier
};
Int64 transactionNumber = await this.DatabaseContext.CreateTransaction(transactionRecord);

return (transactionRecord, transactionNumber);
}

private async Task<(TransactionRecord transactionRecord, Int64 transactionNumber)> CreateTransactionRecord(PerformVoucherIssueRequest request,
CancellationToken cancellationToken)
{
TransactionRecord transactionRecord = new TransactionRecord
{
ApplicationVersion = request.ApplicationVersion,
DeviceIdentifier = request.DeviceIdentifier,
TransactionDateTime = request.TransactionDateTime,
TransactionType = 2,
Amount = request.VoucherAmount,
ProductId = request.ProductId,
ContractId = request.ContractId,
RecipientEmailAddress = request.RecipientEmailAddress,
RecipientMobileNumber = request.RecipientMobileNumber,
CustomerEmailAddress = request.CustomerEmailAddress,
OperatorIdentifier = request.OperatorIdentifier
};
Int64 transactionNumber = await this.DatabaseContext.CreateTransaction(transactionRecord);

return (transactionRecord, transactionNumber);
}

private async Task UpdateTransactionRecord(TransactionRecord transactionRecord,
PerformLogonResponseModel result,
CancellationToken cancellationToken)
{
transactionRecord.IsSuccessful = result.IsSuccessful;
transactionRecord.ResponseMessage = result.ResponseMessage;
transactionRecord.EstateId = result.EstateId;
transactionRecord.MerchantId = result.MerchantId;

await this.DatabaseContext.UpdateTransaction(transactionRecord);
}

private async Task UpdateTransactionRecord(TransactionRecord transactionRecord,
Boolean result,
CancellationToken cancellationToken)
{
transactionRecord.IsSuccessful = result;

await this.DatabaseContext.UpdateTransaction(transactionRecord);
}

public async Task<PerformLogonResponseModel> Handle(LogonTransactionRequest request,
CancellationToken cancellationToken)
{
(TransactionRecord transactionRecord, Int64 transactionNumber) transaction = await this.CreateTransactionRecord(request, cancellationToken);

// TODO: Factory
PerformLogonRequestModel model = new PerformLogonRequestModel
{
ApplicationVersion = request.ApplicationVersion,
DeviceIdentifier = request.DeviceIdentifier,
TransactionDateTime = request.TransactionDateTime,
TransactionNumber = request.TransactionNumber
};

TransactionNumber = transaction.transactionNumber.ToString()
};
PerformLogonResponseModel result = await this.TransactionService.PerformLogon(model, cancellationToken);

await this.UpdateTransactionRecord(transaction.transactionRecord, result, cancellationToken);

return result;
}

Expand All @@ -71,6 +162,7 @@ public async Task<PerformLogonResponseModel> Handle(LogonTransactionRequest requ
public async Task<Boolean> Handle(PerformVoucherIssueRequest request,
CancellationToken cancellationToken)
{
(TransactionRecord transactionRecord, Int64 transactionNumber) transaction = await this.CreateTransactionRecord(request, cancellationToken);
// TODO: Factory
PerformVoucherIssueRequestModel model = new PerformVoucherIssueRequestModel
{
Expand All @@ -84,11 +176,13 @@ public async Task<Boolean> Handle(PerformVoucherIssueRequest request,
ProductId = request.ProductId,
VoucherAmount = request.VoucherAmount,
TransactionDateTime = request.TransactionDateTime,
TransactionNumber = request.TransactionNumber
};
TransactionNumber = transaction.transactionNumber.ToString()
};

Boolean result = await this.TransactionService.PerformVoucherIssue(model, cancellationToken);

await this.UpdateTransactionRecord(transaction.transactionRecord, result, cancellationToken);

return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,8 @@
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="6.0.2-mauipre.1.22102.15" />
<PackageReference Include="Refractored.MvvmHelpers" Version="1.6.2" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\TransactionMobile.Maui.Database\TransactionMobile.Maui.Database.csproj" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

namespace TransactionMobile.Maui.BusinessLogic.ViewModels.Support
{
using Database;
using MvvmHelpers;
using UIServices;

Expand All @@ -15,12 +16,17 @@ public class SupportPageViewModel : BaseViewModel

private readonly IApplicationInfoService ApplicationInfoService;

public SupportPageViewModel(IDeviceService deviceService,IApplicationInfoService applicationInfoService)
private readonly IDatabaseContext DatabaseContext;

public SupportPageViewModel(IDeviceService deviceService,IApplicationInfoService applicationInfoService,IDatabaseContext databaseContext)
{
this.DeviceService = deviceService;
this.ApplicationInfoService = applicationInfoService;
this.DatabaseContext = databaseContext;
}

public String NumberTransactionsStored => $"Transactions Stored: {this.DatabaseContext.GetTransactions().Result.Count()}";

public String ApplicationName => $"{this.ApplicationInfoService.ApplicationName} v{this.ApplicationInfoService.VersionString}";
//public string AppVersion => $"Version: {this.ApplicationInfoService.VersionString}{Environment.NewLine}Copyright © 2022 Stuart Ferguson";

Expand Down
89 changes: 89 additions & 0 deletions TransactionMobile.Maui.Database/IDatabaseContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TransactionMobile.Maui.Database
{
using SQLite;

public interface IDatabaseContext
{
Task InitialiseDatabase();

Task<Int64> CreateTransaction(TransactionRecord transactionRecord);

Task UpdateTransaction(TransactionRecord transactionRecord);

Task<List<TransactionRecord>> GetTransactions();
}

public class DatabaseContext : IDatabaseContext
{
private readonly SQLiteConnection Connection;

public DatabaseContext(String connectionString)
{
this.Connection = new SQLiteConnection(connectionString);
}

public async Task InitialiseDatabase()
{
this.Connection.CreateTable<TransactionRecord>();
}

public async Task<Int64> CreateTransaction(TransactionRecord transactionRecord)
{
this.Connection.Insert(transactionRecord);

return SQLite3.LastInsertRowid(this.Connection.Handle);
}

public async Task UpdateTransaction(TransactionRecord transactionRecord)
{
this.Connection.Update(transactionRecord);
}

public async Task<List<TransactionRecord>> GetTransactions()
{
return this.Connection.Table<TransactionRecord>().ToList();
}
}

public class TransactionRecord
{
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 Amount { get; set; }

public DateTime TransactionDateTime { get; set; }

[PrimaryKey, AutoIncrement]
public Int32 TransactionNumber { get; set; }

public String RecipientMobileNumber { get; set; }
public String RecipientEmailAddress { get; set; }

public Int32 TransactionType { get; set; }

public Guid EstateId { get; set; }
public Guid MerchantId { get; set; }
public Boolean IsSuccessful { get; set; }

public String ResponseMessage { get; set; }

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="sqlite-net-pcl" Version="1.8.116" />
<PackageReference Include="SQLitePCLRaw.core" Version="2.1.0-pre20220207221914" />
<PackageReference Include="SQLitePCLRaw.bundle_green" Version="2.1.0-pre20220207221914" />
<PackageReference Include="SQLitePCLRaw.provider.dynamic_cdecl" Version="2.1.0-pre20220207221914" />
<PackageReference Include="SQLitePCLRaw.provider.sqlite3" Version="2.1.0-pre20220207221914" />
</ItemGroup>

</Project>
11 changes: 9 additions & 2 deletions TransactionMobile.Maui.sln
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{1CBEF4C1-7D9
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{AB312EE3-CBA4-469A-8694-67C5466298C5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TransactionMobile.Maui.BusinessLogic.Tests", "TransactionMobile.Maui.BusinessLogic.Tests\TransactionMobile.Maui.BusinessLogic.Tests.csproj", "{0894F054-5C4D-4DDD-A8E9-636416189234}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TransactionMobile.Maui.BusinessLogic.Tests", "TransactionMobile.Maui.BusinessLogic.Tests\TransactionMobile.Maui.BusinessLogic.Tests.csproj", "{0894F054-5C4D-4DDD-A8E9-636416189234}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TransactionMobile.Maui.BusinessLogic", "TransactionMobile.Maui.BusinessLogic\TransactionMobile.Maui.BusinessLogic.csproj", "{902D54CF-CD5F-4932-B1DC-01A3937AC054}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TransactionMobile.Maui.BusinessLogic", "TransactionMobile.Maui.BusinessLogic\TransactionMobile.Maui.BusinessLogic.csproj", "{902D54CF-CD5F-4932-B1DC-01A3937AC054}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TransactionMobile.Maui.Database", "TransactionMobile.Maui.Database\TransactionMobile.Maui.Database.csproj", "{692DD081-BA36-4289-9A81-96C9F604E864}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -33,6 +35,10 @@ Global
{902D54CF-CD5F-4932-B1DC-01A3937AC054}.Debug|Any CPU.Build.0 = Debug|Any CPU
{902D54CF-CD5F-4932-B1DC-01A3937AC054}.Release|Any CPU.ActiveCfg = Release|Any CPU
{902D54CF-CD5F-4932-B1DC-01A3937AC054}.Release|Any CPU.Build.0 = Release|Any CPU
{692DD081-BA36-4289-9A81-96C9F604E864}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{692DD081-BA36-4289-9A81-96C9F604E864}.Debug|Any CPU.Build.0 = Debug|Any CPU
{692DD081-BA36-4289-9A81-96C9F604E864}.Release|Any CPU.ActiveCfg = Release|Any CPU
{692DD081-BA36-4289-9A81-96C9F604E864}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -41,6 +47,7 @@ Global
{73668181-7A26-435D-83E3-CF141AC8FD0B} = {1CBEF4C1-7D90-4A78-AA55-D81F1447A70E}
{0894F054-5C4D-4DDD-A8E9-636416189234} = {AB312EE3-CBA4-469A-8694-67C5466298C5}
{902D54CF-CD5F-4932-B1DC-01A3937AC054} = {1CBEF4C1-7D90-4A78-AA55-D81F1447A70E}
{692DD081-BA36-4289-9A81-96C9F604E864} = {1CBEF4C1-7D90-4A78-AA55-D81F1447A70E}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {61F7FB11-1E47-470C-91E2-47F8143E1572}
Expand Down
Loading