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 @@ -4,9 +4,11 @@
using System.Threading;
using System.Threading.Tasks;
using BusinessLogic.Services;
using EstateManagement.Client;
using Microsoft.Extensions.Configuration;
using Models;
using Moq;
using SecurityService.Client;
using SettlementAggregates;
using Shared.DomainDrivenDesign.EventSourcing;
using Shared.EventStore.Aggregate;
Expand All @@ -23,16 +25,23 @@ public class SettlementDomainServiceTests

private Mock<IAggregateRepository<SettlementAggregate, DomainEvent>> settlementAggregateRepository;

private Mock<ISecurityServiceClient> securityServiceClient;

private Mock<IEstateClient> estateClient;

private SettlementDomainService settlementDomainService;

public SettlementDomainServiceTests() {
this.transactionAggregateRepository =
new Mock<IAggregateRepository<TransactionAggregate, DomainEvent>>();
this.settlementAggregateRepository =
new Mock<IAggregateRepository<SettlementAggregate, DomainEvent>>();
this.securityServiceClient = new Mock<ISecurityServiceClient>();
this.estateClient = new Mock<IEstateClient>();

this.settlementDomainService =
new SettlementDomainService(this.transactionAggregateRepository.Object, settlementAggregateRepository.Object);
new SettlementDomainService(this.transactionAggregateRepository.Object, settlementAggregateRepository.Object,
this.securityServiceClient.Object, this.estateClient.Object);

IConfigurationRoot configurationRoot = new ConfigurationBuilder().AddInMemoryCollection(TestData.DefaultAppSettings).Build();
ConfigurationReader.Initialise(configurationRoot);
Expand All @@ -48,6 +57,11 @@ public async Task SettlementDomainService_ProcessSettlement_SettlementIsProcesse
this.transactionAggregateRepository.Setup(s => s.GetLatestVersion(It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(TestData.GetCompletedAuthorisedSaleTransactionAggregate);

this.securityServiceClient.Setup(s => s.GetToken(It.IsAny<String>(), It.IsAny<String>(), It.IsAny<CancellationToken>())).ReturnsAsync(TestData.TokenResponse);

this.estateClient.Setup(e => e.GetMerchant(It.IsAny<String>(), It.IsAny<Guid>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(TestData.GetMerchantResponseWithOperator1);

ProcessSettlementResponse response = await settlementDomainService.ProcessSettlement(TestData.SettlementDate,
TestData.EstateId,
TestData.MerchantId,
Expand Down Expand Up @@ -82,6 +96,11 @@ public async Task SettlementDomainService_ProcessSettlement_SettlementAggregateN
settlementAggregateRepository.Setup(s => s.GetLatestVersion(It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(TestData.GetCreatedSettlementAggregate);

this.securityServiceClient.Setup(s => s.GetToken(It.IsAny<String>(), It.IsAny<String>(), It.IsAny<CancellationToken>())).ReturnsAsync(TestData.TokenResponse);

this.estateClient.Setup(e => e.GetMerchant(It.IsAny<String>(), It.IsAny<Guid>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(TestData.GetMerchantResponseWithOperator1);

ProcessSettlementResponse response = await settlementDomainService.ProcessSettlement(TestData.SettlementDate,
TestData.EstateId,
TestData.MerchantId,
Expand All @@ -99,6 +118,11 @@ public async Task SettlementDomainService_ProcessSettlement_AddSettledFeeThrownE
settlementAggregateRepository.Setup(s => s.GetLatestVersion(It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(TestData.GetSettlementAggregateWithPendingMerchantFees(10));

this.securityServiceClient.Setup(s => s.GetToken(It.IsAny<String>(), It.IsAny<String>(), It.IsAny<CancellationToken>())).ReturnsAsync(TestData.TokenResponse);

this.estateClient.Setup(e => e.GetMerchant(It.IsAny<String>(), It.IsAny<Guid>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(TestData.GetMerchantResponseWithOperator1);

ProcessSettlementResponse response = await settlementDomainService.ProcessSettlement(TestData.SettlementDate,
TestData.EstateId,
TestData.MerchantId,
Expand All @@ -110,4 +134,4 @@ public async Task SettlementDomainService_ProcessSettlement_AddSettledFeeThrownE
response.NumberOfFeesSuccessfullySettled.ShouldBe(0);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,21 @@
{
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Common;
using EstateManagement.Client;
using EstateManagement.DataTransferObjects;
using EstateManagement.DataTransferObjects.Responses;
using Models;
using SecurityService.Client;
using SecurityService.DataTransferObjects.Responses;
using SettlementAggregates;
using Shared.DomainDrivenDesign.EventSourcing;
using Shared.EventStore.Aggregate;
using Shared.General;
using Shared.Logger;
using TransactionAggregate;

Expand All @@ -18,6 +25,10 @@ public class SettlementDomainService : ISettlementDomainService
private readonly IAggregateRepository<TransactionAggregate, DomainEvent> TransactionAggregateRepository;
private readonly IAggregateRepository<SettlementAggregate, DomainEvent> SettlementAggregateRepository;

private readonly ISecurityServiceClient SecurityServiceClient;

private readonly IEstateClient EstateClient;

public async Task<ProcessSettlementResponse> ProcessSettlement(DateTime settlementDate,
Guid estateId,
Guid merchantId,
Expand All @@ -36,6 +47,21 @@ public async Task<ProcessSettlementResponse> ProcessSettlement(DateTime settleme
return response;
}

this.TokenResponse = await this.GetToken(cancellationToken);

MerchantResponse merchant = await this.EstateClient.GetMerchant(this.TokenResponse.AccessToken,
estateId,
merchantId,
cancellationToken);

if (merchant.SettlementSchedule == SettlementSchedule.Immediate){
// Mark the settlement as completed
settlementAggregate.StartProcessing(DateTime.Now);
settlementAggregate.ManuallyComplete();
await this.SettlementAggregateRepository.SaveChanges(settlementAggregate, cancellationToken);
return response;
}

List<(Guid transactionId, Guid merchantId, CalculatedFee calculatedFee)> feesToBeSettled = settlementAggregate.GetFeesToBeSettled();
response.NumberOfFeesPendingSettlement = feesToBeSettled.Count;

Expand Down Expand Up @@ -71,10 +97,43 @@ public async Task<ProcessSettlementResponse> ProcessSettlement(DateTime settleme
}

public SettlementDomainService(IAggregateRepository<TransactionAggregate, DomainEvent> transactionAggregateRepository,
IAggregateRepository<SettlementAggregate, DomainEvent> settlementAggregateRepository)
IAggregateRepository<SettlementAggregate, DomainEvent> settlementAggregateRepository,
ISecurityServiceClient securityServiceClient,
IEstateClient estateClient)
{
this.TransactionAggregateRepository = transactionAggregateRepository;
this.SettlementAggregateRepository = settlementAggregateRepository;
this.SecurityServiceClient = securityServiceClient;
this.EstateClient = estateClient;
}

private TokenResponse TokenResponse;

[ExcludeFromCodeCoverage]
private async Task<TokenResponse> GetToken(CancellationToken cancellationToken)
{
// Get a token to talk to the estate service
String clientId = ConfigurationReader.GetValue("AppSettings", "ClientId");
String clientSecret = ConfigurationReader.GetValue("AppSettings", "ClientSecret");
Logger.LogInformation($"Client Id is {clientId}");
Logger.LogInformation($"Client Secret is {clientSecret}");

if (this.TokenResponse == null)
{
TokenResponse token = await this.SecurityServiceClient.GetToken(clientId, clientSecret, cancellationToken);
Logger.LogInformation($"Token is {token.AccessToken}");
return token;
}

if (this.TokenResponse.Expires.UtcDateTime.Subtract(DateTime.UtcNow) < TimeSpan.FromMinutes(2))
{
Logger.LogInformation($"Token is about to expire at {this.TokenResponse.Expires.DateTime:O}");
TokenResponse token = await this.SecurityServiceClient.GetToken(clientId, clientSecret, cancellationToken);
Logger.LogInformation($"Token is {token.AccessToken}");
return token;
}

return this.TokenResponse;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ public void SettlementAggregate_StartProcessing_CalledTwice_ProcessingStarted(){
aggregate.StartProcessing(TestData.SettlementProcessingStartedDateTimeSecondCall);

aggregate.ProcessingStarted.ShouldBeTrue();
aggregate.ProcessingStartedDateTime.ShouldBe(TestData.SettlementProcessingStartedDateTimeSecondCall);
aggregate.ProcessingStartedDateTime.ShouldBe(TestData.SettlementProcessingStartedDateTimeSecondCall);
}

[Fact]
Expand All @@ -221,5 +221,38 @@ public void SettlementAggregate_StartProcessing_SettlementNotCreated_ErrorThron(
aggregate.StartProcessing(TestData.SettlementProcessingStartedDateTime);
});
}

[Fact]
public void SettlementAggregate_ManuallyComplete_SettlementCompleted()
{
SettlementAggregate aggregate = SettlementAggregate.Create(TestData.SettlementAggregateId);
aggregate.Create(TestData.EstateId, TestData.MerchantId, TestData.SettlementDate);
aggregate.StartProcessing(TestData.SettlementProcessingStartedDateTime);
aggregate.ManuallyComplete();

aggregate.SettlementComplete.ShouldBeTrue();
}

[Fact]
public void SettlementAggregate_ManuallyComplete_CalledTwice_SettlementCompleted()
{
SettlementAggregate aggregate = SettlementAggregate.Create(TestData.SettlementAggregateId);
aggregate.Create(TestData.EstateId, TestData.MerchantId, TestData.SettlementDate);
aggregate.StartProcessing(TestData.SettlementProcessingStartedDateTime);
aggregate.ManuallyComplete();
aggregate.ManuallyComplete();

aggregate.SettlementComplete.ShouldBeTrue();
}

[Fact]
public void SettlementAggregate_ManuallyComplete_SettlementNotCreated_ErrorThron()
{
SettlementAggregate aggregate = SettlementAggregate.Create(TestData.SettlementAggregateId);

Should.Throw<InvalidOperationException>(() => {
aggregate.ManuallyComplete();
});
}
}
}
13 changes: 12 additions & 1 deletion TransactionProcessor.SettlementAggregates/SettlementAggregate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,17 @@ public static void StartProcessing(this SettlementAggregate aggregate, DateTime
aggregate.ApplyAndAppend(startedEvent);
}

public static void ManuallyComplete(this SettlementAggregate aggregate){

aggregate.CheckHasBeenCreated();

if (aggregate.SettlementComplete)
return;

SettlementCompletedEvent pendingSettlementCompletedEvent = new SettlementCompletedEvent(aggregate.AggregateId, aggregate.EstateId);
aggregate.ApplyAndAppend(pendingSettlementCompletedEvent);
}

public static void MarkFeeAsSettled(this SettlementAggregate aggregate, Guid merchantId, Guid transactionId, Guid feeId)
{
(Guid transactionId, Guid merchantId, CalculatedFee calculatedFee) pendingFee = SettlementAggregateExtensions.GetPendingFee(aggregate, merchantId, transactionId, feeId);
Expand Down Expand Up @@ -182,7 +193,7 @@ private static void CheckHasNotAlreadyBeenCreated(this SettlementAggregate aggre
throw new InvalidOperationException($"Pending Settlement already created for this date {aggregate.SettlementDate}");
}
}

public static void PlayEvent(this SettlementAggregate aggregate, MerchantFeeSettledEvent domainEvent)
{
// Add to the settled fees list
Expand Down