diff --git a/TransactionProcessor.Aggregates.Tests/MerchantStatementAggregateTests.cs b/TransactionProcessor.Aggregates.Tests/MerchantStatementAggregateTests.cs index d928689e..9cf6c310 100644 --- a/TransactionProcessor.Aggregates.Tests/MerchantStatementAggregateTests.cs +++ b/TransactionProcessor.Aggregates.Tests/MerchantStatementAggregateTests.cs @@ -4,312 +4,6 @@ namespace TransactionProcessor.Aggregates.Tests { - public class MerchantStatementForDateAggregateTests - { - [Fact] - public void MerchantStatementForDateAggregate_CanBeCreated_IsCreated() - { - MerchantStatementForDateAggregate merchantStatementForDateAggregate = MerchantStatementForDateAggregate.Create(TestData.MerchantStatementForDateId1); - - merchantStatementForDateAggregate.ShouldNotBeNull(); - merchantStatementForDateAggregate.AggregateId.ShouldBe(TestData.MerchantStatementForDateId1); - } - - [Fact] - public void MerchantStatementForDateAggregate_AddTransactionToStatement_TransactionAddedToStatement() - { - MerchantStatementForDateAggregate merchantStatementForDateAggregate = MerchantStatementForDateAggregate.Create(TestData.MerchantStatementForDateId1); - merchantStatementForDateAggregate.AddTransactionToStatement(TestData.MerchantStatementId, - TestData.StatementDate, - TestData.EventId1, - TestData.EstateId, - TestData.MerchantId, TestData.Transaction1); - - MerchantStatementForDate merchantStatementForDate = merchantStatementForDateAggregate.GetStatement(true); - List? statementLines = merchantStatementForDate.GetStatementLines(); - statementLines.ShouldNotBeNull(); - statementLines.ShouldNotBeEmpty(); - statementLines.Count.ShouldBe(1); - } - - [Fact] - public void MerchantStatementForDateAggregate_AddTransactionToStatement_DuplicateTransaction_SilentlyHandled() - { - MerchantStatementForDateAggregate merchantStatementForDateAggregate = MerchantStatementForDateAggregate.Create(TestData.MerchantStatementForDateId1); - merchantStatementForDateAggregate.AddTransactionToStatement(TestData.MerchantStatementId, - TestData.StatementDate, - TestData.EventId1, - TestData.EstateId, - TestData.MerchantId, TestData.Transaction1); - - merchantStatementForDateAggregate.AddTransactionToStatement(TestData.MerchantStatementId, - TestData.StatementDate, - TestData.EventId1, - TestData.EstateId, - TestData.MerchantId, TestData.Transaction1); - - MerchantStatementForDate merchantStatementForDate = merchantStatementForDateAggregate.GetStatement(true); - List? statementLines = merchantStatementForDate.GetStatementLines(); - statementLines.ShouldNotBeNull(); - statementLines.ShouldNotBeEmpty(); - statementLines.Count.ShouldBe(1); - } - - [Fact] - public void MerchantStatementForDateAggregate_AddSettledFeeToStatement_FeeAddedToStatement() - { - MerchantStatementForDateAggregate merchantStatementForDateAggregate = MerchantStatementForDateAggregate.Create(TestData.MerchantStatementForDateId1); - merchantStatementForDateAggregate.AddSettledFeeToStatement(TestData.MerchantStatementId, TestData.StatementDate, TestData.EventId1, TestData.EstateId, TestData.MerchantId, TestData.SettledFee1); - - MerchantStatementForDate merchantStatementForDate = merchantStatementForDateAggregate.GetStatement(true); - List? statementLines = merchantStatementForDate.GetStatementLines(); - statementLines.ShouldNotBeNull(); - statementLines.ShouldNotBeEmpty(); - statementLines.Count.ShouldBe(1); - } - - [Fact] - public void MerchantStatementForDateAggregate_AddSettledFeeToStatement_DuplicateFee_Silentlyhandled() - { - MerchantStatementForDateAggregate merchantStatementForDateAggregate = MerchantStatementForDateAggregate.Create(TestData.MerchantStatementForDateId1); - merchantStatementForDateAggregate.AddSettledFeeToStatement(TestData.MerchantStatementId, TestData.StatementDate, TestData.EventId1, TestData.EstateId, TestData.MerchantId, TestData.SettledFee1); - merchantStatementForDateAggregate.AddSettledFeeToStatement(TestData.MerchantStatementId, TestData.StatementDate, TestData.EventId1, TestData.EstateId, TestData.MerchantId, TestData.SettledFee1); - - MerchantStatementForDate merchantStatementForDate = merchantStatementForDateAggregate.GetStatement(true); - List? statementLines = merchantStatementForDate.GetStatementLines(); - 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); }); - } - - [Fact] - public void MerchantStatementAggregate_AddDailySummaryRecord_DuplicateAdd_ExceptionIsThrown() - { - MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); - merchantStatementAggregate.AddDailySummaryRecord(TestData.TransactionDateTime.Date, 1, 100.00m, 1, 0.10m); - Should.Throw(() => { merchantStatementAggregate.AddDailySummaryRecord(TestData.TransactionDateTime.Date, 1, 100.00m, 1, 0.10m); }); - } - - - [Fact] - public void MerchantStatementAggregate_GenerateStatement_StatementIsGenerated() - { - MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); - merchantStatementAggregate.AddDailySummaryRecord(TestData.TransactionDateTime.Date, 1, 100.00m, 1, 0.10m); - 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); - 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); - 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); - 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); - - 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); - 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); - 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); - merchantStatementAggregate.GenerateStatement(TestData.StatementGeneratedDate); - - Should.Throw(() => { - merchantStatementAggregate.EmailStatement(TestData.StatementEmailedDate, TestData.MessageId); - }); - } - - /* - [Fact] - public void MerchantStatementAggregate_GenerateStatement_StatementNotCreated_ErrorThrown() - { - MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); - - Should.Throw(() => - { - merchantStatementAggregate.GenerateStatement(TestData.StatementGeneratedDate); - }); - } - - [Fact] - public void MerchantStatementAggregate_GenerateStatement_StatementAlreadyGenerated_ErrorThrown() - { - MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); - merchantStatementAggregate.AddTransactionToStatement(TestData.MerchantStatementId, - TestData.EventId1, - TestData.StatementCreateDate, - TestData.EstateId, - TestData.MerchantId, TestData.Transaction1); - merchantStatementAggregate.AddSettledFeeToStatement(TestData.MerchantStatementId, - TestData.EventId1, - TestData.StatementCreateDate, - TestData.EstateId, - TestData.MerchantId, TestData.SettledFee1); - merchantStatementAggregate.GenerateStatement(TestData.StatementGeneratedDate); - - Should.Throw(() => - { - merchantStatementAggregate.GenerateStatement(TestData.StatementGeneratedDate); - }); - } - - [Fact] - public void MerchantStatementAggregate_GenerateStatement_StatementHasNoTransactionsOrSettledFees_ErrorThrown() - { - MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); - - Should.Throw(() => - { - merchantStatementAggregate.GenerateStatement(TestData.StatementGeneratedDate); - }); - } - - [Fact] - public void MerchantStatementAggregate_EmailStatement_StatementHasBeenEmailed() - { - MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); - merchantStatementAggregate.AddTransactionToStatement(TestData.MerchantStatementId, - TestData.EventId1, - TestData.StatementCreateDate, - TestData.EstateId, - TestData.MerchantId, TestData.Transaction1); - merchantStatementAggregate.AddSettledFeeToStatement(TestData.MerchantStatementId, - TestData.EventId1, - TestData.StatementCreateDate, - TestData.EstateId, - TestData.MerchantId, - TestData.SettledFee1); - merchantStatementAggregate.GenerateStatement(TestData.StatementGeneratedDate); - - merchantStatementAggregate.EmailStatement(TestData.StatementEmailedDate, TestData.MessageId); - - MerchantStatement statement = merchantStatementAggregate.GetStatement(false); - statement.HasBeenEmailed.ShouldBeTrue(); - } - - [Fact] - public void MerchantStatementAggregate_EmailStatement_NotCreated_ErrorThrown() - { - MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); - //merchantStatementAggregate.CreateStatement(TestData.EstateId, TestData.MerchantId, TestData.StatementCreateDate); - //merchantStatementAggregate.AddTransactionToStatement(TestData.Transaction1); - //merchantStatementAggregate.AddSettledFeeToStatement(TestData.SettledFee1); - //merchantStatementAggregate.GenerateStatement(TestData.StatementGeneratedDate); - - Should.Throw(() => - { - merchantStatementAggregate.EmailStatement(TestData.StatementEmailedDate,TestData.MessageId); - }); - } - - [Fact] - public void MerchantStatementAggregate_EmailStatement_NotGenerated_ErrorThrown() - { - MerchantStatementAggregate merchantStatementAggregate = MerchantStatementAggregate.Create(TestData.MerchantStatementId); - merchantStatementAggregate.AddTransactionToStatement(TestData.MerchantStatementId, - TestData.EventId1, - TestData.StatementCreateDate, - TestData.EstateId, - TestData.MerchantId, TestData.Transaction1); - merchantStatementAggregate.AddSettledFeeToStatement(TestData.MerchantStatementId, - TestData.EventId1, - TestData.StatementCreateDate, - TestData.EstateId, - TestData.MerchantId, TestData.SettledFee1); - - Should.Throw(() => - { - merchantStatementAggregate.EmailStatement(TestData.StatementEmailedDate, TestData.MessageId); - }); - }*/ - } - public class MerchantStatementAggregateTests { [Fact] public void MerchantStatementAggregate_CanBeCreated_IsCreated() diff --git a/TransactionProcessor.Aggregates.Tests/MerchantStatementForDateAggregateTests.cs b/TransactionProcessor.Aggregates.Tests/MerchantStatementForDateAggregateTests.cs new file mode 100644 index 00000000..684c547a --- /dev/null +++ b/TransactionProcessor.Aggregates.Tests/MerchantStatementForDateAggregateTests.cs @@ -0,0 +1,259 @@ +using Shouldly; +using TransactionProcessor.Models.Merchant; +using TransactionProcessor.Testing; + +namespace TransactionProcessor.Aggregates.Tests; + +public class MerchantStatementForDateAggregateTests +{ + [Fact] + public void MerchantStatementForDateAggregate_CanBeCreated_IsCreated() + { + MerchantStatementForDateAggregate merchantStatementForDateAggregate = MerchantStatementForDateAggregate.Create(TestData.MerchantStatementForDateId1); + + merchantStatementForDateAggregate.ShouldNotBeNull(); + merchantStatementForDateAggregate.AggregateId.ShouldBe(TestData.MerchantStatementForDateId1); + } + + [Fact] + public void MerchantStatementForDateAggregate_AddTransactionToStatement_TransactionAddedToStatement() + { + MerchantStatementForDateAggregate merchantStatementForDateAggregate = MerchantStatementForDateAggregate.Create(TestData.MerchantStatementForDateId1); + merchantStatementForDateAggregate.AddTransactionToStatement(TestData.MerchantStatementId, + TestData.StatementDate, + TestData.EventId1, + TestData.EstateId, + TestData.MerchantId, TestData.Transaction1); + + MerchantStatementForDate merchantStatementForDate = merchantStatementForDateAggregate.GetStatement(true); + List? statementLines = merchantStatementForDate.GetStatementLines(); + statementLines.ShouldNotBeNull(); + statementLines.ShouldNotBeEmpty(); + statementLines.Count.ShouldBe(1); + } + + [Fact] + public void MerchantStatementForDateAggregate_AddTransactionToStatement_DuplicateTransaction_SilentlyHandled() + { + MerchantStatementForDateAggregate merchantStatementForDateAggregate = MerchantStatementForDateAggregate.Create(TestData.MerchantStatementForDateId1); + merchantStatementForDateAggregate.AddTransactionToStatement(TestData.MerchantStatementId, + TestData.StatementDate, + TestData.EventId1, + TestData.EstateId, + TestData.MerchantId, TestData.Transaction1); + + merchantStatementForDateAggregate.AddTransactionToStatement(TestData.MerchantStatementId, + TestData.StatementDate, + TestData.EventId1, + TestData.EstateId, + TestData.MerchantId, TestData.Transaction1); + + MerchantStatementForDate merchantStatementForDate = merchantStatementForDateAggregate.GetStatement(true); + List? statementLines = merchantStatementForDate.GetStatementLines(); + statementLines.ShouldNotBeNull(); + statementLines.ShouldNotBeEmpty(); + statementLines.Count.ShouldBe(1); + } + + [Fact] + public void MerchantStatementForDateAggregate_AddSettledFeeToStatement_FeeAddedToStatement() + { + MerchantStatementForDateAggregate merchantStatementForDateAggregate = MerchantStatementForDateAggregate.Create(TestData.MerchantStatementForDateId1); + merchantStatementForDateAggregate.AddSettledFeeToStatement(TestData.MerchantStatementId, TestData.StatementDate, TestData.EventId1, TestData.EstateId, TestData.MerchantId, TestData.SettledFee1); + + MerchantStatementForDate merchantStatementForDate = merchantStatementForDateAggregate.GetStatement(true); + List? statementLines = merchantStatementForDate.GetStatementLines(); + statementLines.ShouldNotBeNull(); + statementLines.ShouldNotBeEmpty(); + statementLines.Count.ShouldBe(1); + } + + [Fact] + public void MerchantStatementForDateAggregate_AddSettledFeeToStatement_DuplicateFee_Silentlyhandled() + { + MerchantStatementForDateAggregate merchantStatementForDateAggregate = MerchantStatementForDateAggregate.Create(TestData.MerchantStatementForDateId1); + merchantStatementForDateAggregate.AddSettledFeeToStatement(TestData.MerchantStatementId, TestData.StatementDate, TestData.EventId1, TestData.EstateId, TestData.MerchantId, TestData.SettledFee1); + merchantStatementForDateAggregate.AddSettledFeeToStatement(TestData.MerchantStatementId, TestData.StatementDate, TestData.EventId1, TestData.EstateId, TestData.MerchantId, TestData.SettledFee1); + + MerchantStatementForDate merchantStatementForDate = merchantStatementForDateAggregate.GetStatement(true); + List? statementLines = merchantStatementForDate.GetStatementLines(); + statementLines.ShouldNotBeNull(); + statementLines.ShouldNotBeEmpty(); + statementLines.Count.ShouldBe(1); + } + + [Theory] + [InlineData(MerchantDepositSource.Manual)] + [InlineData(MerchantDepositSource.Automatic)] + public void MerchantStatementForDateAggregate_AddDepositToStatement_DepositAddedToStatement(MerchantDepositSource source) + { + MerchantStatementForDateAggregate merchantStatementForDateAggregate = MerchantStatementForDateAggregate.Create(TestData.MerchantStatementForDateId1); + merchantStatementForDateAggregate.AddDepositToStatement(TestData.MerchantStatementId, + TestData.StatementDate, + TestData.EventId1, + TestData.EstateId, + TestData.MerchantId, new Deposit { + DepositDateTime = TestData.DepositDateTime, + Amount = TestData.DepositAmount.Value, + DepositId = TestData.DepositId, + Reference = TestData.DepositReference, + Source = source + }); + + MerchantStatementForDate merchantStatementForDate = merchantStatementForDateAggregate.GetStatement(true); + List? statementLines = merchantStatementForDate.GetStatementLines(); + statementLines.ShouldNotBeNull(); + statementLines.ShouldNotBeEmpty(); + statementLines.Count.ShouldBe(1); + } + + [Fact] + public void MerchantStatementForDateAggregate_AddWithdrawalToStatement_WithdrawalAddedToStatement() + { + MerchantStatementForDateAggregate merchantStatementForDateAggregate = MerchantStatementForDateAggregate.Create(TestData.MerchantStatementForDateId1); + merchantStatementForDateAggregate.AddWithdrawalToStatement(TestData.MerchantStatementId, + TestData.StatementDate, + TestData.EventId1, + TestData.EstateId, + TestData.MerchantId, new Withdrawal + { + WithdrawalDateTime = TestData.WithdrawalDateTime, + Amount = TestData.WithdrawalAmount.Value, + WithdrawalId = TestData.WithdrawalId + }); + + MerchantStatementForDate merchantStatementForDate = merchantStatementForDateAggregate.GetStatement(true); + List? statementLines = merchantStatementForDate.GetStatementLines(); + 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 6382eadf..95256b64 100644 --- a/TransactionProcessor.Aggregates/MerchantStatementAggregate.cs +++ b/TransactionProcessor.Aggregates/MerchantStatementAggregate.cs @@ -213,14 +213,6 @@ public static void GenerateStatement(this MerchantStatementAggregate aggregate, aggregate.ApplyAndAppend(statementGeneratedEvent); } - private static void EnsureStatementHasBeenCreated(this MerchantStatementAggregate aggregate) - { - if (aggregate.IsCreated == false) - { - throw new InvalidOperationException("Statement header has not been created"); - } - } - private static void EnsureStatementHasBeenGenerated(this MerchantStatementAggregate aggregate) { if (aggregate.IsGenerated == false) @@ -261,7 +253,11 @@ private static void EnsureStatementHasNotAlreadyBeenEmailed(this MerchantStateme } } - public static void AddDailySummaryRecord(this MerchantStatementAggregate aggregate, DateTime activityDate, Int32 numberOfTransactions, Decimal valueOfTransactions, Int32 numberOfSettledFees, Decimal valueOfSettledFees) { + public static void 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"); } @@ -269,7 +265,7 @@ public static void AddDailySummaryRecord(this MerchantStatementAggregate aggrega // TODO: should this check the date has been added to the statement, before allowing the summary? MerchantStatementDomainEvents.StatementSummaryForDateEvent statementSummaryForDateEvent = new(aggregate.AggregateId, aggregate.EstateId, aggregate.MerchantId, activityDate,aggregate.MerchantStatementSummaries.Count +1 - ,numberOfTransactions, valueOfTransactions, numberOfSettledFees, valueOfSettledFees); + ,numberOfTransactions, valueOfTransactions, numberOfSettledFees, valueOfSettledFees, numberOfDepoits, valueOfDepoits, numberOfWithdrawals, valueOfWithdrawals); aggregate.ApplyAndAppend(statementSummaryForDateEvent); } } diff --git a/TransactionProcessor.Aggregates/MerchantStatementForDateAggregate.cs b/TransactionProcessor.Aggregates/MerchantStatementForDateAggregate.cs index e6c57af8..1595d362 100644 --- a/TransactionProcessor.Aggregates/MerchantStatementForDateAggregate.cs +++ b/TransactionProcessor.Aggregates/MerchantStatementForDateAggregate.cs @@ -5,6 +5,8 @@ using TransactionProcessor.Aggregates.Models; using TransactionProcessor.DomainEvents; using TransactionProcessor.Models.Merchant; +using Deposit = TransactionProcessor.Models.Merchant.Deposit; +using Withdrawal = TransactionProcessor.Models.Merchant.Withdrawal; namespace TransactionProcessor.Aggregates; @@ -25,6 +27,38 @@ public static void AddSettledFeeToStatement(this MerchantStatementForDateAggrega aggregate.ApplyAndAppend(settledFeeAddedToStatementEvent); } + public static void AddDepositToStatement(this MerchantStatementForDateAggregate aggregate, + Guid merchantStatementId, + DateTime statementDate, + Guid eventId, + Guid estateId, + Guid merchantId, + Deposit deposit) + { + // Create statement id required + aggregate.CreateStatementForDate(merchantStatementId, deposit.DepositDateTime.Date, statementDate, estateId, merchantId); + + MerchantStatementForDateDomainEvents.DepositAddedToStatementForDateEvent depositAddedToStatementEvent = new(aggregate.AggregateId, eventId, aggregate.EstateId, aggregate.MerchantId, deposit.DepositId, deposit.DepositDateTime, deposit.Amount); + + aggregate.ApplyAndAppend(depositAddedToStatementEvent); + } + + public static void AddWithdrawalToStatement(this MerchantStatementForDateAggregate aggregate, + Guid merchantStatementId, + DateTime statementDate, + Guid eventId, + Guid estateId, + Guid merchantId, + Withdrawal withdrawal) + { + // Create statement id required + aggregate.CreateStatementForDate(merchantStatementId, withdrawal.WithdrawalDateTime.Date, statementDate, estateId, merchantId); + + MerchantStatementForDateDomainEvents.WithdrawalAddedToStatementForDateEvent withdrawalAddedToStatementEvent = new(aggregate.AggregateId, eventId, aggregate.EstateId, aggregate.MerchantId, withdrawal.WithdrawalId, withdrawal.WithdrawalDateTime, withdrawal.Amount); + + aggregate.ApplyAndAppend(withdrawalAddedToStatementEvent); + } + public static void AddTransactionToStatement(this MerchantStatementForDateAggregate aggregate, Guid merchantStatementId, DateTime statementDate, @@ -86,6 +120,25 @@ public static void PlayEvent(this MerchantStatementForDateAggregate aggregate, M aggregate.SettledFees.Add(new SettledFee(domainEvent.SettledFeeId, domainEvent.TransactionId, domainEvent.SettledDateTime, domainEvent.SettledValue)); } + public static void PlayEvent(this MerchantStatementForDateAggregate aggregate, MerchantStatementForDateDomainEvents.DepositAddedToStatementForDateEvent domainEvent) + { + aggregate.Deposits.Add(new Deposit { + DepositDateTime = domainEvent.DepositDateTime, + Amount = domainEvent.DepositAmount, + DepositId = domainEvent.DepositId, + }); + } + + public static void PlayEvent(this MerchantStatementForDateAggregate aggregate, MerchantStatementForDateDomainEvents.WithdrawalAddedToStatementForDateEvent domainEvent) + { + aggregate.Withdrawals.Add(new Withdrawal() + { + WithdrawalDateTime = domainEvent.WithdrawalDateTime, + Amount = domainEvent.WithdrawalAmount, + WithdrawalId = domainEvent.WithdrawalId, + }); + } + public static MerchantStatementForDate GetStatement(this MerchantStatementForDateAggregate aggregate, Boolean includeStatementLines = false) { MerchantStatementForDate merchantStatement = new MerchantStatementForDate @@ -122,6 +175,28 @@ public static MerchantStatementForDate GetStatement(this MerchantStatementForDat LineType = 2 // Settled Fee }); } + + foreach (Deposit deposit in aggregate.Deposits) + { + merchantStatement.AddStatementLine(new MerchantStatementLine + { + Amount = deposit.Amount, + DateTime = deposit.DepositDateTime, + Description = string.Empty, + LineType = 3 // Deposit + }); + } + + foreach (Withdrawal withdrawal in aggregate.Withdrawals) + { + merchantStatement.AddStatementLine(new MerchantStatementLine + { + Amount = withdrawal.Amount, + DateTime = withdrawal.WithdrawalDateTime, + Description = string.Empty, + LineType = 4 // Withdrawal + }); + } } return merchantStatement; @@ -138,6 +213,8 @@ public record MerchantStatementForDateAggregate : Aggregate internal Guid MerchantId; internal readonly List SettledFees; internal readonly List Transactions; + internal readonly List Deposits; + internal readonly List Withdrawals; internal Guid MerchantStatementId; internal DateTime StatementDate; #endregion @@ -150,6 +227,8 @@ public MerchantStatementForDateAggregate() // Nothing here this.Transactions = new List(); this.SettledFees = new List(); + this.Deposits = new List(); + this.Withdrawals= new List(); } private MerchantStatementForDateAggregate(Guid aggregateId) @@ -159,6 +238,8 @@ private MerchantStatementForDateAggregate(Guid aggregateId) this.AggregateId = aggregateId; this.Transactions = new List(); this.SettledFees = new List(); + this.Deposits = new List(); + this.Withdrawals = new List(); } #endregion diff --git a/TransactionProcessor.Aggregates/Models/SettledFee.cs b/TransactionProcessor.Aggregates/Models/SettledFee.cs index 12833133..405e8d19 100644 --- a/TransactionProcessor.Aggregates/Models/SettledFee.cs +++ b/TransactionProcessor.Aggregates/Models/SettledFee.cs @@ -7,4 +7,6 @@ public record SettledFee(Guid SettledFeeId, Guid TransactionId, DateTime DateTim [ExcludeFromCodeCoverage] public record Transaction(Guid TransactionId, DateTime DateTime, Decimal Amount); + + } \ No newline at end of file diff --git a/TransactionProcessor.BusinessLogic.Tests/DomainEventHandlers/MerchantStatementDomainEventHandlerTests.cs b/TransactionProcessor.BusinessLogic.Tests/DomainEventHandlers/MerchantStatementDomainEventHandlerTests.cs index b94b66f2..572e351f 100644 --- a/TransactionProcessor.BusinessLogic.Tests/DomainEventHandlers/MerchantStatementDomainEventHandlerTests.cs +++ b/TransactionProcessor.BusinessLogic.Tests/DomainEventHandlers/MerchantStatementDomainEventHandlerTests.cs @@ -73,4 +73,34 @@ public async Task MerchantStatementDomainEventHandler_Handle_StatementCreatedFor Result result = await this.EventHandler.Handle(TestData.DomainEvents.StatementCreatedForDateEvent, CancellationToken.None); result.IsSuccess.ShouldBeTrue(); } + + [Fact] + public async Task MerchantStatementDomainEventHandler_Handle_AutomaticDepositMadeEvent_EventIsHandled() + { + this.Mediator.Setup(m => m.Send(It.IsAny>(), It.IsAny())) + .ReturnsAsync(Result.Success()); + + Result result = await this.EventHandler.Handle(TestData.DomainEvents.AutomaticDepositMadeEvent, CancellationToken.None); + result.IsSuccess.ShouldBeTrue(); + } + + [Fact] + public async Task MerchantStatementDomainEventHandler_Handle_ManualDepositMadeEvent_EventIsHandled() + { + this.Mediator.Setup(m => m.Send(It.IsAny>(), It.IsAny())) + .ReturnsAsync(Result.Success()); + + Result result = await this.EventHandler.Handle(TestData.DomainEvents.ManualDepositMadeEvent, CancellationToken.None); + result.IsSuccess.ShouldBeTrue(); + } + + [Fact] + public async Task MerchantStatementDomainEventHandler_Handle_WithdrawalMadeEvent_EventIsHandled() + { + this.Mediator.Setup(m => m.Send(It.IsAny>(), It.IsAny())) + .ReturnsAsync(Result.Success()); + + Result result = await this.EventHandler.Handle(TestData.DomainEvents.WithdrawalMadeEvent, CancellationToken.None); + result.IsSuccess.ShouldBeTrue(); + } } \ No newline at end of file diff --git a/TransactionProcessor.BusinessLogic.Tests/Services/MerchantDomainServiceTests.cs b/TransactionProcessor.BusinessLogic.Tests/Services/MerchantDomainServiceTests.cs index 3138a5ba..da874fac 100644 --- a/TransactionProcessor.BusinessLogic.Tests/Services/MerchantDomainServiceTests.cs +++ b/TransactionProcessor.BusinessLogic.Tests/Services/MerchantDomainServiceTests.cs @@ -1,5 +1,4 @@ -using MessagingService.Client; -using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Configuration; using Moq; using Newtonsoft.Json; using SecurityService.Client; @@ -16,7 +15,6 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -using MessagingService.DataTransferObjects; using TransactionProcessor.Aggregates; using TransactionProcessor.BusinessLogic.Requests; using TransactionProcessor.BusinessLogic.Services; @@ -1060,234 +1058,4 @@ public async Task MerchantDomainService_RemoveContractFromMerchant_ValidationFai var result = await this.DomainService.RemoveContractFromMerchant(TestData.Commands.RemoveMerchantContractCommand, CancellationToken.None); result.IsFailed.ShouldBeTrue(); } -} - -public class MerchantStatementDomainServiceTests { - - private Mock AggregateService; - private Mock StatementBuilder; - private Mock MessagingServiceClient; - private Mock SecurityServiceClient; - private MerchantStatementDomainService DomainService; - public MerchantStatementDomainServiceTests() { - this.AggregateService = new Mock(); - this.StatementBuilder = new Mock(); - this.MessagingServiceClient = new Mock(); - this.SecurityServiceClient = new Mock(); - this.DomainService = new MerchantStatementDomainService(this.AggregateService.Object, this.StatementBuilder.Object, this.MessagingServiceClient.Object, this.SecurityServiceClient.Object); - - IConfigurationRoot configurationRoot = - new ConfigurationBuilder().AddInMemoryCollection(TestData.DefaultAppSettings).Build(); - ConfigurationReader.Initialise(configurationRoot); - Logger.Initialise(new NullLogger()); - } - - [Fact] - public async Task MerchantStatementDomainService_AddTransactionToStatement_TransactionAddedToStatement() { - - this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.EmptyMerchantStatementForDateAggregate)); - this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success()); - Result result = await this.DomainService.AddTransactionToStatement(TestData.Commands.AddTransactionToMerchantStatementCommand, CancellationToken.None); - result.IsSuccess.ShouldBeTrue(); - } - - [Fact] - public async Task MerchantStatementDomainService_AddTransactionToStatement_TransactionNotAuthorised_TransactionNotAddedToStatement() - { - - this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.EmptyMerchantStatementForDateAggregate)); - this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success()); - Result result = await this.DomainService.AddTransactionToStatement(TestData.Commands.AddTransactionNotAuthorisedToMerchantStatementCommand, CancellationToken.None); - result.IsSuccess.ShouldBeTrue(); - } - - [Fact] - public async Task MerchantStatementDomainService_AddTransactionToStatement_TransactionHasNotAmount_TransactionNotAddedToStatement() - { - - this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.EmptyMerchantStatementForDateAggregate)); - this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success()); - Result result = await this.DomainService.AddTransactionToStatement(TestData.Commands.AddTransactionWithNoAmountToMerchantStatementCommand, CancellationToken.None); - result.IsSuccess.ShouldBeTrue(); - } - - [Fact] - public async Task MerchantStatementDomainService_AddTransactionToStatement_SaveFailed_TransactionNotAddedToStatement() - { - - this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.EmptyMerchantStatementForDateAggregate)); - this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure); - Result result = await this.DomainService.AddTransactionToStatement(TestData.Commands.AddTransactionToMerchantStatementCommand, CancellationToken.None); - result.IsFailed.ShouldBeTrue(); - } - - [Fact] - public async Task MerchantStatementDomainService_AddSettledFeeToStatement_SettledFeeAddedToStatement() - { - this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.EmptyMerchantStatementForDateAggregate)); - this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success()); - Result result = await this.DomainService.AddSettledFeeToStatement(TestData.Commands.AddSettledFeeToMerchantStatementCommand, CancellationToken.None); - result.IsSuccess.ShouldBeTrue(); - } - - [Fact] - public async Task MerchantStatementDomainService_AddSettledFeeToStatement_SaveFailed_SettledFeeNotAddedToStatement() - { - this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.EmptyMerchantStatementForDateAggregate)); - this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure); - Result result = await this.DomainService.AddSettledFeeToStatement(TestData.Commands.AddSettledFeeToMerchantStatementCommand, CancellationToken.None); - result.IsFailed.ShouldBeTrue(); - } - - - [Fact] - public async Task MerchantStatementDomainService_RecordActivityDateOnMerchantStatement_SaveFailed_ActivityDateNotRecorded() { - this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.EmptyMerchantStatementAggregate)); - this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success); - Result result = await this.DomainService.RecordActivityDateOnMerchantStatement(TestData.Commands.RecordActivityDateOnMerchantStatementCommand, CancellationToken.None); - result.IsSuccess.ShouldBeTrue(); - } - - [Fact] - public async Task MerchantStatementDomainService_RecordActivityDateOnMerchantStatement_ActivityDateRecorded() - { - this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.EmptyMerchantStatementAggregate)); - this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure); - Result result = await this.DomainService.RecordActivityDateOnMerchantStatement(TestData.Commands.RecordActivityDateOnMerchantStatementCommand, CancellationToken.None); - result.IsFailed.ShouldBeTrue(); - } - - [Fact] - public async Task MerchantStatementDomainService_GenerateStatement_StatementIsGenerated() - { - this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.MerchantStatementAggregateWithActivityDates())); - this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success); - - this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.MerchantStatementForDateAggregateWithTransactionAndFee())); - - Result result = await this.DomainService.GenerateStatement(TestData.Commands.GenerateMerchantStatementCommand, CancellationToken.None); - result.IsSuccess.ShouldBeTrue(); - } - - [Fact] - public async Task MerchantStatementDomainService_GenerateStatement_GetStatementForDateFailed_StatementIsNotGenerated() - { - this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.MerchantStatementAggregateWithActivityDates())); - this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success); - - this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure()); - - Result result = await this.DomainService.GenerateStatement(TestData.Commands.GenerateMerchantStatementCommand, CancellationToken.None); - result.IsFailed.ShouldBeTrue(); - } - - [Fact] - public async Task MerchantStatementDomainService_GenerateStatement_SaveFailed_StatementIsNotGenerated() - { - this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.MerchantStatementAggregateWithActivityDates())); - this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure); - - this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.MerchantStatementForDateAggregateWithTransactionAndFee())); - - Result result = await this.DomainService.GenerateStatement(TestData.Commands.GenerateMerchantStatementCommand, CancellationToken.None); - result.IsFailed.ShouldBeTrue(); - } - - [Fact] - public async Task MerchantStatementDomainService_BuildStatement_StatementIsBuilt() - { - this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.GeneratedMerchantStatementAggregate())); - this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success); - - this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.MerchantStatementForDateAggregateWithTransactionAndFee())); - - this.AggregateService.Setup(a => a.Get(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.MerchantAggregateWithEverything(SettlementSchedule.Immediate))); - - this.StatementBuilder.Setup(s => s.GetStatementHtml(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(""); - - Result result = await this.DomainService.BuildStatement(TestData.Commands.BuildMerchantStatementCommand, CancellationToken.None); - result.IsSuccess.ShouldBeTrue(); - } - - [Fact] - public async Task MerchantStatementDomainService_BuildStatement_GetMerchantFailed_StatementIsNotBuilt() - { - this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.GeneratedMerchantStatementAggregate())); - this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success); - - this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.MerchantStatementForDateAggregateWithTransactionAndFee())); - - this.AggregateService.Setup(a => a.Get(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure()); - - this.StatementBuilder.Setup(s => s.GetStatementHtml(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(""); - - Result result = await this.DomainService.BuildStatement(TestData.Commands.BuildMerchantStatementCommand, CancellationToken.None); - result.IsFailed.ShouldBeTrue(); - } - - [Fact] - public async Task MerchantStatementDomainService_BuildStatement_SaveFailed_StatementIsNotBuilt() - { - this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.GeneratedMerchantStatementAggregate())); - this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure); - - this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.MerchantStatementForDateAggregateWithTransactionAndFee())); - - this.AggregateService.Setup(a => a.Get(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.MerchantAggregateWithEverything(SettlementSchedule.Immediate))); - - this.StatementBuilder.Setup(s => s.GetStatementHtml(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(""); - - Result result = await this.DomainService.BuildStatement(TestData.Commands.BuildMerchantStatementCommand, CancellationToken.None); - result.IsFailed.ShouldBeTrue(); - } - - [Fact] - public async Task MerchantStatementDomainService_EmailStatement_StatementIsEmailed() - { - this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.BuiltMerchantStatementAggregate())); - this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success); - - this.AggregateService.Setup(a => a.Get(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.MerchantAggregateWithEverything(SettlementSchedule.Immediate))); - - this.MessagingServiceClient.Setup(m => m.SendEmail(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success); - - this.SecurityServiceClient.Setup(m => m.GetToken(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.TokenResponse())); - - Result result = await this.DomainService.EmailStatement(TestData.Commands.EmailMerchantStatementCommand, CancellationToken.None); - result.IsSuccess.ShouldBeTrue(); - } - - [Fact] - public async Task MerchantStatementDomainService_EmailStatement_MerchantNotFound_StatementIsNotEmailed() - { - this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.BuiltMerchantStatementAggregate())); - this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success); - - this.AggregateService.Setup(a => a.Get(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure()); - - this.MessagingServiceClient.Setup(m => m.SendEmail(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success); - - this.SecurityServiceClient.Setup(m => m.GetToken(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.TokenResponse())); - - Result result = await this.DomainService.EmailStatement(TestData.Commands.EmailMerchantStatementCommand, CancellationToken.None); - result.IsFailed.ShouldBeTrue(); - } - - [Fact] - public async Task MerchantStatementDomainService_EmailStatement_GetTokenFailed_StatementIsNotEmailed() - { - this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.BuiltMerchantStatementAggregate())); - this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success); - - this.AggregateService.Setup(a => a.Get(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.MerchantAggregateWithEverything(SettlementSchedule.Immediate))); - - this.MessagingServiceClient.Setup(m => m.SendEmail(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success); - - this.SecurityServiceClient.Setup(m => m.GetToken(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure()); - - Result result = await this.DomainService.EmailStatement(TestData.Commands.EmailMerchantStatementCommand, CancellationToken.None); - result.IsFailed.ShouldBeTrue(); - } - - } \ No newline at end of file diff --git a/TransactionProcessor.BusinessLogic.Tests/Services/MerchantStatementDomainServiceTests.cs b/TransactionProcessor.BusinessLogic.Tests/Services/MerchantStatementDomainServiceTests.cs new file mode 100644 index 00000000..63f6a8ac --- /dev/null +++ b/TransactionProcessor.BusinessLogic.Tests/Services/MerchantStatementDomainServiceTests.cs @@ -0,0 +1,269 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using MessagingService.Client; +using MessagingService.DataTransferObjects; +using Microsoft.Extensions.Configuration; +using Moq; +using SecurityService.Client; +using Shared.EventStore.Aggregate; +using Shared.General; +using Shared.Logger; +using Shouldly; +using SimpleResults; +using TransactionProcessor.Aggregates; +using TransactionProcessor.BusinessLogic.Services; +using TransactionProcessor.Models.Merchant; +using TransactionProcessor.Testing; +using Xunit; + +namespace TransactionProcessor.BusinessLogic.Tests.Services; + +public class MerchantStatementDomainServiceTests { + + private readonly Mock AggregateService; + private readonly Mock StatementBuilder; + private readonly Mock MessagingServiceClient; + private readonly Mock SecurityServiceClient; + private readonly MerchantStatementDomainService DomainService; + public MerchantStatementDomainServiceTests() { + this.AggregateService = new Mock(); + this.StatementBuilder = new Mock(); + this.MessagingServiceClient = new Mock(); + this.SecurityServiceClient = new Mock(); + this.DomainService = new MerchantStatementDomainService(this.AggregateService.Object, this.StatementBuilder.Object, this.MessagingServiceClient.Object, this.SecurityServiceClient.Object); + + IConfigurationRoot configurationRoot = + new ConfigurationBuilder().AddInMemoryCollection(TestData.DefaultAppSettings).Build(); + ConfigurationReader.Initialise(configurationRoot); + Logger.Initialise(new NullLogger()); + } + + [Fact] + public async Task MerchantStatementDomainService_AddTransactionToStatement_TransactionAddedToStatement() { + + this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.EmptyMerchantStatementForDateAggregate)); + this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success()); + Result result = await this.DomainService.AddTransactionToStatement(TestData.Commands.AddTransactionToMerchantStatementCommand, CancellationToken.None); + result.IsSuccess.ShouldBeTrue(); + } + + [Fact] + public async Task MerchantStatementDomainService_AddTransactionToStatement_TransactionNotAuthorised_TransactionNotAddedToStatement() + { + + this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.EmptyMerchantStatementForDateAggregate)); + this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success()); + Result result = await this.DomainService.AddTransactionToStatement(TestData.Commands.AddTransactionNotAuthorisedToMerchantStatementCommand, CancellationToken.None); + result.IsSuccess.ShouldBeTrue(); + } + + [Fact] + public async Task MerchantStatementDomainService_AddTransactionToStatement_TransactionHasNotAmount_TransactionNotAddedToStatement() + { + + this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.EmptyMerchantStatementForDateAggregate)); + this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success()); + Result result = await this.DomainService.AddTransactionToStatement(TestData.Commands.AddTransactionWithNoAmountToMerchantStatementCommand, CancellationToken.None); + result.IsSuccess.ShouldBeTrue(); + } + + [Fact] + public async Task MerchantStatementDomainService_AddTransactionToStatement_SaveFailed_TransactionNotAddedToStatement() + { + + this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.EmptyMerchantStatementForDateAggregate)); + this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure); + Result result = await this.DomainService.AddTransactionToStatement(TestData.Commands.AddTransactionToMerchantStatementCommand, CancellationToken.None); + result.IsFailed.ShouldBeTrue(); + } + + [Fact] + public async Task MerchantStatementDomainService_AddSettledFeeToStatement_SettledFeeAddedToStatement() + { + this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.EmptyMerchantStatementForDateAggregate)); + this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success()); + Result result = await this.DomainService.AddSettledFeeToStatement(TestData.Commands.AddSettledFeeToMerchantStatementCommand, CancellationToken.None); + result.IsSuccess.ShouldBeTrue(); + } + + [Fact] + public async Task MerchantStatementDomainService_AddSettledFeeToStatement_SaveFailed_SettledFeeNotAddedToStatement() + { + this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.EmptyMerchantStatementForDateAggregate)); + this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure); + Result result = await this.DomainService.AddSettledFeeToStatement(TestData.Commands.AddSettledFeeToMerchantStatementCommand, CancellationToken.None); + result.IsFailed.ShouldBeTrue(); + } + + [Fact] + public async Task MerchantStatementDomainService_AddDepositToStatement_DepositAddedToStatement() + { + + this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.EmptyMerchantStatementForDateAggregate)); + this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success()); + Result result = await this.DomainService.AddDepositToStatement(TestData.Commands.AddDepositToMerchantStatementCommand, CancellationToken.None); + result.IsSuccess.ShouldBeTrue(); + } + + [Fact] + public async Task MerchantStatementDomainService_AddWithdrawalToStatement_WithdrawalAddedToStatement() + { + + this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.EmptyMerchantStatementForDateAggregate)); + this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success()); + Result result = await this.DomainService.AddWithdrawalToStatement(TestData.Commands.AddWithdrawalToMerchantStatementCommand, CancellationToken.None); + result.IsSuccess.ShouldBeTrue(); + } + + [Fact] + public async Task MerchantStatementDomainService_RecordActivityDateOnMerchantStatement_SaveFailed_ActivityDateNotRecorded() { + this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.EmptyMerchantStatementAggregate)); + this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success); + Result result = await this.DomainService.RecordActivityDateOnMerchantStatement(TestData.Commands.RecordActivityDateOnMerchantStatementCommand, CancellationToken.None); + result.IsSuccess.ShouldBeTrue(); + } + + [Fact] + public async Task MerchantStatementDomainService_RecordActivityDateOnMerchantStatement_ActivityDateRecorded() + { + this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.EmptyMerchantStatementAggregate)); + this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure); + Result result = await this.DomainService.RecordActivityDateOnMerchantStatement(TestData.Commands.RecordActivityDateOnMerchantStatementCommand, CancellationToken.None); + result.IsFailed.ShouldBeTrue(); + } + + [Fact] + public async Task MerchantStatementDomainService_GenerateStatement_StatementIsGenerated() + { + this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.MerchantStatementAggregateWithActivityDates())); + this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success); + + this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.MerchantStatementForDateAggregateWithTransactionAndFee())); + + Result result = await this.DomainService.GenerateStatement(TestData.Commands.GenerateMerchantStatementCommand, CancellationToken.None); + result.IsSuccess.ShouldBeTrue(); + } + + [Fact] + public async Task MerchantStatementDomainService_GenerateStatement_GetStatementForDateFailed_StatementIsNotGenerated() + { + this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.MerchantStatementAggregateWithActivityDates())); + this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success); + + this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure()); + + Result result = await this.DomainService.GenerateStatement(TestData.Commands.GenerateMerchantStatementCommand, CancellationToken.None); + result.IsFailed.ShouldBeTrue(); + } + + [Fact] + public async Task MerchantStatementDomainService_GenerateStatement_SaveFailed_StatementIsNotGenerated() + { + this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.MerchantStatementAggregateWithActivityDates())); + this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure); + + this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.MerchantStatementForDateAggregateWithTransactionAndFee())); + + Result result = await this.DomainService.GenerateStatement(TestData.Commands.GenerateMerchantStatementCommand, CancellationToken.None); + result.IsFailed.ShouldBeTrue(); + } + + [Fact] + public async Task MerchantStatementDomainService_BuildStatement_StatementIsBuilt() + { + this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.GeneratedMerchantStatementAggregate())); + this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success); + + this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.MerchantStatementForDateAggregateWithTransactionAndFee())); + + this.AggregateService.Setup(a => a.Get(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.MerchantAggregateWithEverything(SettlementSchedule.Immediate))); + + this.StatementBuilder.Setup(s => s.GetStatementHtml(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(""); + + Result result = await this.DomainService.BuildStatement(TestData.Commands.BuildMerchantStatementCommand, CancellationToken.None); + result.IsSuccess.ShouldBeTrue(); + } + + [Fact] + public async Task MerchantStatementDomainService_BuildStatement_GetMerchantFailed_StatementIsNotBuilt() + { + this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.GeneratedMerchantStatementAggregate())); + this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success); + + this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.MerchantStatementForDateAggregateWithTransactionAndFee())); + + this.AggregateService.Setup(a => a.Get(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure()); + + this.StatementBuilder.Setup(s => s.GetStatementHtml(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(""); + + Result result = await this.DomainService.BuildStatement(TestData.Commands.BuildMerchantStatementCommand, CancellationToken.None); + result.IsFailed.ShouldBeTrue(); + } + + [Fact] + public async Task MerchantStatementDomainService_BuildStatement_SaveFailed_StatementIsNotBuilt() + { + this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.GeneratedMerchantStatementAggregate())); + this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure); + + this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.MerchantStatementForDateAggregateWithTransactionAndFee())); + + this.AggregateService.Setup(a => a.Get(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.MerchantAggregateWithEverything(SettlementSchedule.Immediate))); + + this.StatementBuilder.Setup(s => s.GetStatementHtml(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(""); + + Result result = await this.DomainService.BuildStatement(TestData.Commands.BuildMerchantStatementCommand, CancellationToken.None); + result.IsFailed.ShouldBeTrue(); + } + + [Fact] + public async Task MerchantStatementDomainService_EmailStatement_StatementIsEmailed() + { + this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.BuiltMerchantStatementAggregate())); + this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success); + + this.AggregateService.Setup(a => a.Get(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.MerchantAggregateWithEverything(SettlementSchedule.Immediate))); + + this.MessagingServiceClient.Setup(m => m.SendEmail(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success); + + this.SecurityServiceClient.Setup(m => m.GetToken(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.TokenResponse())); + + Result result = await this.DomainService.EmailStatement(TestData.Commands.EmailMerchantStatementCommand, CancellationToken.None); + result.IsSuccess.ShouldBeTrue(); + } + + [Fact] + public async Task MerchantStatementDomainService_EmailStatement_MerchantNotFound_StatementIsNotEmailed() + { + this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.BuiltMerchantStatementAggregate())); + this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success); + + this.AggregateService.Setup(a => a.Get(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure()); + + this.MessagingServiceClient.Setup(m => m.SendEmail(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success); + + this.SecurityServiceClient.Setup(m => m.GetToken(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.TokenResponse())); + + Result result = await this.DomainService.EmailStatement(TestData.Commands.EmailMerchantStatementCommand, CancellationToken.None); + result.IsFailed.ShouldBeTrue(); + } + + [Fact] + public async Task MerchantStatementDomainService_EmailStatement_GetTokenFailed_StatementIsNotEmailed() + { + this.AggregateService.Setup(a => a.GetLatest(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.BuiltMerchantStatementAggregate())); + this.AggregateService.Setup(a => a.Save(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success); + + this.AggregateService.Setup(a => a.Get(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.Aggregates.MerchantAggregateWithEverything(SettlementSchedule.Immediate))); + + this.MessagingServiceClient.Setup(m => m.SendEmail(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success); + + this.SecurityServiceClient.Setup(m => m.GetToken(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(Result.Failure()); + + Result result = await this.DomainService.EmailStatement(TestData.Commands.EmailMerchantStatementCommand, CancellationToken.None); + result.IsFailed.ShouldBeTrue(); + } + + +} \ No newline at end of file diff --git a/TransactionProcessor.BusinessLogic.Tests/Services/StatementBuilderTests.cs b/TransactionProcessor.BusinessLogic.Tests/Services/StatementBuilderTests.cs index 046bdcef..f54ad6e8 100644 --- a/TransactionProcessor.BusinessLogic.Tests/Services/StatementBuilderTests.cs +++ b/TransactionProcessor.BusinessLogic.Tests/Services/StatementBuilderTests.cs @@ -35,8 +35,9 @@ public StatementBuilderTests() TestData.EstateId, TestData.MerchantId, TestData.MerchantStatementForDateId1, new DateTime(2025,5,1)); merchantStatementAggregate.RecordActivityDateOnStatement(TestData.MerchantStatementId, TestData.StatementDate, TestData.EstateId, TestData.MerchantId, TestData.MerchantStatementForDateId2, new DateTime(2025, 5, 2)); - merchantStatementAggregate.AddDailySummaryRecord(new DateTime(2025, 5, 1), 100, 1000.00m, 100, 10.00m); - merchantStatementAggregate.AddDailySummaryRecord(new DateTime(2025, 5, 2), 200, 2000.00m, 200, 20.00m); + merchantStatementAggregate.AddDailySummaryRecord(new DateTime(2025, 5, 1), 100, 1000.00m, 100, 10.00m, + 1, 1000, 1, 200); + merchantStatementAggregate.AddDailySummaryRecord(new DateTime(2025, 5, 2), 200, 2000.00m, 200, 20.00m, 2, 1000, 2, 200); merchantStatementAggregate.GenerateStatement(TestData.GeneratedDateTime); // Setup file system mocks for templates and CSS diff --git a/TransactionProcessor.BusinessLogic/EventHandling/MerchantStatementDomainEventHandler.cs b/TransactionProcessor.BusinessLogic/EventHandling/MerchantStatementDomainEventHandler.cs index b18a9417..a13ec2d1 100644 --- a/TransactionProcessor.BusinessLogic/EventHandling/MerchantStatementDomainEventHandler.cs +++ b/TransactionProcessor.BusinessLogic/EventHandling/MerchantStatementDomainEventHandler.cs @@ -16,6 +16,7 @@ using TransactionProcessor.BusinessLogic.Services; using TransactionProcessor.DomainEvents; using Shared.EventStore.Aggregate; +using Shared.ValueObjects; namespace TransactionProcessor.BusinessLogic.EventHandling { @@ -61,6 +62,9 @@ public async Task Handle(IDomainEvent domainEvent, TransactionDomainEvents.TransactionHasBeenCompletedEvent de => this.HandleSpecificDomainEvent(de, cancellationToken), MerchantStatementForDateDomainEvents.StatementCreatedForDateEvent de => this.HandleSpecificDomainEvent(de, cancellationToken), MerchantStatementDomainEvents.StatementBuiltEvent de => this.HandleSpecificDomainEvent(de, cancellationToken), + MerchantDomainEvents.AutomaticDepositMadeEvent de => this.HandleSpecificDomainEvent(de, cancellationToken), + MerchantDomainEvents.ManualDepositMadeEvent de => this.HandleSpecificDomainEvent(de, cancellationToken), + MerchantDomainEvents.WithdrawalMadeEvent de => this.HandleSpecificDomainEvent(de, cancellationToken), _ => null }; @@ -104,16 +108,44 @@ private async Task HandleSpecificDomainEvent(MerchantStatementDomainEven private async Task HandleSpecificDomainEvent(TransactionDomainEvents.TransactionHasBeenCompletedEvent domainEvent, CancellationToken cancellationToken) { - MerchantStatementCommands.AddTransactionToMerchantStatementCommand command = new(domainEvent.EstateId, domainEvent.MerchantId, domainEvent.CompletedDateTime, domainEvent.TransactionAmount, domainEvent.IsAuthorised, domainEvent.TransactionId); + MerchantStatementCommands.AddTransactionToMerchantStatementCommand command = new(domainEvent.EstateId, domainEvent.MerchantId, domainEvent.CompletedDateTime, + Money.Create(domainEvent.TransactionAmount.GetValueOrDefault(0)), domainEvent.IsAuthorised, domainEvent.TransactionId); Result result = await this.Mediator.Send(command, cancellationToken); return result; } + private async Task HandleSpecificDomainEvent(MerchantDomainEvents.AutomaticDepositMadeEvent domainEvent, + CancellationToken cancellationToken) { + MerchantStatementCommands.AddDepositToMerchantStatementCommand command = new(domainEvent.EstateId, domainEvent.MerchantId, domainEvent.DepositId, domainEvent.Reference, domainEvent.DepositDateTime, + PositiveMoney.Create(Money.Create(domainEvent.Amount))); + Result result = await this.Mediator.Send(command, cancellationToken); + return result; + } + + private async Task HandleSpecificDomainEvent(MerchantDomainEvents.ManualDepositMadeEvent domainEvent, + CancellationToken cancellationToken) + { + MerchantStatementCommands.AddDepositToMerchantStatementCommand command = new(domainEvent.EstateId, domainEvent.MerchantId, domainEvent.DepositId, domainEvent.Reference, domainEvent.DepositDateTime, + PositiveMoney.Create(Money.Create(domainEvent.Amount))); + Result result = await this.Mediator.Send(command, cancellationToken); + return result; + } + + private async Task HandleSpecificDomainEvent(MerchantDomainEvents.WithdrawalMadeEvent domainEvent, + CancellationToken cancellationToken) + { + MerchantStatementCommands.AddWithdrawalToMerchantStatementCommand command = new(domainEvent.EstateId, domainEvent.MerchantId, domainEvent.WithdrawalId, domainEvent.WithdrawalDateTime, + PositiveMoney.Create(Money.Create(domainEvent.Amount))); + Result result = await this.Mediator.Send(command, cancellationToken); + return result; + } + private async Task HandleSpecificDomainEvent(SettlementDomainEvents.MerchantFeeSettledEvent domainEvent, CancellationToken cancellationToken) { - MerchantStatementCommands.AddSettledFeeToMerchantStatementCommand command = new(domainEvent.EstateId, domainEvent.MerchantId, domainEvent.FeeCalculatedDateTime, domainEvent.CalculatedValue, domainEvent.TransactionId, domainEvent.FeeId); + MerchantStatementCommands.AddSettledFeeToMerchantStatementCommand command = new(domainEvent.EstateId, domainEvent.MerchantId, domainEvent.FeeCalculatedDateTime, + PositiveMoney.Create(Money.Create(domainEvent.CalculatedValue)), domainEvent.TransactionId, domainEvent.FeeId); //return await this.Mediator.Send(command, cancellationToken); Result result = await this.Mediator.Send(command, cancellationToken); diff --git a/TransactionProcessor.BusinessLogic/RequestHandlers/MerchantStatementRequestHandler.cs b/TransactionProcessor.BusinessLogic/RequestHandlers/MerchantStatementRequestHandler.cs index db1309c6..d6f06a79 100644 --- a/TransactionProcessor.BusinessLogic/RequestHandlers/MerchantStatementRequestHandler.cs +++ b/TransactionProcessor.BusinessLogic/RequestHandlers/MerchantStatementRequestHandler.cs @@ -12,7 +12,9 @@ public class MerchantStatementRequestHandler : IRequestHandler, IRequestHandler, IRequestHandler, - IRequestHandler + IRequestHandler, + IRequestHandler, + IRequestHandler { #region Fields @@ -88,5 +90,15 @@ public async Task Handle(MerchantStatementCommands.RecordActivityDateOnM return await this.MerchantStatementDomainService.RecordActivityDateOnMerchantStatement(request, cancellationToken); } + + public async Task Handle(MerchantStatementCommands.AddDepositToMerchantStatementCommand request, + CancellationToken cancellationToken) { + return await this.MerchantStatementDomainService.AddDepositToStatement(request, cancellationToken); + } + + public async Task Handle(MerchantStatementCommands.AddWithdrawalToMerchantStatementCommand request, + CancellationToken cancellationToken) { + return await this.MerchantStatementDomainService.AddWithdrawalToStatement(request, cancellationToken); + } } } \ No newline at end of file diff --git a/TransactionProcessor.BusinessLogic/Requests/MerchantStatementCommands.cs b/TransactionProcessor.BusinessLogic/Requests/MerchantStatementCommands.cs index a8cce564..74e47743 100644 --- a/TransactionProcessor.BusinessLogic/Requests/MerchantStatementCommands.cs +++ b/TransactionProcessor.BusinessLogic/Requests/MerchantStatementCommands.cs @@ -1,6 +1,7 @@ using System; using System.Diagnostics.CodeAnalysis; using MediatR; +using Shared.ValueObjects; using SimpleResults; namespace TransactionProcessor.BusinessLogic.Requests; @@ -10,10 +11,23 @@ public record MerchantStatementCommands { public record AddTransactionToMerchantStatementCommand(Guid EstateId, Guid MerchantId, DateTime TransactionDateTime, - Decimal? TransactionAmount, + Money? TransactionAmount, Boolean IsAuthorised, Guid TransactionId) : IRequest; + public record AddDepositToMerchantStatementCommand(Guid EstateId, + Guid MerchantId, + Guid DepositId, + String Reference, + DateTime DepositDateTime, + PositiveMoney Amount) : IRequest; + + public record AddWithdrawalToMerchantStatementCommand(Guid EstateId, + Guid MerchantId, + Guid WithdrawalId, + DateTime WithdrawalDateTime, + PositiveMoney Amount) : IRequest; + public record BuildMerchantStatementCommand(Guid EstateId, Guid MerchantId, Guid MerchantStatementId) : IRequest; @@ -25,7 +39,7 @@ public record EmailMerchantStatementCommand(Guid EstateId, public record AddSettledFeeToMerchantStatementCommand(Guid EstateId, Guid MerchantId, DateTime SettledDateTime, - Decimal SettledAmount, + PositiveMoney SettledAmount, Guid TransactionId, Guid SettledFeeId) : IRequest; diff --git a/TransactionProcessor.BusinessLogic/Services/MerchantStatementDomainService.cs b/TransactionProcessor.BusinessLogic/Services/MerchantStatementDomainService.cs index 91c45d58..062c4dd4 100644 --- a/TransactionProcessor.BusinessLogic/Services/MerchantStatementDomainService.cs +++ b/TransactionProcessor.BusinessLogic/Services/MerchantStatementDomainService.cs @@ -1,4 +1,6 @@ -using MessagingService.Client; +using Google.Protobuf.Reflection; +using MessagingService.Client; +using MessagingService.DataTransferObjects; using SecurityService.Client; using SecurityService.DataTransferObjects.Responses; using Shared.DomainDrivenDesign.EventSourcing; @@ -7,6 +9,7 @@ using Shared.General; using Shared.Logger; using Shared.Results; +using Shared.ValueObjects; using SimpleResults; using System; using System.Collections.Generic; @@ -17,8 +20,6 @@ using System.Text; using System.Threading; using System.Threading.Tasks; -using Google.Protobuf.Reflection; -using MessagingService.DataTransferObjects; using TransactionProcessor.Aggregates; using TransactionProcessor.Aggregates.Models; using TransactionProcessor.BusinessLogic.Common; @@ -42,6 +43,9 @@ public interface IMerchantStatementDomainService Task BuildStatement(MerchantStatementCommands.BuildMerchantStatementCommand command, CancellationToken cancellationToken); Task RecordActivityDateOnMerchantStatement(MerchantStatementCommands.RecordActivityDateOnMerchantStatementCommand command, CancellationToken cancellationToken); + Task AddDepositToStatement(MerchantStatementCommands.AddDepositToMerchantStatementCommand command, CancellationToken cancellationToken); + Task AddWithdrawalToStatement(MerchantStatementCommands.AddWithdrawalToMerchantStatementCommand command, CancellationToken cancellationToken); + #endregion } @@ -137,7 +141,7 @@ public async Task AddSettledFeeToStatement(MerchantStatementCommands.Add Result result = await ApplyUpdates( async (MerchantStatementForDateAggregate merchantStatementForDateAggregate) => { - SettledFee settledFee = new SettledFee(settlementFeeId, command.TransactionId, command.SettledDateTime, command.SettledAmount); + SettledFee settledFee = new SettledFee(settlementFeeId, command.TransactionId, command.SettledDateTime, command.SettledAmount.Value); Guid eventId = IdGenerationService.GenerateEventId(new { @@ -204,8 +208,19 @@ public async Task GenerateStatement(MerchantCommands.GenerateMerchantSta .Where(sl => sl.LineType == 2) .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); + var depositsResult = merchantStatementForDateAggregate.GetStatementLines() + .Where(sl => sl.LineType == 3) + .Aggregate(new { Count = 0, TotalAmount = 0m }, + (acc, 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); } merchantStatementAggregate.GenerateStatement(DateTime.Now); @@ -334,13 +349,75 @@ public async Task RecordActivityDateOnMerchantStatement(MerchantStatemen return Result.Success(); } + public async Task AddDepositToStatement(MerchantStatementCommands.AddDepositToMerchantStatementCommand command, + CancellationToken cancellationToken) { + // Work out the next statement date + DateTime nextStatementDate = CalculateStatementDate(command.DepositDateTime.Date); + + Guid merchantStatementId = IdGenerationService.GenerateMerchantStatementAggregateId(command.EstateId, command.MerchantId, nextStatementDate); + Guid merchantStatementForDateId = IdGenerationService.GenerateMerchantStatementForDateAggregateId(command.EstateId, command.MerchantId, nextStatementDate, command.DepositDateTime.Date); + + Result result = await ApplyUpdates( + async (MerchantStatementForDateAggregate merchantStatementForDateAggregate) => { + + Deposit deposit = new Deposit { DepositId = command.DepositId, Reference = command.Reference, DepositDateTime = command.DepositDateTime, Amount = command.Amount.Value }; + + Guid eventId = IdGenerationService.GenerateEventId(new + { + command.DepositId, + deposit, + command.DepositDateTime, + }); + + merchantStatementForDateAggregate.AddDepositToStatement(merchantStatementId, nextStatementDate, eventId, command.EstateId, command.MerchantId, deposit); + + return Result.Success(); + }, merchantStatementForDateId, cancellationToken, false); + + if (result.IsFailed) + return ResultHelpers.CreateFailure(result); + + return Result.Success(); + } + + public async Task AddWithdrawalToStatement(MerchantStatementCommands.AddWithdrawalToMerchantStatementCommand command, + CancellationToken cancellationToken) { + // Work out the next statement date + DateTime nextStatementDate = CalculateStatementDate(command.WithdrawalDateTime.Date); + + Guid merchantStatementId = IdGenerationService.GenerateMerchantStatementAggregateId(command.EstateId, command.MerchantId, nextStatementDate); + Guid merchantStatementForDateId = IdGenerationService.GenerateMerchantStatementForDateAggregateId(command.EstateId, command.MerchantId, nextStatementDate, command.WithdrawalDateTime.Date); + + Result result = await ApplyUpdates( + async (MerchantStatementForDateAggregate merchantStatementForDateAggregate) => { + + Withdrawal withdrawal = new Withdrawal() { WithdrawalId = command.WithdrawalId, WithdrawalDateTime = command.WithdrawalDateTime, Amount = command.Amount.Value }; + + Guid eventId = IdGenerationService.GenerateEventId(new + { + command.WithdrawalId, + withdrawal, + command.WithdrawalDateTime, + }); + + merchantStatementForDateAggregate.AddWithdrawalToStatement(merchantStatementId, nextStatementDate, eventId, command.EstateId, command.MerchantId, withdrawal); + + return Result.Success(); + }, merchantStatementForDateId, cancellationToken, false); + + if (result.IsFailed) + return ResultHelpers.CreateFailure(result); + + return Result.Success(); + } + public async Task AddTransactionToStatement(MerchantStatementCommands.AddTransactionToMerchantStatementCommand command, CancellationToken cancellationToken) { // Transaction Completed arrives(if this is a logon transaction or failed then return) if (command.IsAuthorised == false) return Result.Success(); - if (command.TransactionAmount.HasValue == false) + if (command.TransactionAmount == null) return Result.Success(); // Work out the next statement date @@ -353,12 +430,12 @@ public async Task AddTransactionToStatement(MerchantStatementCommands.Ad async (MerchantStatementForDateAggregate merchantStatementForDateAggregate) => { // Add transaction to statement - Transaction transaction = new(command.TransactionId, command.TransactionDateTime, command.TransactionAmount.GetValueOrDefault(0)); + Transaction transaction = new(command.TransactionId, command.TransactionDateTime, command.TransactionAmount.Value); Guid eventId = IdGenerationService.GenerateEventId(new { command.TransactionId, - TransactionAmount = command.TransactionAmount.GetValueOrDefault(0), + TransactionAmount = command.TransactionAmount.Value, command.TransactionDateTime, }); diff --git a/TransactionProcessor.DomainEvents/MerchantStatementDomainEvents.cs b/TransactionProcessor.DomainEvents/MerchantStatementDomainEvents.cs index 83ffbc2d..c83cef4e 100644 --- a/TransactionProcessor.DomainEvents/MerchantStatementDomainEvents.cs +++ b/TransactionProcessor.DomainEvents/MerchantStatementDomainEvents.cs @@ -16,7 +16,10 @@ public record StatementCreatedEvent(Guid MerchantStatementId, Guid EstateId, Gui public record ActivityDateAddedToStatementEvent(Guid MerchantStatementId, Guid EstateId, Guid MerchantId, Guid MerchantStatementForDateId, DateTime ActivityDate) : DomainEvent(MerchantStatementId, Guid.NewGuid()); public record StatementSummaryForDateEvent(Guid MerchantStatementId, Guid EstateId, Guid MerchantId, DateTime ActivityDate, Int32 LineNumber, - Int32 NumberOfTransactions, Decimal ValueOfTransactions, Int32 NumberOfSettledFees, Decimal ValueOfSettledFees) : DomainEvent(MerchantStatementId, Guid.NewGuid()); + Int32 NumberOfTransactions, Decimal ValueOfTransactions, + Int32 NumberOfSettledFees, Decimal ValueOfSettledFees, + Int32 NumberOfDeposits, Decimal ValueOfDeposits, + Int32 NumberOfWithdrawals, Decimal ValueOfWithdrawals) : DomainEvent(MerchantStatementId, Guid.NewGuid()); } [ExcludeFromCodeCoverage] @@ -27,5 +30,8 @@ public record SettledFeeAddedToStatementForDateEvent(Guid MerchantStatementForDa public record TransactionAddedToStatementForDateEvent(Guid MerchantStatementForDateId, Guid EventId, Guid EstateId, Guid MerchantId, Guid TransactionId, DateTime TransactionDateTime, Decimal TransactionValue) : DomainEvent(MerchantStatementForDateId, EventId); + public record DepositAddedToStatementForDateEvent(Guid MerchantStatementForDateId, Guid EventId, Guid EstateId, Guid MerchantId, Guid DepositId, DateTime DepositDateTime, Decimal DepositAmount) : DomainEvent(MerchantStatementForDateId, EventId); + public record WithdrawalAddedToStatementForDateEvent(Guid MerchantStatementForDateId, Guid EventId, Guid EstateId, Guid MerchantId, Guid WithdrawalId, DateTime WithdrawalDateTime, Decimal WithdrawalAmount) : DomainEvent(MerchantStatementForDateId, EventId); + } } \ No newline at end of file diff --git a/TransactionProcessor.IntegrationTesting.Helpers/SubscriptionsHelper.cs b/TransactionProcessor.IntegrationTesting.Helpers/SubscriptionsHelper.cs index 3ca4f625..aaaaea7e 100644 --- a/TransactionProcessor.IntegrationTesting.Helpers/SubscriptionsHelper.cs +++ b/TransactionProcessor.IntegrationTesting.Helpers/SubscriptionsHelper.cs @@ -25,6 +25,7 @@ public static class SubscriptionsHelper ("$ce-SettlementAggregate", "Transaction Processor - Domain", 0), ("$ce-CallbackMessageAggregate", "Transaction Processor - Domain", 0), ("$ce-MerchantStatementAggregate", "Transaction Processor - Domain", 0), + ("$ce-MerchantDepositListAggregate", "Transaction Processor - Domain", 0), // Ordered ("$ce-MerchantAggregate", "Transaction Processor - Ordered", 2), diff --git a/TransactionProcessor.Testing/TestData.cs b/TransactionProcessor.Testing/TestData.cs index 6ad16ea0..69a2f45a 100644 --- a/TransactionProcessor.Testing/TestData.cs +++ b/TransactionProcessor.Testing/TestData.cs @@ -1,4 +1,5 @@ using System.Text; +using Microsoft.IdentityModel.Tokens; using Newtonsoft.Json; using Shared.EventStore.ProjectionEngine; using Shared.ValueObjects; @@ -2000,6 +2001,8 @@ public static DataTransferObjects.Requests.Contract.AddTransactionFeeForProductT Reference = TestData.WithdrawalReference }; + public static Guid WithdrawalId = Guid.Parse("C5913183-78AE-41C8-9EAE-903F5748DE9A"); + public static String WithdrawalReference = "Withdraw1"; public static String MerchantUserFamilyName = "Merchant"; @@ -2093,29 +2096,24 @@ public static class Commands { public static MerchantCommands.GenerateMerchantStatementCommand GenerateMerchantStatementCommand => new(TestData.EstateId, TestData.MerchantId, TestData.GenerateMerchantStatementRequest); public static MerchantStatementCommands.BuildMerchantStatementCommand BuildMerchantStatementCommand => new(EstateId, MerchantId, MerchantStatementId); public static MerchantStatementCommands.EmailMerchantStatementCommand EmailMerchantStatementCommand => new(EstateId, MerchantStatementId,StatementData); - public static MerchantStatementCommands.AddTransactionToMerchantStatementCommand AddTransactionToMerchantStatementCommand => new(EstateId, MerchantId, TransactionDateTime, TransactionAmount, IsAuthorisedTrue, TransactionId); - public static MerchantStatementCommands.AddTransactionToMerchantStatementCommand AddTransactionNotAuthorisedToMerchantStatementCommand => new(EstateId, MerchantId, TransactionDateTime, TransactionAmount, IsAuthorisedFalse, TransactionId); + public static MerchantStatementCommands.AddTransactionToMerchantStatementCommand AddTransactionToMerchantStatementCommand => new(EstateId, MerchantId, TransactionDateTime, Money.Create(TransactionAmount), IsAuthorisedTrue, TransactionId); + public static MerchantStatementCommands.AddTransactionToMerchantStatementCommand AddTransactionNotAuthorisedToMerchantStatementCommand => new(EstateId, MerchantId, TransactionDateTime, Money.Create(TransactionAmount), IsAuthorisedFalse, TransactionId); public static MerchantStatementCommands.AddTransactionToMerchantStatementCommand AddTransactionWithNoAmountToMerchantStatementCommand => new(EstateId, MerchantId, TransactionDateTime, null, IsAuthorisedTrue, TransactionId); - //public static MerchantStatementCommands.EmailMerchantStatementCommand EmailMerchantStatementCommand => new(EstateId, MerchantId, MerchantStatementId); - public static MerchantStatementCommands.AddSettledFeeToMerchantStatementCommand AddSettledFeeToMerchantStatementCommand => new(EstateId, MerchantId, TransactionDateTime, SettledFeeAmount1, TransactionId, SettledFeeId1); - - public static MerchantStatementCommands.RecordActivityDateOnMerchantStatementCommand RecordActivityDateOnMerchantStatementCommand => new(EstateId, MerchantId, MerchantStatementId,StatementDate,MerchantStatementForDateId1,ActivityDate1); + public static MerchantStatementCommands.AddSettledFeeToMerchantStatementCommand AddSettledFeeToMerchantStatementCommand => new(EstateId, MerchantId, TransactionDateTime, PositiveMoney.Create(Money.Create(SettledFeeAmount1)), TransactionId, SettledFeeId1); - public static TransactionCommands.ResendTransactionReceiptCommand ResendTransactionReceiptCommand => new(TestData.TransactionId, - TestData.EstateId); + public static MerchantStatementCommands.AddDepositToMerchantStatementCommand AddDepositToMerchantStatementCommand => new(EstateId, MerchantId, DepositId, DepositReference, DepositDateTime, DepositAmount); + public static MerchantStatementCommands.AddWithdrawalToMerchantStatementCommand AddWithdrawalToMerchantStatementCommand => new(EstateId, MerchantId, WithdrawalId, WithdrawalDateTime, WithdrawalAmount); + public static MerchantStatementCommands.RecordActivityDateOnMerchantStatementCommand RecordActivityDateOnMerchantStatementCommand => new(EstateId, MerchantId, MerchantStatementId,StatementDate,MerchantStatementForDateId1,ActivityDate1); + public static TransactionCommands.ResendTransactionReceiptCommand ResendTransactionReceiptCommand => new(TestData.TransactionId, TestData.EstateId); 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, FloatCreditId); public static FloatActivityCommands.RecordTransactionCommand RecordTransactionCommand => new(EstateId, TransactionId); public static TransactionCommands.CalculateFeesForTransactionCommand CalculateFeesForTransactionCommand => new(TransactionId, TransactionDateTime, EstateId, MerchantId); - public static TransactionCommands.AddSettledMerchantFeeCommand AddSettledMerchantFeeCommand => new(TransactionId, CalculatedFeeValue, TransactionFeeCalculateDateTime, CalculationType.Percentage, TransactionFeeId, TransactionFeeValue, SettlementDate, SettlementAggregateId); - public static TransactionCommands.ProcessSaleTransactionCommand ProcessSaleTransactionCommand => - new(TestData.TransactionId, - TestData.EstateId, + new(TestData.TransactionId, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, TestData.TransactionTypeLogon.ToString(), @@ -2545,7 +2543,7 @@ public static MerchantStatementAggregate GeneratedMerchantStatementAggregate() { MerchantStatementAggregate aggregate = MerchantStatementAggregate.Create(MerchantStatementId); aggregate.RecordActivityDateOnStatement(MerchantStatementId, StatementDate, EstateId, MerchantId, MerchantStatementForDateId1, ActivityDate1); - aggregate.AddDailySummaryRecord(ActivityDate1, 1, 100, 1,0.10m); + aggregate.AddDailySummaryRecord(ActivityDate1, 1, 100, 1,0.10m, 1,1000, 1,200); aggregate.GenerateStatement(StatementGeneratedDate); return aggregate; } @@ -2554,7 +2552,7 @@ public static MerchantStatementAggregate BuiltMerchantStatementAggregate() { MerchantStatementAggregate aggregate = MerchantStatementAggregate.Create(MerchantStatementId); aggregate.RecordActivityDateOnStatement(MerchantStatementId, StatementDate, EstateId, MerchantId, MerchantStatementForDateId1, ActivityDate1); - aggregate.AddDailySummaryRecord(ActivityDate1, 1, 100, 1, 0.10m); + aggregate.AddDailySummaryRecord(ActivityDate1, 1, 100, 1, 0.10m, 1, 1000, 1, 200); aggregate.GenerateStatement(StatementGeneratedDate); aggregate.BuildStatement(StatementBuiltDate,StatementData); return aggregate; @@ -2632,6 +2630,10 @@ public static class DomainEvents { TestData.TransactionAmount, TestData.TransactionDateTime); + public static MerchantDomainEvents.AutomaticDepositMadeEvent AutomaticDepositMadeEvent => new(MerchantId, EstateId, DepositId, DepositReference, DepositDateTime, DepositAmount.Value); + public static MerchantDomainEvents.ManualDepositMadeEvent ManualDepositMadeEvent => new(MerchantId, EstateId, DepositId, DepositReference, DepositDateTime, DepositAmount.Value); + + public static MerchantDomainEvents.WithdrawalMadeEvent WithdrawalMadeEvent => new(MerchantId, EstateId, WithdrawalId, WithdrawalDateTime, WithdrawalAmount.Value); public static MerchantStatementForDateDomainEvents.StatementCreatedForDateEvent StatementCreatedForDateEvent => new(MerchantStatementForDateId1, ActivityDate1, StatementDate, MerchantStatementId, EstateId, MerchantId); public static SettlementDomainEvents.MerchantFeeSettledEvent MerchantFeeSettledEvent => new(SettlementId, EstateId, MerchantId, TransactionId, CalculatedFeeValue, FeeCalculationType, SettledFeeId1, FeeValue, TransactionFeeCalculateDateTime, SettlementDate); diff --git a/TransactionProcessor/Bootstrapper/MediatorRegistry.cs b/TransactionProcessor/Bootstrapper/MediatorRegistry.cs index a156f573..e907048b 100644 --- a/TransactionProcessor/Bootstrapper/MediatorRegistry.cs +++ b/TransactionProcessor/Bootstrapper/MediatorRegistry.cs @@ -46,6 +46,8 @@ private void RegisterMerchantStatementRequestHandler() { this.AddSingleton, MerchantStatementRequestHandler>(); this.AddSingleton, MerchantStatementRequestHandler>(); this.AddSingleton, MerchantStatementRequestHandler>(); + this.AddSingleton, MerchantStatementRequestHandler>(); + this.AddSingleton, MerchantStatementRequestHandler>(); } private void RegisterMerchantRequestHandler() { diff --git a/TransactionProcessor/appsettings.json b/TransactionProcessor/appsettings.json index 26ad0d27..856332fa 100644 --- a/TransactionProcessor/appsettings.json +++ b/TransactionProcessor/appsettings.json @@ -111,7 +111,8 @@ "StatementCreatedForDateEvent", "StatementGeneratedEvent", "MerchantFeeSettledEvent", - "StatementBuiltEvent" + "StatementBuiltEvent", + "ManualDepositMadeEvent" ] }, "EventHandlerConfigurationOrdered": {