diff --git a/TransactionProcessor.BusinessLogic/Common/Extensions.cs b/TransactionProcessor.BusinessLogic/Common/Extensions.cs index 2c657fcb..623f046c 100644 --- a/TransactionProcessor.BusinessLogic/Common/Extensions.cs +++ b/TransactionProcessor.BusinessLogic/Common/Extensions.cs @@ -8,6 +8,106 @@ namespace TransactionProcessor.BusinessLogic.Common { using System.Diagnostics.CodeAnalysis; + public static class Helpers + { + public static Guid CalculateSettlementAggregateId(DateTime settlementDate, + Guid estateId) + { + Guid aggregateId = GuidCalculator.Combine(estateId, settlementDate.ToGuid()); + return aggregateId; + } + } + + public static class GuidCalculator + { + #region Methods + + /// + /// Combines the specified GUIDs into a new GUID. + /// + /// The first unique identifier. + /// The second unique identifier. + /// The offset. + /// Guid. + public static Guid Combine(Guid firstGuid, + Guid secondGuid, + Byte offset) + { + Byte[] firstAsBytes = firstGuid.ToByteArray(); + Byte[] secondAsBytes = secondGuid.ToByteArray(); + + Byte[] newBytes = new Byte[16]; + + for (Int32 i = 0; i < 16; i++) + { + // Add and truncate any overflow + newBytes[i] = (Byte)(firstAsBytes[i] + secondAsBytes[i] + offset); + } + + return new Guid(newBytes); + } + + /// + /// Combines the specified GUIDs into a new GUID. + /// + /// The first unique identifier. + /// The second unique identifier. + /// Guid. + public static Guid Combine(Guid firstGuid, + Guid secondGuid) + { + return GuidCalculator.Combine(firstGuid, + secondGuid, + 0); + } + + /// + /// Combines the specified first unique identifier. + /// + /// The first unique identifier. + /// The second unique identifier. + /// The third unique identifier. + /// The offset. + /// Guid. + public static Guid Combine(Guid firstGuid, + Guid secondGuid, + Guid thirdGuid, + Byte offset) + { + Byte[] firstAsBytes = firstGuid.ToByteArray(); + Byte[] secondAsBytes = secondGuid.ToByteArray(); + Byte[] thirdAsBytes = thirdGuid.ToByteArray(); + + Byte[] newBytes = new Byte[16]; + + for (Int32 i = 0; i < 16; i++) + { + // Add and truncate any overflow + newBytes[i] = (Byte)(firstAsBytes[i] + secondAsBytes[i] + thirdAsBytes[i] + offset); + } + + return new Guid(newBytes); + } + + /// + /// Combines the specified first unique identifier. + /// + /// The first unique identifier. + /// The second unique identifier. + /// The third unique identifier. + /// Guid. + public static Guid Combine(Guid firstGuid, + Guid secondGuid, + Guid thirdGuid) + { + return GuidCalculator.Combine(firstGuid, + secondGuid, + thirdGuid, + 0); + } + + #endregion + } public static class Extensions { /// diff --git a/TransactionProcessor.BusinessLogic/EventHandling/TransactionDomainEventHandler.cs b/TransactionProcessor.BusinessLogic/EventHandling/TransactionDomainEventHandler.cs index 9f57353c..7b55785f 100644 --- a/TransactionProcessor.BusinessLogic/EventHandling/TransactionDomainEventHandler.cs +++ b/TransactionProcessor.BusinessLogic/EventHandling/TransactionDomainEventHandler.cs @@ -242,7 +242,7 @@ private async Task HandleSpecificDomainEvent(TransactionHasBeenCompletedEvent do Logger.LogInformation($"SettlementSchedule {merchant.SettlementSchedule}"); DateTime settlementDate = CalculateSettlementDate(merchant.SettlementSchedule, domainEvent.CompletedDateTime); Logger.LogInformation($"Settlement Date {settlementDate}"); - Guid aggregateId = settlementDate.ToGuid(); + Guid aggregateId = Helpers.CalculateSettlementAggregateId(settlementDate, domainEvent.EstateId); // We need to add the fees to a pending settlement stream (for today) SettlementAggregate aggregate = await this.SettlementAggregateRepository.GetLatestVersion(aggregateId, cancellationToken); @@ -259,6 +259,8 @@ private async Task HandleSpecificDomainEvent(TransactionHasBeenCompletedEvent do } } + + private DateTime CalculateSettlementDate(SettlementSchedule merchantSettlementSchedule, DateTime completeDateTime) { if (merchantSettlementSchedule == SettlementSchedule.Weekly) @@ -305,7 +307,7 @@ private async Task HandleSpecificDomainEvent(MerchantFeeAddedToTransactionEvent return; } - Guid aggregateId = domainEvent.SettlementDueDate.ToGuid(); + Guid aggregateId = Helpers.CalculateSettlementAggregateId(domainEvent.SettlementDueDate, domainEvent.EstateId); SettlementAggregate pendingSettlementAggregate = await this.SettlementAggregateRepository.GetLatestVersion(aggregateId, cancellationToken); diff --git a/TransactionProcessor.BusinessLogic/Services/SettlementDomainService.cs b/TransactionProcessor.BusinessLogic/Services/SettlementDomainService.cs index 49cd79e3..4e4b1860 100644 --- a/TransactionProcessor.BusinessLogic/Services/SettlementDomainService.cs +++ b/TransactionProcessor.BusinessLogic/Services/SettlementDomainService.cs @@ -22,7 +22,7 @@ public async Task ProcessSettlement(DateTime settleme { ProcessSettlementResponse response = new ProcessSettlementResponse(); - Guid aggregateId = settlementDate.ToGuid(); + Guid aggregateId = Helpers.CalculateSettlementAggregateId(settlementDate,estateId); SettlementAggregate settlementAggregate = await this.SettlementAggregateRepository.GetLatestVersion(aggregateId, cancellationToken); diff --git a/TransactionProcessor.IntegrationTests/Shared/SharedSteps.cs b/TransactionProcessor.IntegrationTests/Shared/SharedSteps.cs index f4951f05..0007a15d 100644 --- a/TransactionProcessor.IntegrationTests/Shared/SharedSteps.cs +++ b/TransactionProcessor.IntegrationTests/Shared/SharedSteps.cs @@ -893,7 +893,7 @@ public async Task WhenIGetThePendingSettlementsTheFollowingInformationShouldBeRe Int32 numberOfFees = SpecflowTableHelper.GetIntValue(tableRow, "NumberOfFees"); DateTime settlementDate = SpecflowTableHelper.GetDateForDateString(settlementDateString, DateTime.UtcNow.Date); - var aggregateid = settlementDate.ToGuid(); + Guid aggregateid = Helpers.CalculateSettlementAggregateId(settlementDate, estateDetails.EstateId); await Retry.For(async () => { SettlementResponse settlements = diff --git a/TransactionProcessor/Controllers/SettlementController.cs b/TransactionProcessor/Controllers/SettlementController.cs index 8dda2e69..372b227b 100644 --- a/TransactionProcessor/Controllers/SettlementController.cs +++ b/TransactionProcessor/Controllers/SettlementController.cs @@ -59,7 +59,7 @@ public async Task GetPendingSettlement([FromRoute] DateTime settl { // TODO: Convert to using a manager/model/factory // Convert the date passed in to a guid - var aggregateId = settlementDate.Date.ToGuid(); + Guid aggregateId = Helpers.CalculateSettlementAggregateId(settlementDate, estateId); Logger.LogInformation($"Settlement Aggregate Id {aggregateId}");