diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml
index dfec0962..a78e1479 100644
--- a/.github/workflows/pullrequest.yml
+++ b/.github/workflows/pullrequest.yml
@@ -34,3 +34,9 @@ jobs:
- name: Run Integration Tests
run: dotnet test "TransactionProcessor.IntegrationTests\TransactionProcessor.IntegrationTests.csproj" --filter Category=PRTest
+
+ - uses: actions/upload-artifact@v2
+ if: ${{ failure() }}
+ with:
+ name: tracelogs
+ path: /home/txnproc/trace/
\ No newline at end of file
diff --git a/TransactionProcessor.BusinessLogic/EventHandling/TransactionDomainEventHandler.cs b/TransactionProcessor.BusinessLogic/EventHandling/TransactionDomainEventHandler.cs
index 19f91de6..390dd03f 100644
--- a/TransactionProcessor.BusinessLogic/EventHandling/TransactionDomainEventHandler.cs
+++ b/TransactionProcessor.BusinessLogic/EventHandling/TransactionDomainEventHandler.cs
@@ -238,14 +238,18 @@ private async Task HandleSpecificDomainEvent(TransactionHasBeenCompletedEvent do
foreach (CalculatedFee calculatedFee in merchantFees)
{
// Determine when the fee should be applied
- Guid aggregateId = merchant.NextSettlementDueDate.ToGuid();
+ Logger.LogInformation($"Completed Date {domainEvent.CompletedDateTime}");
+ Logger.LogInformation($"SettlementSchedule {merchant.SettlementSchedule}");
+ DateTime settlementDate = CalculateSettlementDate(merchant.SettlementSchedule, domainEvent.CompletedDateTime);
+ Logger.LogInformation($"Settlement Date {settlementDate}");
+ Guid aggregateId = settlementDate.ToGuid();
// We need to add the fees to a pending settlement stream (for today)
SettlementAggregate aggregate = await this.SettlementAggregateRepository.GetLatestVersion(aggregateId, cancellationToken);
if (aggregate.IsCreated == false)
{
- aggregate.Create(transactionAggregate.EstateId, merchant.NextSettlementDueDate);
+ aggregate.Create(transactionAggregate.EstateId, settlementDate);
}
aggregate.AddFee(transactionAggregate.MerchantId, transactionAggregate.AggregateId, calculatedFee);
@@ -255,6 +259,19 @@ private async Task HandleSpecificDomainEvent(TransactionHasBeenCompletedEvent do
}
}
+ private DateTime CalculateSettlementDate(SettlementSchedule merchantSettlementSchedule, DateTime completeDateTime)
+ {
+ switch(merchantSettlementSchedule)
+ {
+ case SettlementSchedule.Weekly:
+ return completeDateTime.Date.AddDays(7).Date;
+ case SettlementSchedule.Monthly:
+ return completeDateTime.Date.AddMonths(1).Date;
+ default:
+ throw new Exception("Invalid merchant settlement schedule");
+ }
+ }
+
///
/// Handles the specific domain event.
///
diff --git a/TransactionProcessor.IntegrationTests/Settlement/Settlement.feature b/TransactionProcessor.IntegrationTests/Settlement/Settlement.feature
index d268dfcd..76a95357 100644
--- a/TransactionProcessor.IntegrationTests/Settlement/Settlement.feature
+++ b/TransactionProcessor.IntegrationTests/Settlement/Settlement.feature
@@ -97,9 +97,9 @@ Scenario: Get Pending Settlement
| Test Estate 1 | Test Merchant 3 | 8 | 0000 | SUCCESS |
When I get the pending settlements the following information should be returned
- | NextSettlementDate | EstateName | NumberOfFees |
- | NextWeek | Test Estate 1 | 1 |
- | NextMonth | Test Estate 1 | 1 |
+ | SettlementDate | EstateName | NumberOfFees |
+ | NextWeek | Test Estate 1 | 1 |
+ | NextMonth | Test Estate 1 | 1 |
@PRTest
Scenario: Process Settlement
@@ -142,9 +142,9 @@ Scenario: Process Settlement
| Test Estate 1 | Test Merchant 2 | 6 | 0000 | SUCCESS |
When I get the pending settlements the following information should be returned
- | NextSettlementDate | EstateName | NumberOfFees |
- | NextWeek | Test Estate 1 | 1 |
+ | SettlementDate | EstateName | NumberOfFees |
+ | Yesterday | Test Estate 1 | 1 |
- When I process the settlement for 'NextWeek' on Estate 'Test Estate 1' then 1 fees are marked as settled and the settlement is completed
+ When I process the settlement for 'Yesterday' on Estate 'Test Estate 1' then 1 fees are marked as settled and the settlement is completed
diff --git a/TransactionProcessor.IntegrationTests/Settlement/Settlement.feature.cs b/TransactionProcessor.IntegrationTests/Settlement/Settlement.feature.cs
index fc3e5cbc..c8e5ea31 100644
--- a/TransactionProcessor.IntegrationTests/Settlement/Settlement.feature.cs
+++ b/TransactionProcessor.IntegrationTests/Settlement/Settlement.feature.cs
@@ -247,14 +247,12 @@ void System.IDisposable.Dispose()
[Xunit.SkippableFactAttribute(DisplayName="Get Pending Settlement")]
[Xunit.TraitAttribute("FeatureTitle", "Settlement")]
[Xunit.TraitAttribute("Description", "Get Pending Settlement")]
- [Xunit.TraitAttribute("Category", "PRTest")]
public virtual void GetPendingSettlement()
{
- string[] tagsOfScenario = new string[] {
- "PRTest"};
+ string[] tagsOfScenario = ((string[])(null));
System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary();
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Get Pending Settlement", null, tagsOfScenario, argumentsOfScenario);
-#line 50
+#line 49
this.ScenarioInitialize(scenarioInfo);
#line hidden
bool isScenarioIgnored = default(bool);
@@ -317,7 +315,7 @@ public virtual void GetPendingSettlement()
"testcontact3@merchant2.co.uk",
"Test Estate 1",
"Monthly"});
-#line 51
+#line 50
testRunner.Given("I create the following merchants", ((string)(null)), table71, "Given ");
#line hidden
TechTalk.SpecFlow.Table table72 = new TechTalk.SpecFlow.Table(new string[] {
@@ -362,7 +360,7 @@ public virtual void GetPendingSettlement()
"00000003",
"10000003",
"Test Estate 1"});
-#line 57
+#line 56
testRunner.Given("I have assigned the following operator to the merchants", ((string)(null)), table72, "Given ");
#line hidden
TechTalk.SpecFlow.Table table73 = new TechTalk.SpecFlow.Table(new string[] {
@@ -381,7 +379,7 @@ public virtual void GetPendingSettlement()
"123456782",
"Test Merchant 3",
"Test Estate 1"});
-#line 66
+#line 65
testRunner.Given("I have assigned the following devices to the merchants", ((string)(null)), table73, "Given ");
#line hidden
TechTalk.SpecFlow.Table table74 = new TechTalk.SpecFlow.Table(new string[] {
@@ -408,7 +406,7 @@ public virtual void GetPendingSettlement()
"Today",
"Test Merchant 3",
"Test Estate 1"});
-#line 72
+#line 71
testRunner.Given("I make the following manual merchant deposits", ((string)(null)), table74, "Given ");
#line hidden
TechTalk.SpecFlow.Table table75 = new TechTalk.SpecFlow.Table(new string[] {
@@ -546,7 +544,7 @@ public virtual void GetPendingSettlement()
"10 KES",
"test@recipient.co.uk",
""});
-#line 78
+#line 77
testRunner.When("I perform the following transactions", ((string)(null)), table75, "When ");
#line hidden
TechTalk.SpecFlow.Table table76 = new TechTalk.SpecFlow.Table(new string[] {
@@ -603,11 +601,11 @@ public virtual void GetPendingSettlement()
"8",
"0000",
"SUCCESS"});
-#line 89
+#line 88
testRunner.Then("transaction response should contain the following information", ((string)(null)), table76, "Then ");
#line hidden
TechTalk.SpecFlow.Table table77 = new TechTalk.SpecFlow.Table(new string[] {
- "NextSettlementDate",
+ "SettlementDate",
"EstateName",
"NumberOfFees"});
table77.AddRow(new string[] {
@@ -618,7 +616,7 @@ public virtual void GetPendingSettlement()
"NextMonth",
"Test Estate 1",
"1"});
-#line 101
+#line 99
testRunner.When("I get the pending settlements the following information should be returned", ((string)(null)), table77, "When ");
#line hidden
}
@@ -635,7 +633,7 @@ public virtual void ProcessSettlement()
"PRTest"};
System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary();
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Process Settlement", null, tagsOfScenario, argumentsOfScenario);
-#line 107
+#line 105
this.ScenarioInitialize(scenarioInfo);
#line hidden
bool isScenarioIgnored = default(bool);
@@ -688,7 +686,7 @@ public virtual void ProcessSettlement()
"testcontact2@merchant2.co.uk",
"Test Estate 1",
"Weekly"});
-#line 108
+#line 106
testRunner.Given("I create the following merchants", ((string)(null)), table78, "Given ");
#line hidden
TechTalk.SpecFlow.Table table79 = new TechTalk.SpecFlow.Table(new string[] {
@@ -721,7 +719,7 @@ public virtual void ProcessSettlement()
"00000002",
"10000002",
"Test Estate 1"});
-#line 113
+#line 111
testRunner.Given("I have assigned the following operator to the merchants", ((string)(null)), table79, "Given ");
#line hidden
TechTalk.SpecFlow.Table table80 = new TechTalk.SpecFlow.Table(new string[] {
@@ -736,7 +734,7 @@ public virtual void ProcessSettlement()
"123456781",
"Test Merchant 2",
"Test Estate 1"});
-#line 120
+#line 118
testRunner.Given("I have assigned the following devices to the merchants", ((string)(null)), table80, "Given ");
#line hidden
TechTalk.SpecFlow.Table table81 = new TechTalk.SpecFlow.Table(new string[] {
@@ -757,7 +755,7 @@ public virtual void ProcessSettlement()
"Today",
"Test Merchant 2",
"Test Estate 1"});
-#line 125
+#line 123
testRunner.Given("I make the following manual merchant deposits", ((string)(null)), table81, "Given ");
#line hidden
TechTalk.SpecFlow.Table table82 = new TechTalk.SpecFlow.Table(new string[] {
@@ -850,7 +848,7 @@ public virtual void ProcessSettlement()
"10 KES",
"",
"123456789"});
-#line 130
+#line 128
testRunner.When("I perform the following transactions", ((string)(null)), table82, "When ");
#line hidden
TechTalk.SpecFlow.Table table83 = new TechTalk.SpecFlow.Table(new string[] {
@@ -889,23 +887,23 @@ public virtual void ProcessSettlement()
"6",
"0000",
"SUCCESS"});
-#line 138
+#line 136
testRunner.Then("transaction response should contain the following information", ((string)(null)), table83, "Then ");
#line hidden
TechTalk.SpecFlow.Table table84 = new TechTalk.SpecFlow.Table(new string[] {
- "NextSettlementDate",
+ "SettlementDate",
"EstateName",
"NumberOfFees"});
table84.AddRow(new string[] {
- "NextWeek",
+ "Yesterday",
"Test Estate 1",
"1"});
-#line 146
+#line 144
testRunner.When("I get the pending settlements the following information should be returned", ((string)(null)), table84, "When ");
#line hidden
-#line 150
- testRunner.When("I process the settlement for \'NextWeek\' on Estate \'Test Estate 1\' then 1 fees are" +
- " marked as settled and the settlement is completed", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When ");
+#line 148
+ testRunner.When("I process the settlement for \'Yesterday\' on Estate \'Test Estate 1\' then 1 fees ar" +
+ "e marked as settled and the settlement is completed", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When ");
#line hidden
}
this.ScenarioCleanup();
diff --git a/TransactionProcessor.IntegrationTests/Shared/SharedSteps.cs b/TransactionProcessor.IntegrationTests/Shared/SharedSteps.cs
index 22b82b62..47d230b4 100644
--- a/TransactionProcessor.IntegrationTests/Shared/SharedSteps.cs
+++ b/TransactionProcessor.IntegrationTests/Shared/SharedSteps.cs
@@ -9,6 +9,7 @@ namespace TransactionProcessor.IntegrationTests.Shared
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
+ using BusinessLogic.Common;
using Common;
using DataTransferObjects;
using EstateManagement.DataTransferObjects;
@@ -877,19 +878,24 @@ public async Task WhenIGetThePendingSettlementsTheFollowingInformationShouldBeRe
{
// Get the merchant name
EstateDetails estateDetails = this.TestingContext.GetEstateDetails(tableRow);
- String nextSettlementDateString = SpecflowTableHelper.GetStringRowValue(tableRow, "NextSettlementDate");
+ String settlementDateString = SpecflowTableHelper.GetStringRowValue(tableRow, "SettlementDate");
Int32 numberOfFees = SpecflowTableHelper.GetIntValue(tableRow, "NumberOfFees");
- DateTime nextSettlementDate = this.GetNextSettlementDate(DateTime.Now, nextSettlementDateString);
-
+ DateTime settlementDate = this.GetSettlementDate(DateTime.Today, settlementDateString);
+ if (Environment.GetEnvironmentVariable("CI") == Boolean.TrueString.ToLower())
+ {
+ settlementDate = settlementDate.AddDays(1);
+ }
+
+ var aggregateid = settlementDate.ToGuid();
await Retry.For(async () =>
{
SettlementResponse settlements =
await this.TestingContext.DockerHelper.TransactionProcessorClient.GetSettlementByDate(this.TestingContext.AccessToken,
- nextSettlementDate,
+ settlementDate,
estateDetails.EstateId,
CancellationToken.None);
- settlements.NumberOfFeesPendingSettlement.ShouldBe(numberOfFees);
+ settlements.NumberOfFeesPendingSettlement.ShouldBe(numberOfFees, $"Settlment date {settlementDate}");
}, TimeSpan.FromMinutes(3));
}
}
@@ -897,7 +903,12 @@ await this.TestingContext.DockerHelper.TransactionProcessorClient.GetSettlementB
[When(@"I process the settlement for '([^']*)' on Estate '([^']*)' then (.*) fees are marked as settled and the settlement is completed")]
public async Task WhenIProcessTheSettlementForOnEstateThenFeesAreMarkedAsSettledAndTheSettlementIsCompleted(String dateString, String estateName, Int32 numberOfFeesSettled)
{
- var settlementDate = SpecflowTableHelper.GetDateForDateString(dateString, DateTime.Now);
+ DateTime settlementDate = this.GetSettlementDate(DateTime.Today, dateString);
+ if (Environment.GetEnvironmentVariable("CI") == Boolean.TrueString.ToLower())
+ {
+ settlementDate = settlementDate.AddDays(1);
+ }
+
EstateDetails estateDetails = this.TestingContext.GetEstateDetails(estateName);
await this.TestingContext.DockerHelper.TransactionProcessorClient.ProcessSettlement(this.TestingContext.AccessToken,
settlementDate,
@@ -915,23 +926,28 @@ await this.TestingContext.DockerHelper.TransactionProcessorClient.GetSettlementB
settlement.NumberOfFeesPendingSettlement.ShouldBe(0);
settlement.NumberOfFeesSettled.ShouldBe(numberOfFeesSettled);
settlement.SettlementCompleted.ShouldBeTrue();
- });
+ }, TimeSpan.FromMinutes(2));
}
- private DateTime GetNextSettlementDate(DateTime now,
+ private DateTime GetSettlementDate(DateTime now,
String nextSettlementDate)
{
+ if (nextSettlementDate == "Yesterday")
+ {
+ return now.AddDays(-1).Date;
+ }
+
if (nextSettlementDate == "NextWeek")
{
- return now.AddDays(7);
+ return now.AddDays(7).Date;
}
if (nextSettlementDate == "NextMonth")
{
- return now.AddMonths(1);
+ return now.AddMonths(1).Date;
}
- return now;
+ return now.Date;
}
}
}
diff --git a/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj b/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj
index e2aafeb1..1071db15 100644
--- a/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj
+++ b/TransactionProcessor.IntegrationTests/TransactionProcessor.IntegrationTests.csproj
@@ -34,6 +34,7 @@
+
diff --git a/TransactionProcessor/Controllers/SettlementController.cs b/TransactionProcessor/Controllers/SettlementController.cs
index c44ee5e4..8dda2e69 100644
--- a/TransactionProcessor/Controllers/SettlementController.cs
+++ b/TransactionProcessor/Controllers/SettlementController.cs
@@ -16,6 +16,7 @@ namespace TransactionProcessor.Controllers
using SettlementAggregates;
using Shared.DomainDrivenDesign.EventSourcing;
using Shared.EventStore.Aggregate;
+ using Shared.Logger;
[ExcludeFromCodeCoverage]
[Route(SettlementController.ControllerRoute)]
@@ -60,6 +61,8 @@ public async Task GetPendingSettlement([FromRoute] DateTime settl
// Convert the date passed in to a guid
var aggregateId = settlementDate.Date.ToGuid();
+ Logger.LogInformation($"Settlement Aggregate Id {aggregateId}");
+
var settlementAggregate = await this.SettlmentAggregateRepository.GetLatestVersion(aggregateId, cancellationToken);
var settlementResponse = new SettlementResponse