Skip to content

Commit a46dc6f

Browse files
Merge pull request #111 from TransactionProcessing/task/#110_reduce_number_of_float_credits
Add method to create float deposits only
2 parents 8418d65 + 9f01c08 commit a46dc6f

8 files changed

Lines changed: 196 additions & 400 deletions

File tree

TransactionProcessor.DataGenerator/DataGenerator/Program.cs

Lines changed: 68 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ static async Task Main(string[] args){
8484
Program.baseAddressFunc("TestHostApi"),
8585
clientId,
8686
clientSecret,
87-
RunningMode.Live);
87+
RunningMode.WhatIf);
8888

8989
g.TraceGenerated += arguments => {
9090
Console.WriteLine($"{arguments.TraceLevel}|{arguments.Message}");
@@ -105,50 +105,85 @@ private static async Task GenerateStatements(ITransactionDataGenerator g, Guid e
105105

106106
private static async Task GenerateTransactions(ITransactionDataGenerator g, Guid estateId, CancellationToken cancellationToken){
107107
// Set the date range
108-
DateTime startDate = new DateTime(2024, 7, 2); //27/7
109-
DateTime endDate = new DateTime(2024, 7,3); // This is the date of the last generated transaction
108+
DateTime startDate = new DateTime(2024, 7, 1); //27/7
109+
DateTime endDate = new DateTime(2024, 7,26); // This is the date of the last generated transaction
110110

111111
List<DateTime> dateRange = g.GenerateDateRange(startDate, endDate);
112-
112+
List<ContractResponse> allContracts = await g.GetEstateContracts(estateId, cancellationToken);
113113
List<MerchantResponse> merchants = await g.GetMerchants(estateId, cancellationToken);
114-
115-
Boolean sendLogons = true;
116-
Boolean sendSales = true;
117-
Boolean sendFiles = true;
118-
Boolean sendSettlement = false;
114+
115+
Dictionary<(String, String), Decimal> floatDeposits = new Dictionary<(String, String), Decimal>();
116+
floatDeposits.Add(("Healthcare Centre 1 Contract", "10 KES Voucher"), 1400);
117+
floatDeposits.Add(("Healthcare Centre 1 Contract", "Custom"), 27000);
118+
119+
floatDeposits.Add(("Safaricom Contract", "100 KES Topup"), 14000);
120+
floatDeposits.Add(("Safaricom Contract", "200 KES Topup"), 28000);
121+
floatDeposits.Add(("Safaricom Contract", "Custom"), 27000);
122+
123+
floatDeposits.Add(("PataPawa PostPay Contract", "Post Pay Bill Pay"), 18000);
124+
floatDeposits.Add(("PataPawa prePay Contract", "Pre Pay Bill Pay"), 18000);
125+
126+
127+
// Everything
128+
//DataToSend dataToSend = DataToSend.FloatDeposits | DataToSend.Logons | DataToSend.Sales | DataToSend.Files |
129+
// DataToSend.Settlement;
130+
// Floats
131+
DataToSend dataToSend = DataToSend.FloatDeposits;
132+
133+
// Logons and Sales
134+
//DataToSend dataToSend = DataToSend.Logons | DataToSend.Sales;
135+
136+
// Files
137+
//DataToSend dataToSend = DataToSend.Files;
138+
139+
// Settlement
140+
//DataToSend dataToSend = DataToSend.Settlement;
119141

120142
foreach (DateTime dateTime in dateRange){
121-
122-
if (sendLogons){
123-
foreach (MerchantResponse merchant in merchants){
143+
144+
if ((dataToSend & DataToSend.FloatDeposits) == DataToSend.FloatDeposits)
145+
{
146+
foreach (ContractResponse contractResponse in allContracts) {
147+
foreach (ContractProduct contractResponseProduct in contractResponse.Products) {
148+
// Lookup the deposit amount here
149+
var depositAmount = floatDeposits.SingleOrDefault(f =>
150+
f.Key.Item1 == contractResponse.Description &&
151+
f.Key.Item2 == contractResponseProduct.Name);
152+
153+
await g.MakeFloatDeposit(dateTime, estateId, contractResponse.ContractId,
154+
contractResponseProduct.ProductId, depositAmount.Value, cancellationToken);
155+
}
156+
}
157+
}
158+
159+
if ((dataToSend & DataToSend.Logons) == DataToSend.Logons) {
160+
foreach (MerchantResponse merchant in merchants) {
124161

125162
// Send a logon transaction
126163
await g.PerformMerchantLogon(dateTime, merchant, cancellationToken);
127164
}
128165
}
129166

130-
if (sendSales){
131-
foreach (MerchantResponse merchant in merchants){
167+
if ((dataToSend & DataToSend.Sales) == DataToSend.Sales)
168+
{
169+
foreach (MerchantResponse merchant in merchants) {
132170
// Get the merchants contracts
133171
List<ContractResponse> contracts = await g.GetMerchantContracts(merchant, cancellationToken);
134-
foreach (ContractResponse contract in contracts){
172+
foreach (ContractResponse contract in contracts) {
135173
// Generate and send some sales
136-
137-
await g.SendSales(dateTime, merchant, contract, 0, cancellationToken);
138174

139-
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
175+
await g.SendSales(dateTime, merchant, contract, 0, cancellationToken);
140176
}
141177

142-
//await Task.Delay(TimeSpan.FromSeconds(30), cancellationToken);
143178
}
144179
}
145180

146-
if (sendFiles){
147-
foreach (MerchantResponse merchant in merchants){
181+
if ((dataToSend & DataToSend.Files) == DataToSend.Files) {
182+
foreach (MerchantResponse merchant in merchants) {
148183
// Get the merchants contracts
149184
List<ContractResponse> contracts = await g.GetMerchantContracts(merchant, cancellationToken);
150185

151-
foreach (ContractResponse contract in contracts){
186+
foreach (ContractResponse contract in contracts) {
152187
// Generate a file and upload
153188
await g.SendUploadFile(dateTime, contract, merchant, Guid.Empty, cancellationToken);
154189

@@ -160,12 +195,21 @@ private static async Task GenerateTransactions(ITransactionDataGenerator g, Guid
160195
}
161196

162197
// Settlement
163-
if (sendSettlement){
198+
if ((dataToSend & DataToSend.Settlement) == DataToSend.Settlement) {
164199
await g.PerformSettlement(dateTime, estateId, cancellationToken);
165-
200+
166201
await Task.Delay(TimeSpan.FromSeconds(30), cancellationToken);
167202
}
168203
}
169204
}
205+
206+
[Flags]
207+
enum DataToSend {
208+
FloatDeposits= 0,
209+
Logons = 1,
210+
Sales = 2,
211+
Files = 4,
212+
Settlement = 8
213+
}
170214
}
171215
}

TransactionProcessor.DataGenerator/TransactionProcessing.DataGeneration/ITransactionDataGenerator.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ public interface ITransactionDataGenerator{
77
#region Methods
88

99
List<DateTime> GenerateDateRange(DateTime startDate, DateTime endDate);
10+
11+
Task<List<ContractResponse>> GetEstateContracts(Guid estateId,
12+
CancellationToken cancellationToken);
1013
Task<List<ContractResponse>> GetMerchantContracts(MerchantResponse merchant, CancellationToken cancellationToken);
1114
Task<List<MerchantResponse>> GetMerchants(Guid estateId, CancellationToken cancellationToken);
1215
Task<Boolean> PerformMerchantLogon(DateTime dateTime, MerchantResponse merchant, CancellationToken cancellationToken);
@@ -15,6 +18,7 @@ public interface ITransactionDataGenerator{
1518
Task<Boolean> SendUploadFile(DateTime dateTime, ContractResponse contract, MerchantResponse merchant, Guid userId, CancellationToken cancellationToken);
1619
Task<MerchantResponse> GetMerchant(Guid estateId, Guid merchantId, CancellationToken cancellationToken);
1720
Task<Boolean> GenerateMerchantStatement(Guid estateId, Guid merchantId, DateTime statementDateTime, CancellationToken cancellationToken);
21+
Task<Boolean> MakeFloatDeposit(DateTime dateTime, Guid estateId, Guid contractId, Guid contractProductId, Decimal amount, CancellationToken cancellationToken);
1822

1923
event TraceHandler TraceGenerated;
2024

TransactionProcessor.DataGenerator/TransactionProcessing.DataGeneration/TransactionDataGenerator.cs

Lines changed: 44 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,25 @@ public List<DateTime> GenerateDateRange(DateTime startDate, DateTime endDate){
141141
return dateRange;
142142
}
143143

144+
public async Task<List<ContractResponse>> GetEstateContracts(Guid estateId, CancellationToken cancellationToken) {
145+
String token = await this.GetAuthToken(cancellationToken);
146+
List<ContractResponse> contracts = new List<ContractResponse>();
147+
148+
try
149+
{
150+
this.WriteTrace($"About to get contracts for Estate Id [{estateId}]");
151+
contracts = await this.EstateClient.GetContracts(token, estateId, cancellationToken);
152+
this.WriteTrace($"{contracts.Count} contracts returned for Estate");
153+
}
154+
catch (Exception ex)
155+
{
156+
this.WriteError("Error getting contracts");
157+
this.WriteError(ex);
158+
}
159+
160+
return contracts;
161+
}
162+
144163
public async Task<List<ContractResponse>> GetMerchantContracts(MerchantResponse merchant, CancellationToken cancellationToken){
145164

146165
List<ContractResponse> contracts = new List<ContractResponse>();
@@ -303,13 +322,6 @@ public async Task<Boolean> SendSales(DateTime dateTime, MerchantResponse merchan
303322
return false;
304323
}
305324

306-
List<(Guid, RecordFloatCreditPurchaseRequest)> floatDepositRequests = this.CreateFloatDepositRequests(salesToSend, dateTime);
307-
IOrderedEnumerable<(Guid, RecordFloatCreditPurchaseRequest)> orderedFloatDepositRequests = floatDepositRequests.OrderBy(f => f.Item2.PurchaseDateTime);
308-
foreach ((Guid, RecordFloatCreditPurchaseRequest) recordFloatCreditPurchaseRequest in orderedFloatDepositRequests)
309-
{
310-
await this.SendFloatDepositRequest(recordFloatCreditPurchaseRequest.Item1, recordFloatCreditPurchaseRequest.Item2, cancellationToken);
311-
}
312-
313325
Int32 salesSent = 0;
314326
IOrderedEnumerable<SaleTransactionRequest> orderedSales = salesToSend.OrderBy(s => s.TransactionDateTime);
315327
// Send the sales to the host
@@ -328,54 +340,7 @@ public async Task<Boolean> SendSales(DateTime dateTime, MerchantResponse merchan
328340

329341
return true;
330342
}
331-
332-
private List<(Guid, RecordFloatCreditPurchaseRequest)> CreateFloatDepositRequests(List<SaleTransactionRequest> salesToSend, DateTime dateTime){
333-
334-
List<(Guid,RecordFloatCreditPurchaseRequest)> floatPurchaseRequests = new List<(Guid,RecordFloatCreditPurchaseRequest)>();
335-
336-
List<(Guid estateId, Guid contractId, Guid productId, Decimal amount)> sales = new List<(Guid estateId, Guid contractId, Guid produstId, Decimal amount)>();
337-
foreach (SaleTransactionRequest saleTransactionRequest in salesToSend){
338-
Boolean hasAmount = saleTransactionRequest.AdditionalTransactionMetadata.ContainsKey("Amount");
339-
if (hasAmount == false){
340-
continue;
341-
}
342-
343-
if (saleTransactionRequest.AdditionalTransactionMetadata.TryGetValue("Amount", out String amount)){
344-
Decimal decimalAmount = Decimal.Parse(amount);
345-
sales.Add((saleTransactionRequest.EstateId, saleTransactionRequest.ContractId, saleTransactionRequest.ProductId, decimalAmount));
346-
}
347-
}
348-
349-
var salesByProductList = sales.GroupBy(s => new{
350-
s.estateId,
351-
s.contractId,
352-
s.productId
353-
}).Select(g => new{
354-
g.Key.estateId,
355-
g.Key.contractId,
356-
g.Key.productId,
357-
amount = g.Sum(s => s.amount)
358-
}).ToList();
359-
360-
361-
foreach (var salesByProduct in salesByProductList){
362-
Guid floatId = IdGenerationService.GenerateFloatAggregateId(salesByProduct.estateId, salesByProduct.contractId, salesByProduct.productId);
363-
364-
Decimal costPrice = salesByProduct.amount * 0.85m;
365-
366-
RecordFloatCreditPurchaseRequest request = new RecordFloatCreditPurchaseRequest{
367-
FloatId = floatId,
368-
CreditAmount = salesByProduct.amount,
369-
CostPrice = costPrice,
370-
PurchaseDateTime = dateTime
371-
};
372-
373-
floatPurchaseRequests.Add((salesByProduct.estateId, request));
374-
}
375-
376-
return floatPurchaseRequests;
377-
}
378-
343+
379344
private List<(Guid, RecordFloatCreditPurchaseRequest)> CreateFloatDepositRequests(UploadFile uploadFile, DateTime dateTime){
380345
List<(Guid, RecordFloatCreditPurchaseRequest)> floatPurchaseRequests = new();
381346
Guid floatId = IdGenerationService.GenerateFloatAggregateId(uploadFile.EstateId, uploadFile.ContractId, uploadFile.ProductId);
@@ -417,14 +382,7 @@ public async Task<Boolean> SendUploadFile(DateTime dateTime, ContractResponse co
417382
if (depositSent == false){
418383
return false;
419384
}
420-
421-
List<(Guid, RecordFloatCreditPurchaseRequest)> floatDepositRequests = this.CreateFloatDepositRequests(uploadFile.Item2, dateTime);
422-
IOrderedEnumerable<(Guid, RecordFloatCreditPurchaseRequest)> orderedFloatDepositRequests = floatDepositRequests.OrderBy(f => f.Item2.PurchaseDateTime);
423-
foreach ((Guid, RecordFloatCreditPurchaseRequest) recordFloatCreditPurchaseRequest in orderedFloatDepositRequests)
424-
{
425-
await this.SendFloatDepositRequest(recordFloatCreditPurchaseRequest.Item1, recordFloatCreditPurchaseRequest.Item2, cancellationToken);
426-
}
427-
385+
428386
Boolean fileSent = await this.UploadFile(uploadFile.Item2, uploadFile.Item2.UserId, dateTime, cancellationToken);
429387

430388
if (fileSent == false){
@@ -492,6 +450,29 @@ public async Task<Boolean> GenerateMerchantStatement(Guid estateId, Guid merchan
492450
}
493451
}
494452

453+
public async Task<Boolean> MakeFloatDeposit(DateTime dateTime,
454+
Guid estateId,
455+
Guid contractId,
456+
Guid productId,
457+
Decimal amount,
458+
CancellationToken cancellationToken) {
459+
460+
461+
Guid floatId = IdGenerationService.GenerateFloatAggregateId(estateId, contractId, productId);
462+
463+
Decimal costPrice = amount * 0.85m;
464+
465+
RecordFloatCreditPurchaseRequest request = new RecordFloatCreditPurchaseRequest
466+
{
467+
FloatId = floatId,
468+
CreditAmount = amount,
469+
CostPrice = costPrice,
470+
PurchaseDateTime = dateTime
471+
};
472+
473+
return await this.SendFloatDepositRequest(estateId, request, cancellationToken);
474+
}
475+
495476
public event TraceHandler? TraceGenerated;
496477

497478
private List<(SaleTransactionRequest request, Decimal amount)> BuildPataPawaPostPayBillPaymentSaleRequests(DateTime dateTime, MerchantResponse merchant, ContractResponse contract, ContractProduct product, (Int32 accountNumber, String accountName, Decimal balance) billDetails){

0 commit comments

Comments
 (0)