diff --git a/TransactionProcessor.Aggregates.Tests/MerchantStatementAggregateTests.cs b/TransactionProcessor.Aggregates.Tests/MerchantStatementAggregateTests.cs index 9cf6c31..b63bf44 100644 --- a/TransactionProcessor.Aggregates.Tests/MerchantStatementAggregateTests.cs +++ b/TransactionProcessor.Aggregates.Tests/MerchantStatementAggregateTests.cs @@ -1,4 +1,5 @@ using Shouldly; +using SimpleResults; using TransactionProcessor.Models.Merchant; using TransactionProcessor.Testing; @@ -48,5 +49,169 @@ public void MerchantStatementAggregate_RecordActivityDateOnStatement_DuplicateAc activityDates.ShouldNotBeEmpty(); activityDates.Count.ShouldBe(1); } + + [Fact] + public void MerchantStatementAggregate_RecordActivityDateOnStatement_InvalidStatementId_ErrorReturned() + { + MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); + Result result = merchantStatementAggregate.RecordActivityDateOnStatement(Guid.Empty, + TestData.StatementDate, TestData.EstateId, TestData.MerchantId, TestData.MerchantStatementForDateId1, + TestData.ActivityDate1); + result.IsFailed.ShouldBeTrue(); + result.Status.ShouldBe(ResultStatus.Invalid); + } + + [Fact] + public void MerchantStatementAggregate_RecordActivityDateOnStatement_InvalidEstateId_ErrorReturned() + { + MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); + Result result = merchantStatementAggregate.RecordActivityDateOnStatement(TestData.MerchantStatementId, + TestData.StatementDate, Guid.Empty, TestData.MerchantId, TestData.MerchantStatementForDateId1, + TestData.ActivityDate1); + result.IsFailed.ShouldBeTrue(); + result.Status.ShouldBe(ResultStatus.Invalid); + } + + [Fact] + public void MerchantStatementAggregate_RecordActivityDateOnStatement_InvalidMerchantId_ErrorReturned() + { + MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); + Result result = merchantStatementAggregate.RecordActivityDateOnStatement(TestData.MerchantStatementId, + TestData.StatementDate, TestData.EstateId, Guid.Empty, TestData.MerchantStatementForDateId1, + TestData.ActivityDate1); + result.IsFailed.ShouldBeTrue(); + result.Status.ShouldBe(ResultStatus.Invalid); + } + + [Fact] + public void MerchantStatementAggregate_AddDailySummaryRecord_RecordIsAdded() + { + MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); + Result result = merchantStatementAggregate.AddDailySummaryRecord(TestData.TransactionDateTime.Date, 1, 100.00m, 1, 0.10m, + 1, 1000, 1, 200); + result.IsSuccess.ShouldBeTrue(); + } + + [Fact] + public void MerchantStatementAggregate_AddDailySummaryRecord_DuplicateAdd_ExceptionIsThrown() + { + MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); + merchantStatementAggregate.AddDailySummaryRecord(TestData.TransactionDateTime.Date, 1, 100.00m, 1, 0.10m, + 1, 1000, 1, 200); + Result result = merchantStatementAggregate.AddDailySummaryRecord(TestData.TransactionDateTime.Date, 1, 100.00m, 1, 0.10m, + 1, 1000, 1, 200); + result.IsSuccess.ShouldBeTrue(); + } + + + [Fact] + public void MerchantStatementAggregate_GenerateStatement_StatementIsGenerated() + { + MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); + merchantStatementAggregate.AddDailySummaryRecord(TestData.TransactionDateTime.Date, 1, 100.00m, 1, 0.10m, + 1, 1000, 1, 200); + Result result = merchantStatementAggregate.GenerateStatement(TestData.StatementGeneratedDate); + result.IsSuccess.ShouldBeTrue(); + + MerchantStatement merchantStatement = merchantStatementAggregate.GetStatement(); + merchantStatement.IsGenerated.ShouldBeTrue(); + } + + [Fact] + public void MerchantStatementAggregate_GenerateStatement_StatementIsAlreadyGenerated_ExceptionThrown() + { + MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); + merchantStatementAggregate.AddDailySummaryRecord(TestData.TransactionDateTime.Date, 1, 100.00m, 1, 0.10m, 1, 1000, 1, 200); + merchantStatementAggregate.GenerateStatement(TestData.StatementGeneratedDate); + + Result result = merchantStatementAggregate.GenerateStatement(TestData.StatementGeneratedDate); + result.IsSuccess.ShouldBeTrue(); + } + + [Fact] + public void MerchantStatementAggregate_GenerateStatement_NoSummaries_ExceptionThrown() + { + MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); + + Result result = merchantStatementAggregate.GenerateStatement(TestData.StatementGeneratedDate); + result.IsFailed.ShouldBeTrue(); + result.Status.ShouldBe(ResultStatus.Invalid); + } + + [Fact] + public void MerchantStatementAggregate_BuildStatement_StatementIsBuilt() + { + MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); + merchantStatementAggregate.AddDailySummaryRecord(TestData.TransactionDateTime.Date, 1, 100.00m, 1, 0.10m, 1, 1000, 1, 200); + merchantStatementAggregate.GenerateStatement(TestData.StatementGeneratedDate); + Result result = merchantStatementAggregate.BuildStatement(TestData.StatementBuiltDate, TestData.StatementData); + result.IsSuccess.ShouldBeTrue(); + + MerchantStatement merchantStatement = merchantStatementAggregate.GetStatement(); + merchantStatement.BuiltDateTime.ShouldBe(TestData.StatementBuiltDate); + } + + [Fact] + public void MerchantStatementAggregate_BuildStatement_StatementIsAlreadyBuilt_NoErrorThrown() + { + MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); + merchantStatementAggregate.AddDailySummaryRecord(TestData.TransactionDateTime.Date, 1, 100.00m, 1, 0.10m, 1, 1000, 1, 200); + merchantStatementAggregate.GenerateStatement(TestData.StatementGeneratedDate); + merchantStatementAggregate.BuildStatement(TestData.StatementBuiltDate, TestData.StatementData); + + Result result = merchantStatementAggregate.BuildStatement(TestData.StatementBuiltDate, TestData.StatementData); + result.IsSuccess.ShouldBeTrue(); + } + + [Fact] + public void MerchantStatementAggregate_BuildStatement_StatementIsNotGenerated_ExceptionThrown() + { + MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); + merchantStatementAggregate.AddDailySummaryRecord(TestData.TransactionDateTime.Date, 1, 100.00m, 1, 0.10m, 1, 1000, 1, 200); + + Result result = merchantStatementAggregate.BuildStatement(TestData.StatementBuiltDate, TestData.StatementData); + result.IsFailed.ShouldBeTrue(); + result.Status.ShouldBe(ResultStatus.Invalid); + } + + [Fact] + public void MerchantStatementAggregate_EmailStatement_StatementIsEmailed() + { + MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); + merchantStatementAggregate.AddDailySummaryRecord(TestData.TransactionDateTime.Date, 1, 100.00m, 1, 0.10m, 1, 1000, 1, 200); + merchantStatementAggregate.GenerateStatement(TestData.StatementGeneratedDate); + merchantStatementAggregate.BuildStatement(TestData.StatementBuiltDate, TestData.StatementData); + + Result result = merchantStatementAggregate.EmailStatement(TestData.StatementEmailedDate, TestData.MessageId); + result.IsSuccess.ShouldBeTrue(); + + MerchantStatement merchantStatement = merchantStatementAggregate.GetStatement(); + merchantStatement.HasBeenEmailed.ShouldBeTrue(); + } + + [Fact] + public void MerchantStatementAggregate_EmailStatement_StatementIsAlreadyEmailed_ExceptionThrown() + { + MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); + merchantStatementAggregate.AddDailySummaryRecord(TestData.TransactionDateTime.Date, 1, 100.00m, 1, 0.10m, 1, 1000, 1, 200); + merchantStatementAggregate.GenerateStatement(TestData.StatementGeneratedDate); + merchantStatementAggregate.BuildStatement(TestData.StatementBuiltDate, TestData.StatementData); + merchantStatementAggregate.EmailStatement(TestData.StatementEmailedDate, TestData.MessageId); + + Result result = merchantStatementAggregate.EmailStatement(TestData.StatementEmailedDate, TestData.MessageId); + result.IsSuccess.ShouldBeTrue(); + } + + [Fact] + public void MerchantStatementAggregate_EmailStatement_StatementIsNotBuilt_ExceptionThrown() + { + MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); + merchantStatementAggregate.AddDailySummaryRecord(TestData.TransactionDateTime.Date, 1, 100.00m, 1, 0.10m, 1, 1000, 1, 200); + merchantStatementAggregate.GenerateStatement(TestData.StatementGeneratedDate); + + var result = merchantStatementAggregate.EmailStatement(TestData.StatementEmailedDate, TestData.MessageId); + result.IsFailed.ShouldBeTrue(); + result.Status.ShouldBe(ResultStatus.Invalid); + } } } diff --git a/TransactionProcessor.Aggregates.Tests/MerchantStatementForDateAggregateTests.cs b/TransactionProcessor.Aggregates.Tests/MerchantStatementForDateAggregateTests.cs index 684c547..30a8ca7 100644 --- a/TransactionProcessor.Aggregates.Tests/MerchantStatementForDateAggregateTests.cs +++ b/TransactionProcessor.Aggregates.Tests/MerchantStatementForDateAggregateTests.cs @@ -127,133 +127,5 @@ public void MerchantStatementForDateAggregate_AddWithdrawalToStatement_Withdrawa statementLines.ShouldNotBeNull(); statementLines.ShouldNotBeEmpty(); statementLines.Count.ShouldBe(1); - } - - - [Fact] - public void MerchantStatementAggregate_AddDailySummaryRecord_RecordIsAdded() { - MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); - Should.NotThrow(() => { merchantStatementAggregate.AddDailySummaryRecord(TestData.TransactionDateTime.Date, 1, 100.00m, 1, 0.10m, - 1, 1000, 1, 200); }); - } - - [Fact] - public void MerchantStatementAggregate_AddDailySummaryRecord_DuplicateAdd_ExceptionIsThrown() - { - MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); - merchantStatementAggregate.AddDailySummaryRecord(TestData.TransactionDateTime.Date, 1, 100.00m, 1, 0.10m, - 1, 1000, 1, 200); - Should.Throw(() => { merchantStatementAggregate.AddDailySummaryRecord(TestData.TransactionDateTime.Date, 1, 100.00m, 1, 0.10m, - 1, 1000, 1, 200); }); - } - - - [Fact] - public void MerchantStatementAggregate_GenerateStatement_StatementIsGenerated() - { - MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); - merchantStatementAggregate.AddDailySummaryRecord(TestData.TransactionDateTime.Date, 1, 100.00m, 1, 0.10m, - 1, 1000, 1, 200); - merchantStatementAggregate.GenerateStatement(TestData.StatementGeneratedDate); - - MerchantStatement merchantStatement = merchantStatementAggregate.GetStatement(); - merchantStatement.IsGenerated.ShouldBeTrue(); - } - - [Fact] - public void MerchantStatementAggregate_GenerateStatement_StatementIsAlreadyGenerated_ExceptionThrown() - { - MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); - merchantStatementAggregate.AddDailySummaryRecord(TestData.TransactionDateTime.Date, 1, 100.00m, 1, 0.10m, 1, 1000, 1, 200); - merchantStatementAggregate.GenerateStatement(TestData.StatementGeneratedDate); - Should.Throw(() => { - merchantStatementAggregate.GenerateStatement(TestData.StatementGeneratedDate); - }); - } - - [Fact] - public void MerchantStatementAggregate_GenerateStatement_NoSummaries_ExceptionThrown() - { - MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); - - Should.Throw(() => { - merchantStatementAggregate.GenerateStatement(TestData.StatementGeneratedDate); - }); - } - - [Fact] - public void MerchantStatementAggregate_BuildStatement_StatementIsBuilt() - { - MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); - merchantStatementAggregate.AddDailySummaryRecord(TestData.TransactionDateTime.Date, 1, 100.00m, 1, 0.10m, 1, 1000, 1, 200); - merchantStatementAggregate.GenerateStatement(TestData.StatementGeneratedDate); - merchantStatementAggregate.BuildStatement(TestData.StatementBuiltDate,TestData.StatementData); - - MerchantStatement merchantStatement = merchantStatementAggregate.GetStatement(); - merchantStatement.BuiltDateTime.ShouldBe(TestData.StatementBuiltDate); - } - - [Fact] - public void MerchantStatementAggregate_BuildStatement_StatementIsAlreadyBuilt_ExceptionThrown() - { - MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); - merchantStatementAggregate.AddDailySummaryRecord(TestData.TransactionDateTime.Date, 1, 100.00m, 1, 0.10m, 1, 1000, 1, 200); - merchantStatementAggregate.GenerateStatement(TestData.StatementGeneratedDate); - merchantStatementAggregate.BuildStatement(TestData.StatementBuiltDate, TestData.StatementData); - - Should.Throw(() => { - merchantStatementAggregate.BuildStatement(TestData.StatementBuiltDate, TestData.StatementData); - }); - } - - [Fact] - public void MerchantStatementAggregate_BuildStatement_StatementIsNotGenerated_ExceptionThrown() - { - MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); - merchantStatementAggregate.AddDailySummaryRecord(TestData.TransactionDateTime.Date, 1, 100.00m, 1, 0.10m, 1, 1000, 1, 200); - - Should.Throw(() => { - merchantStatementAggregate.BuildStatement(TestData.StatementBuiltDate, TestData.StatementData); - }); - } - - [Fact] - public void MerchantStatementAggregate_EmailStatement_StatementIsEmailed() - { - MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); - merchantStatementAggregate.AddDailySummaryRecord(TestData.TransactionDateTime.Date, 1, 100.00m, 1, 0.10m, 1, 1000, 1, 200); - merchantStatementAggregate.GenerateStatement(TestData.StatementGeneratedDate); - merchantStatementAggregate.BuildStatement(TestData.StatementBuiltDate, TestData.StatementData); - - merchantStatementAggregate.EmailStatement(TestData.StatementEmailedDate, TestData.MessageId); - - MerchantStatement merchantStatement = merchantStatementAggregate.GetStatement(); - merchantStatement.HasBeenEmailed.ShouldBeTrue(); - } - - [Fact] - public void MerchantStatementAggregate_EmailStatement_StatementIsAlreadyEmailed_ExceptionThrown() - { - MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); - merchantStatementAggregate.AddDailySummaryRecord(TestData.TransactionDateTime.Date, 1, 100.00m, 1, 0.10m, 1, 1000, 1, 200); - merchantStatementAggregate.GenerateStatement(TestData.StatementGeneratedDate); - merchantStatementAggregate.BuildStatement(TestData.StatementBuiltDate, TestData.StatementData); - merchantStatementAggregate.EmailStatement(TestData.StatementEmailedDate, TestData.MessageId); - - Should.Throw(() => { - merchantStatementAggregate.EmailStatement(TestData.StatementEmailedDate, TestData.MessageId); - }); - } - - [Fact] - public void MerchantStatementAggregate_EmailStatement_StatementIsNotBuilt_ExceptionThrown() - { - MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); - merchantStatementAggregate.AddDailySummaryRecord(TestData.TransactionDateTime.Date, 1, 100.00m, 1, 0.10m, 1, 1000, 1, 200); - merchantStatementAggregate.GenerateStatement(TestData.StatementGeneratedDate); - - Should.Throw(() => { - merchantStatementAggregate.EmailStatement(TestData.StatementEmailedDate, TestData.MessageId); - }); - } + } } \ No newline at end of file diff --git a/TransactionProcessor.Aggregates/MerchantStatementAggregate.cs b/TransactionProcessor.Aggregates/MerchantStatementAggregate.cs index 95256b6..8055d1f 100644 --- a/TransactionProcessor.Aggregates/MerchantStatementAggregate.cs +++ b/TransactionProcessor.Aggregates/MerchantStatementAggregate.cs @@ -1,6 +1,7 @@ using Shared.DomainDrivenDesign.EventSourcing; using Shared.EventStore.Aggregate; using Shared.General; +using SimpleResults; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using TransactionProcessor.Aggregates.Models; @@ -120,7 +121,7 @@ public static void PlayEvent(this MerchantStatementAggregate aggregate, domainEvent.NumberOfSettledFees,domainEvent.ValueOfTransactions)); } - public static void RecordActivityDateOnStatement(this MerchantStatementAggregate aggregate, + public static Result RecordActivityDateOnStatement(this MerchantStatementAggregate aggregate, Guid statementId, DateTime statementDate, Guid estateId, @@ -128,25 +129,27 @@ public static void RecordActivityDateOnStatement(this MerchantStatementAggregate Guid merchantStatementForDateId, DateTime activityDate) { - if (aggregate.IsCreated == false) - { - Guard.ThrowIfInvalidGuid(statementId, nameof(statementId)); - Guard.ThrowIfInvalidGuid(estateId, nameof(estateId)); - Guard.ThrowIfInvalidGuid(merchantId, nameof(merchantId)); - - MerchantStatementDomainEvents.StatementCreatedEvent statementCreatedEvent = new(statementId, estateId, merchantId, statementDate); - + if (aggregate.IsCreated == false) { + if (statementId == Guid.Empty) + return Result.Invalid("Statement id cannot be an empty guid"); + if (estateId == Guid.Empty) + return Result.Invalid("Estate id cannot be an empty guid"); + if (merchantId == Guid.Empty) + return Result.Invalid("Merchant id cannot be an empty guid"); + + StatementCreatedEvent statementCreatedEvent = new(statementId, estateId, merchantId, statementDate); aggregate.ApplyAndAppend(statementCreatedEvent); } - if (aggregate.ActivityDates.SingleOrDefault(a => a.activityDate == activityDate) != default) - { + if (aggregate.ActivityDates.SingleOrDefault(a => a.activityDate == activityDate) != default) { // Activity date already exists - return; + return Result.Success(); } - MerchantStatementDomainEvents.ActivityDateAddedToStatementEvent activityDateAddedToStatementEvent = new(statementId, estateId, merchantId, merchantStatementForDateId, activityDate); + ActivityDateAddedToStatementEvent activityDateAddedToStatementEvent = new(statementId, estateId, merchantId, merchantStatementForDateId, activityDate); aggregate.ApplyAndAppend(activityDateAddedToStatementEvent); + + return Result.Success(); } public static MerchantStatement GetStatement(this MerchantStatementAggregate aggregate) @@ -175,91 +178,83 @@ public static MerchantStatement GetStatement(this MerchantStatementAggregate agg return merchantStatement; } - public static void BuildStatement(this MerchantStatementAggregate aggregate, + public static Result BuildStatement(this MerchantStatementAggregate aggregate, DateTime builtDateTime, String statementData) { - aggregate.EnsureStatementHasBeenGenerated(); - aggregate.EnsureStatementHasNotAlreadyBeenBuilt(); + if (aggregate.IsBuilt) + return Result.Success(); + + Result result = aggregate.EnsureStatementHasBeenGenerated(); + if (result.IsFailed) + return result; - MerchantStatementDomainEvents.StatementBuiltEvent statementBuiltEvent = new(aggregate.AggregateId, aggregate.EstateId, aggregate.MerchantId, builtDateTime, statementData); + StatementBuiltEvent statementBuiltEvent = new(aggregate.AggregateId, aggregate.EstateId, aggregate.MerchantId, builtDateTime, statementData); aggregate.ApplyAndAppend(statementBuiltEvent); + + return Result.Success(); } - public static void EmailStatement(this MerchantStatementAggregate aggregate, + public static Result EmailStatement(this MerchantStatementAggregate aggregate, DateTime emailedDateTime, Guid messageId) { - aggregate.EnsureStatementHasBeenBuilt(); - aggregate.EnsureStatementHasNotAlreadyBeenEmailed(); - StatementEmailedEvent statementEmailedEvent = new StatementEmailedEvent(aggregate.AggregateId, aggregate.EstateId, aggregate.MerchantId, emailedDateTime, messageId); + if (aggregate.HasBeenEmailed) { + return Result.Success(); + } + + Result result = aggregate.EnsureStatementHasBeenBuilt(); + if (result.IsFailed) + return result; + + StatementEmailedEvent statementEmailedEvent = new(aggregate.AggregateId, aggregate.EstateId, aggregate.MerchantId, emailedDateTime, messageId); aggregate.ApplyAndAppend(statementEmailedEvent); + + return Result.Success(); } - public static void GenerateStatement(this MerchantStatementAggregate aggregate, + public static Result GenerateStatement(this MerchantStatementAggregate aggregate, DateTime generatedDateTime) { - aggregate.EnsureStatementHasNotAlreadyBeenGenerated(); + if (aggregate.IsGenerated) + return Result.Success(); // Validate days have been added if (aggregate.MerchantStatementSummaries.Any() == false) { - throw new InvalidOperationException("Statement has no transactions or settled fees"); + return Result.Invalid("Statement has no transactions or settled fees"); } - MerchantStatementDomainEvents.StatementGeneratedEvent statementGeneratedEvent = new(aggregate.AggregateId, aggregate.EstateId, aggregate.MerchantId, generatedDateTime); + StatementGeneratedEvent statementGeneratedEvent = new(aggregate.AggregateId, aggregate.EstateId, aggregate.MerchantId, generatedDateTime); aggregate.ApplyAndAppend(statementGeneratedEvent); - } - - private static void EnsureStatementHasBeenGenerated(this MerchantStatementAggregate aggregate) - { - if (aggregate.IsGenerated == false) - { - throw new InvalidOperationException("Statement header has not been generated"); - } - } - - private static void EnsureStatementHasBeenBuilt(this MerchantStatementAggregate aggregate) - { - if (aggregate.IsBuilt == false) - { - throw new InvalidOperationException("Statement header has not been built"); - } - } - private static void EnsureStatementHasNotAlreadyBeenGenerated(this MerchantStatementAggregate aggregate) - { - if (aggregate.IsGenerated) - { - throw new InvalidOperationException("Statement header has already been generated"); - } + return Result.Success(); } - private static void EnsureStatementHasNotAlreadyBeenBuilt(this MerchantStatementAggregate aggregate) - { - if (aggregate.IsBuilt) - { - throw new InvalidOperationException("Statement header has already been built"); + private static Result EnsureStatementHasBeenGenerated(this MerchantStatementAggregate aggregate) { + if (aggregate.IsGenerated == false) { + return Result.Invalid("Statement header has not been generated"); } + return Result.Success(); } - private static void EnsureStatementHasNotAlreadyBeenEmailed(this MerchantStatementAggregate aggregate) + private static Result EnsureStatementHasBeenBuilt(this MerchantStatementAggregate aggregate) { - if (aggregate.HasBeenEmailed) - { - throw new InvalidOperationException("Statement header has already been emailed"); + if (aggregate.IsBuilt == false) { + return Result.Invalid("Statement header has not been built"); } + return Result.Success(); } - public static void AddDailySummaryRecord(this MerchantStatementAggregate aggregate, DateTime activityDate, + public static Result AddDailySummaryRecord(this MerchantStatementAggregate aggregate, DateTime activityDate, Int32 numberOfTransactions, Decimal valueOfTransactions, Int32 numberOfSettledFees, Decimal valueOfSettledFees, Int32 numberOfDepoits, Decimal valueOfDepoits, Int32 numberOfWithdrawals, Decimal valueOfWithdrawals) { if (aggregate.MerchantStatementSummaries.Any(s => s.ActivityDate == activityDate)) { - throw new InvalidOperationException($"Summary Data for Activity Date {activityDate:yyyy-MM-dd} already exists"); + return Result.Success(); } // TODO: should this check the date has been added to the statement, before allowing the summary? @@ -267,6 +262,8 @@ public static void AddDailySummaryRecord(this MerchantStatementAggregate aggrega MerchantStatementDomainEvents.StatementSummaryForDateEvent statementSummaryForDateEvent = new(aggregate.AggregateId, aggregate.EstateId, aggregate.MerchantId, activityDate,aggregate.MerchantStatementSummaries.Count +1 ,numberOfTransactions, valueOfTransactions, numberOfSettledFees, valueOfSettledFees, numberOfDepoits, valueOfDepoits, numberOfWithdrawals, valueOfWithdrawals); aggregate.ApplyAndAppend(statementSummaryForDateEvent); + + return Result.Success(); } } diff --git a/TransactionProcessor.BusinessLogic/Services/MerchantStatementDomainService.cs b/TransactionProcessor.BusinessLogic/Services/MerchantStatementDomainService.cs index 6483834..e75dd0d 100644 --- a/TransactionProcessor.BusinessLogic/Services/MerchantStatementDomainService.cs +++ b/TransactionProcessor.BusinessLogic/Services/MerchantStatementDomainService.cs @@ -149,10 +149,14 @@ public async Task GenerateStatement(MerchantCommands.GenerateMerchantSta sl) => new { Count = acc.Count + 1, TotalAmount = acc.TotalAmount + sl.Amount }); var withdrawalsResult = merchantStatementForDateAggregate.GetStatementLines().Where(sl => sl.LineType == 4).Aggregate(new { Count = 0, TotalAmount = 0m }, (acc, sl) => new { Count = acc.Count + 1, TotalAmount = acc.TotalAmount + sl.Amount }); - merchantStatementAggregate.AddDailySummaryRecord(merchantStatementForDateAggregate.ActivityDate, transactionsResult.Count, transactionsResult.TotalAmount, settledFeesResult.Count, settledFeesResult.TotalAmount, depositsResult.Count, depositsResult.TotalAmount, withdrawalsResult.Count, withdrawalsResult.TotalAmount); + Result result = merchantStatementAggregate.AddDailySummaryRecord(merchantStatementForDateAggregate.ActivityDate, transactionsResult.Count, transactionsResult.TotalAmount, settledFeesResult.Count, settledFeesResult.TotalAmount, depositsResult.Count, depositsResult.TotalAmount, withdrawalsResult.Count, withdrawalsResult.TotalAmount); + if (result.IsFailed) + return ResultHelpers.CreateFailure(result); } - merchantStatementAggregate.GenerateStatement(DateTime.Now); + Result stateResult = merchantStatementAggregate.GenerateStatement(DateTime.Now); + if (stateResult.IsFailed) + return ResultHelpers.CreateFailure(stateResult); Result saveResult = await this.AggregateService.Save(merchantStatementAggregate, cancellationToken); if (saveResult.IsFailed) @@ -210,17 +214,19 @@ public async Task EmailStatement(MerchantStatementCommands.EmailMerchant sendEmailRequest.MessageId = messageId; - var getTokenResult = await Helpers.GetToken(this.TokenResponse, this.SecurityServiceClient, cancellationToken); + Result getTokenResult = await Helpers.GetToken(this.TokenResponse, this.SecurityServiceClient, cancellationToken); if (getTokenResult.IsFailed) return ResultHelpers.CreateFailure(getTokenResult); this.TokenResponse = getTokenResult.Data; - var sendEmailResponseResult = await this.MessagingServiceClient.SendEmail(this.TokenResponse.AccessToken, sendEmailRequest, cancellationToken); + Result sendEmailResponseResult = await this.MessagingServiceClient.SendEmail(this.TokenResponse.AccessToken, sendEmailRequest, cancellationToken); //if (sendEmailResponseResult.IsFailed) { // // TODO: record a failed event?? //} - merchantStatementAggregate.EmailStatement(DateTime.Now, messageId); + Result stateResult = merchantStatementAggregate.EmailStatement(DateTime.Now, messageId); + if (stateResult.IsFailed) + return ResultHelpers.CreateFailure(stateResult); Result saveResult = await this.AggregateService.Save(merchantStatementAggregate, cancellationToken); if (saveResult.IsFailed) @@ -264,7 +270,9 @@ public async Task BuildStatement(MerchantStatementCommands.BuildMerchant String base64 = EncodeTo64(html); - merchantStatementAggregate.BuildStatement(DateTime.Now, base64); + Result stateResult = merchantStatementAggregate.BuildStatement(DateTime.Now, base64); + if (stateResult.IsFailed) + return ResultHelpers.CreateFailure(stateResult); Result saveResult = await this.AggregateService.Save(merchantStatementAggregate, cancellationToken); if (saveResult.IsFailed) @@ -288,9 +296,11 @@ public async Task RecordActivityDateOnMerchantStatement(MerchantStatemen MerchantStatementAggregate merchantStatementAggregate = getMerchantStatementResult.Data; - merchantStatementAggregate.RecordActivityDateOnStatement(command.MerchantStatementId, command.StatementDate, + Result stateResult = merchantStatementAggregate.RecordActivityDateOnStatement(command.MerchantStatementId, command.StatementDate, command.EstateId, command.MerchantId, command.MerchantStatementForDateId, command.StatementActivityDate); + if (stateResult.IsFailed) + return ResultHelpers.CreateFailure(stateResult); Result saveResult = await this.AggregateService.Save(merchantStatementAggregate, cancellationToken); if (saveResult.IsFailed)