From eaad5fdf0cf62035740283e1d82d52ae58a67515 Mon Sep 17 00:00:00 2001 From: logoutdhaval <100835289+logoutdhaval@users.noreply.github.com> Date: Thu, 27 Apr 2023 15:14:32 +0530 Subject: [PATCH] FINERACT-1920:Create Interoperation Loan Repayment API (#3119) --- .../api/InteropApiResource.java | 10 ++++ .../service/InteropService.java | 3 + .../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 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) {