diff --git a/TransactionProcessor.BusinessLogic/Services/MerchantStatementDomainService.cs b/TransactionProcessor.BusinessLogic/Services/MerchantStatementDomainService.cs index c2ea717..53e8275 100644 --- a/TransactionProcessor.BusinessLogic/Services/MerchantStatementDomainService.cs +++ b/TransactionProcessor.BusinessLogic/Services/MerchantStatementDomainService.cs @@ -69,104 +69,43 @@ public MerchantStatementDomainService(Func aggregateService, #endregion #region Methods - - private async Task ApplyUpdates(Func> action, Guid statementId, CancellationToken cancellationToken, Boolean isNotFoundError = true) + + public async Task AddSettledFeeToStatement(MerchantStatementCommands.AddSettledFeeToMerchantStatementCommand command, + CancellationToken cancellationToken) { - try - { - Result getMerchantStatementResult = await this.AggregateService.GetLatest(statementId, cancellationToken); + try { + // Work out the next statement date + DateTime nextStatementDate = CalculateStatementDate(command.SettledDateTime); - Result merchantStatementAggregateResult = - DomainServiceHelper.HandleGetAggregateResult(getMerchantStatementResult, statementId, isNotFoundError); - if (merchantStatementAggregateResult.IsFailed) - return ResultHelpers.CreateFailure(merchantStatementAggregateResult); + Guid merchantStatementId = IdGenerationService.GenerateMerchantStatementAggregateId(command.EstateId, command.MerchantId, nextStatementDate); + Guid merchantStatementForDateId = IdGenerationService.GenerateMerchantStatementForDateAggregateId(command.EstateId, command.MerchantId, nextStatementDate, command.SettledDateTime); + Guid settlementFeeId = GuidCalculator.Combine(command.TransactionId, command.SettledFeeId); - MerchantStatementAggregate merchantStatementAggregate = merchantStatementAggregateResult.Data; - - Result result = await action(merchantStatementAggregate); - if (result.IsFailed) - return ResultHelpers.CreateFailure(result); - - Result saveResult = await this.AggregateService.Save(merchantStatementAggregate, cancellationToken); - if (saveResult.IsFailed) - return ResultHelpers.CreateFailure(saveResult); + Result getMerchantStatementForDateResult = await DomainServiceHelper.GetAggregateOrFailure(ct => this.AggregateService.GetLatest(merchantStatementForDateId, ct), merchantStatementForDateId, cancellationToken, false); + if (getMerchantStatementForDateResult.IsFailed) + return ResultHelpers.CreateFailure(getMerchantStatementForDateResult); - return Result.Success(); - } - catch (Exception ex) - { - return Result.Failure(ex.GetExceptionMessages()); - } - } - - private async Task ApplyUpdates(Func> action, Guid statementId, CancellationToken cancellationToken, Boolean isNotFoundError = true) - { - try - { - Result getMerchantStatementResult = await this.AggregateService.GetLatest(statementId, cancellationToken); + MerchantStatementForDateAggregate merchantStatementForDateAggregate = getMerchantStatementForDateResult.Data; - Result merchantStatementAggregateResult = - DomainServiceHelper.HandleGetAggregateResult(getMerchantStatementResult, statementId, isNotFoundError); - if (merchantStatementAggregateResult.IsFailed) - return ResultHelpers.CreateFailure(merchantStatementAggregateResult); + SettledFee settledFee = new SettledFee(settlementFeeId, command.TransactionId, command.SettledDateTime, command.SettledAmount.Value); - MerchantStatementForDateAggregate merchantStatementAggregate = merchantStatementAggregateResult.Data; + Guid eventId = IdGenerationService.GenerateEventId(new { + command.TransactionId, settlementFeeId, settledFee, command.SettledDateTime, + }); - Result result = await action(merchantStatementAggregate); - if (result.IsFailed) - return ResultHelpers.CreateFailure(result); + merchantStatementForDateAggregate.AddSettledFeeToStatement(merchantStatementId, nextStatementDate, eventId, command.EstateId, command.MerchantId, settledFee); - Result saveResult = await this.AggregateService.Save(merchantStatementAggregate, cancellationToken); + Result saveResult = await this.AggregateService.Save(merchantStatementForDateAggregate, cancellationToken); if (saveResult.IsFailed) return ResultHelpers.CreateFailure(saveResult); return Result.Success(); } - catch (Exception ex) - { + catch (Exception ex) { return Result.Failure(ex.GetExceptionMessages()); } } - public async Task AddSettledFeeToStatement(MerchantStatementCommands.AddSettledFeeToMerchantStatementCommand command, - CancellationToken cancellationToken) - { - // Work out the next statement date - DateTime nextStatementDate = CalculateStatementDate(command.SettledDateTime); - - Guid merchantStatementId = IdGenerationService.GenerateMerchantStatementAggregateId(command.EstateId, command.MerchantId, nextStatementDate); - Guid merchantStatementForDateId = IdGenerationService.GenerateMerchantStatementForDateAggregateId(command.EstateId, command.MerchantId, nextStatementDate, command.SettledDateTime); - Guid settlementFeeId = GuidCalculator.Combine(command.TransactionId, command.SettledFeeId); - - Result result = await ApplyUpdates( - async (MerchantStatementForDateAggregate merchantStatementForDateAggregate) => { - - SettledFee settledFee = new SettledFee(settlementFeeId, command.TransactionId, command.SettledDateTime, command.SettledAmount.Value); - - Guid eventId = IdGenerationService.GenerateEventId(new - { - command.TransactionId, - settlementFeeId, - settledFee, - command.SettledDateTime, - }); - - merchantStatementForDateAggregate.AddSettledFeeToStatement(merchantStatementId, nextStatementDate, eventId, command.EstateId, command.MerchantId, settledFee); - - return Result.Success(); - }, merchantStatementForDateId, cancellationToken, false); - - if (result.IsFailed) - return ResultHelpers.CreateFailure(result); - - return Result.Success(); - } - - /// - /// - /// - /// - /// internal static DateTime CalculateStatementDate(DateTime eventDateTime) { DateTime calculatedDateTime = eventDateTime.Date.AddMonths(1); @@ -174,78 +113,76 @@ internal static DateTime CalculateStatementDate(DateTime eventDateTime) return new DateTime(calculatedDateTime.Year, calculatedDateTime.Month, 1); } - public async Task GenerateStatement(MerchantCommands.GenerateMerchantStatementCommand command, CancellationToken cancellationToken) - { - // Need to rebuild the date time from the command as the Kind is Utc which is different from the date time used to generate the statement id - DateTime dt = new DateTime(command.RequestDto.MerchantStatementDate.Year, command.RequestDto.MerchantStatementDate.Month, command.RequestDto.MerchantStatementDate.Day); - Guid merchantStatementId = IdGenerationService.GenerateMerchantStatementAggregateId(command.EstateId, command.MerchantId, dt); - - Result result = await ApplyUpdates( - async (MerchantStatementAggregate merchantStatementAggregate) => - { - MerchantStatement statement = merchantStatementAggregate.GetStatement(); - List<(Guid merchantStatementForDateId, DateTime activityDate)> activityDates = statement.GetActivityDates(); - - List statementForDateAggregates = new(); - foreach ((Guid merchantStatementForDateId, DateTime activityDate) activityDate in activityDates) - { - Result statementForDateResult = await this.AggregateService.GetLatest(activityDate.merchantStatementForDateId, cancellationToken); - if (statementForDateResult.IsFailed) - return ResultHelpers.CreateFailure(statementForDateResult); - MerchantStatementForDate dailyStatement = statementForDateResult.Data.GetStatement(true); - statementForDateAggregates.Add(dailyStatement); - } + public async Task GenerateStatement(MerchantCommands.GenerateMerchantStatementCommand command, + CancellationToken cancellationToken) { + try { + // Need to rebuild the date time from the command as the Kind is Utc which is different from the date time used to generate the statement id + DateTime dt = new DateTime(command.RequestDto.MerchantStatementDate.Year, command.RequestDto.MerchantStatementDate.Month, command.RequestDto.MerchantStatementDate.Day); + Guid merchantStatementId = IdGenerationService.GenerateMerchantStatementAggregateId(command.EstateId, command.MerchantId, dt); - // Ok so now we have the daily statements we need to add a summary line to the statement aggregate - foreach (MerchantStatementForDate merchantStatementForDateAggregate in statementForDateAggregates) - { - // Build the summary event - var transactionsResult = merchantStatementForDateAggregate.GetStatementLines() - .Where(sl => sl.LineType == 1) - .Aggregate(new { Count = 0, TotalAmount = 0m }, - (acc, sl) => new { Count = acc.Count + 1, TotalAmount = acc.TotalAmount + sl.Amount }); - var settledFeesResult = merchantStatementForDateAggregate.GetStatementLines() - .Where(sl => sl.LineType == 2) - .Aggregate(new { Count = 0, TotalAmount = 0m }, - (acc, sl) => new { Count = acc.Count + 1, TotalAmount = acc.TotalAmount + sl.Amount }); - 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); - } + Result getMerchantStatementResult = await DomainServiceHelper.GetAggregateOrFailure(ct => this.AggregateService.GetLatest(merchantStatementId, ct), merchantStatementId, cancellationToken); + if (getMerchantStatementResult.IsFailed) + return ResultHelpers.CreateFailure(getMerchantStatementResult); - merchantStatementAggregate.GenerateStatement(DateTime.Now); + MerchantStatementAggregate merchantStatementAggregate = getMerchantStatementResult.Data; - return Result.Success(); - }, - merchantStatementId, cancellationToken, false); + MerchantStatement statement = merchantStatementAggregate.GetStatement(); + List<(Guid merchantStatementForDateId, DateTime activityDate)> activityDates = statement.GetActivityDates(); + + List statementForDateAggregates = new(); + foreach ((Guid merchantStatementForDateId, DateTime activityDate) activityDate in activityDates) { + Result statementForDateResult = await this.AggregateService.GetLatest(activityDate.merchantStatementForDateId, cancellationToken); + if (statementForDateResult.IsFailed) + return ResultHelpers.CreateFailure(statementForDateResult); + MerchantStatementForDate dailyStatement = statementForDateResult.Data.GetStatement(true); + statementForDateAggregates.Add(dailyStatement); + } + + // Ok so now we have the daily statements we need to add a summary line to the statement aggregate + foreach (MerchantStatementForDate merchantStatementForDateAggregate in statementForDateAggregates) { + // Build the summary event + var transactionsResult = merchantStatementForDateAggregate.GetStatementLines().Where(sl => sl.LineType == 1).Aggregate(new { Count = 0, TotalAmount = 0m }, (acc, + sl) => new { Count = acc.Count + 1, TotalAmount = acc.TotalAmount + sl.Amount }); + var settledFeesResult = merchantStatementForDateAggregate.GetStatementLines().Where(sl => sl.LineType == 2).Aggregate(new { Count = 0, TotalAmount = 0m }, (acc, + sl) => new { Count = acc.Count + 1, TotalAmount = acc.TotalAmount + sl.Amount }); + 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); - if (result.IsFailed) - return ResultHelpers.CreateFailure(result); + Result saveResult = await this.AggregateService.Save(merchantStatementAggregate, cancellationToken); + if (saveResult.IsFailed) + return ResultHelpers.CreateFailure(saveResult); - return Result.Success(); + return Result.Success(); + } + catch (Exception ex) { + return Result.Failure(ex.GetExceptionMessages()); + } } public async Task EmailStatement(MerchantStatementCommands.EmailMerchantStatementCommand command, CancellationToken cancellationToken) { - Result result = await ApplyUpdates(async (MerchantStatementAggregate merchantStatementAggregate) => { + try + { + // Work out the next statement date + Result getMerchantStatementResult = await DomainServiceHelper.GetAggregateOrFailure(ct => this.AggregateService.GetLatest(command.MerchantStatementId, ct), command.MerchantStatementId, cancellationToken); + if (getMerchantStatementResult.IsFailed) + return ResultHelpers.CreateFailure(getMerchantStatementResult); + + MerchantStatementAggregate merchantStatementAggregate = getMerchantStatementResult.Data; MerchantStatement statement = merchantStatementAggregate.GetStatement(); - // Get the merchant - Result getMerchantResult = await this.AggregateService.Get(statement.MerchantId, cancellationToken); + Result getMerchantResult = await DomainServiceHelper.GetAggregateOrFailure(ct => this.AggregateService.Get(statement.MerchantId, ct), statement.MerchantId, cancellationToken); if (getMerchantResult.IsFailed) return ResultHelpers.CreateFailure(getMerchantResult); + Merchant merchantModel = getMerchantResult.Data.GetMerchant(); List emailAddresses = merchantModel.Contacts.Select(c => c.ContactEmailAddress).ToList(); - + SendEmailRequest sendEmailRequest = new SendEmailRequest { Body = "Please find attached this months statement.", @@ -285,10 +222,16 @@ public async Task EmailStatement(MerchantStatementCommands.EmailMerchant merchantStatementAggregate.EmailStatement(DateTime.Now, messageId); - return Result.Success(); - }, command.MerchantStatementId, cancellationToken, false); + Result saveResult = await this.AggregateService.Save(merchantStatementAggregate, cancellationToken); + if (saveResult.IsFailed) + return ResultHelpers.CreateFailure(saveResult); - return result; + return Result.Success(); + } + catch (Exception ex) + { + return Result.Failure(ex.GetExceptionMessages()); + } } private TokenResponse TokenResponse; @@ -301,153 +244,189 @@ static String EncodeTo64(String toEncode) } public async Task BuildStatement(MerchantStatementCommands.BuildMerchantStatementCommand command, - CancellationToken cancellationToken) - { - Result result = await ApplyUpdates( - async (MerchantStatementAggregate merchantStatementAggregate) => { - - MerchantStatement statement = merchantStatementAggregate.GetStatement(); - Result getMerchantResult = await this.AggregateService.Get(statement.MerchantId, cancellationToken); + CancellationToken cancellationToken) { + try { + // Work out the next statement date + Result getMerchantStatementResult = await DomainServiceHelper.GetAggregateOrFailure(ct => this.AggregateService.GetLatest(command.MerchantStatementId, ct), command.MerchantStatementId, cancellationToken); + if (getMerchantStatementResult.IsFailed) + return ResultHelpers.CreateFailure(getMerchantStatementResult); - if (getMerchantResult.IsFailed) - return ResultHelpers.CreateFailure(getMerchantResult); - MerchantAggregate merchantAggregate = getMerchantResult.Data; - Merchant m = merchantAggregate.GetMerchant(); + MerchantStatementAggregate merchantStatementAggregate = getMerchantStatementResult.Data; + MerchantStatement statement = merchantStatementAggregate.GetStatement(); + Result getMerchantResult = await DomainServiceHelper.GetAggregateOrFailure(ct => this.AggregateService.Get(statement.MerchantId, ct), statement.MerchantId, cancellationToken); + if (getMerchantResult.IsFailed) + return ResultHelpers.CreateFailure(getMerchantResult); - String html = await this.StatementBuilder.GetStatementHtml(merchantStatementAggregate, m, cancellationToken); - // TODO: Record the html to the statement aggregate so we can use it later if needed + Merchant merchantModel = getMerchantResult.Data.GetMerchant(); - String base64 = EncodeTo64(html); + String html = await this.StatementBuilder.GetStatementHtml(merchantStatementAggregate, merchantModel, cancellationToken); + // TODO: Record the html to the statement aggregate so we can use it later if needed - merchantStatementAggregate.BuildStatement(DateTime.Now, base64); + String base64 = EncodeTo64(html); - return Result.Success(); - }, - command.MerchantStatementId, cancellationToken); + merchantStatementAggregate.BuildStatement(DateTime.Now, base64); - if (result.IsFailed) - return ResultHelpers.CreateFailure(result); + Result saveResult = await this.AggregateService.Save(merchantStatementAggregate, cancellationToken); + if (saveResult.IsFailed) + return ResultHelpers.CreateFailure(saveResult); - return Result.Success(); + return Result.Success(); + } + catch (Exception ex) { + return Result.Failure(ex.GetExceptionMessages()); + } } public async Task RecordActivityDateOnMerchantStatement(MerchantStatementCommands.RecordActivityDateOnMerchantStatementCommand command, CancellationToken cancellationToken) { - Result result = await ApplyUpdates( - async (MerchantStatementAggregate merchantStatementAggregate) => { + try + { + // Work out the next statement date + Result getMerchantStatementResult = await DomainServiceHelper.GetAggregateOrFailure(ct => this.AggregateService.GetLatest(command.MerchantStatementId, ct), command.MerchantStatementId, cancellationToken); + if (getMerchantStatementResult.IsFailed) + return ResultHelpers.CreateFailure(getMerchantStatementResult); - merchantStatementAggregate.RecordActivityDateOnStatement(command.MerchantStatementId, command.StatementDate, + MerchantStatementAggregate merchantStatementAggregate = getMerchantStatementResult.Data; + + merchantStatementAggregate.RecordActivityDateOnStatement(command.MerchantStatementId, command.StatementDate, command.EstateId, command.MerchantId, command.MerchantStatementForDateId, command.StatementActivityDate); - - return Result.Success(); - }, command.MerchantStatementId, cancellationToken, false); - if (result.IsFailed) - return ResultHelpers.CreateFailure(result); + Result saveResult = await this.AggregateService.Save(merchantStatementAggregate, cancellationToken); + if (saveResult.IsFailed) + return ResultHelpers.CreateFailure(saveResult); - return Result.Success(); + return Result.Success(); + } + catch (Exception ex) + { + return Result.Failure(ex.GetExceptionMessages()); + } } 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, - }); + try + { + // Work out the next statement date + DateTime nextStatementDate = CalculateStatementDate(command.DepositDateTime.Date); - merchantStatementForDateAggregate.AddDepositToStatement(merchantStatementId, nextStatementDate, eventId, command.EstateId, command.MerchantId, deposit); + Guid merchantStatementId = IdGenerationService.GenerateMerchantStatementAggregateId(command.EstateId, command.MerchantId, nextStatementDate); + Guid merchantStatementForDateId = IdGenerationService.GenerateMerchantStatementForDateAggregateId(command.EstateId, command.MerchantId, nextStatementDate, command.DepositDateTime.Date); - return Result.Success(); - }, merchantStatementForDateId, cancellationToken, false); + Result getMerchantStatementForDateResult = await DomainServiceHelper.GetAggregateOrFailure(ct => this.AggregateService.GetLatest(merchantStatementForDateId, ct), merchantStatementForDateId, cancellationToken, false); + if (getMerchantStatementForDateResult.IsFailed) + return ResultHelpers.CreateFailure(getMerchantStatementForDateResult); + + MerchantStatementForDateAggregate merchantStatementForDateAggregate = getMerchantStatementForDateResult.Data; - if (result.IsFailed) - return ResultHelpers.CreateFailure(result); + Deposit deposit = new Deposit { DepositId = command.DepositId, Reference = command.Reference, DepositDateTime = command.DepositDateTime, Amount = command.Amount.Value }; - return Result.Success(); + Guid eventId = IdGenerationService.GenerateEventId(new + { + command.DepositId, + deposit, + command.DepositDateTime, + }); + + merchantStatementForDateAggregate.AddDepositToStatement(merchantStatementId, nextStatementDate, eventId, command.EstateId, command.MerchantId, deposit); + + Result saveResult = await this.AggregateService.Save(merchantStatementForDateAggregate, cancellationToken); + if (saveResult.IsFailed) + return ResultHelpers.CreateFailure(saveResult); + + return Result.Success(); + } + catch (Exception ex) + { + return Result.Failure(ex.GetExceptionMessages()); + } } public async Task AddWithdrawalToStatement(MerchantStatementCommands.AddWithdrawalToMerchantStatementCommand command, CancellationToken cancellationToken) { - // Work out the next statement date - DateTime nextStatementDate = CalculateStatementDate(command.WithdrawalDateTime.Date); + try + { + // 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); + 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) => { + Result getMerchantStatementForDateResult = await DomainServiceHelper.GetAggregateOrFailure(ct => this.AggregateService.GetLatest(merchantStatementForDateId, ct), merchantStatementForDateId, cancellationToken, false); + if (getMerchantStatementForDateResult.IsFailed) + return ResultHelpers.CreateFailure(getMerchantStatementForDateResult); - Withdrawal withdrawal = new Withdrawal() { WithdrawalId = command.WithdrawalId, WithdrawalDateTime = command.WithdrawalDateTime, Amount = command.Amount.Value }; + MerchantStatementForDateAggregate merchantStatementForDateAggregate = getMerchantStatementForDateResult.Data; - Guid eventId = IdGenerationService.GenerateEventId(new - { - command.WithdrawalId, - withdrawal, - command.WithdrawalDateTime, - }); + Withdrawal withdrawal = new Withdrawal() { WithdrawalId = command.WithdrawalId, WithdrawalDateTime = command.WithdrawalDateTime, Amount = command.Amount.Value }; - merchantStatementForDateAggregate.AddWithdrawalToStatement(merchantStatementId, nextStatementDate, eventId, command.EstateId, command.MerchantId, withdrawal); + Guid eventId = IdGenerationService.GenerateEventId(new + { + command.WithdrawalId, + withdrawal, + command.WithdrawalDateTime, + }); - return Result.Success(); - }, merchantStatementForDateId, cancellationToken, false); + merchantStatementForDateAggregate.AddWithdrawalToStatement(merchantStatementId, nextStatementDate, eventId, command.EstateId, command.MerchantId, withdrawal); - if (result.IsFailed) - return ResultHelpers.CreateFailure(result); + Result saveResult = await this.AggregateService.Save(merchantStatementForDateAggregate, cancellationToken); + if (saveResult.IsFailed) + return ResultHelpers.CreateFailure(saveResult); - return Result.Success(); + return Result.Success(); + } + catch (Exception ex) + { + return Result.Failure(ex.GetExceptionMessages()); + } } 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 == null) - return Result.Success(); + try + { + // Transaction Completed arrives(if this is a logon transaction or failed then return) + if (command.IsAuthorised == false) + return Result.Success(); + if (command.TransactionAmount == null) + return Result.Success(); - // Work out the next statement date - DateTime nextStatementDate = CalculateStatementDate(command.TransactionDateTime); - - Guid merchantStatementId = IdGenerationService.GenerateMerchantStatementAggregateId(command.EstateId, command.MerchantId, nextStatementDate); - Guid merchantStatementForDateId = IdGenerationService.GenerateMerchantStatementForDateAggregateId(command.EstateId, command.MerchantId, nextStatementDate, command.TransactionDateTime); + // Work out the next statement date + DateTime nextStatementDate = CalculateStatementDate(command.TransactionDateTime); - Result result = await ApplyUpdates( - async (MerchantStatementForDateAggregate merchantStatementForDateAggregate) => { + Guid merchantStatementId = IdGenerationService.GenerateMerchantStatementAggregateId(command.EstateId, command.MerchantId, nextStatementDate); + Guid merchantStatementForDateId = IdGenerationService.GenerateMerchantStatementForDateAggregateId(command.EstateId, command.MerchantId, nextStatementDate, command.TransactionDateTime); - // Add transaction to statement - Transaction transaction = new(command.TransactionId, command.TransactionDateTime, command.TransactionAmount.Value); + Result getMerchantStatementForDateResult = await DomainServiceHelper.GetAggregateOrFailure(ct => this.AggregateService.GetLatest(merchantStatementForDateId, ct), merchantStatementForDateId, cancellationToken, false); + if (getMerchantStatementForDateResult.IsFailed) + return ResultHelpers.CreateFailure(getMerchantStatementForDateResult); - Guid eventId = IdGenerationService.GenerateEventId(new - { - command.TransactionId, - TransactionAmount = command.TransactionAmount.Value, - command.TransactionDateTime, - }); + MerchantStatementForDateAggregate merchantStatementForDateAggregate = getMerchantStatementForDateResult.Data; - merchantStatementForDateAggregate.AddTransactionToStatement(merchantStatementId, nextStatementDate, eventId, command.EstateId, command.MerchantId, transaction); + // Add transaction to statement + Transaction transaction = new(command.TransactionId, command.TransactionDateTime, command.TransactionAmount.Value); - return Result.Success(); - }, merchantStatementForDateId, cancellationToken, false); + Guid eventId = IdGenerationService.GenerateEventId(new + { + command.TransactionId, + TransactionAmount = command.TransactionAmount.Value, + command.TransactionDateTime, + }); - if (result.IsFailed) - return ResultHelpers.CreateFailure(result); + merchantStatementForDateAggregate.AddTransactionToStatement(merchantStatementId, nextStatementDate, eventId, command.EstateId, command.MerchantId, transaction); - return Result.Success(); + Result saveResult = await this.AggregateService.Save(merchantStatementForDateAggregate, cancellationToken); + if (saveResult.IsFailed) + return ResultHelpers.CreateFailure(saveResult); + + return Result.Success(); + } + catch (Exception ex) + { + return Result.Failure(ex.GetExceptionMessages()); + } } #endregion