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
31 changes: 17 additions & 14 deletions TransactionProcessor.Aggregates.Tests/FloatAggregateTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Shouldly;
using SimpleResults;
using TransactionProcessor.Testing;

namespace TransactionProcessor.Aggregates.Tests
Expand All @@ -17,7 +18,8 @@ public void FloatAggregate_CanBeCreated_IsCreated()
public void FloatAggregate_CreateFloat_IsCreated()
{
Aggregates.FloatAggregate aggregate = Aggregates.FloatAggregate.Create(TestData.FloatAggregateId);
aggregate.CreateFloat(TestData.EstateId, TestData.ContractId, TestData.ProductId, TestData.FloatCreatedDateTime);
Result result = aggregate.CreateFloat(TestData.EstateId, TestData.ContractId, TestData.ProductId, TestData.FloatCreatedDateTime);
result.IsSuccess.ShouldBeTrue();

aggregate.AggregateId.ShouldBe(TestData.FloatAggregateId);
aggregate.EstateId.ShouldBe(TestData.EstateId);
Expand All @@ -27,23 +29,21 @@ public void FloatAggregate_CreateFloat_IsCreated()
}

[Fact]
public void FloatAggregate_CreateFloat_FloatAlreadyCreated_ErrorThrown()
{
public void FloatAggregate_CreateFloat_FloatAlreadyCreated_NoErrorThrown() {
Aggregates.FloatAggregate aggregate = Aggregates.FloatAggregate.Create(TestData.FloatAggregateId);
aggregate.CreateFloat(TestData.EstateId, TestData.ContractId, TestData.ProductId, TestData.FloatCreatedDateTime);

Should.Throw<InvalidOperationException>(() => {
aggregate.CreateFloat(TestData.EstateId, TestData.ContractId, TestData.ProductId, TestData.FloatCreatedDateTime);
});
Result result = aggregate.CreateFloat(TestData.EstateId, TestData.ContractId, TestData.ProductId, TestData.FloatCreatedDateTime);
result.IsSuccess.ShouldBeTrue();
}

[Fact]
public void FloatAggregate_RecordCreditPurchase_CreditPurchaseIsRecorded()
{
Aggregates.FloatAggregate aggregate = Aggregates.FloatAggregate.Create(TestData.FloatAggregateId);
aggregate.CreateFloat(TestData.EstateId, TestData.ContractId, TestData.ProductId, TestData.FloatCreatedDateTime);
aggregate.RecordCreditPurchase(DateTime.Now, 1000, 900);

Result result = aggregate.RecordCreditPurchase(DateTime.Now, 1000, 900);
result.IsSuccess.ShouldBeTrue();
aggregate.NumberOfCreditPurchases.ShouldBe(1);
aggregate.TotalCostPrice.ShouldBe(900);
aggregate.UnitCostPrice.ShouldBe(0.9m);
Expand All @@ -54,10 +54,11 @@ public void FloatAggregate_RecordCreditPurchase_CreditPurchaseIsRecorded()
public void FloatAggregate_RecordCreditPurchase_FloatNotCreated_ErrorThrown()
{
Aggregates.FloatAggregate aggregate = Aggregates.FloatAggregate.Create(TestData.FloatAggregateId);

Result result = aggregate.RecordCreditPurchase(DateTime.Now, 1000, 900);
result.IsFailed.ShouldBeTrue();
result.Status.ShouldBe(ResultStatus.Invalid);

Should.Throw<InvalidOperationException>(() => {
aggregate.RecordCreditPurchase(DateTime.Now, 1000, 900);
});
}

[Fact]
Expand Down Expand Up @@ -101,9 +102,11 @@ public void FloatAggregate_RecordCreditPurchase_DuplicateCreditPurchase_ErrorThr
DateTime purchaseDateTime = DateTime.Now;
aggregate.RecordCreditPurchase(purchaseDateTime, 1000, 900);

Should.Throw<InvalidOperationException>(() => {
aggregate.RecordCreditPurchase(purchaseDateTime, 1000, 900);
});
Result result = aggregate.RecordCreditPurchase(purchaseDateTime, 1000, 900);

result.IsFailed.ShouldBeTrue();
result.Status.ShouldBe(ResultStatus.Invalid);

}
}
}
52 changes: 30 additions & 22 deletions TransactionProcessor.Aggregates/FloatAggregate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Shared.DomainDrivenDesign.EventSourcing;
using Shared.EventStore.Aggregate;
using Shared.General;
using SimpleResults;
using TransactionProcessor.DomainEvents;

namespace TransactionProcessor.Aggregates
Expand All @@ -26,59 +27,66 @@ public static void PlayEvent(this FloatAggregate aggregate, FloatDomainEvents.Fl
aggregate.Credits.Add((domainEvent.CreditPurchasedDateTime, domainEvent.Amount, domainEvent.CostPrice));
}

public static void CreateFloat(this FloatAggregate aggregate,
public static Result CreateFloat(this FloatAggregate aggregate,
Guid estateId,
Guid contractId,
Guid productId,
DateTime createdDateTime)
{
aggregate.ValidateFloatIsNotAlreadyCreated();
if (aggregate.IsCreated) {
return Result.Success(); // Idempotent
}

FloatDomainEvents.FloatCreatedForContractProductEvent floatCreatedForContractProductEvent = new(aggregate.AggregateId,
estateId, contractId, productId, createdDateTime);

aggregate.ApplyAndAppend(floatCreatedForContractProductEvent);

return Result.Success();
}

public static void RecordCreditPurchase(this FloatAggregate aggregate, DateTime creditPurchasedDate, Decimal amount, Decimal costPrice)
public static Result RecordCreditPurchase(this FloatAggregate aggregate, DateTime creditPurchasedDate, Decimal amount, Decimal costPrice)
{
aggregate.ValidateFloatIsAlreadyCreated();
aggregate.ValidateCreditIsNotADuplicate(creditPurchasedDate, amount, costPrice);
Result result = aggregate.ValidateFloatIsAlreadyCreated();
if (result.IsFailed) {
return result;
}
result = aggregate.ValidateCreditIsNotADuplicate(creditPurchasedDate, amount, costPrice);
if (result.IsFailed) {
return result;
}

FloatDomainEvents.FloatCreditPurchasedEvent floatCreditPurchasedEvent = new(aggregate.AggregateId, aggregate.EstateId,
creditPurchasedDate, amount, costPrice);

aggregate.ApplyAndAppend(floatCreditPurchasedEvent);

return Result.Success();
}

public static Decimal GetUnitCostPrice(this FloatAggregate aggregate)
{
return Math.Round(aggregate.UnitCostPrice, 4);
}

public static void ValidateFloatIsAlreadyCreated(this FloatAggregate aggregate)
{
if (aggregate.IsCreated == false)
{
throw new InvalidOperationException($"Float Aggregate Id {aggregate.AggregateId} must be created to perform this operation");
public static Result ValidateFloatIsAlreadyCreated(this FloatAggregate aggregate) {
if (aggregate.IsCreated == false) {
return Result.Invalid($"Float Aggregate Id {aggregate.AggregateId} must be created to perform this operation");
}
}

public static void ValidateFloatIsNotAlreadyCreated(this FloatAggregate aggregate)
{
if (aggregate.IsCreated == true)
{
throw new InvalidOperationException($"Float Aggregate Id {aggregate.AggregateId} must not be created to perform this operation");
}
return Result.Success();
}

public static void ValidateCreditIsNotADuplicate(this FloatAggregate aggregate, DateTime creditPurchasedDate, Decimal amount, Decimal costPrice)
{
public static Result ValidateCreditIsNotADuplicate(this FloatAggregate aggregate,
DateTime creditPurchasedDate,
Decimal amount,
Decimal costPrice) {
Boolean isDuplicate = aggregate.Credits.Any(c => c.costPrice == costPrice && c.amount == amount && c.creditPurchasedDate == creditPurchasedDate);
if (isDuplicate == true)
{
throw new InvalidOperationException($"Float Aggregate Id {aggregate.AggregateId} already has a credit with this information recorded");
if (isDuplicate) {
return Result.Invalid($"Float Aggregate Id {aggregate.AggregateId} already has a credit with this information recorded");
}

return Result.Success();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@

FloatAggregate floatAggregate = getFloatResult.Data;

floatAggregate.CreateFloat(command.EstateId, command.ContractId, command.ProductId, command.CreateDateTime);
Result stateResult = floatAggregate.CreateFloat(command.EstateId, command.ContractId, command.ProductId, command.CreateDateTime);
if (stateResult.IsFailed)

Check notice on line 94 in TransactionProcessor.BusinessLogic/Services/FloatDomainService.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

TransactionProcessor.BusinessLogic/Services/FloatDomainService.cs#L94

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

Result saveResult = await this.AggregateService.Save(floatAggregate, cancellationToken);
if (saveResult.IsFailed)
Expand All @@ -112,7 +114,9 @@

FloatAggregate floatAggregate = getFloatResult.Data;

floatAggregate.RecordCreditPurchase(command.PurchaseDateTime, command.CreditAmount, command.CostPrice);
Result stateResult = floatAggregate.RecordCreditPurchase(command.PurchaseDateTime, command.CreditAmount, command.CostPrice);
if (stateResult.IsFailed)
return ResultHelpers.CreateFailure(stateResult);

Result saveResult = await this.AggregateService.Save(floatAggregate, cancellationToken);
if (saveResult.IsFailed)
Expand Down
Loading