From 9ad5616b1a014b96c4cb34d3124e4519ca9f69d3 Mon Sep 17 00:00:00 2001 From: Stuart Ferguson Date: Mon, 8 Jun 2020 19:04:29 +0100 Subject: [PATCH] Added Transaction Amount to started event --- .../TransactionAggregateManagerTests.cs | 1 + .../Services/ITransactionAggregateManager.cs | 2 + .../Services/TransactionAggregateManager.cs | 4 +- .../Services/TransactionDomainService.cs | 27 +++++ TransactionProcessor.Testing/TestData.cs | 17 ++- .../TransactionHasStartedEvent.cs | 20 +++- .../DomainEventTests.cs | 4 +- .../TransactionAggregateTests.cs | 106 ++++++++++++------ .../TransactionAggregate.cs | 40 ++++--- 9 files changed, 162 insertions(+), 59 deletions(-) diff --git a/TransactionProcessor.BusinessLogic.Tests/Services/TransactionAggregateManagerTests.cs b/TransactionProcessor.BusinessLogic.Tests/Services/TransactionAggregateManagerTests.cs index b4ee1762..80bb2c5e 100644 --- a/TransactionProcessor.BusinessLogic.Tests/Services/TransactionAggregateManagerTests.cs +++ b/TransactionProcessor.BusinessLogic.Tests/Services/TransactionAggregateManagerTests.cs @@ -216,6 +216,7 @@ await transactionAggregateManager.StartTransaction(TestData.TransactionId, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount, CancellationToken.None); } diff --git a/TransactionProcessor.BusinessLogic/Services/ITransactionAggregateManager.cs b/TransactionProcessor.BusinessLogic/Services/ITransactionAggregateManager.cs index d0396823..75b2ca30 100644 --- a/TransactionProcessor.BusinessLogic/Services/ITransactionAggregateManager.cs +++ b/TransactionProcessor.BusinessLogic/Services/ITransactionAggregateManager.cs @@ -157,6 +157,7 @@ Task RecordAdditionalResponseData(Guid estateId, /// The estate identifier. /// The merchant identifier. /// The device identifier. + /// The transaction amount. /// The cancellation token. /// Task StartTransaction(Guid transactionId, @@ -167,6 +168,7 @@ Task StartTransaction(Guid transactionId, Guid estateId, Guid merchantId, String deviceIdentifier, + Decimal? transactionAmount, CancellationToken cancellationToken); #endregion diff --git a/TransactionProcessor.BusinessLogic/Services/TransactionAggregateManager.cs b/TransactionProcessor.BusinessLogic/Services/TransactionAggregateManager.cs index 59944c80..5ac1c489 100644 --- a/TransactionProcessor.BusinessLogic/Services/TransactionAggregateManager.cs +++ b/TransactionProcessor.BusinessLogic/Services/TransactionAggregateManager.cs @@ -275,6 +275,7 @@ public async Task RequestEmailReceipt(Guid estateId, Guid transactionId, String /// The estate identifier. /// The merchant identifier. /// The device identifier. + /// The transaction amount. /// The cancellation token. public async Task StartTransaction(Guid transactionId, DateTime transactionDateTime, @@ -284,6 +285,7 @@ public async Task StartTransaction(Guid transactionId, Guid estateId, Guid merchantId, String deviceIdentifier, + Decimal? transactionAmount, CancellationToken cancellationToken) { IAggregateRepository transactionAggregateRepository = @@ -291,7 +293,7 @@ public async Task StartTransaction(Guid transactionId, TransactionAggregate transactionAggregate = await transactionAggregateRepository.GetLatestVersion(transactionId, cancellationToken); - transactionAggregate.StartTransaction(transactionDateTime, transactionNumber, transactionType, transactionReference, estateId, merchantId, deviceIdentifier); + transactionAggregate.StartTransaction(transactionDateTime, transactionNumber, transactionType, transactionReference, estateId, merchantId, deviceIdentifier, transactionAmount); await transactionAggregateRepository.SaveChanges(transactionAggregate, cancellationToken); } diff --git a/TransactionProcessor.BusinessLogic/Services/TransactionDomainService.cs b/TransactionProcessor.BusinessLogic/Services/TransactionDomainService.cs index 1d1a1930..d5305f9b 100644 --- a/TransactionProcessor.BusinessLogic/Services/TransactionDomainService.cs +++ b/TransactionProcessor.BusinessLogic/Services/TransactionDomainService.cs @@ -102,6 +102,7 @@ await this.TransactionAggregateManager.StartTransaction(transactionId, estateId, merchantId, deviceIdentifier, + null, // Logon transaction has no amount cancellationToken); (String responseMessage, TransactionResponseCode responseCode) validationResult = @@ -162,6 +163,9 @@ public async Task ProcessSaleTransaction(Guid tr // Generate a transaction reference String transactionReference = this.GenerateTransactionReference(); + // Extract the transaction amount from the metadata + Decimal transactionAmount = this.ExtractFieldFromMetadata("Amount", additionalTransactionMetadata); + await this.TransactionAggregateManager.StartTransaction(transactionId, transactionDateTime, transactionNumber, @@ -170,6 +174,7 @@ await this.TransactionAggregateManager.StartTransaction(transactionId, estateId, merchantId, deviceIdentifier, + transactionAmount, cancellationToken); (String responseMessage, TransactionResponseCode responseCode) validationResult = @@ -255,6 +260,28 @@ await this.TransactionAggregateManager.RecordAdditionalResponseData(estateId, }; } + /// + /// Extracts the field from metadata. + /// + /// + /// Name of the field. + /// The additional transaction metadata. + /// + private T ExtractFieldFromMetadata(String fieldName, + Dictionary additionalTransactionMetadata) + { + if (additionalTransactionMetadata.ContainsKey(fieldName)) + { + String fieldData = additionalTransactionMetadata[fieldName]; + return (T)Convert.ChangeType(fieldData, typeof(T)); + } + else + { + return default(T); + } + + } + private async Task AddDeviceToMerchant(Guid estateId, Guid merchantId, String deviceIdentifier, diff --git a/TransactionProcessor.Testing/TestData.cs b/TransactionProcessor.Testing/TestData.cs index 5e45b128..96d90aa2 100644 --- a/TransactionProcessor.Testing/TestData.cs +++ b/TransactionProcessor.Testing/TestData.cs @@ -91,6 +91,8 @@ public class TestData public static TransactionResponseCode TransactionResponseCodeDeclinedByOperator = TransactionResponseCode.TransactionDeclinedByOperator; + public static Decimal TransactionAmount = 1000.00m; + public static OperatorResponse OperatorResponse => new OperatorResponse { @@ -386,7 +388,8 @@ public static TransactionAggregate GetCompletedTransactionAggregate() TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, - TestData.DeviceIdentifier); + TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.AuthoriseTransactionLocally(TestData.AuthorisationCode, TestData.ResponseCode, TestData.ResponseMessage); @@ -410,7 +413,8 @@ public static TransactionAggregate GetLocallyAuthorisedTransactionAggregate() TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, - TestData.DeviceIdentifier); + TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.AuthoriseTransactionLocally(TestData.AuthorisationCode, TestData.ResponseCode, TestData.ResponseMessage); @@ -427,7 +431,8 @@ public static TransactionAggregate GetLocallyDeclinedTransactionAggregate(Transa TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, - TestData.DeviceIdentifier); + TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.DeclineTransactionLocally(TestData.GetResponseCodeAsString(transactionResponseCode), TestData.GetResponseCodeMessage(transactionResponseCode)); @@ -445,7 +450,8 @@ public static TransactionAggregate GetDeclinedTransactionAggregate(TransactionRe TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, - TestData.DeviceIdentifier); + TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.DeclineTransaction(TestData.OperatorIdentifier1, TestData.DeclinedOperatorResponseCode, @@ -476,7 +482,8 @@ public static TransactionAggregate GetStartedTransactionAggregate() TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, - TestData.DeviceIdentifier); + TestData.DeviceIdentifier, + TestData.TransactionAmount); return transactionAggregate; } diff --git a/TransactionProcessor.Transaction.DomainEvents/TransactionHasStartedEvent.cs b/TransactionProcessor.Transaction.DomainEvents/TransactionHasStartedEvent.cs index d2411ea7..7342af3f 100644 --- a/TransactionProcessor.Transaction.DomainEvents/TransactionHasStartedEvent.cs +++ b/TransactionProcessor.Transaction.DomainEvents/TransactionHasStartedEvent.cs @@ -34,6 +34,7 @@ public TransactionHasStartedEvent() /// Type of the transaction. /// The transaction reference. /// The device identifier. + /// The transaction amount. private TransactionHasStartedEvent(Guid aggregateId, Guid eventId, Guid estateId, @@ -42,7 +43,8 @@ private TransactionHasStartedEvent(Guid aggregateId, String transactionNumber, String transactionType, String transactionReference, - String deviceIdentifier) : base(aggregateId, eventId) + String deviceIdentifier, + Decimal? transactionAmount) : base(aggregateId, eventId) { this.TransactionId = aggregateId; this.EstateId = estateId; @@ -52,6 +54,7 @@ private TransactionHasStartedEvent(Guid aggregateId, this.TransactionType = transactionType; this.TransactionReference = transactionReference; this.DeviceIdentifier = deviceIdentifier; + this.TransactionAmount = transactionAmount; } #endregion @@ -76,6 +79,15 @@ private TransactionHasStartedEvent(Guid aggregateId, [JsonProperty] public String DeviceIdentifier { get; private set; } + /// + /// Gets the transaction amount. + /// + /// + /// The transaction amount. + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public Decimal? TransactionAmount { get; private set; } + /// /// Gets the merchant identifier. /// @@ -139,6 +151,7 @@ private TransactionHasStartedEvent(Guid aggregateId, /// Type of the transaction. /// The transaction reference. /// The device identifier. + /// The transaction amount. /// public static TransactionHasStartedEvent Create(Guid aggregateId, Guid estateId, @@ -147,9 +160,10 @@ public static TransactionHasStartedEvent Create(Guid aggregateId, String transactionNumber, String transactionType, String transactionReference, - String deviceIdentifier) + String deviceIdentifier, + Decimal? transactionAmount) { - return new TransactionHasStartedEvent(aggregateId, Guid.NewGuid(), estateId, merchantId, transactionDateTime, transactionNumber, transactionType, transactionReference, deviceIdentifier); + return new TransactionHasStartedEvent(aggregateId, Guid.NewGuid(), estateId, merchantId, transactionDateTime, transactionNumber, transactionType, transactionReference, deviceIdentifier, transactionAmount); } #endregion diff --git a/TransactionProcessor.TransactionAggregate.Tests/DomainEventTests.cs b/TransactionProcessor.TransactionAggregate.Tests/DomainEventTests.cs index 789160c4..cb2dcbbc 100644 --- a/TransactionProcessor.TransactionAggregate.Tests/DomainEventTests.cs +++ b/TransactionProcessor.TransactionAggregate.Tests/DomainEventTests.cs @@ -24,9 +24,11 @@ public void TransactionHasStartedEvent_CanBeCreated_IsCreated(TransactionType tr TestData.TransactionNumber, transactionType.ToString(), TestData.TransactionReference, - TestData.DeviceIdentifier); + TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionHasStartedEvent.ShouldNotBeNull(); transactionHasStartedEvent.AggregateId.ShouldBe(TestData.TransactionId); + transactionHasStartedEvent.TransactionAmount.ShouldBe(TestData.TransactionAmount); transactionHasStartedEvent.EventCreatedDateTime.ShouldNotBe(DateTime.MinValue); transactionHasStartedEvent.EventId.ShouldNotBe(Guid.Empty); transactionHasStartedEvent.TransactionId.ShouldBe(TestData.TransactionId); diff --git a/TransactionProcessor.TransactionAggregate.Tests/TransactionAggregateTests.cs b/TransactionProcessor.TransactionAggregate.Tests/TransactionAggregateTests.cs index 38f7cb52..82678be7 100644 --- a/TransactionProcessor.TransactionAggregate.Tests/TransactionAggregateTests.cs +++ b/TransactionProcessor.TransactionAggregate.Tests/TransactionAggregateTests.cs @@ -24,7 +24,8 @@ public void TransactionAggregate_StartTransaction_TransactionIsStarted(Transacti { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, - TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.IsStarted.ShouldBeTrue(); transactionAggregate.TransactionDateTime.ShouldBe(TestData.TransactionDateTime); @@ -34,6 +35,7 @@ public void TransactionAggregate_StartTransaction_TransactionIsStarted(Transacti transactionAggregate.MerchantId.ShouldBe(TestData.MerchantId); transactionAggregate.DeviceIdentifier.ShouldBe(TestData.DeviceIdentifier); transactionAggregate.TransactionReference.ShouldBe(TestData.TransactionReference); + transactionAggregate.TransactionAmount.ShouldBe(TestData.TransactionAmount); } [Theory] @@ -42,7 +44,8 @@ public void TransactionAggregate_StartTransaction_TransactionIsStarted(Transacti public void TransactionAggregate_StartTransaction_TransactionAlreadyStarted_ErrorThrown(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); Should.Throw(() => { @@ -52,7 +55,8 @@ public void TransactionAggregate_StartTransaction_TransactionAlreadyStarted_Erro TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, - TestData.DeviceIdentifier); + TestData.DeviceIdentifier, + TestData.TransactionAmount); }); } @@ -62,7 +66,8 @@ public void TransactionAggregate_StartTransaction_TransactionAlreadyStarted_Erro public void TransactionAggregate_StartTransaction_TransactionAlreadyCompleted_ErrorThrown(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); if (transactionType == TransactionType.Logon) { @@ -89,7 +94,8 @@ public void TransactionAggregate_StartTransaction_TransactionAlreadyCompleted_Er TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, - TestData.DeviceIdentifier); + TestData.DeviceIdentifier, + TestData.TransactionAmount); }); } @@ -133,7 +139,8 @@ public void TransactionAggregate_StartTransaction_InvalidData_ErrorThrown(Boolea transactionReference, estateId, merchantId, - deviceIdentifier); + deviceIdentifier, + TestData.TransactionAmount); }); } @@ -142,7 +149,8 @@ public void TransactionAggregate_StartTransaction_InvalidData_ErrorThrown(Boolea public void TransactionAggregate_AuthoriseTransactionLocally_TransactionIsAuthorised(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.AuthoriseTransactionLocally(TestData.AuthorisationCode, TestData.ResponseCode, TestData.ResponseMessage); @@ -171,7 +179,8 @@ public void TransactionAggregate_AuthoriseTransactionLocally_TransactionNotStart public void TransactionAggregate_AuthoriseTransactionLocally_TransactionAlreadyAuthorisedLocally_ErrorThrown(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.AuthoriseTransactionLocally(TestData.AuthorisationCode, TestData.ResponseCode, TestData.ResponseMessage); Should.Throw(() => @@ -187,7 +196,8 @@ public void TransactionAggregate_AuthoriseTransactionLocally_TransactionAlreadyA public void TransactionAggregate_AuthoriseTransactionLocally_TransactionAlreadyAuthorised_ErrorThrown(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.AuthoriseTransaction(TestData.OperatorIdentifier1, TestData.OperatorAuthorisationCode, TestData.OperatorResponseCode, TestData.OperatorResponseMessage, TestData.OperatorTransactionId, TestData.ResponseCode, TestData.ResponseMessage); Should.Throw(() => @@ -203,7 +213,8 @@ public void TransactionAggregate_AuthoriseTransactionLocally_TransactionAlreadyA public void TransactionAggregate_AuthoriseTransactionLocally_TransactionCannotBeLocallyyAuthorised_ErrorThrown(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); Should.Throw(() => { @@ -220,7 +231,8 @@ public void TransactionAggregate_AuthoriseTransactionLocally_TransactionCannotBe public void TransactionAggregate_AuthoriseTransaction_TransactionIsAuthorised(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.AuthoriseTransaction(TestData.OperatorIdentifier1, TestData.OperatorAuthorisationCode, TestData.OperatorResponseCode, TestData.OperatorResponseMessage, TestData.OperatorTransactionId, TestData.ResponseCode, TestData.ResponseMessage); @@ -249,7 +261,8 @@ public void TransactionAggregate_AuthoriseTransaction_TransactionNotStarted_Erro public void TransactionAggregate_AuthoriseTransaction_TransactionAlreadyAuthorised_ErrorThrown(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.AuthoriseTransaction(TestData.OperatorIdentifier1, TestData.OperatorAuthorisationCode, TestData.OperatorResponseCode, TestData.OperatorResponseMessage, TestData.OperatorTransactionId, TestData.ResponseCode, TestData.ResponseMessage); Should.Throw(() => @@ -264,7 +277,8 @@ public void TransactionAggregate_AuthoriseTransaction_TransactionAlreadyAuthoris public void TransactionAggregate_DeclineTransactionLocally_TransactionIsDeclined(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.DeclineTransactionLocally(TestData.DeclinedResponseCode, TestData.DeclinedResponseMessage); @@ -293,7 +307,8 @@ public void TransactionAggregate_DeclineTransactionLocally_TransactionNotStarted public void TransactionAggregate_DeclineTransactionLocally_TransactionAlreadyAuthorisedLocally_ErrorThrown(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.AuthoriseTransactionLocally(TestData.AuthorisationCode, TestData.ResponseCode, TestData.ResponseMessage); Should.Throw(() => @@ -308,7 +323,8 @@ public void TransactionAggregate_DeclineTransactionLocally_TransactionAlreadyAut public void TransactionAggregate_DeclineTransactionLocally_TransactionAlreadyAuthorised_ErrorThrown(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.AuthoriseTransaction(TestData.OperatorIdentifier1, TestData.OperatorAuthorisationCode, TestData.OperatorResponseCode, TestData.OperatorResponseMessage, TestData.OperatorTransactionId, TestData.ResponseCode, TestData.ResponseMessage); Should.Throw(() => @@ -323,7 +339,8 @@ public void TransactionAggregate_DeclineTransactionLocally_TransactionAlreadyAut public void TransactionAggregate_DeclineTransactionLocally_TransactionAlreadyDeclinedLocally_ErrorThrown(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.DeclineTransactionLocally(TestData.ResponseCode, TestData.ResponseMessage); Should.Throw(() => @@ -338,7 +355,8 @@ public void TransactionAggregate_DeclineTransactionLocally_TransactionAlreadyDec public void TransactionAggregate_DeclineTransactionLocally_TransactionAlreadyDeclined_ErrorThrown(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.DeclineTransaction(TestData.OperatorIdentifier1, TestData.OperatorResponseCode, TestData.OperatorResponseMessage, TestData.DeclinedResponseCode, TestData.DeclinedResponseMessage); Should.Throw(() => @@ -353,7 +371,8 @@ public void TransactionAggregate_DeclineTransactionLocally_TransactionAlreadyDec public void TransactionAggregate_DeclineTransaction_TransactionIsDeclined(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.DeclineTransaction(TestData.OperatorIdentifier1, TestData.DeclinedOperatorResponseCode, TestData.DeclinedOperatorResponseMessage, TestData.DeclinedResponseCode, TestData.DeclinedResponseMessage); @@ -398,7 +417,8 @@ public void TransactionAggregate_DeclineTransaction_TransactionNotStarted_ErrorT public void TransactionAggregate_DeclineTransaction_TransactionAlreadyAuthorised_ErrorThrown(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.AuthoriseTransaction(TestData.OperatorIdentifier1, TestData.OperatorAuthorisationCode, TestData.OperatorResponseCode, TestData.OperatorResponseMessage, TestData.OperatorTransactionId, TestData.ResponseCode, TestData.ResponseMessage); Should.Throw(() => @@ -413,7 +433,8 @@ public void TransactionAggregate_DeclineTransaction_TransactionAlreadyAuthorised public void TransactionAggregate_DeclineTransaction_TransactionAlreadyDeclinedLocally_ErrorThrown(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.DeclineTransactionLocally(TestData.ResponseCode, TestData.ResponseMessage); Should.Throw(() => @@ -428,7 +449,8 @@ public void TransactionAggregate_DeclineTransaction_TransactionAlreadyDeclinedLo public void TransactionAggregate_DeclineTransaction_TransactionAlreadyDeclined_ErrorThrown(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.DeclineTransaction(TestData.OperatorIdentifier1, TestData.DeclinedOperatorResponseCode, TestData.DeclinedOperatorResponseMessage, TestData.DeclinedResponseCode, TestData.DeclinedResponseMessage); Should.Throw(() => @@ -443,7 +465,8 @@ public void TransactionAggregate_DeclineTransaction_TransactionAlreadyDeclined_E public void TransactionAggregate_CompleteTransaction_TransactionIsCompleted(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); if (transactionType == TransactionType.Logon) { @@ -477,7 +500,8 @@ public void TransactionAggregate_CompleteTransaction_TransactionNotStarted_Error public void TransactionAggregate_CompleteTransaction_TransactionNotAuthorised_ErrorThrown(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); Should.Throw(() => { @@ -491,7 +515,8 @@ public void TransactionAggregate_CompleteTransaction_TransactionNotAuthorised_Er public void TransactionAggregate_CompleteTransaction_TransactionAlreadyCompleted_ErrorThrown(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); if (transactionType == TransactionType.Logon) { @@ -516,7 +541,8 @@ public void TransactionAggregate_CompleteTransaction_TransactionAlreadyCompleted public void TransactionAggregate_RecordAdditionalRequestData_RequestDataRecorded(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); Should.NotThrow(() => { @@ -544,7 +570,8 @@ public void TransactionAggregate_RecordAdditionalRequestData_TransactionNotStart public void TransactionAggregate_RecordAdditionalRequestData_AdditionalRequestDataAlreadyRecorded_ErrorThrown(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.RecordAdditionalRequestData(TestData.OperatorIdentifier1, TestData.AdditionalTransactionMetaData); Should.Throw(() => @@ -559,7 +586,8 @@ public void TransactionAggregate_RecordAdditionalRequestData_AdditionalRequestDa public void TransactionAggregate_RecordAdditionalRequestData_AlreadyAuthorised_ErrorThrown(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.RecordAdditionalRequestData(TestData.OperatorIdentifier1, TestData.AdditionalTransactionMetaData); if (transactionType == TransactionType.Logon) @@ -583,7 +611,8 @@ public void TransactionAggregate_RecordAdditionalRequestData_AlreadyAuthorised_E public void TransactionAggregate_RecordAdditionalRequestData_AlreadyDeclined_ErrorThrown(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.RecordAdditionalRequestData(TestData.OperatorIdentifier1, TestData.AdditionalTransactionMetaData); if (transactionType == TransactionType.Logon) @@ -607,7 +636,8 @@ public void TransactionAggregate_RecordAdditionalRequestData_AlreadyDeclined_Err public void TransactionAggregate_RecordAdditionalRequestData_AlreadyCompleted_ErrorThrown(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.RecordAdditionalRequestData(TestData.OperatorIdentifier1, TestData.AdditionalTransactionMetaData); if (transactionType == TransactionType.Logon) { @@ -634,7 +664,8 @@ public void TransactionAggregate_RecordAdditionalRequestData_AlreadyCompleted_Er public void TransactionAggregate_RecordAdditionalResponseData_ResponseDataRecorded(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); if (transactionType == TransactionType.Logon) { transactionAggregate.AuthoriseTransactionLocally(TestData.AuthorisationCode, TestData.ResponseCode, TestData.ResponseMessage); @@ -670,7 +701,8 @@ public void TransactionAggregate_RecordAdditionalResponseData_TransactionNotStar public void TransactionAggregate_RecordAdditionalResponseData_AdditionalResponseDataAlreadyRecorded_ErrorThrown(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.RecordAdditionalRequestData(TestData.OperatorIdentifier1, TestData.AdditionalTransactionMetaData); if (transactionType == TransactionType.Logon) { @@ -694,7 +726,8 @@ public void TransactionAggregate_RecordAdditionalResponseData_AdditionalResponse public void TransactionAggregate_RecordAdditionalResponseData_AlreadyCompleted_ErrorThrown(TransactionType transactionType) { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, transactionType, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.RecordAdditionalRequestData(TestData.OperatorIdentifier1, TestData.AdditionalTransactionMetaData); if (transactionType == TransactionType.Logon) { @@ -717,7 +750,8 @@ public void TransactionAggregate_RecordAdditionalResponseData_AlreadyCompleted_E public void TransactionAggregate_RequestEmailReceipt_CustomerEmailReceiptHasBeenRequested() { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, TransactionType.Sale, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, TransactionType.Sale, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.RecordAdditionalRequestData(TestData.OperatorIdentifier1, TestData.AdditionalTransactionMetaData); transactionAggregate.AuthoriseTransaction(TestData.OperatorIdentifier1, TestData.OperatorAuthorisationCode, TestData.OperatorResponseCode, TestData.OperatorResponseMessage, TestData.OperatorTransactionId, TestData.ResponseCode, TestData.ResponseMessage); transactionAggregate.RecordAdditionalResponseData(TestData.OperatorIdentifier1, TestData.AdditionalTransactionMetaData); @@ -732,7 +766,8 @@ public void TransactionAggregate_RequestEmailReceipt_CustomerEmailReceiptHasBeen public void TransactionAggregate_RequestEmailReceipt_TransactionNotCompleted_ErrorThrown() { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, TransactionType.Sale, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, TransactionType.Sale, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.RecordAdditionalRequestData(TestData.OperatorIdentifier1, TestData.AdditionalTransactionMetaData); transactionAggregate.AuthoriseTransaction(TestData.OperatorIdentifier1, TestData.OperatorAuthorisationCode, TestData.OperatorResponseCode, TestData.OperatorResponseMessage, TestData.OperatorTransactionId, TestData.ResponseCode, TestData.ResponseMessage); transactionAggregate.RecordAdditionalResponseData(TestData.OperatorIdentifier1, TestData.AdditionalTransactionMetaData); @@ -744,7 +779,8 @@ public void TransactionAggregate_RequestEmailReceipt_TransactionNotCompleted_Err public void TransactionAggregate_RequestEmailReceipt_EmailReceiptAlreadyRequested_ErrorThrown() { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, TransactionType.Sale, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, TransactionType.Sale, TestData.TransactionReference, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier, + TestData.TransactionAmount); transactionAggregate.RecordAdditionalRequestData(TestData.OperatorIdentifier1, TestData.AdditionalTransactionMetaData); transactionAggregate.AuthoriseTransaction(TestData.OperatorIdentifier1, TestData.OperatorAuthorisationCode, TestData.OperatorResponseCode, TestData.OperatorResponseMessage, TestData.OperatorTransactionId, TestData.ResponseCode, TestData.ResponseMessage); transactionAggregate.RecordAdditionalResponseData(TestData.OperatorIdentifier1, TestData.AdditionalTransactionMetaData); diff --git a/TransactionProcessor.TransactionAgrgegate/TransactionAggregate.cs b/TransactionProcessor.TransactionAgrgegate/TransactionAggregate.cs index c264988b..80ce183b 100644 --- a/TransactionProcessor.TransactionAgrgegate/TransactionAggregate.cs +++ b/TransactionProcessor.TransactionAgrgegate/TransactionAggregate.cs @@ -184,6 +184,14 @@ private TransactionAggregate(Guid aggregateId) /// public String ResponseMessage { get; private set; } + /// + /// Gets the transaction amount. + /// + /// + /// The transaction amount. + /// + public Decimal? TransactionAmount { get; private set; } + /// /// Gets the transaction date time. /// @@ -402,18 +410,6 @@ public void RequestEmailReceipt(String customerEmailAddress) this.ApplyAndPend(customerEmailReceiptRequestedEvent); } - /// - /// Checks the transaction has been completed. - /// - /// Transaction [{this.AggregateId}] has not been completed - private void CheckTransactionHasBeenCompleted() - { - if (this.IsCompleted == false) - { - throw new InvalidOperationException($"Transaction [{this.AggregateId}] has not been completed"); - } - } - /// /// Starts the transaction. /// @@ -424,6 +420,7 @@ private void CheckTransactionHasBeenCompleted() /// The estate identifier. /// The merchant identifier. /// The device identifier. + /// The transaction amount. /// Transaction Number must be numeric /// or /// Invalid Transaction Type [{transactionType}] @@ -435,7 +432,8 @@ public void StartTransaction(DateTime transactionDateTime, String transactionReference, Guid estateId, Guid merchantId, - String deviceIdentifier) + String deviceIdentifier, + Decimal? transactionAmount) { Guard.ThrowIfInvalidDate(transactionDateTime, typeof(ArgumentException), $"Transaction Date Time must not be [{DateTime.MinValue}]"); Guard.ThrowIfNullOrEmpty(transactionNumber, typeof(ArgumentException), "Transaction Number must not be null or empty"); @@ -467,7 +465,8 @@ public void StartTransaction(DateTime transactionDateTime, transactionNumber, transactionType.ToString(), transactionReference, - deviceIdentifier); + deviceIdentifier, + transactionAmount); this.ApplyAndPend(transactionHasStartedEvent); } @@ -555,6 +554,18 @@ private void CheckTransactionHasBeenAuthorisedOrDeclined() } } + /// + /// Checks the transaction has been completed. + /// + /// Transaction [{this.AggregateId}] has not been completed + private void CheckTransactionHasBeenCompleted() + { + if (this.IsCompleted == false) + { + throw new InvalidOperationException($"Transaction [{this.AggregateId}] has not been completed"); + } + } + /// /// Checks the transaction has been started. /// @@ -662,6 +673,7 @@ private void PlayEvent(TransactionHasStartedEvent domainEvent) this.IsDeclined = false; this.IsLocallyAuthorised = false; this.IsAuthorised = false; + this.TransactionAmount = domainEvent.TransactionAmount.HasValue ? domainEvent.TransactionAmount : null; } ///