You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by ma...@apache.org on 2023/04/27 09:44:39 UTC
[fineract] branch develop updated: FINERACT-1920:Create Interoperation Loan Repayment API (#3119)
This is an automated email from the ASF dual-hosted git repository.
manojvm pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
The following commit(s) were added to refs/heads/develop by this push:
new eaad5fdf0 FINERACT-1920:Create Interoperation Loan Repayment API (#3119)
eaad5fdf0 is described below
commit eaad5fdf0cf62035740283e1d82d52ae58a67515
Author: logoutdhaval <10...@users.noreply.github.com>
AuthorDate: Thu Apr 27 15:14:32 2023 +0530
FINERACT-1920:Create Interoperation Loan Repayment API (#3119)
---
.../interoperation/api/InteropApiResource.java | 10 ++++
.../interoperation/service/InteropService.java | 3 ++
.../interoperation/service/InteropServiceImpl.java | 13 +++++
.../ClientLoanIntegrationTest.java | 55 ++++++++++++++++++++++
.../common/loans/LoanTransactionHelper.java | 9 ++++
5 files changed, 90 insertions(+)
diff --git a/fineract-provider/src/main/java/org/apache/fineract/interoperation/api/InteropApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/interoperation/api/InteropApiResource.java
index cc093fb68..3703416bb 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/interoperation/api/InteropApiResource.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/interoperation/api/InteropApiResource.java
@@ -416,4 +416,14 @@ public class InteropApiResource {
return interopService.disburseLoan(accountId, apiRequestBodyAsJson);
}
+ @POST
+ @Consumes({ MediaType.APPLICATION_JSON })
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Path("transactions/{accountId}/loanrepayment")
+ @Operation(summary = "Disburse Loan by Account Id", description = "")
+ public String loanRepayment(@PathParam("accountId") @Parameter(description = "accountId") String accountId,
+ @Parameter(hidden = true) final String apiRequestBodyAsJson, @Context UriInfo uriInfo) {
+ return interopService.loanRepayment(accountId, apiRequestBodyAsJson);
+ }
+
}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/interoperation/service/InteropService.java b/fineract-provider/src/main/java/org/apache/fineract/interoperation/service/InteropService.java
index 92b0473d7..9dcb1a859 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/interoperation/service/InteropService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/interoperation/service/InteropService.java
@@ -81,4 +81,7 @@ public interface InteropService {
@NotNull
String disburseLoan(@NotNull String accountId, String apiRequestBodyAsJson);
+
+ @NotNull
+ String loanRepayment(@NotNull String accountId, String apiRequestBodyAsJson);
}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/interoperation/service/InteropServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/interoperation/service/InteropServiceImpl.java
index c045c09aa..398f22218 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/interoperation/service/InteropServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/interoperation/service/InteropServiceImpl.java
@@ -544,6 +544,19 @@ public class InteropServiceImpl implements InteropService {
return this.toApiJsonSerializer.serialize(result);
}
+ @Override
+ public @NotNull String loanRepayment(@NotNull String accountId, String apiRequestBodyAsJson) {
+ Loan loan = validateAndGetLoan(accountId);
+ Long loanId = loan.getId();
+
+ final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
+
+ final CommandWrapper commandRequest = builder.loanRepaymentTransaction(loanId).build();
+ CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+
+ return this.toApiJsonSerializer.serialize(result);
+ }
+
private SavingsAccount validateAndGetSavingAccount(String accountId) {
SavingsAccount savingsAccount = savingsAccountRepository.findByExternalId(accountId);
if (savingsAccount == null) {
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java
index 04884c44f..b204a2e88 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java
@@ -3983,6 +3983,61 @@ public class ClientLoanIntegrationTest {
}
+ @Test
+ public void testInteroperationLoanRepaymentAPI() {
+ this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
+ final ResponseSpecification errorResponse = new ResponseSpecBuilder().expectStatusCode(403).build();
+ DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
+ dateFormat.setTimeZone(Utils.getTimeZoneOfTenant());
+ GlobalConfigurationHelper.updateEnabledFlagForGlobalConfiguration(this.requestSpec, this.responseSpec, "42", true);
+ Calendar startDate = Calendar.getInstance(Utils.getTimeZoneOfTenant());
+ startDate.add(Calendar.MONTH, -8);
+
+ Calendar firstRepaymentDate = (Calendar) startDate.clone();
+ firstRepaymentDate.add(Calendar.MONTH, 1);
+ firstRepaymentDate.add(Calendar.DAY_OF_MONTH, firstRepaymentDate.getActualMaximum(Calendar.DAY_OF_MONTH) - Calendar.DAY_OF_MONTH);
+ String firstRepayment = dateFormat.format(firstRepaymentDate.getTime());
+
+ final String loanDisbursementDate = dateFormat.format(startDate.getTime());
+ final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
+ ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID);
+ final Integer loanProductID = createLoanProductWithInterestRecalculationAndCompoundingDetails(
+ LoanProductTestBuilder.INTEREST_PRINCIPAL_PENALTIES_FEES_ORDER_STRATEGY,
+ LoanProductTestBuilder.RECALCULATION_COMPOUNDING_METHOD_NONE,
+ LoanProductTestBuilder.RECALCULATION_STRATEGY_REDUCE_NUMBER_OF_INSTALLMENTS,
+ LoanProductTestBuilder.RECALCULATION_FREQUENCY_TYPE_SAME_AS_REPAYMENT_PERIOD,
+ LoanProductTestBuilder.INTEREST_APPLICABLE_STRATEGY_ON_PRE_CLOSE_DATE, null, "12");
+
+ final Integer loanID = applyForLoanApplicationForInterestRecalculation(clientID, loanProductID, loanDisbursementDate,
+ LoanApplicationTestBuilder.INTEREST_PRINCIPAL_PENALTIES_FEES_ORDER_STRATEGY, firstRepayment);
+
+ Assertions.assertNotNull(loanID);
+ HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
+ LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
+
+ LOG.info("-----------------------------------APPROVE LOAN-----------------------------------------");
+ loanStatusHashMap = this.loanTransactionHelper.approveLoan(loanDisbursementDate, loanID);
+ LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
+ LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
+
+ LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------");
+ String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID);
+ loanStatusHashMap = this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(loanDisbursementDate, loanID,
+ JsonPath.from(loanDetails).get("netDisbursalAmount").toString());
+ LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
+
+ ArrayList<HashMap> loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
+ Assertions.assertNotNull(loanSchedule);
+ startDate.add(Calendar.DAY_OF_MONTH, 2);
+ String loanFirstRepaymentDate = dateFormat.format(startDate.getTime());
+
+ Float earlyPayment = Float.parseFloat("3000");
+ String accountNo = JsonPath.from(loanDetails).get("accountNo").toString();
+
+ HashMap loanRepayment = this.loanTransactionHelper.makeRepaymentWithAccountNo(loanFirstRepaymentDate, earlyPayment, accountNo);
+ assertNotNull(loanRepayment);
+ }
+
@Test
public void testLoanScheduleWithInterestRecalculation_WITH_REST_WEEKLY_INTEREST_COMPOUND_INTEREST_FEE_STRATEGY_REDUCE_NEXT_INSTALLMENTS() {
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java
index 0af276d95..fb475c1d2 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java
@@ -507,6 +507,11 @@ public class LoanTransactionHelper extends IntegrationTest {
getRepaymentBodyAsJSON(date, amountToBePaid), "");
}
+ public HashMap makeRepaymentWithAccountNo(final String date, final Float amountToBePaid, final String accountNo) {
+ return (HashMap) performLoanTransaction(createInteroperationLoanTransactionURL(accountNo),
+ getRepaymentBodyAsJSON(date, amountToBePaid), "");
+ }
+
public HashMap reverseRepayment(final Integer loanId, final Integer transactionId, String date) {
return (HashMap) performLoanTransaction(createLoanTransactionURL(UNDO, loanId, transactionId),
getAdjustTransactionJsonBody(date, "0"), "");
@@ -1285,6 +1290,10 @@ public class LoanTransactionHelper extends IntegrationTest {
return "/fineract-provider/api/v1/loans/" + loanID + "/transactions?command=" + command + "&" + Utils.TENANT_IDENTIFIER;
}
+ private String createInteroperationLoanTransactionURL(final String accountNo) {
+ return "/fineract-provider/api/v1/interoperation/transactions/" + accountNo + "/loanrepayment";
+ }
+
private String createLoanTransactionURL(final String command, final Integer loanID, final Integer transactionId) {
String url = "/fineract-provider/api/v1/loans/" + loanID + "/transactions/" + transactionId + "?";
if (command != null) {