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 @@ -208,11 +208,11 @@ public async Task FloatDomainService_RecordCreditPurchase_ExceptionThrown()
public async Task FloatDomainService_RecordCreditPurchase_FloatActivity_PurchaseRecorded()
{
FloatActivityAggregate floatAggregate = FloatActivityAggregate.Create(TestData.FloatAggregateId);
this.FloatActivityAggregateRepository.Setup(f => f.GetLatestVersionFromLastEvent(It.IsAny<Guid>(), It.IsAny<CancellationToken>())).ReturnsAsync(floatAggregate);
this.FloatActivityAggregateRepository.Setup(f => f.GetLatestVersion(It.IsAny<Guid>(), It.IsAny<CancellationToken>())).ReturnsAsync(floatAggregate);
this.FloatActivityAggregateRepository.Setup(f => f.SaveChanges(It.IsAny<FloatActivityAggregate>(), It.IsAny<CancellationToken>())).ReturnsAsync(Result.Success);

var command = new FloatActivityCommands.RecordCreditPurchaseCommand(TestData.EstateId,
TestData.FloatAggregateId, TestData.CreditPurchasedDateTime, TestData.FloatCreditAmount);
TestData.FloatAggregateId, TestData.CreditPurchasedDateTime, TestData.FloatCreditAmount, TestData.FloatCreditId);
var result = await this.FloatDomainService.RecordCreditPurchase(command, CancellationToken.None);
result.IsSuccess.ShouldBeTrue();
}
Expand All @@ -221,11 +221,11 @@ public async Task FloatDomainService_RecordCreditPurchase_FloatActivity_Purchase
public async Task FloatDomainService_RecordCreditPurchase_FloatActivity_SaveFailed()
{
FloatActivityAggregate floatAggregate = FloatActivityAggregate.Create(TestData.FloatAggregateId);
this.FloatActivityAggregateRepository.Setup(f => f.GetLatestVersionFromLastEvent(It.IsAny<Guid>(), It.IsAny<CancellationToken>())).ReturnsAsync(floatAggregate);
this.FloatActivityAggregateRepository.Setup(f => f.GetLatestVersion(It.IsAny<Guid>(), It.IsAny<CancellationToken>())).ReturnsAsync(floatAggregate);
this.FloatActivityAggregateRepository.Setup(f => f.SaveChanges(It.IsAny<FloatActivityAggregate>(), It.IsAny<CancellationToken>())).ReturnsAsync(Result.Failure);

var command = new FloatActivityCommands.RecordCreditPurchaseCommand(TestData.EstateId,
TestData.FloatAggregateId, TestData.CreditPurchasedDateTime, TestData.FloatCreditAmount);
TestData.FloatAggregateId, TestData.CreditPurchasedDateTime, TestData.FloatCreditAmount, TestData.FloatCreditId);
var result = await this.FloatDomainService.RecordCreditPurchase(command, CancellationToken.None);
result.IsFailed.ShouldBeTrue();
}
Expand All @@ -234,11 +234,11 @@ public async Task FloatDomainService_RecordCreditPurchase_FloatActivity_SaveFail
public async Task FloatDomainService_RecordCreditPurchase_FloatActivity_ExceptionThrown()
{
FloatActivityAggregate floatAggregate = FloatActivityAggregate.Create(TestData.FloatAggregateId);
this.FloatActivityAggregateRepository.Setup(f => f.GetLatestVersionFromLastEvent(It.IsAny<Guid>(), It.IsAny<CancellationToken>())).ReturnsAsync(floatAggregate);
this.FloatActivityAggregateRepository.Setup(f => f.GetLatestVersion(It.IsAny<Guid>(), It.IsAny<CancellationToken>())).ReturnsAsync(floatAggregate);
this.FloatActivityAggregateRepository.Setup(f => f.SaveChanges(It.IsAny<FloatActivityAggregate>(), It.IsAny<CancellationToken>())).ThrowsAsync(new Exception());

var command = new FloatActivityCommands.RecordCreditPurchaseCommand(TestData.EstateId,
TestData.FloatAggregateId, TestData.CreditPurchasedDateTime, TestData.FloatCreditAmount);
TestData.FloatAggregateId, TestData.CreditPurchasedDateTime, TestData.FloatCreditAmount, TestData.FloatCreditId);
var result = await this.FloatDomainService.RecordCreditPurchase(command, CancellationToken.None);
result.IsFailed.ShouldBeTrue();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ private async Task<Result> HandleSpecificDomainEvent(FloatCreditPurchasedEvent d
CancellationToken cancellationToken) {
FloatActivityCommands.RecordCreditPurchaseCommand command =
new(domainEvent.EstateId, domainEvent.FloatId,
domainEvent.CreditPurchasedDateTime, domainEvent.Amount);
domainEvent.CreditPurchasedDateTime, domainEvent.Amount, domainEvent.EventId);

return await this.Mediator.Send(command, cancellationToken);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace TransactionProcessor.BusinessLogic.Requests;

[ExcludeFromCodeCoverage]
public record FloatActivityCommands {
public record RecordCreditPurchaseCommand(Guid EstateId, Guid FloatId, DateTime CreditPurchasedDateTime, Decimal Amount) : IRequest<Result>;
public record RecordCreditPurchaseCommand(Guid EstateId, Guid FloatId, DateTime CreditPurchasedDateTime, Decimal Amount, Guid CreditId) : IRequest<Result>;

public record RecordTransactionCommand(Guid EstateId, Guid TransactionId) : IRequest<Result>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ private async Task<Result> ApplyFloatActivityUpdates(Func<FloatActivityAggregate
{
try
{
Result<FloatActivityAggregate> getFloatResult = await this.FloatActivityAggregateRepository.GetLatestVersionFromLastEvent(floatId, cancellationToken);
Result<FloatActivityAggregate> getFloatResult = await this.FloatActivityAggregateRepository.GetLatestVersion(floatId, cancellationToken);
Result<FloatActivityAggregate> floatActivityAggregateResult = DomainServiceHelper.HandleGetAggregateResult(getFloatResult, floatId, isNotFoundError);

if (floatActivityAggregateResult.IsFailed)
Expand Down Expand Up @@ -192,7 +192,7 @@ public async Task<Result> RecordCreditPurchase(FloatCommands.RecordCreditPurchas
public async Task<Result> RecordCreditPurchase(FloatActivityCommands.RecordCreditPurchaseCommand command,
CancellationToken cancellationToken) {
Result result = await ApplyFloatActivityUpdates((floatAggregate) => {
floatAggregate.RecordCreditPurchase(command.EstateId, command.CreditPurchasedDateTime, command.Amount);
floatAggregate.RecordCreditPurchase(command.EstateId, command.CreditPurchasedDateTime, command.Amount, command.CreditId);
return Result.Success();
}, command.FloatId, cancellationToken,false);
return result;
Expand All @@ -207,7 +207,7 @@ public async Task<Result> RecordTransaction(FloatActivityCommands.RecordTransact
Guid floatId = IdGenerationService.GenerateFloatAggregateId(command.EstateId, getTransactionResult.Data.ContractId, getTransactionResult.Data.ProductId);

Result result = await ApplyFloatActivityUpdates((floatAggregate) => {
floatAggregate.RecordTransactionAgainstFloat(command.EstateId, getTransactionResult.Data.TransactionDateTime, getTransactionResult.Data.TransactionAmount.GetValueOrDefault());
floatAggregate.RecordTransactionAgainstFloat(command.EstateId, getTransactionResult.Data.TransactionDateTime, getTransactionResult.Data.TransactionAmount.GetValueOrDefault(), command.TransactionId);
return Result.Success();
}, floatId, cancellationToken, false);
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ namespace TransactionProcessor.Float.DomainEvents
public record FloatAggregateCreditedEvent(Guid FloatId,
Guid EstateId,
DateTime ActivityDateTime,
Decimal Amount) : DomainEvent(FloatId, Guid.NewGuid());
Decimal Amount, Guid CreditId) : DomainEvent(FloatId, Guid.NewGuid());

[ExcludeFromCodeCoverage]
public record FloatAggregateDebitedEvent(Guid FloatId,
Guid EstateId,
DateTime ActivityDateTime,
Decimal Amount) : DomainEvent(FloatId, Guid.NewGuid());
Decimal Amount, Guid DebitId) : DomainEvent(FloatId, Guid.NewGuid());
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,37 @@ public void FloatActivityAggregate_CanBeCreated_IsCreated()
[Fact]
public void FloatActivityAggregate_RecordCreditPurchase_PurchaseRecorded() {
FloatActivityAggregate aggregate = FloatActivityAggregate.Create(TestData.FloatAggregateId);
aggregate.RecordCreditPurchase(TestData.EstateId, TestData.CreditPurchasedDateTime, TestData.FloatCreditAmount);
aggregate.RecordCreditPurchase(TestData.EstateId, TestData.CreditPurchasedDateTime, TestData.FloatCreditAmount, TestData.FloatCreditId);
aggregate.CreditCount.ShouldBe(1);
aggregate.Credits.Contains(TestData.FloatCreditId).ShouldBeTrue();
}

[Fact]
public void FloatActivityAggregate_RecordCreditPurchase_DuplicateCredit_PurchaseNotRecorded()
{
FloatActivityAggregate aggregate = FloatActivityAggregate.Create(TestData.FloatAggregateId);
aggregate.RecordCreditPurchase(TestData.EstateId, TestData.CreditPurchasedDateTime, TestData.FloatCreditAmount, TestData.FloatCreditId);
aggregate.CreditCount.ShouldBe(1);
aggregate.RecordCreditPurchase(TestData.EstateId, TestData.CreditPurchasedDateTime, TestData.FloatCreditAmount, TestData.FloatCreditId);
aggregate.CreditCount.ShouldBe(1);
}

[Fact]
public void FloatActivityAggregate_RecordTransactionAgainstFloat_TransactionRecorded()
{
FloatActivityAggregate aggregate = FloatActivityAggregate.Create(TestData.FloatAggregateId);
aggregate.RecordTransactionAgainstFloat(TestData.EstateId, TestData.TransactionDateTime, TestData.TransactionAmount);
aggregate.RecordTransactionAgainstFloat(TestData.EstateId, TestData.TransactionDateTime, TestData.TransactionAmount, TestData.TransactionId);
aggregate.DebitCount.ShouldBe(1);
aggregate.Debits.Contains(TestData.TransactionId).ShouldBeTrue();
}

[Fact]
public void FloatActivityAggregate_RecordTransactionAgainstFloat_DuplicateTransaction_TransactionNotRecorded()
{
FloatActivityAggregate aggregate = FloatActivityAggregate.Create(TestData.FloatAggregateId);
aggregate.RecordTransactionAgainstFloat(TestData.EstateId, TestData.TransactionDateTime, TestData.TransactionAmount, TestData.TransactionId);
aggregate.DebitCount.ShouldBe(1);
aggregate.RecordTransactionAgainstFloat(TestData.EstateId, TestData.TransactionDateTime, TestData.TransactionAmount, TestData.TransactionId);
aggregate.DebitCount.ShouldBe(1);
}
}
49 changes: 35 additions & 14 deletions TransactionProcessor.FloatAggregate/FloatActivityAggregate.cs
Original file line number Diff line number Diff line change
@@ -1,41 +1,59 @@
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using Shared.DomainDrivenDesign.EventSourcing;
using Shared.EventStore.Aggregate;
using Shared.General;
using TransactionProcessor.Float.DomainEvents;

namespace TransactionProcessor.FloatAggregate;

public static class FloatActivityAggregateExtensions
{
public static void PlayEvent(this FloatActivityAggregate aggregate, FloatAggregateCreditedEvent domainEvent)
{
public static class FloatActivityAggregateExtensions {

public static void PlayEvent(this FloatActivityAggregate aggregate,
FloatAggregateCreditedEvent domainEvent) {
aggregate.CreditCount++;
aggregate.Credits.Add(domainEvent.CreditId);
}

public static void PlayEvent(this FloatActivityAggregate aggregate, FloatAggregateDebitedEvent domainEvent)
{
public static void PlayEvent(this FloatActivityAggregate aggregate,
FloatAggregateDebitedEvent domainEvent) {
aggregate.DebitCount++;
aggregate.Debits.Add(domainEvent.DebitId);
}

public static void RecordCreditPurchase(this FloatActivityAggregate aggregate,
Guid estateId,
DateTime activityDateTime,
Decimal creditAmount) {
FloatAggregateCreditedEvent floatAggregateCreditedEvent =
new (aggregate.AggregateId, estateId, activityDateTime, creditAmount);
Decimal creditAmount,
Guid creditId) {

if (aggregate.Credits.Any(c => c == creditId))

Check failure on line 30 in TransactionProcessor.FloatAggregate/FloatActivityAggregate.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

TransactionProcessor.FloatAggregate/FloatActivityAggregate.cs#L30

Add curly braces around the nested statement(s) in this 'if' block.
return;

FloatAggregateCreditedEvent floatAggregateCreditedEvent = new(aggregate.AggregateId, estateId, activityDateTime, creditAmount, creditId);
aggregate.ApplyAndAppend(floatAggregateCreditedEvent);
}

public static void RecordTransactionAgainstFloat(this FloatActivityAggregate aggregate, Guid estateId, DateTime activityDateTime, Decimal transactionAmount)
{
FloatAggregateDebitedEvent floatAggregateCreditedEvent =
new (aggregate.AggregateId, estateId, activityDateTime, transactionAmount);
public static void RecordTransactionAgainstFloat(this FloatActivityAggregate aggregate,
Guid estateId,
DateTime activityDateTime,
Decimal transactionAmount,
Guid transactionId) {
if (aggregate.Debits.Any(c => c == transactionId))

Check failure on line 42 in TransactionProcessor.FloatAggregate/FloatActivityAggregate.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

TransactionProcessor.FloatAggregate/FloatActivityAggregate.cs#L42

Add curly braces around the nested statement(s) in this 'if' block.
return;

FloatAggregateDebitedEvent floatAggregateCreditedEvent = new(aggregate.AggregateId, estateId, activityDateTime, transactionAmount, transactionId);
aggregate.ApplyAndAppend(floatAggregateCreditedEvent);
}
}

public record FloatActivityAggregate : Aggregate {
public override void PlayEvent(IDomainEvent domainEvent) => FloatActivityAggregateExtensions.PlayEvent(this, (dynamic)domainEvent);

public Int32 CreditCount { get; internal set; }
public Int32 DebitCount { get; internal set; }
public List<Guid> Credits { get; internal set; }
public List<Guid> Debits { get; internal set; }
[ExcludeFromCodeCoverage]
protected override Object GetMetadata()
{
Expand All @@ -49,14 +67,17 @@
[ExcludeFromCodeCoverage]
public FloatActivityAggregate()
{

this.Credits = new List<Guid>();
this.Debits = new List<Guid>();
}

private FloatActivityAggregate(Guid aggregateId)
{
Guard.ThrowIfInvalidGuid(aggregateId, "Aggregate Id cannot be an Empty Guid");

this.AggregateId = aggregateId;
this.Credits = new List<Guid>();
this.Debits = new List<Guid>();
}

public static FloatActivityAggregate Create(Guid aggregateId)
Expand Down
3 changes: 2 additions & 1 deletion TransactionProcessor.Testing/TestData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,7 @@ public static Dictionary<String, String> AdditionalTransactionMetaDataForPataPaw
public static SettlementCommands.AddMerchantFeePendingSettlementCommand AddMerchantFeePendingSettlementCommand => new(TransactionId, CalculatedFeeValue, TransactionFeeCalculateDateTime, CalculationType.Fixed, TransactionFeeId, CalculatedFeeValue, TransactionFeeSettlementDueDate, MerchantId, EstateId);
public static SettlementCommands.AddSettledFeeToSettlementCommand AddSettledFeeToSettlementCommand => new(SettlementDate,MerchantId,EstateId,TransactionFeeId, TransactionId);

public static FloatActivityCommands.RecordCreditPurchaseCommand RecordCreditPurchaseCommand => new(EstateId, FloatAggregateId, CreditPurchasedDateTime, FloatCreditAmount);
public static FloatActivityCommands.RecordCreditPurchaseCommand RecordCreditPurchaseCommand => new(EstateId, FloatAggregateId, CreditPurchasedDateTime, FloatCreditAmount, FloatCreditId);
public static FloatActivityCommands.RecordTransactionCommand RecordTransactionCommand => new(EstateId, TransactionId);
public static TransactionCommands.CalculateFeesForTransactionCommand CalculateFeesForTransactionCommand => new(TransactionId, TransactionDateTime, EstateId, MerchantId);

Expand Down Expand Up @@ -1459,6 +1459,7 @@ public static SettlementAggregate GetSettlementAggregateWithNotAllFeesSettled(In

public static DateTime CreditPurchasedDateTime = DateTime.Now;

public static Guid FloatCreditId = Guid.Parse("97CAFCB1-B9BF-47FA-9438-422ABFCCD790");
public static Decimal FloatCreditAmount = 100m;

public static Decimal FloatCreditCostPrice = 90m;
Expand Down
Loading