77
88namespace TransactionProcessor . BusinessLogic . Services
99{
10- using System ;
11- using System . Collections . Generic ;
12- using System . Linq ;
13- using System . Threading ;
14- using System . Threading . Tasks ;
1510 using Common ;
1611 using Models ;
12+ using Polly ;
1713 using Shared . DomainDrivenDesign . EventSourcing ;
1814 using Shared . EventStore . Aggregate ;
1915 using Shared . Exceptions ;
2016 using Shared . Logger ;
17+ using System ;
18+ using System . Collections . Generic ;
19+ using System . Linq ;
20+ using System . Threading ;
21+ using System . Threading . Tasks ;
2122
2223 public interface ISettlementDomainService
2324 {
@@ -98,56 +99,53 @@ private async Task<Result> ApplyTransactionUpdates(Func<TransactionAggregate, Ta
9899 // TODO: Add in a Get Settlement
99100
100101 public async Task < Result < Guid > > ProcessSettlement ( SettlementCommands . ProcessSettlementCommand command ,
101- CancellationToken cancellationToken )
102- {
103- Guid settlementAggregateId = Helpers . CalculateSettlementAggregateId ( command . SettlementDate , command . MerchantId , command . EstateId ) ;
104- List < ( Guid transactionId , Guid merchantId , CalculatedFee calculatedFee ) > feesToBeSettled = new ( ) ;
102+ CancellationToken cancellationToken ) {
103+ IAsyncPolicy < Result < Guid > > retryPolicy = PolicyFactory . CreatePolicy < Guid > ( policyTag : "SettlementDomainService - ProcessSettlement" ) ;
104+
105+ return await PolicyFactory . ExecuteWithPolicyAsync < Guid > ( async ( ) => {
106+ Guid settlementAggregateId = Helpers . CalculateSettlementAggregateId ( command . SettlementDate , command . MerchantId , command . EstateId ) ;
107+ List < ( Guid transactionId , Guid merchantId , CalculatedFee calculatedFee ) > feesToBeSettled = new ( ) ;
108+
109+ Result settlementResult = await ApplySettlementUpdates ( async ( SettlementAggregate settlementAggregate ) => {
110+ if ( settlementAggregate . IsCreated == false ) {
111+ Logger . LogInformation ( $ "No pending settlement for { command . SettlementDate : yyyy-MM-dd} ") ;
112+ // Not pending settlement for this date
113+ return Result . Success ( ) ;
114+ }
115+
116+ Result < MerchantAggregate > getMerchantResult = await this . AggregateService . Get < MerchantAggregate > ( command . MerchantId , cancellationToken ) ;
117+ if ( getMerchantResult . IsFailed )
118+ return ResultHelpers . CreateFailure ( getMerchantResult ) ;
119+
120+ MerchantAggregate merchant = getMerchantResult . Data ;
121+ if ( merchant . SettlementSchedule == SettlementSchedule . Immediate ) {
122+ // Mark the settlement as completed
123+ settlementAggregate . StartProcessing ( DateTime . Now ) ;
124+ settlementAggregate . ManuallyComplete ( ) ;
125+ Result result = await this . AggregateService . Save ( settlementAggregate , cancellationToken ) ;
126+ return result ;
127+ }
128+
129+ feesToBeSettled = settlementAggregate . GetFeesToBeSettled ( ) ;
130+
131+ if ( feesToBeSettled . Any ( ) ) {
132+ // Record the process call
133+ settlementAggregate . StartProcessing ( DateTime . Now ) ;
134+ return await this . AggregateService . Save ( settlementAggregate , cancellationToken ) ;
135+ }
105136
106- Result settlementResult = await ApplySettlementUpdates ( async ( SettlementAggregate settlementAggregate ) => {
107- if ( settlementAggregate . IsCreated == false )
108- {
109- Logger . LogInformation ( $ "No pending settlement for { command . SettlementDate : yyyy-MM-dd} ") ;
110- // Not pending settlement for this date
111137 return Result . Success ( ) ;
112- }
113138
114- Result < MerchantAggregate > getMerchantResult = await this . AggregateService . Get < MerchantAggregate > ( command . MerchantId , cancellationToken ) ;
115- if ( getMerchantResult . IsFailed )
116- return ResultHelpers . CreateFailure ( getMerchantResult ) ;
117-
118- MerchantAggregate merchant = getMerchantResult . Data ;
119- if ( merchant . SettlementSchedule == SettlementSchedule . Immediate )
120- {
121- // Mark the settlement as completed
122- settlementAggregate . StartProcessing ( DateTime . Now ) ;
123- settlementAggregate . ManuallyComplete ( ) ;
124- Result result = await this . AggregateService . Save ( settlementAggregate , cancellationToken ) ;
125- return result ;
126- }
139+ } , settlementAggregateId , cancellationToken ) ;
127140
128- feesToBeSettled = settlementAggregate . GetFeesToBeSettled ( ) ;
129-
130- if ( feesToBeSettled . Any ( ) )
131- {
132- // Record the process call
133- settlementAggregate . StartProcessing ( DateTime . Now ) ;
134- return await this . AggregateService . Save ( settlementAggregate , cancellationToken ) ;
135- }
141+ if ( settlementResult . IsFailed )
142+ return settlementResult ;
136143
137- return Result . Success ( ) ;
138-
139- } , settlementAggregateId , cancellationToken ) ;
140-
141- if ( settlementResult . IsFailed )
142- return settlementResult ;
143-
144- List < Result > failedResults = new ( ) ;
145- foreach ( ( Guid transactionId , Guid merchantId , CalculatedFee calculatedFee ) feeToSettle in feesToBeSettled ) {
146- Result transactionResult = await ApplyTransactionUpdates (
147- async ( TransactionAggregate transactionAggregate ) => {
144+ List < Result > failedResults = new ( ) ;
145+ foreach ( ( Guid transactionId , Guid merchantId , CalculatedFee calculatedFee ) feeToSettle in feesToBeSettled ) {
146+ Result transactionResult = await ApplyTransactionUpdates ( async ( TransactionAggregate transactionAggregate ) => {
148147 try {
149- transactionAggregate . AddSettledFee ( feeToSettle . calculatedFee , command . SettlementDate ,
150- settlementAggregateId ) ;
148+ transactionAggregate . AddSettledFee ( feeToSettle . calculatedFee , command . SettlementDate , settlementAggregateId ) ;
151149 return Result . Success ( ) ;
152150 }
153151 catch ( Exception ex ) {
@@ -156,15 +154,17 @@ public async Task<Result<Guid>> ProcessSettlement(SettlementCommands.ProcessSett
156154 }
157155 } , feeToSettle . transactionId , cancellationToken ) ;
158156
159- if ( transactionResult . IsFailed ) {
160- failedResults . Add ( transactionResult ) ;
157+ if ( transactionResult . IsFailed ) {
158+ failedResults . Add ( transactionResult ) ;
159+ }
161160 }
162- }
163161
164- if ( failedResults . Any ( ) ) {
165- return Result . Failure ( $ "Not all fees were processed successfully { failedResults . Count } have failed") ;
166- }
167- return Result . Success ( settlementAggregateId ) ;
162+ if ( failedResults . Any ( ) ) {
163+ return Result . Failure ( $ "Not all fees were processed successfully { failedResults . Count } have failed") ;
164+ }
165+
166+ return Result . Success ( settlementAggregateId ) ;
167+ } , retryPolicy , "SettlementDomainService - ProcessSettlement" ) ;
168168 }
169169
170170 public async Task < Result > AddMerchantFeePendingSettlement ( SettlementCommands . AddMerchantFeePendingSettlementCommand command ,
0 commit comments