@@ -518,12 +518,12 @@ public async Task<Result<ResendReceiptResponse>> ResendReceipt(Guid estateId,
518518 return Result . Invalid ( "Recipient email address is not valid." ) ;
519519 }
520520
521- Result < ResendReceiptResponse > resendResult = await this . InvokeResendReceiptAsync ( accessTokenResult . Data . AccessToken ,
522- estateId ,
523- merchantId ,
524- reference ,
525- recipientEmailAddress ,
526- cancellationToken ) ;
521+ Result < ResendReceiptResponse > resendResult = await this . InvokeResendReceipt ( accessTokenResult . Data . AccessToken ,
522+ estateId ,
523+ merchantId ,
524+ reference ,
525+ recipientEmailAddress ,
526+ cancellationToken ) ;
527527
528528 if ( resendResult . IsFailed ) {
529529 return resendResult ;
@@ -532,95 +532,127 @@ public async Task<Result<ResendReceiptResponse>> ResendReceipt(Guid estateId,
532532 return resendResult ;
533533 }
534534
535- private async Task < Result < ResendReceiptResponse > > InvokeResendReceiptAsync ( String accessToken ,
536- Guid estateId ,
537- Guid merchantId ,
538- String reference ,
539- String recipientEmailAddress ,
540- CancellationToken cancellationToken )
535+ private async Task < Result < ResendReceiptResponse > > InvokeResendReceipt ( String accessToken ,
536+ Guid estateId ,
537+ Guid merchantId ,
538+ String reference ,
539+ String recipientEmailAddress ,
540+ CancellationToken cancellationToken )
541541 {
542- System . Reflection . MethodInfo ? method = typeof ( ITransactionProcessorClient )
543- . GetMethods ( )
544- . SingleOrDefault ( m => string . Equals ( m . Name , "ResendEmailReceipt" , StringComparison . Ordinal ) ) ;
545-
542+ System . Reflection . MethodInfo ? method = FindResendEmailReceiptMethod ( ) ;
546543 if ( method == null ) {
547544 return Result . Failure ( "Receipt resend is not supported by the transaction client." ) ;
548545 }
549546
547+ object ? [ ] ? args = BuildResendReceiptArguments ( method , accessToken , estateId , merchantId , reference , recipientEmailAddress , cancellationToken ) ;
548+ if ( args == null ) {
549+ return Result . Failure ( "Unable to prepare receipt resend request." ) ;
550+ }
551+
552+ object ? invocationResult = method . Invoke ( this . TransactionProcessorClient , args ) ;
553+ if ( invocationResult is not Task task ) {
554+ return Result . Failure ( "Receipt resend call did not return a task." ) ;
555+ }
556+
557+ await task . ConfigureAwait ( false ) ;
558+ return MapResendReceiptInvocationResult ( task , reference ) ;
559+ }
560+
561+ private static System . Reflection . MethodInfo ? FindResendEmailReceiptMethod ( )
562+ {
563+ return typeof ( ITransactionProcessorClient )
564+ . GetMethods ( )
565+ . SingleOrDefault ( m => string . Equals ( m . Name , "ResendEmailReceipt" , StringComparison . Ordinal ) ) ;
566+ }
567+
568+ private static object ? [ ] ? BuildResendReceiptArguments ( System . Reflection . MethodInfo method ,
569+ String accessToken ,
570+ Guid estateId ,
571+ Guid merchantId ,
572+ String reference ,
573+ String recipientEmailAddress ,
574+ CancellationToken cancellationToken )
575+ {
550576 System . Reflection . ParameterInfo [ ] parameters = method . GetParameters ( ) ;
551577 object ? [ ] args = new object ? [ parameters . Length ] ;
552- bool estateAssigned = false ;
553- bool merchantAssigned = false ;
554- object ? request = null ;
578+ ResendReceiptInvocationState state = new ( ) ;
555579
556580 for ( int index = 0 ; index < parameters . Length ; index ++ ) {
557- System . Reflection . ParameterInfo parameter = parameters [ index ] ;
558-
559- if ( parameter . ParameterType == typeof ( String ) ) {
560- args [ index ] = accessToken ;
561- continue ;
581+ object ? argument = BuildResendReceiptArgument ( parameters [ index ] ,
582+ state ,
583+ accessToken ,
584+ estateId ,
585+ merchantId ,
586+ reference ,
587+ recipientEmailAddress ,
588+ cancellationToken ) ;
589+ if ( argument == ResendReceiptInvocationState . UnableToBuildArgument ) {
590+ return null ;
562591 }
563592
564- if ( parameter . ParameterType == typeof ( Guid ) ) {
565- if ( estateAssigned == false ) {
566- args [ index ] = estateId ;
567- estateAssigned = true ;
568- }
569- else if ( merchantAssigned == false ) {
570- args [ index ] = merchantId ;
571- merchantAssigned = true ;
572- }
573- else {
574- args [ index ] = Guid . Empty ;
575- }
576-
577- continue ;
578- }
593+ args [ index ] = argument ;
594+ }
579595
580- if ( parameter . ParameterType == typeof ( CancellationToken ) ) {
581- args [ index ] = cancellationToken ;
582- continue ;
583- }
596+ return args ;
597+ }
584598
585- request ??= System . Activator . CreateInstance ( parameter . ParameterType ) ;
586- if ( request == null ) {
587- return Result . Failure ( $ "Unable to create resend receipt request type '{ parameter . ParameterType . FullName } '.") ;
588- }
599+ private static object ? BuildResendReceiptArgument ( System . Reflection . ParameterInfo parameter ,
600+ ResendReceiptInvocationState state ,
601+ String accessToken ,
602+ Guid estateId ,
603+ Guid merchantId ,
604+ String reference ,
605+ String recipientEmailAddress ,
606+ CancellationToken cancellationToken )
607+ {
608+ if ( parameter . ParameterType == typeof ( String ) ) {
609+ return accessToken ;
610+ }
589611
590- PopulateResendReceiptRequest ( request , estateId , merchantId , reference , recipientEmailAddress ) ;
591- args [ index ] = request ;
612+ if ( parameter . ParameterType == typeof ( Guid ) ) {
613+ return state . GetNextGuidArgument ( estateId , merchantId ) ;
592614 }
593615
594- object ? invocationResult = method . Invoke ( this . TransactionProcessorClient , args ) ;
595- if ( invocationResult is not Task task ) {
596- return Result . Failure ( "Receipt resend call did not return a task." ) ;
616+ if ( parameter . ParameterType == typeof ( CancellationToken ) ) {
617+ return cancellationToken ;
597618 }
598619
599- await task . ConfigureAwait ( false ) ;
620+ return state . GetResendReceiptRequest ( parameter . ParameterType , estateId , merchantId , reference , recipientEmailAddress ) ;
621+ }
600622
623+ private static Result < ResendReceiptResponse > MapResendReceiptInvocationResult ( Task task , String reference )
624+ {
601625 object ? taskResult = task . GetType ( ) . GetProperty ( "Result" ) ? . GetValue ( task ) ;
602626 if ( taskResult == null ) {
603627 return Result . Failure ( "Receipt resend call returned no result." ) ;
604628 }
605629
606- bool isFailed = ( bool ) ( taskResult . GetType ( ) . GetProperty ( "IsFailed" ) ? . GetValue ( taskResult ) ?? true ) ;
607- if ( isFailed ) {
608- string ? message = taskResult . GetType ( ) . GetProperty ( "Message" ) ? . GetValue ( taskResult ) ? . ToString ( ) ;
609- string ? status = taskResult . GetType ( ) . GetProperty ( "Status" ) ? . GetValue ( taskResult ) ? . ToString ( ) ;
630+ if ( IsFailedResult ( taskResult , out String ? message , out String ? status ) ) {
631+ return MapResendReceiptFailure ( status , message ) ;
632+ }
610633
611- if ( string . Equals ( status , "NotFound" , StringComparison . OrdinalIgnoreCase ) ) {
612- return Result . NotFound ( message ?? "Receipt could not be found." ) ;
613- }
634+ object ? data = taskResult . GetType ( ) . GetProperty ( "Data" ) ? . GetValue ( taskResult ) ;
635+ return Result . Success ( MapResendReceiptResponse ( data , reference ) ) ;
636+ }
614637
615- if ( string . Equals ( status , "Invalid" , StringComparison . OrdinalIgnoreCase ) ) {
616- return Result . Invalid ( message ?? "Receipt resend request was invalid." ) ;
617- }
638+ private static bool IsFailedResult ( object taskResult , out String ? message , out String ? status )
639+ {
640+ message = taskResult . GetType ( ) . GetProperty ( "Message" ) ? . GetValue ( taskResult ) ? . ToString ( ) ;
641+ status = taskResult . GetType ( ) . GetProperty ( "Status" ) ? . GetValue ( taskResult ) ? . ToString ( ) ;
642+ return ( bool ) ( taskResult . GetType ( ) . GetProperty ( "IsFailed" ) ? . GetValue ( taskResult ) ?? true ) ;
643+ }
618644
619- return Result . Failure ( message ?? "Receipt resend failed." ) ;
645+ private static Result < ResendReceiptResponse > MapResendReceiptFailure ( String ? status , String ? message )
646+ {
647+ if ( string . Equals ( status , "NotFound" , StringComparison . OrdinalIgnoreCase ) ) {
648+ return Result . NotFound ( message ?? "Receipt could not be found." ) ;
620649 }
621650
622- object ? data = taskResult . GetType ( ) . GetProperty ( "Data" ) ? . GetValue ( taskResult ) ;
623- return Result . Success ( MapResendReceiptResponse ( data , reference ) ) ;
651+ if ( string . Equals ( status , "Invalid" , StringComparison . OrdinalIgnoreCase ) ) {
652+ return Result . Invalid ( message ?? "Receipt resend request was invalid." ) ;
653+ }
654+
655+ return Result . Failure ( message ?? "Receipt resend failed." ) ;
624656 }
625657
626658 private static void PopulateResendReceiptRequest ( object request ,
@@ -686,6 +718,45 @@ private static ResendReceiptResponse MapResendReceiptResponse(object? data, Stri
686718 return property ? . GetValue ( instance ) ? . ToString ( ) ;
687719 }
688720
721+ private sealed class ResendReceiptInvocationState
722+ {
723+ public static readonly object UnableToBuildArgument = new ( ) ;
724+
725+ private bool estateAssigned ;
726+ private bool merchantAssigned ;
727+ private object ? request ;
728+
729+ public object ? GetNextGuidArgument ( Guid estateId , Guid merchantId )
730+ {
731+ if ( this . estateAssigned == false ) {
732+ this . estateAssigned = true ;
733+ return estateId ;
734+ }
735+
736+ if ( this . merchantAssigned == false ) {
737+ this . merchantAssigned = true ;
738+ return merchantId ;
739+ }
740+
741+ return Guid . Empty ;
742+ }
743+
744+ public object ? GetResendReceiptRequest ( Type requestType ,
745+ Guid estateId ,
746+ Guid merchantId ,
747+ String reference ,
748+ String recipientEmailAddress )
749+ {
750+ this . request ??= System . Activator . CreateInstance ( requestType ) ;
751+ if ( this . request == null ) {
752+ return UnableToBuildArgument ;
753+ }
754+
755+ PopulateResendReceiptRequest ( this . request , estateId , merchantId , reference , recipientEmailAddress ) ;
756+ return this . request ;
757+ }
758+ }
759+
689760 private static ProcessReconciliationResponse CreateProcessReconciliationResponse ( ReconciliationResponse reconciliationResponse )
690761 {
691762 return new ProcessReconciliationResponse
0 commit comments