2424import io .cucumber .java .en .Then ;
2525import io .cucumber .java .en .When ;
2626import java .io .IOException ;
27+ import java .lang .reflect .Method ;
28+ import java .math .BigDecimal ;
29+ import java .util .Arrays ;
30+ import java .util .LinkedHashMap ;
2731import java .util .List ;
32+ import java .util .Map ;
33+ import java .util .Set ;
2834import lombok .extern .slf4j .Slf4j ;
2935import okhttp3 .ResponseBody ;
3036import org .apache .fineract .client .models .PostLoansLoanIdTransactionsRequest ;
@@ -57,11 +63,20 @@ public void createReAgingTransaction(DataTable table) throws IOException {
5763 Response <PostLoansResponse > loanResponse = testContext ().get (TestContextKey .LOAN_CREATE_RESPONSE );
5864 long loanId = loanResponse .body ().getLoanId ();
5965
60- List <String > data = table .asLists ().get (1 );
61- int frequencyNumber = Integer .parseInt (data .get (0 ));
62- String frequencyType = data .get (1 );
63- String startDate = data .get (2 );
64- int numberOfInstallments = Integer .parseInt (data .get (3 ));
66+ List <List <String >> tableRows = table .asLists ();
67+ List <String > headers = tableRows .get (0 );
68+ List <String > values = tableRows .get (1 );
69+
70+ Map <String , String > rowData = new LinkedHashMap <>();
71+ int columnCount = Math .min (headers .size (), values .size ());
72+ for (int i = 0 ; i < columnCount ; i ++) {
73+ rowData .put (headers .get (i ), values .get (i ));
74+ }
75+
76+ int frequencyNumber = Integer .parseInt (resolveValue (rowData , values , 0 , "frequencyNumber" ));
77+ String frequencyType = resolveValue (rowData , values , 1 , "frequencyType" );
78+ String startDate = resolveValue (rowData , values , 2 , "startDate" );
79+ int numberOfInstallments = Integer .parseInt (resolveValue (rowData , values , 3 , "numberOfInstallments" ));
6580
6681 PostLoansLoanIdTransactionsRequest reAgingRequest = LoanRequestFactory //
6782 .defaultReAgingRequest ()//
@@ -70,12 +85,102 @@ public void createReAgingTransaction(DataTable table) throws IOException {
7085 .startDate (startDate )//
7186 .numberOfInstallments (numberOfInstallments );//
7287
88+ applyAdditionalFields (reAgingRequest , rowData , Set .of ("frequencyNumber" , "frequencyType" , "startDate" , "numberOfInstallments" ));
89+
7390 Response <PostLoansLoanIdTransactionsResponse > response = loanTransactionsApi .executeLoanTransaction (loanId , reAgingRequest , "reAge" )
7491 .execute ();
7592 ErrorHelper .checkSuccessfulApiCall (response );
7693 testContext ().set (TestContextKey .LOAN_REAGING_RESPONSE , response );
7794 }
7895
96+ private void applyAdditionalFields (PostLoansLoanIdTransactionsRequest request , Map <String , String > rowData , Set <String > excludedKeys ) {
97+ rowData .forEach ((key , value ) -> {
98+ if (!excludedKeys .contains (key )) {
99+ setRequestField (request , key , value );
100+ }
101+ });
102+ }
103+
104+ private void setRequestField (PostLoansLoanIdTransactionsRequest request , String fieldName , String rawValue ) {
105+ if (fieldName == null || fieldName .isBlank ()) {
106+ return ;
107+ }
108+
109+ try {
110+ Method targetMethod = Arrays .stream (PostLoansLoanIdTransactionsRequest .class .getMethods ())
111+ .filter (method -> method .getParameterCount () == 1 && method .getName ().equals (fieldName )).findFirst ().orElse (null );
112+
113+ if (targetMethod == null ) {
114+ log .warn ("No setter method found on PostLoansLoanIdTransactionsRequest for field {}" , fieldName );
115+ return ;
116+ }
117+
118+ Class <?> parameterType = targetMethod .getParameterTypes ()[0 ];
119+ Object convertedValue = convertValue (rawValue , parameterType );
120+
121+ if (convertedValue == null && parameterType .isPrimitive ()) {
122+ log .warn ("Cannot assign null to primitive field {} on PostLoansLoanIdTransactionsRequest" , fieldName );
123+ return ;
124+ }
125+
126+ targetMethod .invoke (request , convertedValue );
127+ } catch (Exception ex ) {
128+ log .warn ("Failed to set additional field {} on PostLoansLoanIdTransactionsRequest" , fieldName , ex );
129+ }
130+ }
131+
132+ private Object convertValue (String rawValue , Class <?> targetType ) {
133+ if (rawValue == null || rawValue .isBlank ()) {
134+ return null ;
135+ }
136+
137+ try {
138+ if (String .class .equals (targetType )) {
139+ return rawValue ;
140+ }
141+ if (Integer .class .equals (targetType ) || int .class .equals (targetType )) {
142+ return Integer .valueOf (rawValue );
143+ }
144+ if (Long .class .equals (targetType ) || long .class .equals (targetType )) {
145+ return Long .valueOf (rawValue );
146+ }
147+ if (Double .class .equals (targetType ) || double .class .equals (targetType )) {
148+ return Double .valueOf (rawValue );
149+ }
150+ if (Float .class .equals (targetType ) || float .class .equals (targetType )) {
151+ return Float .valueOf (rawValue );
152+ }
153+ if (Short .class .equals (targetType ) || short .class .equals (targetType )) {
154+ return Short .valueOf (rawValue );
155+ }
156+ if (Byte .class .equals (targetType ) || byte .class .equals (targetType )) {
157+ return Byte .valueOf (rawValue );
158+ }
159+ if (Boolean .class .equals (targetType ) || boolean .class .equals (targetType )) {
160+ return Boolean .parseBoolean (rawValue );
161+ }
162+ if (BigDecimal .class .equals (targetType )) {
163+ return new BigDecimal (rawValue );
164+ }
165+ } catch (NumberFormatException ex ) {
166+ log .warn ("Unable to convert value '{}' to type {}. Falling back to raw string." , rawValue , targetType .getSimpleName (), ex );
167+ return rawValue ;
168+ }
169+
170+ return rawValue ;
171+ }
172+
173+ private String resolveValue (Map <String , String > rowData , List <String > values , int index , String key ) {
174+ String value = rowData .get (key );
175+ if (value != null ) {
176+ return value ;
177+ }
178+ if (index >= 0 && index < values .size ()) {
179+ return values .get (index );
180+ }
181+ return null ;
182+ }
183+
79184 @ When ("Admin creates a Loan re-aging transaction by Loan external ID with the following data:" )
80185 public void createReAgingTransactionByLoanExternalId (DataTable table ) throws IOException {
81186 Response <PostLoansResponse > loanResponse = testContext ().get (TestContextKey .LOAN_CREATE_RESPONSE );
0 commit comments