FINERACT-2181: Batch Api - Add Interest pause API support
This commit is contained in:
+3
-3
@@ -228,12 +228,12 @@ public class CommandStrategyProvider {
|
||||
.resource("v1\\/datatables\\/" + ALPHANUMBERIC_WITH_UNDERSCORE_REGEX + "\\/query" + MANDATORY_QUERY_PARAM_REGEX).method(GET)
|
||||
.build(), "getDatatableEntryByQueryCommandStrategy");
|
||||
commandStrategies.put(CommandContext.resource("v1\\/loans\\/" + NUMBER_REGEX + "\\/interest-pauses").method(GET).build(),
|
||||
"getLoanInterestPausesByExternalIdCommandStrategy");
|
||||
"getLoanInterestPausesByLoanIdCommandStrategy");
|
||||
commandStrategies.put(CommandContext.resource("v1\\/loans\\/" + NUMBER_REGEX + "\\/interest-pauses").method(POST).build(),
|
||||
"createLoanInterestPauseByExternalIdCommandStrategy");
|
||||
"createLoanInterestPauseByLoanIdCommandStrategy");
|
||||
commandStrategies.put(
|
||||
CommandContext.resource("v1\\/loans\\/" + NUMBER_REGEX + "\\/interest-pauses\\/" + NUMBER_REGEX).method(PUT).build(),
|
||||
"updateLoanInterestPauseByExternalIdCommandStrategy");
|
||||
"updateLoanInterestPauseByLoanIdCommandStrategy");
|
||||
commandStrategies.put(
|
||||
CommandContext.resource("v1\\/loans\\/external-id\\/" + UUID_PARAM_REGEX + "\\/interest-pauses").method(GET).build(),
|
||||
"getLoanInterestPausesByExternalIdCommandStrategy");
|
||||
|
||||
+195
@@ -26,6 +26,7 @@ import io.cucumber.datatable.DataTable;
|
||||
import io.cucumber.java.en.Then;
|
||||
import io.cucumber.java.en.When;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
@@ -954,6 +955,112 @@ public class BatchApiStepDef extends AbstractStepDef {
|
||||
}
|
||||
}
|
||||
|
||||
@When("Run Batch API with steps: createClient, createLoan, approveLoan, disburseLoan, applyInterestPause by external ids")
|
||||
public void runBatchApiWithInterestPauseByExternalIds() throws IOException {
|
||||
String idempotencyKey = UUID.randomUUID().toString();
|
||||
String clientExternalId = UUID.randomUUID().toString();
|
||||
String loanExternalId = UUID.randomUUID().toString();
|
||||
|
||||
List<BatchRequest> requestList = new ArrayList<>();
|
||||
|
||||
// Create client
|
||||
requestList.add(createClient(1L, idempotencyKey, clientExternalId));
|
||||
|
||||
// Create loan
|
||||
requestList.add(createProgressiveLoan(2L, 1L, idempotencyKey, loanExternalId));
|
||||
|
||||
// Approve loan
|
||||
requestList.add(approveLoanByExternalId(3L, 2L, idempotencyKey));
|
||||
|
||||
// Disburse loan
|
||||
PostLoansLoanIdRequest loanDisburseRequest = LoanRequestFactory.defaultLoanDisburseRequest();
|
||||
String bodyLoanDisburseRequest = GSON.toJson(loanDisburseRequest);
|
||||
BatchRequest disburseRequest = new BatchRequest();
|
||||
disburseRequest.requestId(4L);
|
||||
disburseRequest.relativeUrl("loans/external-id/$.resourceExternalId?command=disburse");
|
||||
disburseRequest.method(BATCH_API_METHOD_POST);
|
||||
disburseRequest.reference(2L);
|
||||
disburseRequest.headers(setHeaders(idempotencyKey));
|
||||
disburseRequest.body(bodyLoanDisburseRequest);
|
||||
requestList.add(disburseRequest);
|
||||
|
||||
// Apply interest pause (1 day starting from tomorrow)
|
||||
String startDate = DateTimeFormatter.ofPattern(DATE_FORMAT).format(Utils.now().minusMonths(1).plusDays(1));
|
||||
String endDate = DateTimeFormatter.ofPattern(DATE_FORMAT).format(Utils.now().minusMonths(1).plusDays(2));
|
||||
requestList.add(applyInterestPauseByExternalId(5L, 2L, idempotencyKey, startDate, endDate));
|
||||
|
||||
// Execute batch request
|
||||
Response<List<BatchResponse>> batchResponseList = batchApiApi.handleBatchRequests(requestList, true).execute();
|
||||
testContext().set(TestContextKey.BATCH_API_CALL_RESPONSE, batchResponseList);
|
||||
testContext().set(TestContextKey.BATCH_API_CALL_IDEMPOTENCY_KEY, idempotencyKey);
|
||||
testContext().set(TestContextKey.BATCH_API_CALL_CLIENT_EXTERNAL_ID, clientExternalId);
|
||||
testContext().set(TestContextKey.BATCH_API_CALL_LOAN_EXTERNAL_ID, loanExternalId);
|
||||
|
||||
// Log response for debugging
|
||||
if (batchResponseList.isSuccessful() && batchResponseList.body() != null && !batchResponseList.body().isEmpty()) {
|
||||
for (int i = 0; i < batchResponseList.body().size(); i++) {
|
||||
BatchResponse response = batchResponseList.body().get(i);
|
||||
log.debug("Batch step {} status code: {}", i + 1, response.getStatusCode());
|
||||
log.debug("Batch step {} response body: {}", i + 1, response.getBody());
|
||||
}
|
||||
} else {
|
||||
log.warn("Batch API call failed or returned empty response");
|
||||
}
|
||||
}
|
||||
|
||||
@When("Run Batch API with steps: createClient, createLoan, approveLoan, disburseLoan, applyInterestPause")
|
||||
public void runBatchApiWithInterestPause() throws IOException {
|
||||
String idempotencyKey = UUID.randomUUID().toString();
|
||||
String clientExternalId = UUID.randomUUID().toString();
|
||||
String loanExternalId = UUID.randomUUID().toString();
|
||||
|
||||
List<BatchRequest> requestList = new ArrayList<>();
|
||||
|
||||
// Create client
|
||||
requestList.add(createClient(1L, idempotencyKey, clientExternalId));
|
||||
|
||||
// Create loan
|
||||
requestList.add(createProgressiveLoan(2L, 1L, idempotencyKey, loanExternalId));
|
||||
|
||||
// Approve loan
|
||||
requestList.add(approveLoanByExternalId(3L, 2L, idempotencyKey));
|
||||
|
||||
// Disburse loan
|
||||
PostLoansLoanIdRequest loanDisburseRequest = LoanRequestFactory.defaultLoanDisburseRequest();
|
||||
String bodyLoanDisburseRequest = GSON.toJson(loanDisburseRequest);
|
||||
BatchRequest disburseRequest = new BatchRequest();
|
||||
disburseRequest.requestId(4L);
|
||||
disburseRequest.relativeUrl("loans/$.loanId?command=disburse");
|
||||
disburseRequest.method(BATCH_API_METHOD_POST);
|
||||
disburseRequest.reference(2L);
|
||||
disburseRequest.headers(setHeaders(idempotencyKey));
|
||||
disburseRequest.body(bodyLoanDisburseRequest);
|
||||
requestList.add(disburseRequest);
|
||||
|
||||
// Apply interest pause (1 day starting from tomorrow)
|
||||
String startDate = DateTimeFormatter.ofPattern(DATE_FORMAT).format(Utils.now().minusMonths(1).plusDays(1));
|
||||
String endDate = DateTimeFormatter.ofPattern(DATE_FORMAT).format(Utils.now().minusMonths(1).plusDays(2));
|
||||
requestList.add(applyInterestPause(5L, 2L, idempotencyKey, startDate, endDate));
|
||||
|
||||
// Execute batch request
|
||||
Response<List<BatchResponse>> batchResponseList = batchApiApi.handleBatchRequests(requestList, true).execute();
|
||||
testContext().set(TestContextKey.BATCH_API_CALL_RESPONSE, batchResponseList);
|
||||
testContext().set(TestContextKey.BATCH_API_CALL_IDEMPOTENCY_KEY, idempotencyKey);
|
||||
testContext().set(TestContextKey.BATCH_API_CALL_CLIENT_EXTERNAL_ID, clientExternalId);
|
||||
testContext().set(TestContextKey.BATCH_API_CALL_LOAN_EXTERNAL_ID, loanExternalId);
|
||||
|
||||
// Log response for debugging
|
||||
if (batchResponseList.isSuccessful() && batchResponseList.body() != null && !batchResponseList.body().isEmpty()) {
|
||||
for (int i = 0; i < batchResponseList.body().size(); i++) {
|
||||
BatchResponse response = batchResponseList.body().get(i);
|
||||
log.debug("Batch step {} status code: {}", i + 1, response.getStatusCode());
|
||||
log.debug("Batch step {} response body: {}", i + 1, response.getBody());
|
||||
}
|
||||
} else {
|
||||
log.warn("Batch API call failed or returned empty response");
|
||||
}
|
||||
}
|
||||
|
||||
private BatchRequest createChargeOffRequest(Long requestId, Long loanId, String idempotencyKey, String chargeOffDate) {
|
||||
// Create a charge-off request with the specified date
|
||||
Map<String, Object> requestMap = new HashMap<>();
|
||||
@@ -1043,6 +1150,24 @@ public class BatchApiStepDef extends AbstractStepDef {
|
||||
return batchRequest;
|
||||
}
|
||||
|
||||
private BatchRequest createProgressiveLoan(Long requestId, Long referenceId, String idempotencyKey, String loanExternalId) {
|
||||
PostLoansRequest loansRequest = loanExternalId == null ? loanRequestFactory.defaultProgressiveLoansRequest(1L)
|
||||
: loanRequestFactory.defaultProgressiveLoansRequest(1L).externalId(loanExternalId);
|
||||
loansRequest.setInterestRatePerPeriod(BigDecimal.ONE);
|
||||
String bodyLoansRequest = GSON.toJson(loansRequest);
|
||||
String bodyLoansRequestMod = bodyLoansRequest.replace("\"clientId\":1", "\"clientId\":\"$.clientId\"");
|
||||
|
||||
BatchRequest batchRequest = new BatchRequest();
|
||||
batchRequest.requestId(requestId);
|
||||
batchRequest.relativeUrl(BATCH_API_SAMPLE_RELATIVE_URL_LOANS);
|
||||
batchRequest.method(BATCH_API_METHOD_POST);
|
||||
batchRequest.headers(setHeaders(idempotencyKey));
|
||||
batchRequest.reference(referenceId);
|
||||
batchRequest.body(bodyLoansRequestMod);
|
||||
|
||||
return batchRequest;
|
||||
}
|
||||
|
||||
private BatchRequest queryDatatable(Long requestId) {
|
||||
String datatableName = testContext().get(DATATABLE_NAME);
|
||||
|
||||
@@ -1113,6 +1238,37 @@ public class BatchApiStepDef extends AbstractStepDef {
|
||||
return batchRequest;
|
||||
}
|
||||
|
||||
private BatchRequest applyInterestPause(Long requestId, Long referenceId, String idempotencyKey, String startDate, String endDate) {
|
||||
BatchRequest batchRequest = new BatchRequest();
|
||||
batchRequest.requestId(requestId);
|
||||
batchRequest.relativeUrl("loans/$.loanId/interest-pauses");
|
||||
batchRequest.method(BATCH_API_METHOD_POST);
|
||||
batchRequest.reference(referenceId);
|
||||
batchRequest.headers(setHeaders(idempotencyKey));
|
||||
|
||||
String interestPauseRequest = String
|
||||
.format("{\"dateFormat\":\"dd MMMM yyyy\",\"locale\":\"en\",\"startDate\":\"%s\",\"endDate\":\"%s\"}", startDate, endDate);
|
||||
batchRequest.body(interestPauseRequest);
|
||||
|
||||
return batchRequest;
|
||||
}
|
||||
|
||||
private BatchRequest applyInterestPauseByExternalId(Long requestId, Long referenceId, String idempotencyKey, String startDate,
|
||||
String endDate) {
|
||||
BatchRequest batchRequest = new BatchRequest();
|
||||
batchRequest.requestId(requestId);
|
||||
batchRequest.relativeUrl("loans/external-id/$.resourceExternalId/interest-pauses");
|
||||
batchRequest.method(BATCH_API_METHOD_POST);
|
||||
batchRequest.reference(referenceId);
|
||||
batchRequest.headers(setHeaders(idempotencyKey));
|
||||
|
||||
String interestPauseRequest = String
|
||||
.format("{\"dateFormat\":\"dd MMMM yyyy\",\"locale\":\"en\",\"startDate\":\"%s\",\"endDate\":\"%s\"}", startDate, endDate);
|
||||
batchRequest.body(interestPauseRequest);
|
||||
|
||||
return batchRequest;
|
||||
}
|
||||
|
||||
private Set<Header> setHeaders(String idempotencyKey) {
|
||||
Set<Header> headers = new HashSet<>();
|
||||
headers.add(HEADER);
|
||||
@@ -1122,4 +1278,43 @@ public class BatchApiStepDef extends AbstractStepDef {
|
||||
|
||||
return headers;
|
||||
}
|
||||
|
||||
@Then("Loan should have an active interest pause period starting on {int}st day and ending on {int}nd day")
|
||||
public void verifyInterestPausePeriod(int startDay, int endDay) throws IOException {
|
||||
// Get the loan ID from the batch response
|
||||
Response<List<BatchResponse>> batchResponseList = testContext().get(TestContextKey.BATCH_API_CALL_RESPONSE);
|
||||
assertThat(batchResponseList.isSuccessful()).isTrue();
|
||||
assertThat(batchResponseList.body()).isNotNull();
|
||||
|
||||
// The loan creation response is the second response in the batch (index 1)
|
||||
BatchResponse loanCreateResponse = batchResponseList.body().get(1);
|
||||
assertThat(loanCreateResponse.getStatusCode()).isEqualTo(200);
|
||||
|
||||
// Parse the loan ID from the response
|
||||
String loanCreateResponseBody = loanCreateResponse.getBody();
|
||||
com.google.gson.JsonObject loanCreateJson = com.google.gson.JsonParser.parseString(loanCreateResponseBody).getAsJsonObject();
|
||||
long loanId = loanCreateJson.get("loanId").getAsLong();
|
||||
|
||||
// Get the loan details
|
||||
Response<GetLoansLoanIdResponse> loanResponse = loansApi.retrieveLoan(loanId, false, "all", "", "").execute();
|
||||
assertThat(loanResponse.isSuccessful()).isTrue();
|
||||
assertThat(loanResponse.body()).isNotNull();
|
||||
|
||||
// Verify the interest pause period
|
||||
GetLoansLoanIdResponse loan = loanResponse.body();
|
||||
assertThat(loan.getLoanTermVariations().get(0).getTermType().getValue().equals("interestPause")).isTrue();
|
||||
|
||||
// Verify the start date is the specified day of the previous month
|
||||
LocalDate today = Utils.now();
|
||||
LocalDate expectedStartDate = today.minusMonths(1).plusDays(startDay);
|
||||
LocalDate actualStartDate = loan.getLoanTermVariations().get(0).getTermVariationApplicableFrom();
|
||||
assertThat(actualStartDate).isEqualTo(expectedStartDate);
|
||||
|
||||
// Verify the end date is the specified day of the previous month
|
||||
LocalDate expectedEndDate = today.minusMonths(1).plusDays(endDay);
|
||||
LocalDate actualEndDate = loan.getLoanTermVariations().get(0).getDateValue();
|
||||
assertThat(actualEndDate).isEqualTo(expectedEndDate);
|
||||
|
||||
log.debug("Verified interest pause period from {} to {}", actualStartDate, actualEndDate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,18 @@ Feature: Batch API
|
||||
When Batch API call with steps done twice: createClient, createLoan, approveLoan, getLoanDetails runs with enclosingTransaction: "false"
|
||||
Then Admin checks that all steps result 200OK
|
||||
|
||||
@TestRailId:C3876
|
||||
Scenario: Create loan, approve, disburse and apply interest pause in a single Batch API call
|
||||
And Run Batch API with steps: createClient, createLoan, approveLoan, disburseLoan, applyInterestPause
|
||||
Then Admin checks that all steps result 200OK
|
||||
And Loan should have an active interest pause period starting on 1st day and ending on 2nd day
|
||||
|
||||
@TestRailId:C3877
|
||||
Scenario: Create loan, approve, disburse and apply interest pause in a single Batch API call by external ids
|
||||
And Run Batch API with steps: createClient, createLoan, approveLoan, disburseLoan, applyInterestPause by external ids
|
||||
Then Admin checks that all steps result 200OK
|
||||
And Loan should have an active interest pause period starting on 1st day and ending on 2nd day
|
||||
|
||||
@TestRailId:C2645
|
||||
Scenario: Verify Batch API call in case of enclosing transaction is FALSE, there are two reference-trees and one of the steps in second tree fails
|
||||
When Batch API call with steps done twice: createClient, createLoan, approveLoan, getLoanDetails runs with enclosingTransaction: "false", with failed approve step in second tree
|
||||
@@ -141,4 +153,4 @@ Feature: Batch API
|
||||
| 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 |
|
||||
| 01 February 2024 | Accrual | 0.58 | 0.0 | 0.58 | 0.0 | 0.0 | 0.0 |
|
||||
| 01 February 2024 | Charge-off | 83.57 | 83.57 | 0.0 | 0.0 | 0.0 | 0.0 |
|
||||
And Admin checks the loan has been charged-off on "01 February 2024"
|
||||
And Admin checks the loan has been charged-off on "01 February 2024"
|
||||
|
||||
+8
@@ -50,4 +50,12 @@ public class InterestPauseRequestDto {
|
||||
throw new IllegalArgumentException("Error serializing request to JSON", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static InterestPauseRequestDto fromJson(String json) {
|
||||
try {
|
||||
return new ObjectMapper().readValue(json, InterestPauseRequestDto.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new IllegalArgumentException("Error deserializing request from JSON", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.batch.command.internal;
|
||||
|
||||
import static org.apache.fineract.batch.command.CommandStrategyUtils.relativeUrlWithoutVersion;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import jakarta.ws.rs.core.UriInfo;
|
||||
import java.util.List;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.batch.command.CommandStrategy;
|
||||
import org.apache.fineract.batch.domain.BatchRequest;
|
||||
import org.apache.fineract.batch.domain.BatchResponse;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||
import org.apache.fineract.portfolio.interestpauses.api.LoanInterestPauseApiResource;
|
||||
import org.apache.fineract.portfolio.interestpauses.data.InterestPauseRequestDto;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Implements {@link CommandStrategy} and creates a loan interest pause by external id. It passes the contents of the
|
||||
* body from the BatchRequest to {@link LoanInterestPauseApiResource} and gets back the response. This class will also
|
||||
* catch any errors raised by {@link LoanInterestPauseApiResource} and map those errors to appropriate status codes in
|
||||
* BatchResponse.
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class CreateLoanInterestPauseByExternalIdCommandStrategy implements CommandStrategy {
|
||||
|
||||
private final LoanInterestPauseApiResource loanInterestPauseApiResource;
|
||||
|
||||
private final DefaultToApiJsonSerializer<CommandProcessingResult> toApiJsonSerializer;
|
||||
|
||||
@Override
|
||||
public BatchResponse execute(final BatchRequest request, @SuppressWarnings("unused") final UriInfo uriInfo) {
|
||||
final BatchResponse response = new BatchResponse();
|
||||
|
||||
response.setRequestId(request.getRequestId());
|
||||
response.setHeaders(request.getHeaders());
|
||||
|
||||
// Expected pattern - loans\/external-id\/[\w\d_-]+\/interest-pauses
|
||||
final List<String> pathParameters = Splitter.on('/').splitToList(relativeUrlWithoutVersion(request));
|
||||
final String loanExternalId = pathParameters.get(2);
|
||||
|
||||
final InterestPauseRequestDto interestPauseRequestDto = InterestPauseRequestDto.fromJson(request.getBody());
|
||||
final CommandProcessingResult commandProcessingResult = loanInterestPauseApiResource.createInterestPauseByExternalId(loanExternalId,
|
||||
interestPauseRequestDto);
|
||||
|
||||
response.setStatusCode(HttpStatus.SC_OK);
|
||||
response.setBody(toApiJsonSerializer.serialize(commandProcessingResult));
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.batch.command.internal;
|
||||
|
||||
import static org.apache.fineract.batch.command.CommandStrategyUtils.relativeUrlWithoutVersion;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import jakarta.ws.rs.core.UriInfo;
|
||||
import java.util.List;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.batch.command.CommandStrategy;
|
||||
import org.apache.fineract.batch.domain.BatchRequest;
|
||||
import org.apache.fineract.batch.domain.BatchResponse;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||
import org.apache.fineract.portfolio.interestpauses.api.LoanInterestPauseApiResource;
|
||||
import org.apache.fineract.portfolio.interestpauses.data.InterestPauseRequestDto;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Implements {@link CommandStrategy} and creates a loan interest pause by loan id. It passes the contents of the body
|
||||
* from the BatchRequest to {@link LoanInterestPauseApiResource} and gets back the response. This class will also catch
|
||||
* any errors raised by {@link LoanInterestPauseApiResource} and map those errors to appropriate status codes in
|
||||
* BatchResponse.
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class CreateLoanInterestPauseByLoanIdCommandStrategy implements CommandStrategy {
|
||||
|
||||
private final LoanInterestPauseApiResource loanInterestPauseApiResource;
|
||||
|
||||
private final DefaultToApiJsonSerializer<CommandProcessingResult> toApiJsonSerializer;
|
||||
|
||||
@Override
|
||||
public BatchResponse execute(final BatchRequest request, @SuppressWarnings("unused") final UriInfo uriInfo) {
|
||||
final BatchResponse response = new BatchResponse();
|
||||
|
||||
response.setRequestId(request.getRequestId());
|
||||
response.setHeaders(request.getHeaders());
|
||||
|
||||
// Expected pattern - loans\/\d+\/interest-pauses
|
||||
final List<String> pathParameters = Splitter.on('/').splitToList(relativeUrlWithoutVersion(request));
|
||||
final Long loanId = Long.parseLong(pathParameters.get(1));
|
||||
|
||||
final InterestPauseRequestDto interestPauseRequestDto = InterestPauseRequestDto.fromJson(request.getBody());
|
||||
final CommandProcessingResult commandProcessingResult = loanInterestPauseApiResource.createInterestPause(loanId,
|
||||
interestPauseRequestDto);
|
||||
|
||||
response.setStatusCode(HttpStatus.SC_OK);
|
||||
response.setBody(toApiJsonSerializer.serialize(commandProcessingResult));
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.batch.command.internal;
|
||||
|
||||
import static org.apache.fineract.batch.command.CommandStrategyUtils.relativeUrlWithoutVersion;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import jakarta.ws.rs.core.UriInfo;
|
||||
import java.util.List;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.batch.command.CommandStrategy;
|
||||
import org.apache.fineract.batch.domain.BatchRequest;
|
||||
import org.apache.fineract.batch.domain.BatchResponse;
|
||||
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||
import org.apache.fineract.portfolio.interestpauses.api.LoanInterestPauseApiResource;
|
||||
import org.apache.fineract.portfolio.interestpauses.data.InterestPauseResponseDto;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Implements {@link CommandStrategy} and retrieves loan interest pauses by external id. It passes the contents of the
|
||||
* body from the BatchRequest to {@link LoanInterestPauseApiResource} and gets back the response. This class will also
|
||||
* catch any errors raised by {@link LoanInterestPauseApiResource} and map those errors to appropriate status codes in
|
||||
* BatchResponse.
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class GetLoanInterestPausesByExternalIdCommandStrategy implements CommandStrategy {
|
||||
|
||||
private final LoanInterestPauseApiResource loanInterestPauseApiResource;
|
||||
|
||||
private final DefaultToApiJsonSerializer<List<InterestPauseResponseDto>> toApiJsonSerializer;
|
||||
|
||||
@Override
|
||||
public BatchResponse execute(final BatchRequest request, @SuppressWarnings("unused") final UriInfo uriInfo) {
|
||||
final BatchResponse response = new BatchResponse();
|
||||
|
||||
response.setRequestId(request.getRequestId());
|
||||
response.setHeaders(request.getHeaders());
|
||||
|
||||
// Expected pattern - loans\/external-id\/[\w\d_-]+\/interest-pauses
|
||||
final List<String> pathParameters = Splitter.on('/').splitToList(relativeUrlWithoutVersion(request));
|
||||
final String loanExternalId = pathParameters.get(2);
|
||||
|
||||
final List<InterestPauseResponseDto> responseDtos = loanInterestPauseApiResource.retrieveInterestPausesByExternalId(loanExternalId);
|
||||
|
||||
response.setStatusCode(HttpStatus.SC_OK);
|
||||
response.setBody(toApiJsonSerializer.serialize(responseDtos));
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.batch.command.internal;
|
||||
|
||||
import static org.apache.fineract.batch.command.CommandStrategyUtils.relativeUrlWithoutVersion;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import jakarta.ws.rs.core.UriInfo;
|
||||
import java.util.List;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.batch.command.CommandStrategy;
|
||||
import org.apache.fineract.batch.domain.BatchRequest;
|
||||
import org.apache.fineract.batch.domain.BatchResponse;
|
||||
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||
import org.apache.fineract.portfolio.interestpauses.api.LoanInterestPauseApiResource;
|
||||
import org.apache.fineract.portfolio.interestpauses.data.InterestPauseResponseDto;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Implements {@link CommandStrategy} and retrieves loan interest pauses by loan id. It passes the contents of the body
|
||||
* from the BatchRequest to {@link LoanInterestPauseApiResource} and gets back the response. This class will also catch
|
||||
* any errors raised by {@link LoanInterestPauseApiResource} and map those errors to appropriate status codes in
|
||||
* BatchResponse.
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class GetLoanInterestPausesByLoanIdCommandStrategy implements CommandStrategy {
|
||||
|
||||
private final LoanInterestPauseApiResource loanInterestPauseApiResource;
|
||||
|
||||
private final DefaultToApiJsonSerializer<List<InterestPauseResponseDto>> toApiJsonSerializer;
|
||||
|
||||
@Override
|
||||
public BatchResponse execute(final BatchRequest request, @SuppressWarnings("unused") final UriInfo uriInfo) {
|
||||
final BatchResponse response = new BatchResponse();
|
||||
|
||||
response.setRequestId(request.getRequestId());
|
||||
response.setHeaders(request.getHeaders());
|
||||
|
||||
// Expected pattern - loans\/\d+\/interest-pauses
|
||||
final List<String> pathParameters = Splitter.on('/').splitToList(relativeUrlWithoutVersion(request));
|
||||
final Long loanId = Long.parseLong(pathParameters.get(1));
|
||||
|
||||
final List<InterestPauseResponseDto> responseDtos = loanInterestPauseApiResource.retrieveInterestPauses(loanId);
|
||||
|
||||
response.setStatusCode(HttpStatus.SC_OK);
|
||||
response.setBody(toApiJsonSerializer.serialize(responseDtos));
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.batch.command.internal;
|
||||
|
||||
import static org.apache.fineract.batch.command.CommandStrategyUtils.relativeUrlWithoutVersion;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import jakarta.ws.rs.core.UriInfo;
|
||||
import java.util.List;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.batch.command.CommandStrategy;
|
||||
import org.apache.fineract.batch.domain.BatchRequest;
|
||||
import org.apache.fineract.batch.domain.BatchResponse;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||
import org.apache.fineract.portfolio.interestpauses.api.LoanInterestPauseApiResource;
|
||||
import org.apache.fineract.portfolio.interestpauses.data.InterestPauseRequestDto;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Implements {@link CommandStrategy} and updates a loan interest pause by external id. It passes the contents of the
|
||||
* body from the BatchRequest to {@link LoanInterestPauseApiResource} and gets back the response. This class will also
|
||||
* catch any errors raised by {@link LoanInterestPauseApiResource} and map those errors to appropriate status codes in
|
||||
* BatchResponse.
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class UpdateLoanInterestPauseByExternalIdCommandStrategy implements CommandStrategy {
|
||||
|
||||
private final LoanInterestPauseApiResource loanInterestPauseApiResource;
|
||||
|
||||
private final DefaultToApiJsonSerializer<CommandProcessingResult> toApiJsonSerializer;
|
||||
|
||||
@Override
|
||||
public BatchResponse execute(final BatchRequest request, @SuppressWarnings("unused") final UriInfo uriInfo) {
|
||||
final BatchResponse response = new BatchResponse();
|
||||
|
||||
response.setRequestId(request.getRequestId());
|
||||
response.setHeaders(request.getHeaders());
|
||||
|
||||
// Expected pattern - loans\/external-id\/[\w\d_-]+\/interest-pauses\/\d+
|
||||
final List<String> pathParameters = Splitter.on('/').splitToList(relativeUrlWithoutVersion(request));
|
||||
final String loanExternalId = pathParameters.get(2);
|
||||
final Long variationId = Long.parseLong(pathParameters.get(4));
|
||||
|
||||
final InterestPauseRequestDto interestPauseRequestDto = InterestPauseRequestDto.fromJson(request.getBody());
|
||||
final CommandProcessingResult commandProcessingResult = loanInterestPauseApiResource.updateInterestPauseByExternalId(loanExternalId,
|
||||
variationId, interestPauseRequestDto);
|
||||
|
||||
response.setStatusCode(HttpStatus.SC_OK);
|
||||
response.setBody(toApiJsonSerializer.serialize(commandProcessingResult));
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.batch.command.internal;
|
||||
|
||||
import static org.apache.fineract.batch.command.CommandStrategyUtils.relativeUrlWithoutVersion;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import jakarta.ws.rs.core.UriInfo;
|
||||
import java.util.List;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.batch.command.CommandStrategy;
|
||||
import org.apache.fineract.batch.domain.BatchRequest;
|
||||
import org.apache.fineract.batch.domain.BatchResponse;
|
||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
|
||||
import org.apache.fineract.portfolio.interestpauses.api.LoanInterestPauseApiResource;
|
||||
import org.apache.fineract.portfolio.interestpauses.data.InterestPauseRequestDto;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Implements {@link CommandStrategy} and updates a loan interest pause by loan id. It passes the contents of the body
|
||||
* from the BatchRequest to {@link LoanInterestPauseApiResource} and gets back the response. This class will also catch
|
||||
* any errors raised by {@link LoanInterestPauseApiResource} and map those errors to appropriate status codes in
|
||||
* BatchResponse.
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class UpdateLoanInterestPauseByLoanIdCommandStrategy implements CommandStrategy {
|
||||
|
||||
private final LoanInterestPauseApiResource loanInterestPauseApiResource;
|
||||
|
||||
private final DefaultToApiJsonSerializer<CommandProcessingResult> toApiJsonSerializer;
|
||||
|
||||
@Override
|
||||
public BatchResponse execute(final BatchRequest request, @SuppressWarnings("unused") final UriInfo uriInfo) {
|
||||
final BatchResponse response = new BatchResponse();
|
||||
|
||||
response.setRequestId(request.getRequestId());
|
||||
response.setHeaders(request.getHeaders());
|
||||
|
||||
// Expected pattern - loans\/\d+\/interest-pauses\/\d+
|
||||
final List<String> pathParameters = Splitter.on('/').splitToList(relativeUrlWithoutVersion(request));
|
||||
final Long loanId = Long.parseLong(pathParameters.get(1));
|
||||
final Long variationId = Long.parseLong(pathParameters.get(3));
|
||||
|
||||
final InterestPauseRequestDto interestPauseRequestDto = InterestPauseRequestDto.fromJson(request.getBody());
|
||||
final CommandProcessingResult commandProcessingResult = loanInterestPauseApiResource.updateInterestPause(loanId, variationId,
|
||||
interestPauseRequestDto);
|
||||
|
||||
response.setStatusCode(HttpStatus.SC_OK);
|
||||
response.setBody(toApiJsonSerializer.serialize(commandProcessingResult));
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -195,11 +195,11 @@ public class CommandStrategyProviderTest {
|
||||
"getDatatableEntryByQueryCommandStrategy", mock(GetDatatableEntryByQueryCommandStrategy.class)),
|
||||
Arguments.of("datatables/test_dt_table/query?columnFilter=custom_id&valueFilter=10a62-d438-2319&resultColumns=id",
|
||||
HttpMethod.GET, "getDatatableEntryByQueryCommandStrategy", mock(GetDatatableEntryByQueryCommandStrategy.class)),
|
||||
Arguments.of("loans/123/interest-pauses", HttpMethod.GET, "getLoanInterestPausesByExternalIdCommandStrategy",
|
||||
Arguments.of("loans/123/interest-pauses", HttpMethod.GET, "getLoanInterestPausesByLoanIdCommandStrategy",
|
||||
mock(CommandStrategy.class)),
|
||||
Arguments.of("loans/123/interest-pauses", HttpMethod.POST, "createLoanInterestPauseByExternalIdCommandStrategy",
|
||||
Arguments.of("loans/123/interest-pauses", HttpMethod.POST, "createLoanInterestPauseByLoanIdCommandStrategy",
|
||||
mock(CommandStrategy.class)),
|
||||
Arguments.of("loans/123/interest-pauses/123", HttpMethod.PUT, "updateLoanInterestPauseByExternalIdCommandStrategy",
|
||||
Arguments.of("loans/123/interest-pauses/456", HttpMethod.PUT, "updateLoanInterestPauseByLoanIdCommandStrategy",
|
||||
mock(CommandStrategy.class)),
|
||||
Arguments.of("loans/external-id/8dfad438-2319-48ce-8520-10a62801e9a1/interest-pauses", HttpMethod.GET,
|
||||
"getLoanInterestPausesByExternalIdCommandStrategy", mock(CommandStrategy.class)),
|
||||
|
||||
Reference in New Issue
Block a user