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 2016/01/28 06:46:54 UTC
[09/51] [partial] incubator-fineract git commit: initial code push
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/4b1ec9ef/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/HookIntegrationTest.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/HookIntegrationTest.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/HookIntegrationTest.java
new file mode 100644
index 0000000..5013a40
--- /dev/null
+++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/HookIntegrationTest.java
@@ -0,0 +1,115 @@
+/**
+ * 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.integrationtests;
+
+import org.junit.Assert;
+
+import static org.junit.Assert.fail;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.fineract.integrationtests.common.HookHelper;
+import org.apache.fineract.integrationtests.common.OfficeHelper;
+import org.apache.fineract.integrationtests.common.Utils;
+import org.apache.http.conn.HttpHostConnectException;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.jayway.restassured.RestAssured;
+import com.jayway.restassured.builder.RequestSpecBuilder;
+import com.jayway.restassured.builder.ResponseSpecBuilder;
+import com.jayway.restassured.http.ContentType;
+import com.jayway.restassured.path.json.JsonPath;
+import com.jayway.restassured.specification.RequestSpecification;
+import com.jayway.restassured.specification.ResponseSpecification;
+
+public class HookIntegrationTest {
+
+ private RequestSpecification requestSpec;
+ private ResponseSpecification responseSpec;
+
+ private HookHelper hookHelper;
+ private OfficeHelper officeHelper;
+
+ @Before
+ public void setUp() throws Exception {
+ Utils.initializeRESTAssured();
+ this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
+ this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
+ this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
+ this.hookHelper = new HookHelper(this.requestSpec, this.responseSpec);
+ this.officeHelper = new OfficeHelper(this.requestSpec, this.responseSpec);
+ }
+
+ @Test
+ public void shouldSendOfficeCreationNotification() {
+ // Subject to https://echo-webhook.herokuapp.com being up
+ // See
+ // http://www.jamesward.com/2014/06/11/testing-webhooks-was-a-pain-so-i-fixed-the-glitch
+ final String payloadURL = "http://echo-webhook.herokuapp.com:80/Z7RXoCBdLSFMDrpn?";
+ this.hookHelper.createHook(payloadURL);
+ final Integer createdOfficeID = this.officeHelper.createOffice("01 January 2012");
+ try {
+
+ /**
+ * sleep for a three seconds after each failure to increase the
+ * likelihood of the previous request for creating office completing
+ **/
+
+ for (int i = 0; i < 6; i++) {
+ try {
+ final String json = RestAssured.get(payloadURL.replace("?", "")).asString();
+ final Integer notificationOfficeId = JsonPath.with(json).get("officeId");
+ Assert.assertEquals("Equality check for created officeId and hook received payload officeId", createdOfficeID,
+ notificationOfficeId);
+ System.out.println("Notification Office Id - " + notificationOfficeId);
+ i = 6;
+ } catch (Exception e) {
+ TimeUnit.SECONDS.sleep(3);
+ i++;
+ }
+ }
+
+ } catch (final Exception e) {
+ if (e instanceof HttpHostConnectException) {
+ fail("Failed to connect to https://echo-webhook.herokuapp.com platform");
+ }
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ @Test
+ public void createUpdateAndDeleteHook(){
+ final String payloadURL = "http://echo-webhook.herokuapp.com:80/Z7RXoCBdLSFMDrpn?";
+ final String updateURL = "http://localhost";
+
+ Long hookId = this.hookHelper.createHook(payloadURL).longValue();
+ Assert.assertNotNull(hookId);
+ this.hookHelper.verifyHookCreatedOnServer(hookId);
+ System.out.println("---------------------SUCCESSFULLY CREATED AND VERIFIED HOOK-------------------------"+hookId);
+ this.hookHelper.updateHook(updateURL, hookId);
+ this.hookHelper.verifyUpdateHook(updateURL, hookId);
+ System.out.println("---------------------SUCCESSFULLY UPDATED AND VERIFIED HOOK-------------------------"+hookId);
+ this.hookHelper.deleteHook(hookId);
+ this.hookHelper.verifyDeleteHook(hookId);
+ System.out.println("---------------------SUCCESSFULLY DELETED AND VERIFIED HOOK-------------------------"+hookId);
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/4b1ec9ef/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanApplicationApprovalTest.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanApplicationApprovalTest.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanApplicationApprovalTest.java
new file mode 100644
index 0000000..1ef1a20
--- /dev/null
+++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanApplicationApprovalTest.java
@@ -0,0 +1,281 @@
+/**
+ * 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.integrationtests;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.fineract.integrationtests.common.ClientHelper;
+import org.apache.fineract.integrationtests.common.CommonConstants;
+import org.apache.fineract.integrationtests.common.Utils;
+import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder;
+import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
+import org.apache.fineract.integrationtests.common.loans.LoanStatusChecker;
+import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.jayway.restassured.builder.RequestSpecBuilder;
+import com.jayway.restassured.builder.ResponseSpecBuilder;
+import com.jayway.restassured.http.ContentType;
+import com.jayway.restassured.specification.RequestSpecification;
+import com.jayway.restassured.specification.ResponseSpecification;
+
+@SuppressWarnings("rawtypes")
+public class LoanApplicationApprovalTest {
+
+ private ResponseSpecification responseSpec;
+ private ResponseSpecification responseSpecForStatusCode403;
+ private ResponseSpecification responseSpecForStatusCode400;
+ private RequestSpecification requestSpec;
+ private LoanTransactionHelper loanTransactionHelper;
+
+ @Before
+ public void setup() {
+ Utils.initializeRESTAssured();
+ this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
+ this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
+ this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
+ this.responseSpecForStatusCode403 = new ResponseSpecBuilder().expectStatusCode(403).build();
+ this.responseSpecForStatusCode400 = new ResponseSpecBuilder().expectStatusCode(400).build();
+ this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
+ }
+
+ /*
+ * Positive test case: Approved amount non zero is less than proposed amount
+ */
+ @Test
+ public void loanApplicationApprovedAmountLessThanProposedAmount() {
+
+ final String proposedAmount = "8000";
+ final String approvalAmount = "5000";
+ final String approveDate = "20 September 2012";
+
+ final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2012");
+ final Integer loanProductID = this.loanTransactionHelper.getLoanProductId(new LoanProductTestBuilder().build(null));
+ final Integer loanID = applyForLoanApplication(clientID, loanProductID, proposedAmount);
+
+ HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
+ LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
+
+ final String expectedDisbursementDate = null;
+ List<HashMap> approveTranches = null;
+ loanStatusHashMap = this.loanTransactionHelper.approveLoanWithApproveAmount(approveDate, expectedDisbursementDate, approvalAmount,
+ loanID, approveTranches);
+ LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
+
+ }
+
+ /*
+ * Negative test case: Approved amount non zero is greater than proposed
+ * amount
+ */
+ @Test
+ public void loanApplicationApprovedAmountGreaterThanProposedAmount() {
+
+ final String proposedAmount = "5000";
+ final String approvalAmount = "9000";
+ final String approveDate = "20 September 2011";
+
+ final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2012");
+ final Integer loanProductID = this.loanTransactionHelper.getLoanProductId(new LoanProductTestBuilder().build(null));
+ final Integer loanID = applyForLoanApplication(clientID, loanProductID, proposedAmount);
+
+ HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
+ LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
+
+ this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpecForStatusCode403);
+
+ @SuppressWarnings("unchecked")
+ List<HashMap> error = (List<HashMap>) this.loanTransactionHelper.approveLoan(approveDate, approvalAmount, loanID,
+ CommonConstants.RESPONSE_ERROR);
+
+ assertEquals("error.msg.loan.approval.amount.can't.be.greater.than.loan.amount.demanded",
+ error.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
+
+ }
+
+ public HashMap createTrancheDetail(final String date, final String amount) {
+ HashMap<String, Object> detail = new HashMap<>();
+ detail.put("expectedDisbursementDate", date);
+ detail.put("principal", amount);
+
+ return detail;
+ }
+
+ @Test
+ public void loanApplicationApprovalAndValidationForMultiDisburseLoans() {
+
+ List<HashMap> createTranches = new ArrayList<>();
+ createTranches.add(createTrancheDetail("1 March 2014", "1000"));
+ createTranches.add(createTrancheDetail("23 March 2014", "4000"));
+
+ final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2014");
+ System.out.println("---------------------------------CLIENT CREATED WITH ID---------------------------------------------------"
+ + clientID);
+
+ final Integer loanProductID = this.loanTransactionHelper.getLoanProductId(new LoanProductTestBuilder()
+ .withInterestTypeAsDecliningBalance().withTranches(true).withInterestCalculationPeriodTypeAsRepaymentPeriod(true)
+ .build(null));
+ System.out.println("----------------------------------LOAN PRODUCT CREATED WITH ID-------------------------------------------"
+ + loanProductID);
+
+ this.trancheLoansApprovedAmountLesserThanProposedAmount(clientID, loanProductID, createTranches);
+ this.trancheLoansApprovalValidation(clientID, loanProductID, createTranches);
+
+ }
+
+ private void trancheLoansApprovedAmountLesserThanProposedAmount(Integer clientID, Integer loanProductID, List<HashMap> createTranches) {
+ final String proposedAmount = "5000";
+ final String approvalAmount = "2000";
+ final String approveDate = "1 March 2014";
+ final String expectedDisbursementDate = "1 March 2014";
+
+ List<HashMap> approveTranches = new ArrayList<>();
+ approveTranches.add(createTrancheDetail("1 March 2014", "1000"));
+ approveTranches.add(createTrancheDetail("23 March 2014", "1000"));
+
+ final Integer loanID = applyForLoanApplicationWithTranches(clientID, loanProductID, proposedAmount, createTranches);
+ System.out.println("-----------------------------------LOAN CREATED WITH LOANID-------------------------------------------------"
+ + loanID);
+
+ HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
+ LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
+
+ System.out.println("-----------------------------------APPROVE LOAN-----------------------------------------------------------");
+ loanStatusHashMap = this.loanTransactionHelper.approveLoanWithApproveAmount(approveDate, expectedDisbursementDate, approvalAmount,
+ loanID, approveTranches);
+ LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
+ LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
+ System.out
+ .println("-----------------------------------MULTI DISBURSAL LOAN APPROVED SUCCESSFULLY---------------------------------------");
+
+ }
+
+ private void trancheLoansApprovalValidation(Integer clientID, Integer loanProductID, List<HashMap> createTranches) {
+ final String proposedAmount = "5000";
+ final String approvalAmount1 = "10000";
+ final String approvalAmount2 = "3000";
+ final String approvalAmount3 = "400";
+ final String approvalAmount4 = "200";
+
+ final String approveDate = "1 March 2014";
+ final String expectedDisbursementDate = "1 March 2014";
+
+ List<HashMap> approveTranche1 = new ArrayList<>();
+ approveTranche1.add(createTrancheDetail("1 March 2014", "5000"));
+ approveTranche1.add(createTrancheDetail("23 March 2014", "5000"));
+
+ List<HashMap> approveTranche2 = new ArrayList<>();
+ approveTranche2.add(createTrancheDetail("1 March 2014", "1000"));
+ approveTranche2.add(createTrancheDetail("23 March 2014", "1000"));
+ approveTranche2.add(createTrancheDetail("23 March 2014", "1000"));
+
+ List<HashMap> approveTranche3 = new ArrayList<>();
+ approveTranche3.add(createTrancheDetail("1 March 2014", "100"));
+ approveTranche3.add(createTrancheDetail("23 March 2014", "100"));
+ approveTranche3.add(createTrancheDetail("24 March 2014", "100"));
+ approveTranche3.add(createTrancheDetail("25 March 2014", "100"));
+
+ List<HashMap> approveTranche4 = new ArrayList<>();
+ approveTranche4.add(createTrancheDetail("1 March 2014", "100"));
+ approveTranche4.add(createTrancheDetail("23 March 2014", "100"));
+ approveTranche4.add(createTrancheDetail("24 March 2014", "100"));
+
+ final Integer loanID = applyForLoanApplicationWithTranches(clientID, loanProductID, proposedAmount, createTranches);
+ System.out.println("-----------------------------------LOAN CREATED WITH LOANID-------------------------------------------------"
+ + loanID);
+
+ HashMap<String, Object> loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
+ LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
+
+ System.out.println("-----------------------------------APPROVE LOAN-----------------------------------------------------------");
+ this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpecForStatusCode400);
+
+ /* Tranches with same expected disbursement date */
+ List<HashMap<String, Object>> error = this.loanTransactionHelper.approveLoanForTranches(approveDate, expectedDisbursementDate,
+ approvalAmount2, loanID, approveTranche2, CommonConstants.RESPONSE_ERROR);
+ assertEquals("validation.msg.loan.expectedDisbursementDate.disbursement.date.must.be.unique.for.tranches",
+ error.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
+
+ /* Sum of tranches is greater than approved amount */
+ error = this.loanTransactionHelper.approveLoanForTranches(approveDate, expectedDisbursementDate, approvalAmount4, loanID,
+ approveTranche4, CommonConstants.RESPONSE_ERROR);
+ assertEquals("validation.msg.loan.principal.sum.of.multi.disburse.amounts.must.be.equal.to.or.lesser.than.approved.principal",
+ error.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
+
+ this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpecForStatusCode403);
+
+ /* Sum of tranches exceeds the proposed amount */
+ error = this.loanTransactionHelper.approveLoanForTranches(approveDate, expectedDisbursementDate, approvalAmount1, loanID,
+ approveTranche1, CommonConstants.RESPONSE_ERROR);
+ assertEquals("error.msg.loan.approval.amount.can't.be.greater.than.loan.amount.demanded",
+ error.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
+
+ /* No. of tranches exceeds the max tranche count at product level */
+ error = this.loanTransactionHelper.approveLoanForTranches(approveDate, expectedDisbursementDate, approvalAmount3, loanID,
+ approveTranche3, CommonConstants.RESPONSE_ERROR);
+ assertEquals("error.msg.disbursementData.exceeding.max.tranche.count", error.get(0)
+ .get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
+
+ /* If tranches are not specified for a multi-disburse loan */
+ /**
+ * error =
+ * this.loanTransactionHelper.approveLoanForTranches(approveDate,
+ * expectedDisbursementDate, approvalAmount5, loanID, approveTranche5,
+ * CommonConstants.RESPONSE_ERROR);
+ * assertEquals("error.msg.disbursementData.required",
+ * error.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
+ **/
+ }
+
+ private Integer applyForLoanApplication(final Integer clientID, final Integer loanProductID, final String proposedAmount) {
+ final String loanApplication = new LoanApplicationTestBuilder().withPrincipal(proposedAmount).withLoanTermFrequency("5")
+ .withLoanTermFrequencyAsMonths().withNumberOfRepayments("5").withRepaymentEveryAfter("1")
+ .withRepaymentFrequencyTypeAsMonths().withInterestRatePerPeriod("2").withExpectedDisbursementDate("04 April 2012")
+ .withSubmittedOnDate("02 April 2012").build(clientID.toString(), loanProductID.toString(), null);
+ return this.loanTransactionHelper.getLoanId(loanApplication);
+ }
+
+ public Integer applyForLoanApplicationWithTranches(final Integer clientID, final Integer loanProductID, String principal,
+ List<HashMap> tranches) {
+ System.out.println("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
+ final String loanApplicationJSON = new LoanApplicationTestBuilder()
+ //
+ .withPrincipal(principal)
+ //
+ .withLoanTermFrequency("5")
+ //
+ .withLoanTermFrequencyAsMonths()
+ //
+ .withNumberOfRepayments("5").withRepaymentEveryAfter("1").withRepaymentFrequencyTypeAsMonths() //
+ .withInterestRatePerPeriod("2") //
+ .withExpectedDisbursementDate("1 March 2014") //
+ .withTranches(tranches) //
+ .withInterestTypeAsDecliningBalance() //
+ .withSubmittedOnDate("1 March 2014") //
+ .build(clientID.toString(), loanProductID.toString(), null);
+
+ return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/4b1ec9ef/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanApplicationUndoLastTrancheTest.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanApplicationUndoLastTrancheTest.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanApplicationUndoLastTrancheTest.java
new file mode 100644
index 0000000..672972e
--- /dev/null
+++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanApplicationUndoLastTrancheTest.java
@@ -0,0 +1,157 @@
+/**
+ * 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.integrationtests;
+
+import java.math.BigDecimal;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.fineract.integrationtests.LoanApplicationApprovalTest;
+import org.apache.fineract.integrationtests.common.ClientHelper;
+import org.apache.fineract.integrationtests.common.Utils;
+import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder;
+import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
+import org.apache.fineract.integrationtests.common.loans.LoanStatusChecker;
+import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.jayway.restassured.builder.RequestSpecBuilder;
+import com.jayway.restassured.builder.ResponseSpecBuilder;
+import com.jayway.restassured.http.ContentType;
+import com.jayway.restassured.specification.RequestSpecification;
+import com.jayway.restassured.specification.ResponseSpecification;
+
+@SuppressWarnings("rawtypes")
+public class LoanApplicationUndoLastTrancheTest {
+
+ private ResponseSpecification responseSpec;
+ private RequestSpecification requestSpec;
+ private LoanTransactionHelper loanTransactionHelper;
+ private LoanApplicationApprovalTest loanApplicationApprovalTest;
+
+ @Before
+ public void setup() {
+ Utils.initializeRESTAssured();
+ this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
+ this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
+ this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
+ this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
+ this.loanApplicationApprovalTest = new LoanApplicationApprovalTest();
+ }
+
+ @Test
+ public void LoanApplicationUndoLastTranche() {
+
+ final String proposedAmount = "5000";
+ final String approvalAmount = "2000";
+ final String approveDate = "1 March 2014";
+ final String expectedDisbursementDate = "1 March 2014";
+ final String disbursalDate = "1 March 2014";
+
+ // CREATE CLIENT
+ final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2014");
+ System.out.println("---------------------------------CLIENT CREATED WITH ID---------------------------------------------------"
+ + clientID);
+
+ // CREATE LOAN MULTIDISBURSAL PRODUCT
+ final Integer loanProductID = this.loanTransactionHelper.getLoanProductId(new LoanProductTestBuilder()
+ .withInterestTypeAsDecliningBalance().withTranches(true).withInterestCalculationPeriodTypeAsRepaymentPeriod(true)
+ .build(null));
+ System.out.println("----------------------------------LOAN PRODUCT CREATED WITH ID-------------------------------------------"
+ + loanProductID);
+
+ // CREATE TRANCHES
+ List<HashMap> createTranches = new ArrayList<>();
+ createTranches.add(this.loanApplicationApprovalTest.createTrancheDetail("1 March 2014", "1000"));
+ createTranches.add(this.loanApplicationApprovalTest.createTrancheDetail("23 June 2014", "4000"));
+
+ // APPROVE TRANCHES
+ List<HashMap> approveTranches = new ArrayList<>();
+ approveTranches.add(this.loanApplicationApprovalTest.createTrancheDetail("1 March 2014", "1000"));
+ approveTranches.add(this.loanApplicationApprovalTest.createTrancheDetail("23 June 2014", "1000"));
+
+ // APPLY FOR LOAN WITH TRANCHES
+ final Integer loanID = applyForLoanApplicationWithTranches(clientID, loanProductID, proposedAmount, createTranches);
+ System.out.println("-----------------------------------LOAN CREATED WITH LOANID-------------------------------------------------"
+ + loanID);
+ HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
+
+ // VALIDATE THE LOAN STATUS
+ LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
+
+ System.out.println("-----------------------------------APPROVE LOAN-----------------------------------------------------------");
+ loanStatusHashMap = this.loanTransactionHelper.approveLoanWithApproveAmount(approveDate, expectedDisbursementDate, approvalAmount,
+ loanID, approveTranches);
+
+ // VALIDATE THE LOAN IS APPROVED
+ LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
+ LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
+
+ // DISBURSE A LOAN
+ this.loanTransactionHelper.disburseLoan(disbursalDate, loanID);
+ loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
+
+ // VALIDATE THE LOAN IS ACTIVE STATUS
+ LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
+
+ System.out.println("-------------Make repayment 1-----------");
+ this.loanTransactionHelper.makeRepayment("01 April 2014", Float.valueOf("420"), loanID);
+ System.out.println("-------------Make repayment 2-----------");
+ this.loanTransactionHelper.makeRepayment("01 May 2014", Float.valueOf("412"), loanID);
+ System.out.println("-------------Make repayment 3-----------");
+ this.loanTransactionHelper.makeRepayment("01 June 2014", Float.valueOf("204"), loanID);
+ // DISBURSE A SECOND TRANCHE
+ this.loanTransactionHelper.disburseLoan("23 June 2014", loanID);
+ // UNDO LAST TRANCHE
+ Float disbursedAmount = this.loanTransactionHelper.undoLastDisbursal(loanID);
+ validateDisbursedAmount(disbursedAmount);
+ }
+
+ private void validateDisbursedAmount(Float disbursedAmount) {
+ Assert.assertEquals(Float.valueOf("1000.0"), disbursedAmount);
+
+ }
+
+ public Integer applyForLoanApplicationWithTranches(final Integer clientID, final Integer loanProductID, String principal,
+ List<HashMap> tranches) {
+ System.out.println("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
+ final String loanApplicationJSON = new LoanApplicationTestBuilder()
+ //
+ .withPrincipal(principal)
+ //
+ .withLoanTermFrequency("5")
+ //
+ .withLoanTermFrequencyAsMonths()
+ //
+ .withNumberOfRepayments("5").withRepaymentEveryAfter("1").withRepaymentFrequencyTypeAsMonths() //
+ .withInterestRatePerPeriod("2") //
+ .withExpectedDisbursementDate("1 March 2014") //
+ .withTranches(tranches) //
+ .withInterestTypeAsDecliningBalance() //
+ .withSubmittedOnDate("1 March 2014") //
+ .build(clientID.toString(), loanProductID.toString(), null);
+
+ return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/4b1ec9ef/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanDisbursementDetailsIntegrationTest.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanDisbursementDetailsIntegrationTest.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanDisbursementDetailsIntegrationTest.java
new file mode 100644
index 0000000..cecac3d
--- /dev/null
+++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanDisbursementDetailsIntegrationTest.java
@@ -0,0 +1,501 @@
+/**
+ * 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.integrationtests;
+
+import static org.junit.Assert.assertEquals;
+
+import java.math.BigDecimal;
+import java.math.MathContext;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.fineract.integrationtests.common.ClientHelper;
+import org.apache.fineract.integrationtests.common.Utils;
+import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder;
+import org.apache.fineract.integrationtests.common.loans.LoanDisbursementTestBuilder;
+import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
+import org.apache.fineract.integrationtests.common.loans.LoanStatusChecker;
+import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.jayway.restassured.builder.RequestSpecBuilder;
+import com.jayway.restassured.builder.ResponseSpecBuilder;
+import com.jayway.restassured.http.ContentType;
+import com.jayway.restassured.specification.RequestSpecification;
+import com.jayway.restassured.specification.ResponseSpecification;
+
+@SuppressWarnings({ "rawtypes", "unchecked" })
+public class LoanDisbursementDetailsIntegrationTest {
+
+ private ResponseSpecification responseSpec;
+ private RequestSpecification requestSpec;
+ private LoanTransactionHelper loanTransactionHelper;
+ private Integer loanID;
+ private Integer disbursementId;
+ final String approveDate = "01 March 2014";
+ final String expectedDisbursementDate = "01 March 2014";
+ final String proposedAmount = "5000";
+ final String approvalAmount = "5000";
+
+ @Before
+ public void setup() {
+ Utils.initializeRESTAssured();
+ this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
+ this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
+ this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
+ this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
+ }
+
+ @Test
+ public void createAndValidateMultiDisburseLoansBasedOnEmi() {
+ List<HashMap> createTranches = new ArrayList<>();
+ String id = null;
+ String installmentAmount = "800";
+ String withoutInstallmentAmount = "";
+ String proposedAmount = "10000";
+ createTranches.add(this.loanTransactionHelper.createTrancheDetail(id, "01 June 2015", "5000"));
+ createTranches.add(this.loanTransactionHelper.createTrancheDetail(id, "01 Sep 2015", "5000"));
+
+ final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2014");
+ System.out.println("---------------------------------CLIENT CREATED WITH ID---------------------------------------------------"
+ + clientID);
+
+ final Integer loanProductID = this.loanTransactionHelper.getLoanProductId(new LoanProductTestBuilder()
+ .withInterestTypeAsDecliningBalance().withMoratorium("", "").withAmortizationTypeAsEqualInstallments().withTranches(true)
+ .withInterestCalculationPeriodTypeAsRepaymentPeriod(true).build(null));
+ System.out.println("----------------------------------LOAN PRODUCT CREATED WITH ID-------------------------------------------"
+ + loanProductID);
+
+ final Integer loanIDWithEmi = applyForLoanApplicationWithEmiAmount(clientID, loanProductID, proposedAmount, createTranches,
+ installmentAmount);
+
+ System.out
+ .println("-----------------------------------LOAN CREATED WITH EMI LOANID-------------------------------------------------"
+ + loanIDWithEmi);
+
+ HashMap repaymentScheduleWithEmi = (HashMap) this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec,
+ loanIDWithEmi, "repaymentSchedule");
+
+ ArrayList<HashMap> periods = (ArrayList<HashMap>) repaymentScheduleWithEmi.get("periods");
+ assertEquals(periods.size(), 15);
+
+ this.validateRepaymentScheduleWithEMI(periods);
+
+ HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanIDWithEmi);
+ LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
+
+ System.out.println("-----------------------------------APPROVE LOAN-----------------------------------------------------------");
+ loanStatusHashMap = this.loanTransactionHelper.approveLoanWithApproveAmount("01 June 2015", "01 June 2015", "10000", loanIDWithEmi,
+ createTranches);
+ LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
+ LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
+ System.out
+ .println("-----------------------------------MULTI DISBURSAL LOAN WITH EMI APPROVED SUCCESSFULLY---------------------------------------");
+
+ final Integer loanIDWithoutEmi = applyForLoanApplicationWithEmiAmount(clientID, loanProductID, proposedAmount, createTranches,
+ withoutInstallmentAmount);
+
+ HashMap repaymentScheduleWithoutEmi = (HashMap) this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec,
+ loanIDWithoutEmi, "repaymentSchedule");
+
+ ArrayList<HashMap> periods1 = (ArrayList<HashMap>) repaymentScheduleWithEmi.get("periods");
+ assertEquals(periods1.size(), 15);
+
+ System.out
+ .println("-----------------------------------LOAN CREATED WITHOUT EMI LOANID-------------------------------------------------"
+ + loanIDWithoutEmi);
+
+ /* To be uncommented once issue MIFOSX-2006 is closed. */
+ // this.validateRepaymentScheduleWithoutEMI(periods1);
+
+ HashMap loanStatusMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanIDWithoutEmi);
+ LoanStatusChecker.verifyLoanIsPending(loanStatusMap);
+
+ System.out.println("-----------------------------------APPROVE LOAN-----------------------------------------------------------");
+ loanStatusHashMap = this.loanTransactionHelper.approveLoanWithApproveAmount("01 June 2015", "01 June 2015", "10000",
+ loanIDWithoutEmi, createTranches);
+ LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
+ LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
+ System.out
+ .println("-----------------------------------MULTI DISBURSAL LOAN WITHOUT EMI APPROVED SUCCESSFULLY---------------------------------------");
+
+ }
+
+ private void validateRepaymentScheduleWithEMI(ArrayList<HashMap> periods) {
+ LoanDisbursementTestBuilder expectedRepaymentSchedule0 = new LoanDisbursementTestBuilder("[2015, 6, 1]", 0.0f, 0.0f, null, null,
+ 5000.0f, null, null, null);
+
+ LoanDisbursementTestBuilder expectedRepaymentSchedule1 = new LoanDisbursementTestBuilder("[2015, 7, 1]", 800f, 800.0f, 50.0f,
+ 750.0f, 4250.0f, 750.0f, 750.0f, "[2015, 6, 1]");
+
+ LoanDisbursementTestBuilder expectedRepaymentSchedule2 = new LoanDisbursementTestBuilder("[2015, 8, 1]", 800.0f, 800.0f, 42.5f,
+ 757.5f, 3492.5f, 757.5f, 757.5f, "[2015, 7, 1]");
+
+ LoanDisbursementTestBuilder expectedRepaymentSchedule3 = new LoanDisbursementTestBuilder("[2015, 9, 1]", 0.0f, 0.0f, null, null,
+ 5000.0f, null, null, null);
+
+ LoanDisbursementTestBuilder expectedRepaymentSchedule4 = new LoanDisbursementTestBuilder("[2015, 9, 1]", 800.0f, 800.0f, 34.92f,
+ 765.08f, 7727.42f, 765.08f, 765.08f, "[2015, 8, 1]");
+
+ LoanDisbursementTestBuilder expectedRepaymentSchedule5 = new LoanDisbursementTestBuilder("[2015, 10, 1]", 800.0f, 800.0f, 77.27f,
+ 722.73f, 7004.69f, 722.73f, 722.73f, "[2015, 9, 1]");
+
+ LoanDisbursementTestBuilder expectedRepaymentSchedule6 = new LoanDisbursementTestBuilder("[2015, 11, 1]", 800.0f, 800.0f, 70.05f,
+ 729.95f, 6274.74f, 729.95f, 729.95f, "[2015, 10, 1]");
+
+ LoanDisbursementTestBuilder expectedRepaymentSchedule7 = new LoanDisbursementTestBuilder("[2015, 12, 1]", 800.0f, 800.0f, 62.75f,
+ 737.25f, 5537.49f, 737.25f, 737.25f, "[2015, 11, 1]");
+
+ LoanDisbursementTestBuilder expectedRepaymentSchedule8 = new LoanDisbursementTestBuilder("[2016, 1, 1]", 800.0f, 800.0f, 55.37f,
+ 744.63f, 4792.86f, 744.63f, 744.63f, "[2015, 12, 1]");
+
+ LoanDisbursementTestBuilder expectedRepaymentSchedule9 = new LoanDisbursementTestBuilder("[2016, 2, 1]", 800.0f, 800.0f, 47.93f,
+ 752.07f, 4040.79f, 752.07f, 752.07f, "[2016, 1, 1]");
+
+ LoanDisbursementTestBuilder expectedRepaymentSchedule10 = new LoanDisbursementTestBuilder("[2016, 3, 1]", 800.0f, 800.0f, 40.41f,
+ 759.59f, 3281.2f, 759.59f, 759.59f, "[2016, 2, 1]");
+
+ LoanDisbursementTestBuilder expectedRepaymentSchedule11 = new LoanDisbursementTestBuilder("[2016, 4, 1]", 800.0f, 800.0f, 32.81f,
+ 767.19f, 2514.01f, 767.19f, 767.19f, "[2016, 3, 1]");
+
+ LoanDisbursementTestBuilder expectedRepaymentSchedule12 = new LoanDisbursementTestBuilder("[2016, 5, 1]", 800.0f, 800.0f, 25.14f,
+ 774.86f, 1739.15f, 774.86f, 774.86f, "[2016, 4, 1]");
+
+ LoanDisbursementTestBuilder expectedRepaymentSchedule13 = new LoanDisbursementTestBuilder("[2016, 6, 1]", 800.0f, 800.0f, 17.39f,
+ 782.61f, 956.54f, 782.61f, 782.61f, "[2016, 5, 1]");
+
+ LoanDisbursementTestBuilder expectedRepaymentSchedule14 = new LoanDisbursementTestBuilder("[2016, 7, 1]", 966.11f, 966.11f, 9.57f,
+ 956.54f, 0.0f, 956.54f, 956.54f, "[2016, 6, 1]");
+
+ ArrayList<LoanDisbursementTestBuilder> list = new ArrayList<LoanDisbursementTestBuilder>();
+ list.add(expectedRepaymentSchedule0);
+ list.add(expectedRepaymentSchedule1);
+ list.add(expectedRepaymentSchedule2);
+ list.add(expectedRepaymentSchedule3);
+ list.add(expectedRepaymentSchedule4);
+ list.add(expectedRepaymentSchedule5);
+ list.add(expectedRepaymentSchedule6);
+ list.add(expectedRepaymentSchedule7);
+ list.add(expectedRepaymentSchedule8);
+ list.add(expectedRepaymentSchedule9);
+ list.add(expectedRepaymentSchedule10);
+ list.add(expectedRepaymentSchedule11);
+ list.add(expectedRepaymentSchedule12);
+ list.add(expectedRepaymentSchedule13);
+ list.add(expectedRepaymentSchedule14);
+
+ for (int i = 0; i < list.size(); i++) {
+ this.assertRepaymentScheduleValuesWithEMI(periods.get(i), list.get(i), i);
+ }
+ }
+
+ private void assertRepaymentScheduleValuesWithEMI(HashMap period, LoanDisbursementTestBuilder expectedRepaymentSchedule, int position) {
+
+ assertEquals(period.get("dueDate").toString(), expectedRepaymentSchedule.getDueDate());
+ assertEquals(period.get("principalLoanBalanceOutstanding"), expectedRepaymentSchedule.getPrincipalLoanBalanceOutstanding());
+ System.out.println(period.get("totalOriginalDueForPeriod").toString());
+ assertEquals(new Float(period.get("totalOriginalDueForPeriod").toString()), expectedRepaymentSchedule
+ .getTotalOriginalDueForPeriod().floatValue(), 0.0f);
+
+ assertEquals(new Float(period.get("totalOutstandingForPeriod").toString()).floatValue(),
+ expectedRepaymentSchedule.getTotalOutstandingForPeriod(), 0.0f);
+
+ if (position != 0 && position != 3) {
+
+ assertEquals(new Float(period.get("interestOutstanding").toString()).floatValue(),
+ expectedRepaymentSchedule.getInterestOutstanding(), 0.0f);
+ assertEquals(new Float(period.get("principalOutstanding").toString()).floatValue(),
+ expectedRepaymentSchedule.getPrincipalOutstanding(), 0.0f);
+ assertEquals(new Float(period.get("principalDue").toString()).floatValue(), expectedRepaymentSchedule.getPrincipalDue(), 0.0f);
+ assertEquals(new Float(period.get("principalOriginalDue").toString()).floatValue(),
+ expectedRepaymentSchedule.getPrincipalOriginalDue(), 0.0f);
+ assertEquals(period.get("fromDate").toString(), expectedRepaymentSchedule.getFromDate());
+ }
+ }
+
+ /* Uncomment and modify test builder values once MIFOSX-2006 is closed. */
+ /*
+ * private void validateRepaymentScheduleWithoutEMI(ArrayList<HashMap>
+ * periods){ LoanDisbursementTestBuilder expectedRepaymentSchedule0 = new
+ * LoanDisbursementTestBuilder( "[2015, 6, 1]", 0.0f, 0.0f, null, null,
+ * 5000.0f, null, null, null);
+ *
+ * LoanDisbursementTestBuilder expectedRepaymentSchedule1 = new
+ * LoanDisbursementTestBuilder( "[2015, 7, 1]", 800.0f, 800.0f, 50.0f,
+ * 750.0f, 4250.0f, 750.0f, 750.0f, "[2015, 6, 1]");
+ *
+ * LoanDisbursementTestBuilder expectedRepaymentSchedule2 = new
+ * LoanDisbursementTestBuilder( "[2015, 8, 1]", 800.0f, 800.0f, 42.5f,
+ * 757.5f, 3492.5f, 757.5f, 757.5f, "[2015, 7, 1]");
+ *
+ * LoanDisbursementTestBuilder expectedRepaymentSchedule3 = new
+ * LoanDisbursementTestBuilder( "[2015, 9, 1]", 0.0f, 0.0f, null, null,
+ * 5000.0f, null, null, null);
+ *
+ * LoanDisbursementTestBuilder expectedRepaymentSchedule4 = new
+ * LoanDisbursementTestBuilder( "[2015, 9, 1]", 800.0f, 800.0f, 34.92f,
+ * 765.08f, 7727.42f, 765.08f, 765.08f, "[2015, 8, 1]");
+ *
+ * LoanDisbursementTestBuilder expectedRepaymentSchedule5 = new
+ * LoanDisbursementTestBuilder( "[2015, 10, 1]", 800.0f, 800.0f, 77.27f,
+ * 722.73f, 7004.69f, 722.73f, 722.73f, "[2015, 9, 1]");
+ *
+ * LoanDisbursementTestBuilder expectedRepaymentSchedule6 = new
+ * LoanDisbursementTestBuilder( "[2015, 11, 1]", 800.0f, 800.0f, 70.05f,
+ * 729.95f, 6274.74f, 729.95f, 729.95f, "[2015, 10, 1]");
+ *
+ * LoanDisbursementTestBuilder expectedRepaymentSchedule7 = new
+ * LoanDisbursementTestBuilder( "[2015, 12, 1]", 800.0f, 800.0f, 62.75f,
+ * 737.25f, 5537.49f, 737.25f, 737.25f, "[2015, 11, 1]");
+ *
+ * LoanDisbursementTestBuilder expectedRepaymentSchedule8 = new
+ * LoanDisbursementTestBuilder( "[2016, 1, 1]", 800.0f, 800.0f, 55.37f,
+ * 744.63f, 4792.86f, 744.63f, 744.63f, "[2015, 12, 1]");
+ *
+ * LoanDisbursementTestBuilder expectedRepaymentSchedule9 = new
+ * LoanDisbursementTestBuilder( "[2016, 2, 1]", 800.0f, 800.0f, 47.93f,
+ * 752.07f, 4040.79f, 752.07f, 752.07f, "[2016, 1, 1]");
+ *
+ * LoanDisbursementTestBuilder expectedRepaymentSchedule10 = new
+ * LoanDisbursementTestBuilder( "[2016, 3, 1]", 800.0f, 800.0f, 40.41f,
+ * 759.59f, 3281.2f, 759.59f, 759.59f, "[2016, 2, 1]");
+ *
+ * LoanDisbursementTestBuilder expectedRepaymentSchedule11 = new
+ * LoanDisbursementTestBuilder( "[2016, 4, 1]", 800.0f, 800.0f, 32.81f,
+ * 767.19f, 2514.01f, 767.19f, 767.19f, "[2016, 3, 1]");
+ *
+ * LoanDisbursementTestBuilder expectedRepaymentSchedule12 = new
+ * LoanDisbursementTestBuilder( "[2016, 5, 1]", 800.0f, 800.0f, 25.14f,
+ * 774.86f, 1739.15f, 774.86f, 774.86f, "[2016, 4, 1]");
+ *
+ * LoanDisbursementTestBuilder expectedRepaymentSchedule13 = new
+ * LoanDisbursementTestBuilder( "[2016, 6, 1]", 800.0f, 800.0f, 17.39f,
+ * 782.61f, 956.54f, 782.61f, 782.61f, "[2016, 5, 1]");
+ *
+ * LoanDisbursementTestBuilder expectedRepaymentSchedule14 = new
+ * LoanDisbursementTestBuilder( "[2016, 7, 1]", 966.11f, 966.11f, 9.57f,
+ * 956.54f, 0.0f, 956.54f, 956.54f, "[2016, 6, 1]");
+ *
+ * ArrayList<LoanDisbursementTestBuilder> list = new
+ * ArrayList<LoanDisbursementTestBuilder>();
+ * list.add(expectedRepaymentSchedule0);
+ * list.add(expectedRepaymentSchedule1);
+ * list.add(expectedRepaymentSchedule2);
+ * list.add(expectedRepaymentSchedule3);
+ * list.add(expectedRepaymentSchedule4);
+ * list.add(expectedRepaymentSchedule5);
+ * list.add(expectedRepaymentSchedule6);
+ * list.add(expectedRepaymentSchedule7);
+ * list.add(expectedRepaymentSchedule8);
+ * list.add(expectedRepaymentSchedule9);
+ * list.add(expectedRepaymentSchedule10);
+ * list.add(expectedRepaymentSchedule11);
+ * list.add(expectedRepaymentSchedule12);
+ * list.add(expectedRepaymentSchedule13);
+ * list.add(expectedRepaymentSchedule14);
+ *
+ * for (int i = 0; i < list.size(); i++) {
+ * this.assertRepaymentScheduleValuesWithoutEMI(periods.get(i), list.get(i),
+ * i); } }
+ *
+ * private void assertRepaymentScheduleValuesWithoutEMI(HashMap period,
+ * LoanDisbursementTestBuilder expectedRepaymentSchedule, int position) {
+ *
+ * assertEquals(period.get("dueDate").toString(),
+ * expectedRepaymentSchedule.getDueDate());
+ * assertEquals(period.get("principalLoanBalanceOutstanding"),
+ * expectedRepaymentSchedule.getPrincipalLoanBalanceOutstanding());
+ * assertEquals(period.get("totalOriginalDueForPeriod"),
+ * expectedRepaymentSchedule.getTotalOriginalDueForPeriod());
+ * assertEquals(period.get("totalOutstandingForPeriod"),
+ * expectedRepaymentSchedule.getTotalOutstandingForPeriod());
+ *
+ * if (position != 0 && position != 3) {
+ *
+ * assertEquals(period.get("interestOutstanding"),
+ * expectedRepaymentSchedule.getInterestOutstanding());
+ * assertEquals(period.get("principalOutstanding"),
+ * expectedRepaymentSchedule.getPrincipalOutstanding());
+ * assertEquals(period.get("principalDue"),
+ * expectedRepaymentSchedule.getPrincipalDue());
+ * assertEquals(period.get("principalOriginalDue"),
+ * expectedRepaymentSchedule.getPrincipalOriginalDue());
+ * assertEquals(period.get("fromDate").toString(),
+ * expectedRepaymentSchedule.getFromDate()); } }
+ */
+ private Integer applyForLoanApplicationWithEmiAmount(final Integer clientID, final Integer loanProductID, final String proposedAmount,
+ List<HashMap> tranches, final String installmentAmount) {
+
+ System.out.println("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
+ final String loanApplicationJSON = new LoanApplicationTestBuilder()
+ //
+ .withPrincipal(proposedAmount)
+ //
+ .withLoanTermFrequency("12")
+ //
+ .withLoanTermFrequencyAsMonths()
+ //
+ .withNumberOfRepayments("12").withRepaymentEveryAfter("1").withRepaymentFrequencyTypeAsMonths() //
+ .withInterestRatePerPeriod("1") //
+ .withExpectedDisbursementDate("01 June 2015") //
+ .withTranches(tranches) //
+ .withFixedEmiAmount(installmentAmount) //
+ .withInterestTypeAsDecliningBalance() //
+ .withSubmittedOnDate("01 June 2015") //
+ .withAmortizationTypeAsEqualInstallments() //
+ .build(clientID.toString(), loanProductID.toString(), null);
+
+ return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
+
+ }
+
+ @Test
+ public void createApproveAndValidateMultiDisburseLoan() {
+
+ List<HashMap> createTranches = new ArrayList<>();
+ String id = null;
+ createTranches.add(this.loanTransactionHelper.createTrancheDetail(id, "01 March 2014", "1000"));
+
+ final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2014");
+ System.out.println("---------------------------------CLIENT CREATED WITH ID---------------------------------------------------"
+ + clientID);
+
+ final Integer loanProductID = this.loanTransactionHelper.getLoanProductId(new LoanProductTestBuilder()
+ .withInterestTypeAsDecliningBalance().withTranches(true).withInterestCalculationPeriodTypeAsRepaymentPeriod(true)
+ .build(null));
+ System.out.println("----------------------------------LOAN PRODUCT CREATED WITH ID-------------------------------------------"
+ + loanProductID);
+
+ this.loanID = applyForLoanApplicationWithTranches(clientID, loanProductID, proposedAmount, createTranches);
+ System.out.println("-----------------------------------LOAN CREATED WITH LOANID-------------------------------------------------"
+ + loanID);
+
+ HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
+ LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
+
+ System.out.println("-----------------------------------APPROVE LOAN-----------------------------------------------------------");
+ loanStatusHashMap = this.loanTransactionHelper.approveLoanWithApproveAmount(approveDate, expectedDisbursementDate, approvalAmount,
+ loanID, createTranches);
+ LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
+ LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
+ System.out
+ .println("-----------------------------------MULTI DISBURSAL LOAN APPROVED SUCCESSFULLY---------------------------------------");
+ ArrayList<HashMap> disbursementDetails = (ArrayList<HashMap>) this.loanTransactionHelper.getLoanDetail(this.requestSpec,
+ this.responseSpec, this.loanID, "disbursementDetails");
+ this.disbursementId = (Integer) disbursementDetails.get(0).get("id");
+ this.editLoanDisbursementDetails();
+ }
+
+ private void editLoanDisbursementDetails() {
+ this.editDateAndPrincipalOfExistingTranche();
+ this.addNewDisbursementDetails();
+ this.deleteDisbursmentDetails();
+ }
+
+ private void addNewDisbursementDetails() {
+ List<HashMap> addTranches = new ArrayList<>();
+ ArrayList<HashMap> disbursementDetails = (ArrayList<HashMap>) this.loanTransactionHelper.getLoanDetail(this.requestSpec,
+ this.responseSpec, this.loanID, "disbursementDetails");
+ ArrayList expectedDisbursementDate = (ArrayList) disbursementDetails.get(0).get("expectedDisbursementDate");
+ String date = formatExpectedDisbursementDate(expectedDisbursementDate.toString());
+
+ String id = null;
+ addTranches.add(this.loanTransactionHelper.createTrancheDetail(disbursementDetails.get(0).get("id").toString(), date,
+ disbursementDetails.get(0).get("principal").toString()));
+ addTranches.add(this.loanTransactionHelper.createTrancheDetail(id, "3 March 2014", "2000"));
+ addTranches.add(this.loanTransactionHelper.createTrancheDetail(id, "4 March 2014", "500"));
+
+ /* Add disbursement detail */
+ this.loanTransactionHelper.addAndDeleteDisbursementDetail(this.loanID, this.approvalAmount, this.expectedDisbursementDate,
+ addTranches, "");
+ }
+
+ private void deleteDisbursmentDetails() {
+ List<HashMap> deleteTranches = new ArrayList<>();
+ ArrayList<HashMap> disbursementDetails = (ArrayList<HashMap>) this.loanTransactionHelper.getLoanDetail(this.requestSpec,
+ this.responseSpec, this.loanID, "disbursementDetails");
+ /* Delete the last tranche */
+ for (int i = 0; i < disbursementDetails.size() - 1; i++) {
+ ArrayList expectedDisbursementDate = (ArrayList) disbursementDetails.get(i).get("expectedDisbursementDate");
+ String disbursementDate = formatExpectedDisbursementDate(expectedDisbursementDate.toString());
+ deleteTranches.add(this.loanTransactionHelper.createTrancheDetail(disbursementDetails.get(i).get("id").toString(),
+ disbursementDate, disbursementDetails.get(i).get("principal").toString()));
+ }
+
+ /* Add disbursement detail */
+ this.loanTransactionHelper.addAndDeleteDisbursementDetail(this.loanID, this.approvalAmount, this.expectedDisbursementDate,
+ deleteTranches, "");
+ }
+
+ private void editDateAndPrincipalOfExistingTranche() {
+ String updatedExpectedDisbursementDate = "01 March 2014";
+ String updatedPrincipal = "900";
+ /* Update */
+ this.loanTransactionHelper.editDisbursementDetail(this.loanID, this.disbursementId, this.approvalAmount,
+ this.expectedDisbursementDate, updatedExpectedDisbursementDate, updatedPrincipal, "");
+ /* Validate Edit */
+ ArrayList<HashMap> disbursementDetails = (ArrayList<HashMap>) this.loanTransactionHelper.getLoanDetail(this.requestSpec,
+ this.responseSpec, this.loanID, "disbursementDetails");
+ assertEquals(Float.valueOf(updatedPrincipal), disbursementDetails.get(0).get("principal"));
+ ArrayList expectedDisbursementDate = (ArrayList) disbursementDetails.get(0).get("expectedDisbursementDate");
+ String date = formatExpectedDisbursementDate(expectedDisbursementDate.toString());
+ assertEquals(updatedExpectedDisbursementDate, date);
+
+ }
+
+ private String formatExpectedDisbursementDate(String expectedDisbursementDate) {
+
+ SimpleDateFormat source = new SimpleDateFormat("[yyyy, MM, dd]");
+ SimpleDateFormat target = new SimpleDateFormat("dd MMMM yyyy");
+ String date = null;
+ try {
+ date = target.format(source.parse(expectedDisbursementDate));
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ return date;
+ }
+
+ private Integer applyForLoanApplicationWithTranches(final Integer clientID, final Integer loanProductID, String principal,
+ List<HashMap> tranches) {
+ System.out.println("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
+ final String loanApplicationJSON = new LoanApplicationTestBuilder()
+ //
+ .withPrincipal(principal)
+ //
+ .withLoanTermFrequency("5")
+ //
+ .withLoanTermFrequencyAsMonths()
+ //
+ .withNumberOfRepayments("5").withRepaymentEveryAfter("1").withRepaymentFrequencyTypeAsMonths() //
+ .withInterestRatePerPeriod("2") //
+ .withExpectedDisbursementDate("01 March 2014") //
+ .withTranches(tranches) //
+ .withInterestTypeAsDecliningBalance() //
+ .withSubmittedOnDate("01 March 2014") //
+ .build(clientID.toString(), loanProductID.toString(), null);
+
+ return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/4b1ec9ef/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanRepaymentRescheduleAtDisbursementTest.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanRepaymentRescheduleAtDisbursementTest.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanRepaymentRescheduleAtDisbursementTest.java
new file mode 100644
index 0000000..d0018cd
--- /dev/null
+++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanRepaymentRescheduleAtDisbursementTest.java
@@ -0,0 +1,241 @@
+/**
+ * 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.integrationtests;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.fineract.integrationtests.common.ClientHelper;
+import org.apache.fineract.integrationtests.common.Utils;
+import org.apache.fineract.integrationtests.common.accounting.Account;
+import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder;
+import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
+import org.apache.fineract.integrationtests.common.loans.LoanStatusChecker;
+import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.jayway.restassured.builder.RequestSpecBuilder;
+import com.jayway.restassured.builder.ResponseSpecBuilder;
+import com.jayway.restassured.http.ContentType;
+import com.jayway.restassured.specification.RequestSpecification;
+import com.jayway.restassured.specification.ResponseSpecification;
+
+@SuppressWarnings("rawtypes")
+public class LoanRepaymentRescheduleAtDisbursementTest {
+
+ private ResponseSpecification responseSpec;
+ private RequestSpecification requestSpec;
+ private LoanTransactionHelper loanTransactionHelper;
+ private LoanApplicationApprovalTest loanApplicationApprovalTest;
+ private ResponseSpecification generalResponseSpec;
+
+ @Before
+ public void setup() {
+ Utils.initializeRESTAssured();
+ this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
+ this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
+ this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
+ this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
+ this.loanApplicationApprovalTest = new LoanApplicationApprovalTest();
+ this.generalResponseSpec = new ResponseSpecBuilder().build();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testLoanRepaymentRescheduleAtDisbursement(){
+
+ final String approvalAmount = "10000";
+ final String approveDate = "01 March 2015";
+ final String expectedDisbursementDate = "01 March 2015";
+ final String disbursementDate = "01 March 2015";
+ final String adjustRepaymentDate = "16 March 2015";
+ final String recalculationRestFrequencyDate = "01 January 2012";
+
+ // CREATE CLIENT
+ final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2014");
+ System.out.println("---------------------------------CLIENT CREATED WITH ID---------------------------------------------------"
+ + clientID);
+
+ // CREATE LOAN MULTIDISBURSAL PRODUCT WITH INTEREST RECALCULATION
+ final Integer loanProductID = createLoanProductWithInterestRecalculation(LoanProductTestBuilder.RBI_INDIA_STRATEGY,
+ LoanProductTestBuilder.RECALCULATION_COMPOUNDING_METHOD_NONE,
+ LoanProductTestBuilder.RECALCULATION_STRATEGY_REDUCE_NUMBER_OF_INSTALLMENTS,
+ LoanProductTestBuilder.RECALCULATION_FREQUENCY_TYPE_DAILY, "0", recalculationRestFrequencyDate,
+ LoanProductTestBuilder.INTEREST_APPLICABLE_STRATEGY_ON_PRE_CLOSE_DATE, null);
+
+ // CREATE TRANCHES
+ List<HashMap> createTranches = new ArrayList<>();
+ createTranches.add(this.loanApplicationApprovalTest.createTrancheDetail("01 March 2015", "5000"));
+ createTranches.add(this.loanApplicationApprovalTest.createTrancheDetail("01 May 2015", "5000"));
+
+ // APPROVE TRANCHES
+ List<HashMap> approveTranches = new ArrayList<>();
+ approveTranches.add(this.loanApplicationApprovalTest.createTrancheDetail("01 March 2015", "5000"));
+ approveTranches.add(this.loanApplicationApprovalTest.createTrancheDetail("01 May 2015", "5000"));
+
+ // APPLY FOR TRANCHE LOAN WITH INTEREST RECALCULATION
+ final Integer loanID = applyForLoanApplicationForInterestRecalculation(clientID, loanProductID, disbursementDate,
+ recalculationRestFrequencyDate, LoanApplicationTestBuilder.RBI_INDIA_STRATEGY, new ArrayList<HashMap>(0), createTranches);
+
+ HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
+
+ // VALIDATE THE LOAN STATUS
+ LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
+
+ System.out.println("-----------------------------------APPROVE LOAN-----------------------------------------------------------");
+ loanStatusHashMap = this.loanTransactionHelper.approveLoanWithApproveAmount(approveDate, expectedDisbursementDate, approvalAmount,
+ loanID, approveTranches);
+
+ // VALIDATE THE LOAN IS APPROVED
+ LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
+ LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
+
+ // DISBURSE A FIRST TRANCHE
+ this.loanTransactionHelper.disburseLoanWithRepaymentReschedule(disbursementDate, loanID, adjustRepaymentDate);
+ loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
+
+ ArrayList<HashMap> loanRepaymnetSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(requestSpec, generalResponseSpec, loanID);
+ HashMap firstInstallement = loanRepaymnetSchedule.get(1);
+ Map<String, Object> expectedvalues = new HashMap<>(3);
+ Calendar date = Calendar.getInstance(Utils.getTimeZoneOfTenant());
+ date.set(2015, Calendar.MARCH, 16);
+ expectedvalues.put("dueDate", getDateAsArray(date, 0));
+ expectedvalues.put("principalDue", "834.71");
+ expectedvalues.put("interestDue", "49.32");
+ expectedvalues.put("feeChargesDue", "0");
+ expectedvalues.put("penaltyChargesDue", "0");
+ expectedvalues.put("totalDueForPeriod", "884.03");
+
+ // VALIDATE REPAYMENT SCHEDULE
+ verifyLoanRepaymentSchedule(firstInstallement, expectedvalues);
+
+ }
+
+ private void verifyLoanRepaymentSchedule(final HashMap firstInstallement, final Map<String, Object> expectedvalues) {
+
+ assertEquals(expectedvalues.get("dueDate"), firstInstallement.get("dueDate"));
+ assertEquals(String.valueOf(expectedvalues.get("principalDue")), String.valueOf(firstInstallement.get("principalDue")));
+ assertEquals(String.valueOf(expectedvalues.get("interestDue")), String.valueOf(firstInstallement.get("interestDue")));
+ assertEquals(String.valueOf(expectedvalues.get("feeChargesDue")), String.valueOf(firstInstallement.get("feeChargesDue")));
+ assertEquals(String.valueOf(expectedvalues.get("penaltyChargesDue")), String.valueOf(firstInstallement.get("penaltyChargesDue")));
+ assertEquals(String.valueOf(expectedvalues.get("totalDueForPeriod")), String.valueOf(firstInstallement.get("totalDueForPeriod")));
+
+ }
+
+ private Integer createLoanProductWithInterestRecalculation(final String repaymentStrategy,
+ final String interestRecalculationCompoundingMethod, final String rescheduleStrategyMethod,
+ final String recalculationRestFrequencyType, final String recalculationRestFrequencyInterval,
+ final String recalculationRestFrequencyDate, final String preCloseInterestCalculationStrategy, final Account[] accounts) {
+ final String recalculationCompoundingFrequencyType = null;
+ final String recalculationCompoundingFrequencyInterval = null;
+ final String recalculationCompoundingFrequencyDate = null;
+ return createLoanProductWithInterestRecalculation(repaymentStrategy, interestRecalculationCompoundingMethod,
+ rescheduleStrategyMethod, recalculationRestFrequencyType, recalculationRestFrequencyInterval,
+ recalculationRestFrequencyDate, recalculationCompoundingFrequencyType, recalculationCompoundingFrequencyInterval,
+ recalculationCompoundingFrequencyDate, preCloseInterestCalculationStrategy, accounts, null, false);
+ }
+
+ private Integer createLoanProductWithInterestRecalculation(final String repaymentStrategy,
+ final String interestRecalculationCompoundingMethod, final String rescheduleStrategyMethod,
+ final String recalculationRestFrequencyType, final String recalculationRestFrequencyInterval,
+ final String recalculationRestFrequencyDate, final String recalculationCompoundingFrequencyType,
+ final String recalculationCompoundingFrequencyInterval, final String recalculationCompoundingFrequencyDate,
+ final String preCloseInterestCalculationStrategy, final Account[] accounts, final String chargeId,
+ boolean isArrearsBasedOnOriginalSchedule) {
+ System.out.println("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------");
+ LoanProductTestBuilder builder = new LoanProductTestBuilder()
+ .withPrincipal("10000.00")
+ .withNumberOfRepayments("12")
+ .withRepaymentAfterEvery("2")
+ .withRepaymentTypeAsWeek()
+ .withinterestRatePerPeriod("2")
+ .withInterestRateFrequencyTypeAsMonths()
+ .withTranches(true)
+ .withInterestCalculationPeriodTypeAsRepaymentPeriod(true)
+ .withRepaymentStrategy(repaymentStrategy)
+ .withInterestTypeAsDecliningBalance()
+ .withInterestRecalculationDetails(interestRecalculationCompoundingMethod, rescheduleStrategyMethod,
+ preCloseInterestCalculationStrategy)
+ .withInterestRecalculationRestFrequencyDetails(recalculationRestFrequencyType, recalculationRestFrequencyInterval,
+ recalculationRestFrequencyDate)
+ .withInterestRecalculationCompoundingFrequencyDetails(recalculationCompoundingFrequencyType,
+ recalculationCompoundingFrequencyInterval, recalculationCompoundingFrequencyDate);
+ if (accounts != null) {
+ builder = builder.withAccountingRulePeriodicAccrual(accounts);
+ }
+
+ if (isArrearsBasedOnOriginalSchedule) builder = builder.withArrearsConfiguration();
+
+ final String loanProductJSON = builder.build(chargeId);
+ return this.loanTransactionHelper.getLoanProductId(loanProductJSON);
+ }
+
+ private Integer applyForLoanApplicationForInterestRecalculation(final Integer clientID, final Integer loanProductID,
+ final String disbursementDate, final String restStartDate, final String repaymentStrategy, final List<HashMap> charges, List<HashMap> tranches) {
+ final String graceOnInterestPayment = null;
+ final String compoundingStartDate = null;
+ final String graceOnPrincipalPayment = null;
+ return applyForLoanApplicationForInterestRecalculation(clientID, loanProductID, disbursementDate, restStartDate,
+ compoundingStartDate, repaymentStrategy, charges, graceOnInterestPayment, graceOnPrincipalPayment,tranches);
+ }
+
+ private Integer applyForLoanApplicationForInterestRecalculation(final Integer clientID, final Integer loanProductID,
+ final String disbursementDate, final String restStartDate, final String compoundingStartDate, final String repaymentStrategy,
+ final List<HashMap> charges, final String graceOnInterestPayment, final String graceOnPrincipalPayment, List<HashMap> tranches) {
+ System.out.println("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
+ final String loanApplicationJSON = new LoanApplicationTestBuilder() //
+ .withPrincipal("10000.00") //
+ .withLoanTermFrequency("24") //
+ .withLoanTermFrequencyAsWeeks() //
+ .withNumberOfRepayments("12") //
+ .withRepaymentEveryAfter("2") //
+ .withRepaymentFrequencyTypeAsWeeks() //
+ .withInterestRatePerPeriod("2") //
+ .withAmortizationTypeAsEqualInstallments() //
+ .withTranches(tranches)
+ .withFixedEmiAmount("") //
+ .withInterestTypeAsDecliningBalance() //
+ .withInterestCalculationPeriodTypeAsDays() //
+ .withInterestCalculationPeriodTypeAsDays() //
+ .withExpectedDisbursementDate(disbursementDate) //
+ .withSubmittedOnDate(disbursementDate) //
+ .withRestFrequencyDate(restStartDate)//
+ .withwithRepaymentStrategy(repaymentStrategy) //
+ .withCharges(charges)//
+ .build(clientID.toString(), loanProductID.toString(), null);
+ return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
+ }
+
+ private List getDateAsArray(Calendar date, int addPeriod) {
+ return getDateAsArray(date, addPeriod, Calendar.DAY_OF_MONTH);
+ }
+
+ private List getDateAsArray(Calendar date, int addvalue, int type) {
+ date.add(type, addvalue);
+ return new ArrayList<>(Arrays.asList(date.get(Calendar.YEAR), date.get(Calendar.MONTH) + 1,
+ date.get(Calendar.DAY_OF_MONTH)));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/4b1ec9ef/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanRescheduleRequestTest.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanRescheduleRequestTest.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanRescheduleRequestTest.java
new file mode 100644
index 0000000..2b00a98
--- /dev/null
+++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/LoanRescheduleRequestTest.java
@@ -0,0 +1,219 @@
+/**
+ * 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.integrationtests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashMap;
+
+import org.apache.fineract.integrationtests.common.ClientHelper;
+import org.apache.fineract.integrationtests.common.LoanRescheduleRequestHelper;
+import org.apache.fineract.integrationtests.common.Utils;
+import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder;
+import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
+import org.apache.fineract.integrationtests.common.loans.LoanRescheduleRequestTestBuilder;
+import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.jayway.restassured.builder.RequestSpecBuilder;
+import com.jayway.restassured.builder.ResponseSpecBuilder;
+import com.jayway.restassured.http.ContentType;
+import com.jayway.restassured.specification.RequestSpecification;
+import com.jayway.restassured.specification.ResponseSpecification;
+
+/**
+ * Test the creation, approval and rejection of a loan reschedule request
+ **/
+@SuppressWarnings({ "rawtypes" })
+public class LoanRescheduleRequestTest {
+ private ResponseSpecification responseSpec;
+ private ResponseSpecification generalResponseSpec;
+ private RequestSpecification requestSpec;
+ private LoanTransactionHelper loanTransactionHelper;
+ private LoanRescheduleRequestHelper loanRescheduleRequestHelper;
+ private Integer clientId;
+ private Integer loanProductId;
+ private Integer loanId;
+ private Integer loanRescheduleRequestId;
+ private String loanPrincipalAmount = "100000.00";
+ private String numberOfRepayments = "12";
+ private String interestRatePerPeriod = "18";
+ private String dateString = "4 September 2014";
+
+ @Before
+ public void initialize() {
+ Utils.initializeRESTAssured();
+ this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
+ this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
+ this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
+ this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
+ this.loanRescheduleRequestHelper = new LoanRescheduleRequestHelper(this.requestSpec, this.responseSpec);
+
+ this.generalResponseSpec = new ResponseSpecBuilder().build();
+
+ // create all required entities
+ this.createRequiredEntities();
+ }
+
+ /**
+ * Creates the client, loan product, and loan entities
+ **/
+ private void createRequiredEntities() {
+ this.createClientEntity();
+ this.createLoanProductEntity();
+ this.createLoanEntity();
+ }
+
+ /**
+ * create a new client
+ **/
+ private void createClientEntity() {
+ this.clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec);
+
+ ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, this.clientId);
+ }
+
+ /**
+ * create a new loan product
+ **/
+ private void createLoanProductEntity() {
+ System.out.println("---------------------------------CREATING LOAN PRODUCT------------------------------------------");
+
+ final String loanProductJSON = new LoanProductTestBuilder()
+ .withPrincipal(loanPrincipalAmount)
+ .withNumberOfRepayments(numberOfRepayments)
+ .withinterestRatePerPeriod(interestRatePerPeriod)
+ .withInterestRateFrequencyTypeAsYear()
+ .build(null);
+
+ this.loanProductId = this.loanTransactionHelper.getLoanProductId(loanProductJSON);
+ System.out.println("Successfully created loan product (ID: " + this.loanProductId + ")");
+ }
+
+ /**
+ * submit a new loan application, approve and disburse the loan
+ **/
+ private void createLoanEntity() {
+ System.out.println("---------------------------------NEW LOAN APPLICATION------------------------------------------");
+
+ final String loanApplicationJSON = new LoanApplicationTestBuilder()
+ .withPrincipal(loanPrincipalAmount)
+ .withLoanTermFrequency(numberOfRepayments)
+ .withLoanTermFrequencyAsMonths()
+ .withNumberOfRepayments(numberOfRepayments)
+ .withRepaymentEveryAfter("1")
+ .withRepaymentFrequencyTypeAsMonths()
+ .withAmortizationTypeAsEqualInstallments()
+ .withInterestCalculationPeriodTypeAsDays()
+ .withInterestRatePerPeriod(interestRatePerPeriod)
+ .withLoanTermFrequencyAsMonths()
+ .withSubmittedOnDate(dateString)
+ .withExpectedDisbursementDate(dateString)
+ .withPrincipalGrace("2")
+ .withInterestGrace("2")
+ .build(this.clientId.toString(), this.loanProductId.toString(), null);
+
+ this.loanId = this.loanTransactionHelper.getLoanId(loanApplicationJSON);
+
+ System.out.println("Sucessfully created loan (ID: " + this.loanId + ")");
+
+ this.approveLoanApplication();
+ this.disburseLoan();
+ }
+
+ /**
+ * approve the loan application
+ **/
+ private void approveLoanApplication() {
+
+ if(this.loanId != null) {
+ this.loanTransactionHelper.approveLoan(this.dateString, this.loanId);
+ System.out.println("Successfully approved loan (ID: " + this.loanId + ")");
+ }
+ }
+
+ /**
+ * disburse the newly created loan
+ **/
+ private void disburseLoan() {
+
+ if(this.loanId != null) {
+ this.loanTransactionHelper.disburseLoan(this.dateString, this.loanId);
+ System.out.println("Successfully disbursed loan (ID: " + this.loanId + ")");
+ }
+ }
+
+ /**
+ * create new loan reschedule request
+ **/
+ private void createLoanRescheduleRequest() {
+ System.out.println("---------------------------------CREATING LOAN RESCHEDULE REQUEST------------------------------------------");
+
+ final String requestJSON = new LoanRescheduleRequestTestBuilder().build(this.loanId.toString());
+
+ this.loanRescheduleRequestId = this.loanRescheduleRequestHelper.createLoanRescheduleRequest(requestJSON);
+ this.loanRescheduleRequestHelper.verifyCreationOfLoanRescheduleRequest(this.loanRescheduleRequestId);
+
+ System.out.println("Successfully created loan reschedule request (ID: " + this.loanRescheduleRequestId + ")");
+ }
+
+ @Test
+ public void testCreateLoanRescheduleRequest() {
+ this.createLoanRescheduleRequest();
+ }
+
+ @Test
+ public void testRejectLoanRescheduleRequest() {
+ this.createLoanRescheduleRequest();
+
+ System.out.println("-----------------------------REJECTING LOAN RESCHEDULE REQUEST--------------------------");
+
+ final String requestJSON = new LoanRescheduleRequestTestBuilder().getRejectLoanRescheduleRequestJSON();
+ this.loanRescheduleRequestHelper.rejectLoanRescheduleRequest(this.loanRescheduleRequestId, requestJSON);
+
+ final HashMap response = (HashMap) this.loanRescheduleRequestHelper.getLoanRescheduleRequest(loanRescheduleRequestId, "statusEnum");
+ assertTrue((Boolean)response.get("rejected"));
+
+ System.out.println("Successfully rejected loan reschedule request (ID: " + this.loanRescheduleRequestId + ")");
+ }
+
+ @Test
+ public void testApproveLoanRescheduleRequest() {
+ this.createLoanRescheduleRequest();
+
+ System.out.println("-----------------------------APPROVING LOAN RESCHEDULE REQUEST--------------------------");
+
+ final String requestJSON = new LoanRescheduleRequestTestBuilder().getApproveLoanRescheduleRequestJSON();
+ this.loanRescheduleRequestHelper.approveLoanRescheduleRequest(this.loanRescheduleRequestId, requestJSON);
+
+ final HashMap response = (HashMap) this.loanRescheduleRequestHelper.getLoanRescheduleRequest(loanRescheduleRequestId, "statusEnum");
+ assertTrue((Boolean)response.get("approved"));
+
+ final Integer numberOfRepayments = (Integer) this.loanTransactionHelper.getLoanDetail(requestSpec, generalResponseSpec, loanId, "numberOfRepayments");
+ final HashMap loanSummary = this.loanTransactionHelper.getLoanSummary(requestSpec, generalResponseSpec, loanId);
+ final Float totalExpectedRepayment = (Float) loanSummary.get("totalExpectedRepayment");
+
+ assertEquals("NUMBER OF REPAYMENTS SHOULD BE 16, NOT 12", "16", numberOfRepayments.toString());
+ assertEquals("TOTAL EXPECTED REPAYMENT MUST BE EQUAL TO 118000.0", "118000.0", totalExpectedRepayment.toString());
+
+ System.out.println("Successfully approved loan reschedule request (ID: " + this.loanRescheduleRequestId + ")");
+ }
+}