You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by vi...@apache.org on 2019/06/14 20:05:58 UTC
[fineract] branch develop updated: FINERACT-767: Batch Repayment
for loans
This is an automated email from the ASF dual-hosted git repository.
vishwasbabu 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 86e105f FINERACT-767: Batch Repayment for loans
new f10bff2 Merge pull request #584 from mohitsinha/repaymentbatch
86e105f is described below
commit 86e105ff154c91f37c13b4040e3bb07e9f081198
Author: Mohit Sinha <mo...@gmail.com>
AuthorDate: Fri Jun 14 17:07:12 2019 +0700
FINERACT-767: Batch Repayment for loans
---
api-docs/apiLive.htm | 1 +
.../fineract/integrationtests/BatchApiTest.java | 66 ++++++++++++++++
.../integrationtests/common/BatchHelper.java | 34 ++++++++
.../batch/command/CommandStrategyProvider.java | 2 +
.../command/internal/RepayLoanCommandStrategy.java | 90 ++++++++++++++++++++++
5 files changed, 193 insertions(+)
diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm
index 67dfc71..236fc25 100644
--- a/api-docs/apiLive.htm
+++ b/api-docs/apiLive.htm
@@ -4777,6 +4777,7 @@ Successful transaction response:
<li><a href="#clients_activate">Activate a Pending Client</a>
<li><a href="#loans_approve">Approve a Pending Loan</a>
<li><a href="#loans_disburse">Disburse a Loan</a>
+ <li><a href="#loans_transaction_repayment">Repayment for a Loan</a>
</ul>
</div>
</div>
diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/BatchApiTest.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/BatchApiTest.java
index aae79a0..38f89e9 100644
--- a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/BatchApiTest.java
+++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/BatchApiTest.java
@@ -21,6 +21,8 @@ package org.apache.fineract.integrationtests;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
import org.apache.fineract.batch.domain.BatchRequest;
import org.apache.fineract.batch.domain.BatchResponse;
@@ -340,6 +342,70 @@ public class BatchApiTest {
}
/**
+ * Tests that batch repayment for loans is happening properly.
+ * Collected properly 200(OK) status was returned for successful responses.
+ * It first creates a new loan and then makes two repayments for it
+ * and then verifies that 200(OK) is returned for the repayment requests.
+ *
+ * @see org.apache.fineract.batch.command.internal.RepayLoanCommandStrategy
+ */
+ @Test
+ public void shouldReturnOkStatusForBatchRepayment() {
+
+ final String loanProductJSON = new LoanProductTestBuilder() //
+ .withPrincipal("10000000.00") //
+ .withNumberOfRepayments("24") //
+ .withRepaymentAfterEvery("1") //
+ .withRepaymentTypeAsMonth() //
+ .withinterestRatePerPeriod("2") //
+ .withInterestRateFrequencyTypeAsMonths() //
+ .withAmortizationTypeAsEqualPrincipalPayment() //
+ .withInterestTypeAsDecliningBalance() //
+ .currencyDetails("0", "100").build(null);
+
+ final Integer productId = new LoanTransactionHelper(this.requestSpec, this.responseSpec).getLoanProductId(loanProductJSON);
+
+ // Create a createClient Request
+ final BatchRequest br1 = BatchHelper.createClientRequest(4730L, "");
+
+ // Create a activateClient Request
+ final BatchRequest br2 = BatchHelper.activateClientRequest(4731L, 4730L);
+
+ // Create a ApplyLoan Request
+ final BatchRequest br3 = BatchHelper.applyLoanRequest(4732L, 4731L, productId);
+
+ // Create a approveLoan Request
+ final BatchRequest br4 = BatchHelper.approveLoanRequest(4733L, 4732L);
+
+ // Create a disburseLoan Request
+ final BatchRequest br5 = BatchHelper.disburseLoanRequest(4734L, 4733L);
+
+ // Create a loanRepay Request
+ final BatchRequest br6 = BatchHelper.repayLoanRequest(4735L, 4734L);
+
+ // Create a loanRepay Request
+ final BatchRequest br7 = BatchHelper.repayLoanRequest(4736L, 4734L);
+
+ final List<BatchRequest> batchRequests = new ArrayList<>();
+
+ batchRequests.add(br1);
+ batchRequests.add(br2);
+ batchRequests.add(br3);
+ batchRequests.add(br4);
+ batchRequests.add(br5);
+ batchRequests.add(br6);
+ batchRequests.add(br7);
+
+ final String jsonifiedRequest = BatchHelper.toJsonString(batchRequests);
+
+ final List<BatchResponse> response = BatchHelper.postBatchRequestsWithoutEnclosingTransaction(this.requestSpec, this.responseSpec,
+ jsonifiedRequest);
+
+ Assert.assertEquals("Verify Status Code 200 for Repayment", 200L, (long) response.get(5).getStatusCode());
+ Assert.assertEquals("Verify Status Code 200 for Repayment", 200L, (long) response.get(6).getStatusCode());
+ }
+
+ /**
* Test for the successful activation of a pending client using
* 'ActivateClientCommandStrategy'. A '200' status code is expected on
* successful activation.
diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/BatchHelper.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/BatchHelper.java
index 5a9a4d3..170ede5 100644
--- a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/BatchHelper.java
+++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/BatchHelper.java
@@ -20,6 +20,7 @@ package org.apache.fineract.integrationtests.common;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import org.apache.fineract.batch.domain.BatchRequest;
import org.apache.fineract.batch.domain.BatchResponse;
@@ -59,6 +60,16 @@ public class BatchHelper {
}
/**
+ * Returns a Map from Json String
+ *
+ * @param jsonBody
+ * @return Map
+ */
+ public static Map generateMapFromJsonString(final String jsonString) {
+ return new Gson().fromJson(jsonString, Map.class);
+ }
+
+ /**
* Returns the converted string response into JSON.
*
* @param json
@@ -379,6 +390,29 @@ public class BatchHelper {
return br;
}
+
+ /**
+ * Creates and returns a
+ * {@link org.apache.fineract.batch.command.internal.RepayLoanCommandStrategy}
+ * Request with given requestId.
+ *
+ *
+ * @param requestId
+ * @param reference
+ * @return BatchRequest
+ */
+ public static BatchRequest repayLoanRequest(final Long requestId, final Long reference) {
+ final BatchRequest br = new BatchRequest();
+
+ br.setRequestId(requestId);
+ br.setReference(reference);
+ br.setRelativeUrl("loans/$.loanId/transactions?command=repayment");
+ br.setMethod("POST");
+ br.setBody("{\"locale\": \"en\", \"dateFormat\": \"dd MMMM yyyy\", " +
+ "\"transactionDate\": \"15 September 2013\", \"transactionAmount\": 500}");
+
+ return br;
+ }
/**
* Checks that the client with given externalId is not created on the
diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/command/CommandStrategyProvider.java b/fineract-provider/src/main/java/org/apache/fineract/batch/command/CommandStrategyProvider.java
index e506004..8a95fd8 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/batch/command/CommandStrategyProvider.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/batch/command/CommandStrategyProvider.java
@@ -92,6 +92,8 @@ public class CommandStrategyProvider {
this.commandStrategies.put(CommandContext.resource("loans\\/\\d+\\/charges").method("POST").build(), "createChargeCommandStrategy");
this.commandStrategies
.put(CommandContext.resource("loans\\/\\d+\\/charges").method("GET").build(), "collectChargesCommandStrategy");
+ this.commandStrategies
+ .put(CommandContext.resource("loans\\/\\d+\\/transactions\\?command=repayment").method("POST").build(), "repayLoanCommandStrategy");
this.commandStrategies.put(CommandContext.resource("clients\\/\\d+\\?command=activate").method("POST").build(),
"activateClientCommandStrategy");
this.commandStrategies.put(CommandContext.resource("loans\\/\\d+\\?command=approve").method("POST").build(),
diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/RepayLoanCommandStrategy.java b/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/RepayLoanCommandStrategy.java
new file mode 100644
index 0000000..16d710c
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/batch/command/internal/RepayLoanCommandStrategy.java
@@ -0,0 +1,90 @@
+/**
+ * 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 org.apache.fineract.batch.command.CommandStrategy;
+import org.apache.fineract.batch.domain.BatchRequest;
+import org.apache.fineract.batch.domain.BatchResponse;
+import org.apache.fineract.batch.exception.ErrorHandler;
+import org.apache.fineract.batch.exception.ErrorInfo;
+import org.apache.fineract.portfolio.loanaccount.api.LoanTransactionsApiResource;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.ws.rs.core.UriInfo;
+
+/**
+ * Implements {@link CommandStrategy} and handles
+ * repayment for a Loan. It passes the contents of the body from the BatchRequest
+ * to {@link LoanTransactionsApiResource} and
+ * gets back the response. This class will also catch any errors raised by
+ * {@link LoanTransactionsApiResource} and map
+ * those errors to appropriate status codes in BatchResponse.
+ *
+ * @author Mohit Sinha
+ *
+ * @see CommandStrategy
+ * @see BatchRequest
+ * @see BatchResponse
+ */
+@Component
+public class RepayLoanCommandStrategy implements CommandStrategy {
+
+ private final LoanTransactionsApiResource loanTransactionsApiResource;
+
+ @Autowired
+ public RepayLoanCommandStrategy(final LoanTransactionsApiResource loanTransactionsApiResource) {
+ this.loanTransactionsApiResource = loanTransactionsApiResource;
+ }
+
+ @Override
+ public BatchResponse execute(BatchRequest request, @SuppressWarnings("unused") UriInfo uriInfo) {
+
+ final BatchResponse response = new BatchResponse();
+ final String responseBody;
+
+ response.setRequestId(request.getRequestId());
+ response.setHeaders(request.getHeaders());
+
+ final String[] pathParameters = request.getRelativeUrl().split("/");
+ Long loanId = Long.parseLong(pathParameters[1]);
+
+ // Try-catch blocks to map exceptions to appropriate status codes
+ try {
+
+ responseBody = loanTransactionsApiResource.executeLoanTransaction(loanId, "repayment", request.getBody());
+
+ response.setStatusCode(200);
+ // Sets the body of the response after Charge has been successfully
+ // created
+ response.setBody(responseBody);
+
+ } catch (RuntimeException e) {
+
+ // Gets an object of type ErrorInfo, containing information about
+ // raised exception
+ ErrorInfo ex = ErrorHandler.handler(e);
+
+ response.setStatusCode(ex.getStatusCode());
+ response.setBody(ex.getMessage());
+ }
+
+ return response;
+ }
+}