2626import io .cucumber .java .en .Then ;
2727import io .cucumber .java .en .When ;
2828import java .io .IOException ;
29+ import java .math .BigDecimal ;
2930import java .nio .charset .StandardCharsets ;
3031import java .time .LocalDate ;
3132import java .time .format .DateTimeFormatter ;
@@ -954,6 +955,112 @@ public void runBatchApiCallWithChargeOffCommand(String chargeOffDate) throws IOE
954955 }
955956 }
956957
958+ @ When ("Run Batch API with steps: createClient, createLoan, approveLoan, disburseLoan, applyInterestPause by external ids" )
959+ public void runBatchApiWithInterestPauseByExternalIds () throws IOException {
960+ String idempotencyKey = UUID .randomUUID ().toString ();
961+ String clientExternalId = UUID .randomUUID ().toString ();
962+ String loanExternalId = UUID .randomUUID ().toString ();
963+
964+ List <BatchRequest > requestList = new ArrayList <>();
965+
966+ // Create client
967+ requestList .add (createClient (1L , idempotencyKey , clientExternalId ));
968+
969+ // Create loan
970+ requestList .add (createProgressiveLoan (2L , 1L , idempotencyKey , loanExternalId ));
971+
972+ // Approve loan
973+ requestList .add (approveLoanByExternalId (3L , 2L , idempotencyKey ));
974+
975+ // Disburse loan
976+ PostLoansLoanIdRequest loanDisburseRequest = LoanRequestFactory .defaultLoanDisburseRequest ();
977+ String bodyLoanDisburseRequest = GSON .toJson (loanDisburseRequest );
978+ BatchRequest disburseRequest = new BatchRequest ();
979+ disburseRequest .requestId (4L );
980+ disburseRequest .relativeUrl ("loans/external-id/$.resourceExternalId?command=disburse" );
981+ disburseRequest .method (BATCH_API_METHOD_POST );
982+ disburseRequest .reference (2L );
983+ disburseRequest .headers (setHeaders (idempotencyKey ));
984+ disburseRequest .body (bodyLoanDisburseRequest );
985+ requestList .add (disburseRequest );
986+
987+ // Apply interest pause (1 day starting from tomorrow)
988+ String startDate = DateTimeFormatter .ofPattern (DATE_FORMAT ).format (Utils .now ().minusMonths (1 ).plusDays (1 ));
989+ String endDate = DateTimeFormatter .ofPattern (DATE_FORMAT ).format (Utils .now ().minusMonths (1 ).plusDays (2 ));
990+ requestList .add (applyInterestPauseByExternalId (5L , 2L , idempotencyKey , startDate , endDate ));
991+
992+ // Execute batch request
993+ Response <List <BatchResponse >> batchResponseList = batchApiApi .handleBatchRequests (requestList , true ).execute ();
994+ testContext ().set (TestContextKey .BATCH_API_CALL_RESPONSE , batchResponseList );
995+ testContext ().set (TestContextKey .BATCH_API_CALL_IDEMPOTENCY_KEY , idempotencyKey );
996+ testContext ().set (TestContextKey .BATCH_API_CALL_CLIENT_EXTERNAL_ID , clientExternalId );
997+ testContext ().set (TestContextKey .BATCH_API_CALL_LOAN_EXTERNAL_ID , loanExternalId );
998+
999+ // Log response for debugging
1000+ if (batchResponseList .isSuccessful () && batchResponseList .body () != null && !batchResponseList .body ().isEmpty ()) {
1001+ for (int i = 0 ; i < batchResponseList .body ().size (); i ++) {
1002+ BatchResponse response = batchResponseList .body ().get (i );
1003+ log .debug ("Batch step {} status code: {}" , i + 1 , response .getStatusCode ());
1004+ log .debug ("Batch step {} response body: {}" , i + 1 , response .getBody ());
1005+ }
1006+ } else {
1007+ log .warn ("Batch API call failed or returned empty response" );
1008+ }
1009+ }
1010+
1011+ @ When ("Run Batch API with steps: createClient, createLoan, approveLoan, disburseLoan, applyInterestPause" )
1012+ public void runBatchApiWithInterestPause () throws IOException {
1013+ String idempotencyKey = UUID .randomUUID ().toString ();
1014+ String clientExternalId = UUID .randomUUID ().toString ();
1015+ String loanExternalId = UUID .randomUUID ().toString ();
1016+
1017+ List <BatchRequest > requestList = new ArrayList <>();
1018+
1019+ // Create client
1020+ requestList .add (createClient (1L , idempotencyKey , clientExternalId ));
1021+
1022+ // Create loan
1023+ requestList .add (createProgressiveLoan (2L , 1L , idempotencyKey , loanExternalId ));
1024+
1025+ // Approve loan
1026+ requestList .add (approveLoanByExternalId (3L , 2L , idempotencyKey ));
1027+
1028+ // Disburse loan
1029+ PostLoansLoanIdRequest loanDisburseRequest = LoanRequestFactory .defaultLoanDisburseRequest ();
1030+ String bodyLoanDisburseRequest = GSON .toJson (loanDisburseRequest );
1031+ BatchRequest disburseRequest = new BatchRequest ();
1032+ disburseRequest .requestId (4L );
1033+ disburseRequest .relativeUrl ("loans/$.loanId?command=disburse" );
1034+ disburseRequest .method (BATCH_API_METHOD_POST );
1035+ disburseRequest .reference (2L );
1036+ disburseRequest .headers (setHeaders (idempotencyKey ));
1037+ disburseRequest .body (bodyLoanDisburseRequest );
1038+ requestList .add (disburseRequest );
1039+
1040+ // Apply interest pause (1 day starting from tomorrow)
1041+ String startDate = DateTimeFormatter .ofPattern (DATE_FORMAT ).format (Utils .now ().minusMonths (1 ).plusDays (1 ));
1042+ String endDate = DateTimeFormatter .ofPattern (DATE_FORMAT ).format (Utils .now ().minusMonths (1 ).plusDays (2 ));
1043+ requestList .add (applyInterestPause (5L , 2L , idempotencyKey , startDate , endDate ));
1044+
1045+ // Execute batch request
1046+ Response <List <BatchResponse >> batchResponseList = batchApiApi .handleBatchRequests (requestList , true ).execute ();
1047+ testContext ().set (TestContextKey .BATCH_API_CALL_RESPONSE , batchResponseList );
1048+ testContext ().set (TestContextKey .BATCH_API_CALL_IDEMPOTENCY_KEY , idempotencyKey );
1049+ testContext ().set (TestContextKey .BATCH_API_CALL_CLIENT_EXTERNAL_ID , clientExternalId );
1050+ testContext ().set (TestContextKey .BATCH_API_CALL_LOAN_EXTERNAL_ID , loanExternalId );
1051+
1052+ // Log response for debugging
1053+ if (batchResponseList .isSuccessful () && batchResponseList .body () != null && !batchResponseList .body ().isEmpty ()) {
1054+ for (int i = 0 ; i < batchResponseList .body ().size (); i ++) {
1055+ BatchResponse response = batchResponseList .body ().get (i );
1056+ log .debug ("Batch step {} status code: {}" , i + 1 , response .getStatusCode ());
1057+ log .debug ("Batch step {} response body: {}" , i + 1 , response .getBody ());
1058+ }
1059+ } else {
1060+ log .warn ("Batch API call failed or returned empty response" );
1061+ }
1062+ }
1063+
9571064 private BatchRequest createChargeOffRequest (Long requestId , Long loanId , String idempotencyKey , String chargeOffDate ) {
9581065 // Create a charge-off request with the specified date
9591066 Map <String , Object > requestMap = new HashMap <>();
@@ -1043,6 +1150,24 @@ private BatchRequest createLoan(Long requestId, Long referenceId, String idempot
10431150 return batchRequest ;
10441151 }
10451152
1153+ private BatchRequest createProgressiveLoan (Long requestId , Long referenceId , String idempotencyKey , String loanExternalId ) {
1154+ PostLoansRequest loansRequest = loanExternalId == null ? loanRequestFactory .defaultProgressiveLoansRequest (1L )
1155+ : loanRequestFactory .defaultProgressiveLoansRequest (1L ).externalId (loanExternalId );
1156+ loansRequest .setInterestRatePerPeriod (BigDecimal .ONE );
1157+ String bodyLoansRequest = GSON .toJson (loansRequest );
1158+ String bodyLoansRequestMod = bodyLoansRequest .replace ("\" clientId\" :1" , "\" clientId\" :\" $.clientId\" " );
1159+
1160+ BatchRequest batchRequest = new BatchRequest ();
1161+ batchRequest .requestId (requestId );
1162+ batchRequest .relativeUrl (BATCH_API_SAMPLE_RELATIVE_URL_LOANS );
1163+ batchRequest .method (BATCH_API_METHOD_POST );
1164+ batchRequest .headers (setHeaders (idempotencyKey ));
1165+ batchRequest .reference (referenceId );
1166+ batchRequest .body (bodyLoansRequestMod );
1167+
1168+ return batchRequest ;
1169+ }
1170+
10461171 private BatchRequest queryDatatable (Long requestId ) {
10471172 String datatableName = testContext ().get (DATATABLE_NAME );
10481173
@@ -1113,6 +1238,37 @@ private BatchRequest getLoanDetailsByExternalId(Long requestId, Long referenceId
11131238 return batchRequest ;
11141239 }
11151240
1241+ private BatchRequest applyInterestPause (Long requestId , Long referenceId , String idempotencyKey , String startDate , String endDate ) {
1242+ BatchRequest batchRequest = new BatchRequest ();
1243+ batchRequest .requestId (requestId );
1244+ batchRequest .relativeUrl ("loans/$.loanId/interest-pauses" );
1245+ batchRequest .method (BATCH_API_METHOD_POST );
1246+ batchRequest .reference (referenceId );
1247+ batchRequest .headers (setHeaders (idempotencyKey ));
1248+
1249+ String interestPauseRequest = String
1250+ .format ("{\" dateFormat\" :\" dd MMMM yyyy\" ,\" locale\" :\" en\" ,\" startDate\" :\" %s\" ,\" endDate\" :\" %s\" }" , startDate , endDate );
1251+ batchRequest .body (interestPauseRequest );
1252+
1253+ return batchRequest ;
1254+ }
1255+
1256+ private BatchRequest applyInterestPauseByExternalId (Long requestId , Long referenceId , String idempotencyKey , String startDate ,
1257+ String endDate ) {
1258+ BatchRequest batchRequest = new BatchRequest ();
1259+ batchRequest .requestId (requestId );
1260+ batchRequest .relativeUrl ("loans/external-id/$.resourceExternalId/interest-pauses" );
1261+ batchRequest .method (BATCH_API_METHOD_POST );
1262+ batchRequest .reference (referenceId );
1263+ batchRequest .headers (setHeaders (idempotencyKey ));
1264+
1265+ String interestPauseRequest = String
1266+ .format ("{\" dateFormat\" :\" dd MMMM yyyy\" ,\" locale\" :\" en\" ,\" startDate\" :\" %s\" ,\" endDate\" :\" %s\" }" , startDate , endDate );
1267+ batchRequest .body (interestPauseRequest );
1268+
1269+ return batchRequest ;
1270+ }
1271+
11161272 private Set <Header > setHeaders (String idempotencyKey ) {
11171273 Set <Header > headers = new HashSet <>();
11181274 headers .add (HEADER );
@@ -1122,4 +1278,43 @@ private Set<Header> setHeaders(String idempotencyKey) {
11221278
11231279 return headers ;
11241280 }
1281+
1282+ @ Then ("Loan should have an active interest pause period starting on {int}st day and ending on {int}nd day" )
1283+ public void verifyInterestPausePeriod (int startDay , int endDay ) throws IOException {
1284+ // Get the loan ID from the batch response
1285+ Response <List <BatchResponse >> batchResponseList = testContext ().get (TestContextKey .BATCH_API_CALL_RESPONSE );
1286+ assertThat (batchResponseList .isSuccessful ()).isTrue ();
1287+ assertThat (batchResponseList .body ()).isNotNull ();
1288+
1289+ // The loan creation response is the second response in the batch (index 1)
1290+ BatchResponse loanCreateResponse = batchResponseList .body ().get (1 );
1291+ assertThat (loanCreateResponse .getStatusCode ()).isEqualTo (200 );
1292+
1293+ // Parse the loan ID from the response
1294+ String loanCreateResponseBody = loanCreateResponse .getBody ();
1295+ com .google .gson .JsonObject loanCreateJson = com .google .gson .JsonParser .parseString (loanCreateResponseBody ).getAsJsonObject ();
1296+ long loanId = loanCreateJson .get ("loanId" ).getAsLong ();
1297+
1298+ // Get the loan details
1299+ Response <GetLoansLoanIdResponse > loanResponse = loansApi .retrieveLoan (loanId , false , "all" , "" , "" ).execute ();
1300+ assertThat (loanResponse .isSuccessful ()).isTrue ();
1301+ assertThat (loanResponse .body ()).isNotNull ();
1302+
1303+ // Verify the interest pause period
1304+ GetLoansLoanIdResponse loan = loanResponse .body ();
1305+ assertThat (loan .getLoanTermVariations ().get (0 ).getTermType ().getValue ().equals ("interestPause" )).isTrue ();
1306+
1307+ // Verify the start date is the specified day of the previous month
1308+ LocalDate today = Utils .now ();
1309+ LocalDate expectedStartDate = today .minusMonths (1 ).plusDays (startDay );
1310+ LocalDate actualStartDate = loan .getLoanTermVariations ().get (0 ).getTermVariationApplicableFrom ();
1311+ assertThat (actualStartDate ).isEqualTo (expectedStartDate );
1312+
1313+ // Verify the end date is the specified day of the previous month
1314+ LocalDate expectedEndDate = today .minusMonths (1 ).plusDays (endDay );
1315+ LocalDate actualEndDate = loan .getLoanTermVariations ().get (0 ).getDateValue ();
1316+ assertThat (actualEndDate ).isEqualTo (expectedEndDate );
1317+
1318+ log .debug ("Verified interest pause period from {} to {}" , actualStartDate , actualEndDate );
1319+ }
11251320}
0 commit comments