Merge pull request #1173 from pramodn02/develop

MIFOSX-1709 : added test cases and api documentation
This commit is contained in:
Vishwas Babu A J
2014-12-09 02:01:47 -08:00
14 changed files with 1148 additions and 101 deletions
+126 -2
View File
@@ -997,6 +997,14 @@
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td>loans/{loanId}?command=recoverGuarantees</td>
<td><a href="#loans_recoverguarantee">Recover From Guarantors</a></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td><a href="#loans_transactions">Loan Transactions</a></td>
<td>loans/{loanId}/transactions?command=repayment</td>
@@ -7383,6 +7391,11 @@ GET https://DomainName/api/v1/loans/template?templateType=individual&clientId=1&
optional, <span>Either 'all' or a comma separated list of
loan 'associations' (itemised below).</span>
</dd>
<dt>exclude</dt>
<dd>
optional, <span>'all' and a comma separated list of
loan associations (itemised below) as 'exclude'.</span>
</dd>
<dd>
<br>Associations are just extra pieces of data that you
might or might not want to retrieve.<br>
@@ -7422,6 +7435,8 @@ GET https://DomainName/api/v1/loans/template?templateType=individual&clientId=1&
<br>
<div class=apiClick>loans/1?associations=all</div>
<br>
<div class=apiClick>loans/1?associations=all&exclude=guarantors</div>
<br>
<br>
<div class=apiClick>loans/1?fields=id,principal,annualInterestRate&associations=repaymentSchedule,transactions</div>
</div>
@@ -8239,6 +8254,30 @@ Request Body:
</div>
</div>
<a id="loans_recoverguarantee" name="loans_recoverguarantee" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Recover Loan Guarantee </h4>
</div>
<div class="method-example">
<code class="method-declaration">
POST https://DomainName/api/v1/loans/{loanId}?command=recoverGuarantees
</code>
<code class="method-request">
POST loans/1?command=approve
Content-Type: application/json
No Request Body:
</code>
<code class="method-response">
{
"loanId": 1
}
</code>
</div>
</div>
<a id="loans_approve_undo" name="loans_approve_undo" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
@@ -9144,6 +9183,20 @@ Request Body:
birth details of an external guarantor
</td>
</tr>
<tr class=alt>
<td>savingsId</td>
</tr>
<tr>
<td class=fielddesc>Guarantors Savings Account on which Amount will be blocked
</td>
</tr>
<tr class=alt>
<td>amount</td>
</tr>
<tr>
<td class=fielddesc>Guarantee amount which will be blocked on savings account.
</td>
</tr>
</table>
</div>
</div>
@@ -9203,6 +9256,7 @@ GET https://DomainName/api/v1/loans/{loanId}/guarantors
</p>
<p>Example Request:</p>
<div class=apiClick>loans/1/guarantors/template</div>
<div class=apiClick>loans/1/guarantors/accounts/template?clientId=1</div>
</div>
<div class="method-example">
<code class="method-declaration">
@@ -9232,6 +9286,39 @@ GET https://DomainName/api/v1/loans/{loanId}/guarantors/template
"value": "EXTERNAL"
}
]
}
</code>
<code class="method-declaration">
GET https://DomainName/api/v1/loans/{loanId}/guarantors/accounts/template?clientId={clientId}
</code>
<code class="method-response">
{
"guarantorType": {
"id": 1,
"code": "guarantor.existing.customer",
"value": "CUSTOMER"
},
"status": false,
"accountLinkingOptions": [
{
"id": 1,
"accountNo": "000000001",
"clientId": 3,
"clientName": "Client_FirstName_UUV18 Client_LastName_9T2D",
"productId": 1,
"productName": "FIXED_DEPOSIT_PRODUCT_U0NS9T",
"fieldOfficerId": 0,
"currency": {
"code": "USD",
"name": "US Dollar",
"decimalPlaces": 4,
"inMultiplesOf": 100,
"displaySymbol": "$",
"nameCode": "currency.USD",
"displayLabel": "US Dollar ($)"
}
}
]
}
</code>
</div>
@@ -9299,6 +9386,15 @@ GET https://DomainName/api/v1/loans/{loanId}/guarantors/{guarantorId}
<tr class=alt>
<td>guarantorTypeId, firstname, lastname</td>
</tr>
</table>
<table class=matrixHeading>
<tr class="matrixHeadingBG">
<td><div class="mifosXHeading2">Optional Fields
for "internal" guarantors</div></td>
</tr>
<tr class=alt>
<td>savingsId, amount</td>
</tr>
</table>
</div>
<div class="method-example">
@@ -9382,9 +9478,12 @@ Request Body:
<div class="method-example">
<code class="method-declaration">
DELETE https://DomainName/api/v1/loans/{loanId}/guarantors/{guarantorId}
DELETE https://DomainName/api/v1/loans/{loanId}/guarantors/{guarantorId}?guarantorFundingId={guarantorFundingId}
</code>
<code class="method-request">
DELETE loans/1/guarantors/1
DELETE loans/1/guarantors/1?guarantorFundingId=1
Content-Type: application/json
No Request Body:
</code>
@@ -12282,7 +12381,7 @@ GET https://DomainName/api/v1/loanproducts/{productId}
numberOfRepaymentVariationsForBorrowerCycle,
interestRateVariationsForBorrowerCycle,
multiDisburseLoan,maxTrancheCount,
outstandingLoanBalance,overdueDaysForNPA
outstandingLoanBalance,overdueDaysForNPA,holdGuaranteeFunds
</td>
</tr>
</table>
@@ -12323,6 +12422,22 @@ GET https://DomainName/api/v1/loanproducts/{productId}
<td>recalculationRestFrequencyInterval, recalculationRestFrequencyDate</td>
</tr>
</table>
<table class=matrixHeading>
<tr class="matrixHeadingBG">
<td><div class="mifosXHeading2">Additional Mandatory Fields if Hold Guarantee funds is enabled(true)</div></td>
</tr>
<tr class=alt>
<td>mandatoryGuarantee</td>
</tr>
</table>
<table class=matrixHeading>
<tr class="matrixHeadingBG">
<td><div class="mifosXHeading2">Additional Optional Fields if Hold Guarantee funds is enabled(true)</div></td>
</tr>
<tr class=alt>
<td>minimumGuaranteeFromOwnFunds,minimumGuaranteeFromGuarantor</td>
</tr>
</table>
</div>
<div class="method-example">
<code class="method-declaration">
@@ -12385,7 +12500,8 @@ Request Body:
"overpaymentLiabilityAccountId":11,
"daysInMonthType":1,
"daysInYearType":1,
"isInterestRecalculationEnabled":"false"
"isInterestRecalculationEnabled":"false",
"holdGuaranteeFunds":"false"
}
</code>
<code class="method-response">
@@ -33482,6 +33598,14 @@ No Request Body:
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td>loans/{loanId}?command=recoverGuarantees</td>
<td><a href="#loans_recoverguarantee">Recover From Guarantors</a></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td>loans/{loanId}/transactions/template</td>
@@ -36,8 +36,6 @@ import org.mifosplatform.integrationtests.common.loans.LoanProductTestBuilder;
import org.mifosplatform.integrationtests.common.loans.LoanStatusChecker;
import org.mifosplatform.integrationtests.common.loans.LoanTransactionHelper;
import org.mifosplatform.integrationtests.common.savings.SavingsAccountHelper;
import org.mifosplatform.integrationtests.common.savings.SavingsProductHelper;
import org.mifosplatform.integrationtests.common.savings.SavingsStatusChecker;
import com.jayway.restassured.builder.RequestSpecBuilder;
import com.jayway.restassured.builder.ResponseSpecBuilder;
@@ -87,7 +85,8 @@ public class ClientLoanIntegrationTest {
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID);
final Integer loanProductID = createLoanProduct(false, NONE);
final Integer loanID = applyForLoanApplication(clientID, loanProductID, null, null, "12,000.00");
final ArrayList<HashMap> loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec,loanID);
final ArrayList<HashMap> loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec,
loanID);
verifyLoanRepaymentSchedule(loanSchedule);
}
@@ -324,7 +323,8 @@ public class ClientLoanIntegrationTest {
validateCharge(flat, loanCharges, "150.0", "150.0", "0.0", "0.0");
validateNumberForEqual("654.24", String.valueOf(firstInstallment.get("feeChargesDue")));
final Integer savingsId = createSavings(clientID);
final Integer savingsId = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID,
MINIMUM_OPENING_BALANCE);
this.loanTransactionHelper.updateLoan(loanID,
updateLoanJson(clientID, loanProductID, copyChargesForUpdate(loanCharges, null, null), String.valueOf(savingsId)));
@@ -527,7 +527,8 @@ public class ClientLoanIntegrationTest {
"0.0");
validateChargeExcludePrecission(flat, loanCharges, "100.0", "400", "0.0", "0.0");
final Integer savingsId = createSavings(clientID);
final Integer savingsId = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID,
MINIMUM_OPENING_BALANCE);
this.loanTransactionHelper.updateLoan(loanID,
updateLoanJson(clientID, loanProductID, copyChargesForUpdate(loanCharges, null, null), String.valueOf(savingsId)));
@@ -687,7 +688,8 @@ public class ClientLoanIntegrationTest {
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID);
final Integer loanProductID = createLoanProduct(false, NONE);
final Integer savingsId = createSavings(clientID);
final Integer savingsId = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID,
MINIMUM_OPENING_BALANCE);
final Integer loanID = applyForLoanApplication(clientID, loanProductID, null, savingsId.toString(), "12,000.00");
Assert.assertNotNull(loanID);
@@ -770,7 +772,8 @@ public class ClientLoanIntegrationTest {
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID);
final Integer loanProductID = createLoanProduct(true, NONE);
final Integer savingsId = createSavings(clientID);
final Integer savingsId = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID,
MINIMUM_OPENING_BALANCE);
List<HashMap> tranches = new ArrayList<>();
tranches.add(createTrancheDetail("1 March 2014", "25000"));
@@ -1158,38 +1161,6 @@ public class ClientLoanIntegrationTest {
return map;
}
private Integer createSavings(Integer clientID) {
final Integer savingsProductID = createSavingsProduct(this.requestSpec, this.responseSpec, MINIMUM_OPENING_BALANCE);
Assert.assertNotNull(savingsProductID);
SavingsAccountHelper savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec);
final Integer savingsId = savingsAccountHelper.applyForSavingsApplication(clientID, savingsProductID, ACCOUNT_TYPE_INDIVIDUAL);
Assert.assertNotNull(savingsProductID);
HashMap savingsStatusHashMap = SavingsStatusChecker.getStatusOfSavings(this.requestSpec, this.responseSpec, savingsId);
SavingsStatusChecker.verifySavingsIsPending(savingsStatusHashMap);
savingsStatusHashMap = savingsAccountHelper.approveSavings(savingsId);
SavingsStatusChecker.verifySavingsIsApproved(savingsStatusHashMap);
savingsStatusHashMap = savingsAccountHelper.activateSavings(savingsId);
SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
return savingsId;
}
private Integer createSavingsProduct(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final String minOpenningBalance) {
System.out.println("------------------------------CREATING NEW SAVINGS PRODUCT ---------------------------------------");
SavingsProductHelper savingsProductHelper = new SavingsProductHelper();
final String savingsProductJSON = savingsProductHelper //
.withInterestCompoundingPeriodTypeAsDaily() //
.withInterestPostingPeriodTypeAsMonthly() //
.withInterestCalculationPeriodTypeAsDailyBalance() //
.withMinimumOpenningBalance(minOpenningBalance).build();
return SavingsProductHelper.createSavingsProduct(savingsProductJSON, requestSpec, responseSpec);
}
private HashMap createTrancheDetail(final String date, final String amount) {
HashMap detail = new HashMap();
detail.put("expectedDisbursementDate", date);
@@ -89,7 +89,7 @@ public class LoanApplicationApprovalTest {
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpecForStatusCode403);
@SuppressWarnings("unchecked")
List<HashMap> error = (List<HashMap>) this.loanTransactionHelper.approveLoanWithApproveAmount(approveDate, approvalAmount, loanID,
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
@@ -88,6 +88,10 @@ public class LoanProductTestBuilder {
private String recalculationRestFrequencyInterval = "0";
private String recalculationRestFrequencyDate = null;
private String minimumDaysBetweenDisbursalAndFirstRepayment = null;
private Boolean holdGuaranteeFunds = null;
private String mandatoryGuarantee = null;
private String minimumGuaranteeFromOwnFunds = null;
private String minimumGuaranteeFromGuarantor = null;
public String build(final String chargeId) {
final HashMap<String, Object> map = new HashMap<>();
@@ -145,6 +149,14 @@ public class LoanProductTestBuilder {
map.put("recalculationRestFrequencyInterval", recalculationRestFrequencyInterval);
map.put("recalculationRestFrequencyDate", recalculationRestFrequencyDate);
}
if (holdGuaranteeFunds != null) {
map.put("holdGuaranteeFunds", this.holdGuaranteeFunds);
if (this.holdGuaranteeFunds) {
map.put("mandatoryGuarantee", this.mandatoryGuarantee);
map.put("minimumGuaranteeFromGuarantor", this.minimumGuaranteeFromGuarantor);
map.put("minimumGuaranteeFromOwnFunds", this.minimumGuaranteeFromOwnFunds);
}
}
return new Gson().toJson(map);
}
@@ -385,4 +397,14 @@ public class LoanProductTestBuilder {
this.minimumDaysBetweenDisbursalAndFirstRepayment = minimumDaysBetweenDisbursalAndFirstRepayment;
return this;
}
public LoanProductTestBuilder withOnHoldFundDetails(final String mandatoryGuarantee, final String minimumGuaranteeFromGuarantor,
final String minimumGuaranteeFromOwnFunds) {
this.holdGuaranteeFunds = true;
this.mandatoryGuarantee = mandatoryGuarantee;
this.minimumGuaranteeFromGuarantor = minimumGuaranteeFromGuarantor;
this.minimumGuaranteeFromOwnFunds = minimumGuaranteeFromOwnFunds;
return this;
}
}
@@ -35,6 +35,7 @@ public class LoanTransactionHelper {
private static final String WAIVE_INTEREST_COMMAND = "waiveinterest";
private static final String MAKE_REPAYMENT_COMMAND = "repayment";
private static final String WITHDRAW_LOAN_APPLICATION_COMMAND = "withdrawnByApplicant";
private static final String RECOVER_FROM_GUARANTORS_COMMAND = "recoverGuarantees";
public LoanTransactionHelper(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) {
this.requestSpec = requestSpec;
@@ -48,19 +49,19 @@ public class LoanTransactionHelper {
public Integer getLoanId(final String loanApplicationJSON) {
return Utils.performServerPost(this.requestSpec, this.responseSpec, APPLY_LOAN_URL, loanApplicationJSON, "loanId");
}
public Integer getLoanOfficerId(final String loanId) {
final String GET_LOAN_URL = "/mifosng-provider/api/v1/loans/" + loanId + "?" + Utils.TENANT_IDENTIFIER;
return Utils.performServerGet(this.requestSpec, this.responseSpec, GET_LOAN_URL, "loanOfficerId");
}
public Object createLoanAccount(final String loanApplicationJSON, final String responseAttribute) {
return Utils.performServerPost(this.requestSpec, this.responseSpec, APPLY_LOAN_URL, loanApplicationJSON, responseAttribute);
}
public Integer updateLoan(final Integer id, final String loanApplicationJSON) {
return Utils.performServerPut(this.requestSpec, this.responseSpec, "/mifosng-provider/api/v1/loans/" + id
+ "?" + Utils.TENANT_IDENTIFIER, loanApplicationJSON, "loanId");
return Utils.performServerPut(this.requestSpec, this.responseSpec, "/mifosng-provider/api/v1/loans/" + id + "?"
+ Utils.TENANT_IDENTIFIER, loanApplicationJSON, "loanId");
}
public ArrayList getLoanRepaymentSchedule(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
@@ -69,10 +70,11 @@ public class LoanTransactionHelper {
final HashMap response = Utils.performServerGet(requestSpec, responseSpec, URL, "repaymentSchedule");
return (ArrayList) response.get("periods");
}
public ArrayList getLoanFutureRepaymentSchedule(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final Integer loanID) {
final String URL = "/mifosng-provider/api/v1/loans/" + loanID + "?associations=repaymentSchedule,futureSchedule&" + Utils.TENANT_IDENTIFIER;
final String URL = "/mifosng-provider/api/v1/loans/" + loanID + "?associations=repaymentSchedule,futureSchedule&"
+ Utils.TENANT_IDENTIFIER;
final HashMap response = Utils.performServerGet(requestSpec, responseSpec, URL, "repaymentSchedule");
return (ArrayList) response.get("futurePeriods");
}
@@ -97,17 +99,17 @@ public class LoanTransactionHelper {
public HashMap approveLoan(final String approvalDate, final Integer loanID) {
return performLoanTransaction(createLoanOperationURL(APPROVE_LOAN_COMMAND, loanID), getApproveLoanAsJSON(approvalDate));
}
public HashMap approveLoanWithApproveAmount(final String approvalDate, final String approvalAmount, final Integer loanID) {
return performLoanTransaction(createLoanOperationURL(APPROVE_LOAN_COMMAND, loanID), getApproveLoanAsJSON(approvalDate, approvalAmount));
return performLoanTransaction(createLoanOperationURL(APPROVE_LOAN_COMMAND, loanID),
getApproveLoanAsJSON(approvalDate, approvalAmount));
}
public Object approveLoanWithApproveAmount(final String approvalDate, final String approvalAmount, final Integer loanID,
final String responseAttribute) {
public Object approveLoan(final String approvalDate, final String approvalAmount, final Integer loanID, final String responseAttribute) {
final String approvalURL = createLoanOperationURL(APPROVE_LOAN_COMMAND, loanID);
final String approvalJSONData = getApproveLoanAsJSON(approvalDate, approvalAmount);
return performLoanTransaction(approvalURL, approvalJSONData, responseAttribute);
}
@@ -136,6 +138,10 @@ public class LoanTransactionHelper {
return performLoanTransaction(createLoanOperationURL(UNDO_DISBURSE_LOAN_COMMAND, loanID), undoDisburseJson);
}
public void recoverFromGuarantor(final Integer loanID) {
performLoanTransaction(createLoanOperationURL(RECOVER_FROM_GUARANTORS_COMMAND, loanID), "", "");
}
public HashMap writeOffLoan(final String date, final Integer loanID) {
return performLoanTransaction(createLoanTransactionURL(WRITE_OFF_LOAN_COMMAND, loanID), getWriteOffBodyAsJSON(date));
}
@@ -151,8 +157,8 @@ public class LoanTransactionHelper {
}
public HashMap makeRepayment(final String date, final Float amountToBePaid, final Integer loanID) {
return performLoanTransaction(createLoanTransactionURL(MAKE_REPAYMENT_COMMAND, loanID),
getRepaymentBodyAsJSON(date, amountToBePaid));
return (HashMap) performLoanTransaction(createLoanTransactionURL(MAKE_REPAYMENT_COMMAND, loanID),
getRepaymentBodyAsJSON(date, amountToBePaid), "");
}
public HashMap withdrawLoanApplicationByClient(final String date, final Integer loanID) {
@@ -169,32 +175,32 @@ public class LoanTransactionHelper {
public Integer updateChargesForLoan(final Integer loanId, final Integer loanchargeId, final String request) {
System.out.println("--------------------------------- ADD CHARGES FOR LOAN --------------------------------");
final String UPDATE_CHARGES_URL = "/mifosng-provider/api/v1/loans/" + loanId + "/charges/" + loanchargeId
+ "?" + Utils.TENANT_IDENTIFIER;
final String UPDATE_CHARGES_URL = "/mifosng-provider/api/v1/loans/" + loanId + "/charges/" + loanchargeId + "?"
+ Utils.TENANT_IDENTIFIER;
final HashMap response = Utils.performServerPut(requestSpec, responseSpec, UPDATE_CHARGES_URL, request, "");
return (Integer) response.get("resourceId");
}
public Integer deleteChargesForLoan(final Integer loanId, final Integer loanchargeId) {
System.out.println("--------------------------------- DELETE CHARGES FOR LOAN --------------------------------");
final String DELETE_CHARGES_URL = "/mifosng-provider/api/v1/loans/" + loanId + "/charges/" + loanchargeId
+ "?" + Utils.TENANT_IDENTIFIER;
final String DELETE_CHARGES_URL = "/mifosng-provider/api/v1/loans/" + loanId + "/charges/" + loanchargeId + "?"
+ Utils.TENANT_IDENTIFIER;
final HashMap response = Utils.performServerDelete(requestSpec, responseSpec, DELETE_CHARGES_URL, "");
return (Integer) response.get("resourceId");
}
public Integer waiveChargesForLoan(final Integer loanId, final Integer loanchargeId, final String json) {
System.out.println("--------------------------------- WAIVE CHARGES FOR LOAN --------------------------------");
final String CHARGES_URL = "/mifosng-provider/api/v1/loans/" + loanId + "/charges/" + loanchargeId
+ "?command=waive&" + Utils.TENANT_IDENTIFIER;
final String CHARGES_URL = "/mifosng-provider/api/v1/loans/" + loanId + "/charges/" + loanchargeId + "?command=waive&"
+ Utils.TENANT_IDENTIFIER;
final HashMap response = Utils.performServerPost(requestSpec, responseSpec, CHARGES_URL, json, "");
return (Integer) response.get("resourceId");
}
public Integer payChargesForLoan(final Integer loanId, final Integer loanchargeId, final String json) {
System.out.println("--------------------------------- WAIVE CHARGES FOR LOAN --------------------------------");
final String CHARGES_URL = "/mifosng-provider/api/v1/loans/" + loanId + "/charges/" + loanchargeId
+ "?command=pay&" + Utils.TENANT_IDENTIFIER;
final String CHARGES_URL = "/mifosng-provider/api/v1/loans/" + loanId + "/charges/" + loanchargeId + "?command=pay&"
+ Utils.TENANT_IDENTIFIER;
final HashMap response = Utils.performServerPost(requestSpec, responseSpec, CHARGES_URL, json, "");
return (Integer) response.get("resourceId");
}
@@ -212,19 +218,16 @@ public class LoanTransactionHelper {
}
private String getApproveLoanAsJSON(final String approvalDate) {
final HashMap<String, String> map = new HashMap<>();
map.put("locale", "en");
map.put("dateFormat", "dd MMMM yyyy");
map.put("approvedOnDate", approvalDate);
map.put("note", "Approval NOTE");
return new Gson().toJson(map);
return getApproveLoanAsJSON(approvalDate, null);
}
private String getApproveLoanAsJSON(final String approvalDate, final String approvalAmount) {
final HashMap<String, String> map = new HashMap<>();
map.put("locale", "en");
map.put("dateFormat", "dd MMMM yyyy");
map.put("approvedLoanAmount", approvalAmount);
if (approvalAmount != null) {
map.put("approvedLoanAmount", approvalAmount);
}
map.put("approvedOnDate", approvalDate);
map.put("note", "Approval NOTE");
return new Gson().toJson(map);
@@ -378,14 +381,36 @@ public class LoanTransactionHelper {
"changes");
return (HashMap) response.get("status");
}
private Object performLoanTransaction(final String postURLForLoanTransaction, final String jsonToBeSent, final String responseAttribute) {
return Utils.performServerPost(this.requestSpec, this.responseSpec, postURLForLoanTransaction, jsonToBeSent, responseAttribute);
}
public Object adjustLoanTransaction(final Integer loanId, final Integer transactionId, final String date,
final String transactionAmount, final String responseAttribute) {
return adjustLoanTransaction(loanId, transactionId, getAdjustTransactionJSON(date, transactionAmount), responseAttribute);
}
private Object adjustLoanTransaction(final Integer loanId, final Integer tansactionId, final String jsonToBeSent,
final String responseAttribute) {
final String URL = "/mifosng-provider/api/v1/loans/" + loanId + "/transactions/" + tansactionId + "?" + Utils.TENANT_IDENTIFIER;
return Utils.performServerPost(this.requestSpec, this.responseSpec, URL, jsonToBeSent, responseAttribute);
}
private String getAdjustTransactionJSON(final String date, final String transactionAmount) {
final HashMap<String, String> map = new HashMap<>();
map.put("locale", "en_GB");
map.put("dateFormat", "dd MMMM yyyy");
map.put("transactionDate", date);
map.put("transactionAmount", transactionAmount);
String json = new Gson().toJson(map);
System.out.println(json);
return json;
}
public HashMap getPrepayAmount(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, final Integer loanID) {
final String URL = "/mifosng-provider/api/v1/loans/" + loanID + "/transactions/template?command=prepayLoan&" + Utils.TENANT_IDENTIFIER;
final String URL = "/mifosng-provider/api/v1/loans/" + loanID + "/transactions/template?command=prepayLoan&"
+ Utils.TENANT_IDENTIFIER;
final HashMap response = Utils.performServerGet(requestSpec, responseSpec, URL, "");
return response;
}
@@ -12,6 +12,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import org.junit.Assert;
import org.mifosplatform.integrationtests.common.CommonConstants;
import org.mifosplatform.integrationtests.common.Utils;
@@ -45,6 +46,7 @@ public class SavingsAccountHelper {
public static final String CREATED_DATE_MINUS_ONE = "07 January 2013";
public static final String TRANSACTION_DATE = "01 March 2013";
public static final String LAST_TRANSACTION_DATE = "01 March 2013";
public static final String ACCOUNT_TYPE_INDIVIDUAL = "INDIVIDUAL";
public SavingsAccountHelper(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) {
this.requestSpec = requestSpec;
@@ -59,12 +61,12 @@ public class SavingsAccountHelper {
}
public Integer applyForSavingsApplication(final Integer ID, final Integer savingsProductID, final String accountType) {
return applyForSavingsApplicationOnDate(ID, savingsProductID, accountType, CREATED_DATE);
return applyForSavingsApplicationOnDate(ID, savingsProductID, accountType, CREATED_DATE);
}
public Integer applyForSavingsApplicationOnDate(final Integer ID, final Integer savingsProductID, final String accountType,
final String submittedOnDate) {
System.out.println("--------------------------------APPLYING FOR SAVINGS APPLICATION--------------------------------");
final String submittedOnDate) {
System.out.println("--------------------------------APPLYING FOR SAVINGS APPLICATION--------------------------------");
final String savingsApplicationJSON = new SavingsApplicationTestBuilder() //
.withSubmittedOnDate(submittedOnDate) //
.build(ID.toString(), savingsProductID.toString(), accountType);
@@ -82,15 +84,15 @@ public class SavingsAccountHelper {
}
public HashMap approveSavings(final Integer savingsID) {
return approveSavingsOnDate(savingsID, null);
return approveSavingsOnDate(savingsID, null);
}
public HashMap approveSavingsOnDate(final Integer savingsID, final String approvalDate) {
System.out.println("--------------------------------- APPROVING SAVINGS APPLICATION ------------------------------------");
final String savingsOperationURL = createSavingsOperationURL(APPROVE_SAVINGS_COMMAND, savingsID);
if(approvalDate == null || approvalDate == "")
return performSavingApplicationActions(savingsOperationURL, getApproveSavingsAsJSON());
return performSavingApplicationActions(savingsOperationURL, getApproveSavingsAsJsonOnDate(approvalDate));
System.out.println("--------------------------------- APPROVING SAVINGS APPLICATION ------------------------------------");
final String savingsOperationURL = createSavingsOperationURL(APPROVE_SAVINGS_COMMAND, savingsID);
if (approvalDate == null || approvalDate == "")
return performSavingApplicationActions(savingsOperationURL, getApproveSavingsAsJSON());
return performSavingApplicationActions(savingsOperationURL, getApproveSavingsAsJsonOnDate(approvalDate));
}
public HashMap undoApproval(final Integer savingsID) {
@@ -124,7 +126,8 @@ public class SavingsAccountHelper {
public HashMap closeSavingsAccount(final Integer savingsID, String withdrawBalance) {
System.out.println("---------------------------------- CLOSE SAVINGS APPLICATION ----------------------------------");
return performSavingApplicationActions(createSavingsOperationURL(CLOSE_SAVINGS_COMMAND, savingsID), getCloseAccountJSON(withdrawBalance, LAST_TRANSACTION_DATE));
return performSavingApplicationActions(createSavingsOperationURL(CLOSE_SAVINGS_COMMAND, savingsID),
getCloseAccountJSON(withdrawBalance, LAST_TRANSACTION_DATE));
}
public Object deleteSavingsApplication(final Integer savingsId, final String jsonAttributeToGetBack) {
@@ -199,9 +202,9 @@ public class SavingsAccountHelper {
private String getApproveSavingsAsJSON() {
return getApproveSavingsAsJsonOnDate(CREATED_DATE_PLUS_ONE);
}
private String getApproveSavingsAsJsonOnDate(final String approvalDate) {
final HashMap<String, String> map = new HashMap<>();
final HashMap<String, String> map = new HashMap<>();
map.put("locale", CommonConstants.locale);
map.put("dateFormat", CommonConstants.dateFormat);
map.put("approvedOnDate", approvalDate);
@@ -352,13 +355,19 @@ public class SavingsAccountHelper {
final HashMap response = Utils.performServerGet(requestSpec, responseSpec, URL, "summary");
return response;
}
public HashMap getSavingsDetails(final Integer savingsID) {
final String URL = SAVINGS_ACCOUNT_URL + "/" + savingsID + "?associations=all&" + Utils.TENANT_IDENTIFIER;
final HashMap response = Utils.performServerGet(requestSpec, responseSpec, URL, "");
return response;
}
public Object getSavingsDetails(final Integer savingsID, final String returnAttribute) {
final String URL = SAVINGS_ACCOUNT_URL + "/" + savingsID + "?" + Utils.TENANT_IDENTIFIER;
final Object response = Utils.performServerGet(requestSpec, responseSpec, URL, returnAttribute);
return response;
}
private HashMap performSavingApplicationActions(final String postURLForSavingsTransaction, final String jsonToBeSent) {
HashMap status = null;
final HashMap response = Utils.performServerPost(this.requestSpec, this.responseSpec, postURLForSavingsTransaction, jsonToBeSent,
@@ -421,4 +430,38 @@ public class SavingsAccountHelper {
String josn = new Gson().toJson(map);
return josn;
}
public static Integer openSavingsAccount(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final Integer clientId, final String minimumOpeningBalance) {
final Integer savingsProductID = createSavingsProduct(requestSpec, responseSpec, minimumOpeningBalance);
Assert.assertNotNull(savingsProductID);
SavingsAccountHelper savingsAccountHelper = new SavingsAccountHelper(requestSpec, responseSpec);
final Integer savingsId = savingsAccountHelper.applyForSavingsApplication(clientId, savingsProductID, ACCOUNT_TYPE_INDIVIDUAL);
Assert.assertNotNull(savingsProductID);
HashMap savingsStatusHashMap = SavingsStatusChecker.getStatusOfSavings(requestSpec, responseSpec, savingsId);
SavingsStatusChecker.verifySavingsIsPending(savingsStatusHashMap);
savingsStatusHashMap = savingsAccountHelper.approveSavings(savingsId);
SavingsStatusChecker.verifySavingsIsApproved(savingsStatusHashMap);
savingsStatusHashMap = savingsAccountHelper.activateSavings(savingsId);
SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
return savingsId;
}
private static Integer createSavingsProduct(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final String minOpenningBalance) {
System.out.println("------------------------------CREATING NEW SAVINGS PRODUCT ---------------------------------------");
SavingsProductHelper savingsProductHelper = new SavingsProductHelper();
final String savingsProductJSON = savingsProductHelper //
.withInterestCompoundingPeriodTypeAsDaily() //
.withInterestPostingPeriodTypeAsMonthly() //
.withInterestCalculationPeriodTypeAsDailyBalance() //
.withMinimumOpenningBalance(minOpenningBalance).build();
return SavingsProductHelper.createSavingsProduct(savingsProductJSON, requestSpec, responseSpec);
}
}
@@ -0,0 +1,59 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.integrationtests.loanaccount.guarantor;
import java.util.HashMap;
import java.util.List;
import org.mifosplatform.integrationtests.common.CommonConstants;
import org.mifosplatform.integrationtests.common.Utils;
import com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification;
public class GuarantorHelper {
private static final String LOAN_URL = "/mifosng-provider/api/v1/loans/";
private static final String GUARANTOR_API_URL = "/guarantors/";
private static final String TENANT = "?" + Utils.TENANT_IDENTIFIER;
private final RequestSpecification requestSpec;
private final ResponseSpecification responseSpec;
public GuarantorHelper(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) {
this.requestSpec = requestSpec;
this.responseSpec = responseSpec;
}
public Integer createGuarantor(final Integer loanId, final String guarantorJSON) {
return Utils.performServerPost(this.requestSpec, this.responseSpec, LOAN_URL + loanId + GUARANTOR_API_URL + TENANT, guarantorJSON,
CommonConstants.RESPONSE_RESOURCE_ID);
}
public HashMap updateGuarantor(final Integer guarantorId, final Integer loanId, final String guarantorJSON) {
return Utils.performServerPut(this.requestSpec, this.responseSpec, LOAN_URL + loanId + GUARANTOR_API_URL + guarantorId + TENANT,
guarantorJSON, CommonConstants.RESPONSE_CHANGES);
}
public HashMap deleteGuarantor(final Integer guarantorId, final Integer fundId, final Integer loanId) {
return Utils.performServerDelete(this.requestSpec, this.responseSpec, LOAN_URL + loanId + GUARANTOR_API_URL + guarantorId + TENANT
+ "&guarantorFundingId=" + fundId, "");
}
public HashMap deleteGuarantor(final Integer guarantorId, final Integer loanId) {
return Utils.performServerDelete(this.requestSpec, this.responseSpec, LOAN_URL + loanId + GUARANTOR_API_URL + guarantorId + TENANT,
"");
}
public Object getGuarantor(final Integer guarantorId, final Integer loanId, final String jsonToGetBack) {
return Utils.performServerGet(this.requestSpec, this.responseSpec, LOAN_URL + loanId + GUARANTOR_API_URL + guarantorId + TENANT,
jsonToGetBack);
}
public List getAllGuarantor(final Integer loanId) {
return Utils.performServerGet(this.requestSpec, this.responseSpec, LOAN_URL + loanId + GUARANTOR_API_URL + TENANT, "");
}
}
@@ -0,0 +1,607 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.integrationtests.loanaccount.guarantor;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mifosplatform.integrationtests.common.ClientHelper;
import org.mifosplatform.integrationtests.common.CommonConstants;
import org.mifosplatform.integrationtests.common.Utils;
import org.mifosplatform.integrationtests.common.loans.LoanApplicationTestBuilder;
import org.mifosplatform.integrationtests.common.loans.LoanProductTestBuilder;
import org.mifosplatform.integrationtests.common.loans.LoanStatusChecker;
import org.mifosplatform.integrationtests.common.loans.LoanTransactionHelper;
import org.mifosplatform.integrationtests.common.savings.SavingsAccountHelper;
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;
public class GuarantorTest {
private ResponseSpecification responseSpec;
private RequestSpecification requestSpec;
private LoanTransactionHelper loanTransactionHelper;
private GuarantorHelper guarantorHelper;
private SavingsAccountHelper savingsAccountHelper;
private final Float self1_balance = new Float(5000);
private final Float external1_balance = new Float(5000);
private final Float external2_balance = new Float(5000);
private final Float self1_guarantee = new Float(2000);
private final Float external1_guarantee = new Float(2000);
private final Float external2_guarantee = new Float(1000);
@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().build();
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
this.guarantorHelper = new GuarantorHelper(this.requestSpec, this.responseSpec);
savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testGuarantor() {
Float self1_hold_funds = new Float(0);
Float external1_hold_funds = new Float(0);
Float external2_hold_funds = new Float(0);
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID);
final Integer clientID_external = ClientHelper.createClient(this.requestSpec, this.responseSpec);
final Integer clientID_external2 = ClientHelper.createClient(this.requestSpec, this.responseSpec);
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID_external);
final Integer selfSavigsId = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID,
String.valueOf(self1_balance));
final Integer externalSavigsId_1 = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID_external,
String.valueOf(external1_balance));
final Integer externalSavigsId_2 = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID_external2,
String.valueOf(external2_balance));
final Integer loanProductID = createLoanProductWithHoldFunds("50", "20", "20");
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
Calendar todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -7 * 4);
String LOAN_DISBURSEMENT_DATE = dateFormat.format(todaysDate.getTime());
final Integer loanID = applyForLoanApplication(clientID, loanProductID, LOAN_DISBURSEMENT_DATE);
Assert.assertNotNull(loanID);
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
String guarantorJSON = new GuarantorTestBuilder().externalCustomer().build();
Integer externalGuarantor = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
Assert.assertNotNull(externalGuarantor);
guarantorJSON = new GuarantorTestBuilder().existingCustomerWithoutGuaranteeAmount(String.valueOf(clientID_external)).build();
Integer withoutGuaranteeAmount = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
Assert.assertNotNull(withoutGuaranteeAmount);
ArrayList<HashMap> errorData = (ArrayList<HashMap>) this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, null, loanID,
CommonConstants.RESPONSE_ERROR);
assertTrue(checkForErrorCode(errorData, "validation.msg.loan.guarantor.min.self.guarantee.required"));
assertTrue(checkForErrorCode(errorData, "validation.msg.loan.guarantor.min.external.guarantee.required"));
assertTrue(checkForErrorCode(errorData, "validation.msg.loan.guarantor.mandated.guarantee.required"));
guarantorJSON = new GuarantorTestBuilder().existingCustomerWithGuaranteeAmount(String.valueOf(clientID),
String.valueOf(selfSavigsId), String.valueOf(self1_guarantee)).build();
Integer selfGuarantee = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
verifySavingsOnHoldBalance(selfSavigsId, null);
Assert.assertNotNull(selfGuarantee);
errorData = (ArrayList<HashMap>) this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, null, loanID,
CommonConstants.RESPONSE_ERROR);
assertFalse(checkForErrorCode(errorData, "validation.msg.loan.guarantor.min.self.guarantee.required"));
assertTrue(checkForErrorCode(errorData, "validation.msg.loan.guarantor.min.external.guarantee.required"));
assertTrue(checkForErrorCode(errorData, "validation.msg.loan.guarantor.mandated.guarantee.required"));
guarantorJSON = new GuarantorTestBuilder().existingCustomerWithGuaranteeAmount(String.valueOf(clientID_external),
String.valueOf(externalSavigsId_1), String.valueOf(external1_guarantee)).build();
Integer externalGuarantee_1 = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
verifySavingsOnHoldBalance(externalSavigsId_1, null);
Assert.assertNotNull(externalGuarantee_1);
errorData = (ArrayList<HashMap>) this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, null, loanID,
CommonConstants.RESPONSE_ERROR);
assertFalse(checkForErrorCode(errorData, "validation.msg.loan.guarantor.min.self.guarantee.required"));
assertFalse(checkForErrorCode(errorData, "validation.msg.loan.guarantor.min.external.guarantee.required"));
assertTrue(checkForErrorCode(errorData, "validation.msg.loan.guarantor.mandated.guarantee.required"));
guarantorJSON = new GuarantorTestBuilder().existingCustomerWithGuaranteeAmount(String.valueOf(clientID_external2),
String.valueOf(externalSavigsId_2), String.valueOf(external2_guarantee)).build();
Integer externalGuarantee_2 = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
verifySavingsOnHoldBalance(externalSavigsId_2, null);
Assert.assertNotNull(externalGuarantee_2);
System.out.println("-----------------------------------APPROVE LOAN-----------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
self1_hold_funds += self1_guarantee;
external1_hold_funds += external1_guarantee;
external2_hold_funds += external2_guarantee;
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_1, external1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_2, external2_hold_funds);
System.out.println("-----------------------------------UNDO APPROVE LOAN-----------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.undoApproval(loanID);
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
verifySavingsOnHoldBalance(selfSavigsId, new Float(0));
verifySavingsOnHoldBalance(externalSavigsId_1, new Float(0));
verifySavingsOnHoldBalance(externalSavigsId_2, new Float(0));
System.out.println("-----------------------------------APPROVE LOAN-----------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_1, external1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_2, external2_hold_funds);
System.out.println("-------------------------------DISBURSE LOAN-------------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID);
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
// First repayment
ArrayList<HashMap> loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -7 * 3);
String LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
Float totalDueForCurrentPeriod = (Float) loanSchedule.get(1).get("totalDueForPeriod");
external1_hold_funds -= new Float(827.5867);
external2_hold_funds -= new Float(413.7933);
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, totalDueForCurrentPeriod, loanID);
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_1, external1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_2, external2_hold_funds);
// Second repayment
todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -7 * 2);
LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
totalDueForCurrentPeriod = (Float) loanSchedule.get(2).get("totalDueForPeriod");
external1_hold_funds -= new Float(831.4067);
external2_hold_funds -= new Float(415.7033333);
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, totalDueForCurrentPeriod, loanID);
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_1, external1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_2, external2_hold_funds);
// third repayment
todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -7);
LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
totalDueForCurrentPeriod = (Float) loanSchedule.get(3).get("totalDueForPeriod");
self1_hold_funds -= new Float(741.355);
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, totalDueForCurrentPeriod, loanID);
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_1, new Float(0));
verifySavingsOnHoldBalance(externalSavigsId_2, new Float(0));
// forth repayment
todaysDate = Calendar.getInstance();
LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
totalDueForCurrentPeriod = (Float) loanSchedule.get(3).get("totalDueForPeriod");
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, totalDueForCurrentPeriod, loanID);
verifySavingsOnHoldBalance(selfSavigsId, new Float(0));
verifySavingsOnHoldBalance(externalSavigsId_1, new Float(0));
verifySavingsOnHoldBalance(externalSavigsId_2, new Float(0));
loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
LoanStatusChecker.verifyLoanAccountIsClosed(loanStatusHashMap);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testGuarantor_UNDO_DISBURSAL() {
Float self1_hold_funds = new Float(0);
Float external1_hold_funds = new Float(0);
Float external2_hold_funds = new Float(0);
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID);
final Integer clientID_external = ClientHelper.createClient(this.requestSpec, this.responseSpec);
final Integer clientID_external2 = ClientHelper.createClient(this.requestSpec, this.responseSpec);
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID_external);
final Integer selfSavigsId = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID,
String.valueOf(self1_balance));
final Integer externalSavigsId_1 = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID_external,
String.valueOf(external1_balance));
final Integer externalSavigsId_3 = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID_external,
String.valueOf(external1_balance));
final Integer externalSavigsId_2 = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID_external2,
String.valueOf(external2_balance));
final Integer loanProductID = createLoanProductWithHoldFunds("50", "20", "20");
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
Calendar todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -7 * 4);
String LOAN_DISBURSEMENT_DATE = dateFormat.format(todaysDate.getTime());
final Integer loanID = applyForLoanApplication(clientID, loanProductID, LOAN_DISBURSEMENT_DATE);
Assert.assertNotNull(loanID);
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
String guarantorJSON = new GuarantorTestBuilder().externalCustomer().build();
Integer externalGuarantor = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
Assert.assertNotNull(externalGuarantor);
guarantorJSON = new GuarantorTestBuilder().existingCustomerWithoutGuaranteeAmount(String.valueOf(clientID_external)).build();
Integer withoutGuaranteeAmount = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
Assert.assertNotNull(withoutGuaranteeAmount);
ArrayList<HashMap> errorData = (ArrayList<HashMap>) this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, null, loanID,
CommonConstants.RESPONSE_ERROR);
assertTrue(checkForErrorCode(errorData, "validation.msg.loan.guarantor.min.self.guarantee.required"));
assertTrue(checkForErrorCode(errorData, "validation.msg.loan.guarantor.min.external.guarantee.required"));
assertTrue(checkForErrorCode(errorData, "validation.msg.loan.guarantor.mandated.guarantee.required"));
guarantorJSON = new GuarantorTestBuilder().existingCustomerWithGuaranteeAmount(String.valueOf(clientID),
String.valueOf(selfSavigsId), String.valueOf(self1_guarantee)).build();
Integer selfGuarantee = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
verifySavingsOnHoldBalance(selfSavigsId, null);
Assert.assertNotNull(selfGuarantee);
errorData = (ArrayList<HashMap>) this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, null, loanID,
CommonConstants.RESPONSE_ERROR);
assertFalse(checkForErrorCode(errorData, "validation.msg.loan.guarantor.min.self.guarantee.required"));
assertTrue(checkForErrorCode(errorData, "validation.msg.loan.guarantor.min.external.guarantee.required"));
assertTrue(checkForErrorCode(errorData, "validation.msg.loan.guarantor.mandated.guarantee.required"));
guarantorJSON = new GuarantorTestBuilder().existingCustomerWithGuaranteeAmount(String.valueOf(clientID_external),
String.valueOf(externalSavigsId_1), String.valueOf(external1_guarantee)).build();
Integer externalGuarantee_1 = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
verifySavingsOnHoldBalance(externalSavigsId_1, null);
Assert.assertNotNull(externalGuarantee_1);
errorData = (ArrayList<HashMap>) this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, null, loanID,
CommonConstants.RESPONSE_ERROR);
assertFalse(checkForErrorCode(errorData, "validation.msg.loan.guarantor.min.self.guarantee.required"));
assertFalse(checkForErrorCode(errorData, "validation.msg.loan.guarantor.min.external.guarantee.required"));
assertTrue(checkForErrorCode(errorData, "validation.msg.loan.guarantor.mandated.guarantee.required"));
guarantorJSON = new GuarantorTestBuilder().existingCustomerWithGuaranteeAmount(String.valueOf(clientID_external2),
String.valueOf(externalSavigsId_2), String.valueOf(external2_guarantee)).build();
Integer externalGuarantee_2 = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
Assert.assertNotNull(externalGuarantee_2);
verifySavingsOnHoldBalance(externalSavigsId_2, null);
System.out.println("-----------------------------------APPROVE LOAN-----------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
self1_hold_funds += self1_guarantee;
external1_hold_funds += external1_guarantee;
external2_hold_funds += external2_guarantee;
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_1, external1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_2, external2_hold_funds);
System.out.println("-----------------------------------UNDO APPROVE LOAN-----------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.undoApproval(loanID);
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
verifySavingsOnHoldBalance(selfSavigsId, new Float(0));
verifySavingsOnHoldBalance(externalSavigsId_1, new Float(0));
verifySavingsOnHoldBalance(externalSavigsId_2, new Float(0));
System.out.println("-----------------------------------APPROVE LOAN-----------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_1, external1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_2, external2_hold_funds);
List<HashMap> guarantors = this.guarantorHelper.getAllGuarantor(loanID);
this.guarantorHelper.deleteGuarantor(externalGuarantor, loanID);
assertFalse((Boolean) this.guarantorHelper.getGuarantor(externalGuarantor, loanID, "status"));
HashMap errorlog = this.guarantorHelper.deleteGuarantor(withoutGuaranteeAmount, loanID);
ArrayList<HashMap> error = (ArrayList<HashMap>) errorlog.get(CommonConstants.RESPONSE_ERROR);
assertTrue(checkForErrorCode(error, "error.msg.loan.guarantor.not.found"));
guarantors = this.guarantorHelper.getAllGuarantor(loanID);
assertEquals(4, guarantors.size());
List<HashMap> externalGuarantee_1_details = (List<HashMap>) this.guarantorHelper.getGuarantor(externalGuarantee_1, loanID,
"guarantorFundingDetails");
Integer fundDetailId = (Integer) externalGuarantee_1_details.get(0).get("id");
errorlog = this.guarantorHelper.deleteGuarantor(externalGuarantee_1, fundDetailId, loanID);
error = (ArrayList<HashMap>) errorlog.get(CommonConstants.RESPONSE_ERROR);
assertTrue(checkForErrorCode(error, "validation.msg.loan.guarantor.min.external.guarantee.required"));
guarantorJSON = new GuarantorTestBuilder().existingCustomerWithGuaranteeAmount(String.valueOf(clientID_external),
String.valueOf(externalSavigsId_3), String.valueOf(external1_guarantee)).build();
Integer externalGuarantee_3 = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
verifySavingsOnHoldBalance(externalSavigsId_3, external1_guarantee);
Assert.assertNotNull(externalGuarantee_3);
this.guarantorHelper.deleteGuarantor(externalGuarantee_1, fundDetailId, loanID);
guarantors = this.guarantorHelper.getAllGuarantor(loanID);
assertEquals(4, guarantors.size());
externalGuarantee_1_details = (List<HashMap>) this.guarantorHelper.getGuarantor(externalGuarantee_1, loanID,
"guarantorFundingDetails");
assertEquals(2, externalGuarantee_1_details.size());
for (HashMap map : externalGuarantee_1_details) {
if (map.get("id").equals(fundDetailId)) {
HashMap status = (HashMap) map.get("status");
assertEquals("guarantorFundStatusType.withdrawn", status.get("code"));
}
}
System.out.println("-------------------------------DISBURSE LOAN-------------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID);
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
// First repayment
ArrayList<HashMap> loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -7 * 3);
String LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
Float totalDueForCurrentPeriod = (Float) loanSchedule.get(1).get("totalDueForPeriod");
external1_hold_funds -= new Float(827.5867);
external2_hold_funds -= new Float(413.7933);
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, totalDueForCurrentPeriod, loanID);
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_3, external1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_2, external2_hold_funds);
// Second repayment
todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -7 * 2);
LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
totalDueForCurrentPeriod = (Float) loanSchedule.get(2).get("totalDueForPeriod");
external1_hold_funds -= new Float(831.4067);
external2_hold_funds -= new Float(415.7033333);
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, totalDueForCurrentPeriod, loanID);
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_3, external1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_2, external2_hold_funds);
// third repayment
todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -7);
LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
totalDueForCurrentPeriod = (Float) loanSchedule.get(3).get("totalDueForPeriod");
Float self1_hold_funds_temp = self1_hold_funds - new Float(741.355);
HashMap transactionDetail = this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, totalDueForCurrentPeriod, loanID);
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds_temp);
verifySavingsOnHoldBalance(externalSavigsId_3, new Float(0));
verifySavingsOnHoldBalance(externalSavigsId_2, new Float(0));
// undo repayment
this.loanTransactionHelper.adjustLoanTransaction(loanID, (Integer) transactionDetail.get(CommonConstants.RESPONSE_RESOURCE_ID),
LOAN_REPAYMENT_DATE, "0", "");
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_3, external1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_2, external2_hold_funds);
// undo disbursal
loanStatusHashMap = this.loanTransactionHelper.undoDisbursal(loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
verifySavingsOnHoldBalance(selfSavigsId, new Float(self1_guarantee));
verifySavingsOnHoldBalance(externalSavigsId_3, new Float(external1_guarantee));
verifySavingsOnHoldBalance(externalSavigsId_2, new Float(external2_guarantee));
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testGuarantor_RECOVER_GUARANTEES() {
Float self1_hold_funds = new Float(0);
Float external1_hold_funds = new Float(0);
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID);
final Integer clientID_external = ClientHelper.createClient(this.requestSpec, this.responseSpec);
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID_external);
final Integer selfSavigsId = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID,
String.valueOf(self1_balance));
final Integer externalSavigsId_1 = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID_external,
String.valueOf(external1_balance));
final Integer loanProductID = createLoanProductWithHoldFunds("40", "20", "20");
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
Calendar todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -21);
String LOAN_DISBURSEMENT_DATE = dateFormat.format(todaysDate.getTime());
final Integer loanID = applyForLoanApplication(clientID, loanProductID, LOAN_DISBURSEMENT_DATE);
Assert.assertNotNull(loanID);
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
String guarantorJSON = new GuarantorTestBuilder().existingCustomerWithGuaranteeAmount(String.valueOf(clientID),
String.valueOf(selfSavigsId), String.valueOf(self1_guarantee)).build();
Integer selfGuarantee = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
verifySavingsOnHoldBalance(selfSavigsId, null);
Assert.assertNotNull(selfGuarantee);
guarantorJSON = new GuarantorTestBuilder().existingCustomerWithGuaranteeAmount(String.valueOf(clientID_external),
String.valueOf(externalSavigsId_1), String.valueOf(external1_guarantee)).build();
Integer externalGuarantee_1 = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
verifySavingsOnHoldBalance(externalSavigsId_1, null);
Assert.assertNotNull(externalGuarantee_1);
System.out.println("-----------------------------------APPROVE LOAN-----------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
self1_hold_funds += self1_guarantee;
external1_hold_funds += external1_guarantee;
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_1, external1_hold_funds);
System.out.println("-------------------------------DISBURSE LOAN-------------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID);
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
// First repayment
ArrayList<HashMap> loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -14);
String LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
Float totalDueForCurrentPeriod = (Float) loanSchedule.get(1).get("totalDueForPeriod");
external1_hold_funds -= new Float(993.104);
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, totalDueForCurrentPeriod, loanID);
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_1, external1_hold_funds);
this.loanTransactionHelper.recoverFromGuarantor(loanID);
verifySavingsBalanceAndOnHoldBalance(selfSavigsId, new Float(0), self1_balance - self1_hold_funds);
verifySavingsBalanceAndOnHoldBalance(externalSavigsId_1, new Float(0), external1_balance - external1_hold_funds);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testGuarantor_WRITE_OFF_LOAN() {
Float self1_hold_funds = new Float(0);
Float external1_hold_funds = new Float(0);
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID);
final Integer clientID_external = ClientHelper.createClient(this.requestSpec, this.responseSpec);
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID_external);
final Integer selfSavigsId = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID,
String.valueOf(self1_balance));
final Integer externalSavigsId_1 = SavingsAccountHelper.openSavingsAccount(this.requestSpec, this.responseSpec, clientID_external,
String.valueOf(external1_balance));
final Integer loanProductID = createLoanProductWithHoldFunds("40", "20", "20");
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
Calendar todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -21);
String LOAN_DISBURSEMENT_DATE = dateFormat.format(todaysDate.getTime());
final Integer loanID = applyForLoanApplication(clientID, loanProductID, LOAN_DISBURSEMENT_DATE);
Assert.assertNotNull(loanID);
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
String guarantorJSON = new GuarantorTestBuilder().existingCustomerWithGuaranteeAmount(String.valueOf(clientID),
String.valueOf(selfSavigsId), String.valueOf(self1_guarantee)).build();
Integer selfGuarantee = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
verifySavingsOnHoldBalance(selfSavigsId, null);
Assert.assertNotNull(selfGuarantee);
guarantorJSON = new GuarantorTestBuilder().existingCustomerWithGuaranteeAmount(String.valueOf(clientID_external),
String.valueOf(externalSavigsId_1), String.valueOf(external1_guarantee)).build();
Integer externalGuarantee_1 = this.guarantorHelper.createGuarantor(loanID, guarantorJSON);
Assert.assertNotNull(externalGuarantee_1);
verifySavingsOnHoldBalance(externalSavigsId_1, null);
System.out.println("-----------------------------------APPROVE LOAN-----------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.approveLoan(LOAN_DISBURSEMENT_DATE, loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
self1_hold_funds += self1_guarantee;
external1_hold_funds += external1_guarantee;
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_1, external1_hold_funds);
System.out.println("-------------------------------DISBURSE LOAN-------------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID);
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
// First repayment
ArrayList<HashMap> loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -14);
String LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
Float totalDueForCurrentPeriod = (Float) loanSchedule.get(1).get("totalDueForPeriod");
external1_hold_funds -= new Float(993.104);
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, totalDueForCurrentPeriod, loanID);
verifySavingsOnHoldBalance(selfSavigsId, self1_hold_funds);
verifySavingsOnHoldBalance(externalSavigsId_1, external1_hold_funds);
todaysDate = Calendar.getInstance();
String LOAN_WRITEOFF_DATE = dateFormat.format(todaysDate.getTime());
this.loanTransactionHelper.writeOffLoan(LOAN_WRITEOFF_DATE, loanID);
verifySavingsBalanceAndOnHoldBalance(selfSavigsId, new Float(0), self1_balance);
verifySavingsBalanceAndOnHoldBalance(externalSavigsId_1, new Float(0), external1_balance);
}
private void verifySavingsOnHoldBalance(final Integer savingsId, final Float expectedBalance) {
Float onHoldAmount = (Float) this.savingsAccountHelper.getSavingsDetails(savingsId, "onHoldFunds");
assertEquals("Verifying On Hold Funds", expectedBalance, onHoldAmount);
}
@SuppressWarnings({ "rawtypes", "cast" })
private void verifySavingsBalanceAndOnHoldBalance(final Integer savingsId, final Float expectedBalance, final Float accountBalance) {
HashMap savingsDetails = (HashMap) this.savingsAccountHelper.getSavingsDetails(savingsId);
assertEquals("Verifying On Hold Funds", expectedBalance, savingsDetails.get("onHoldFunds"));
HashMap summary = (HashMap) savingsDetails.get("summary");
assertEquals("Verifying Account balance", accountBalance, summary.get("accountBalance"));
}
@SuppressWarnings("rawtypes")
private boolean checkForErrorCode(final ArrayList<HashMap> errorData, final String errorcode) {
boolean isExists = false;
for (HashMap errorMap : errorData) {
String actualErrorCode = (String) errorMap.get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE);
if (actualErrorCode != null && actualErrorCode.equals(errorcode)) {
isExists = true;
break;
}
}
return isExists;
}
private Integer createLoanProductWithHoldFunds(final String mandatoryGuarantee, final String minimumGuaranteeFromGuarantor,
final String minimumGuaranteeFromOwnFunds) {
System.out.println("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------");
LoanProductTestBuilder builder = new LoanProductTestBuilder().withPrincipal("10000.00").withNumberOfRepayments("4")
.withRepaymentAfterEvery("1").withRepaymentTypeAsWeek().withinterestRatePerPeriod("2")
.withInterestRateFrequencyTypeAsMonths().withAmortizationTypeAsEqualPrincipalPayment().withInterestTypeAsDecliningBalance()
.withOnHoldFundDetails(mandatoryGuarantee, minimumGuaranteeFromGuarantor, minimumGuaranteeFromOwnFunds);
final String loanProductJSON = builder.build(null);
return this.loanTransactionHelper.getLoanProductId(loanProductJSON);
}
private Integer applyForLoanApplication(final Integer clientID, final Integer loanProductID, final String disbursementDate) {
System.out.println("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
final String loanApplicationJSON = new LoanApplicationTestBuilder() //
.withPrincipal("10000.00") //
.withLoanTermFrequency("4") //
.withLoanTermFrequencyAsWeeks() //
.withNumberOfRepayments("4") //
.withRepaymentEveryAfter("1") //
.withRepaymentFrequencyTypeAsWeeks() //
.withInterestRatePerPeriod("2") //
.withAmortizationTypeAsEqualInstallments() //
.withInterestTypeAsDecliningBalance() //
.withInterestCalculationPeriodTypeSameAsRepaymentPeriod() //
.withExpectedDisbursementDate(disbursementDate) //
.withSubmittedOnDate(disbursementDate) //
.build(clientID.toString(), loanProductID.toString(), null);
return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
}
}
@@ -0,0 +1,74 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.integrationtests.loanaccount.guarantor;
import java.util.HashMap;
import org.mifosplatform.integrationtests.common.Utils;
import com.google.gson.Gson;
public class GuarantorTestBuilder {
private static final String GUARANTOR_TYPE_CUSTOMER = "1";
@SuppressWarnings("unused")
private static final String GUARANTOR_TYPE_STAFF = "2";
private static final String GUARANTOR_TYPE_EXTERNAL = "3";
private String guarantorTypeId = "1";
private String entityId = null;
private String addressLine1 = "addressLine1";
private String addressLine2 = "addressLine2";
private String city = "city";
private String state = "state";
private String zip = "123456";
private String guaranteeAmount = "500";
private String savingsId = null;
public String build() {
final HashMap<String, String> map = new HashMap<>();
map.put("guarantorTypeId", guarantorTypeId);
map.put("locale", "en");
if (GUARANTOR_TYPE_EXTERNAL.equals(guarantorTypeId)) {
map.put("firstname", Utils.randomNameGenerator("guarantor_FirstName_", 5));
map.put("lastname", Utils.randomNameGenerator("guarantor_LastName_", 4));
map.put("addressLine1", addressLine1);
map.put("addressLine2", addressLine2);
map.put("city", city);
map.put("state", state);
map.put("zip", zip);
} else if (GUARANTOR_TYPE_CUSTOMER.equals(guarantorTypeId)) {
map.put("entityId", entityId);
map.put("amount", guaranteeAmount);
map.put("savingsId", savingsId);
}
System.out.println("map : " + map);
return new Gson().toJson(map);
}
public GuarantorTestBuilder existingCustomerWithGuaranteeAmount(final String entityId, final String savingsId,
final String guaranteeAmount) {
this.entityId = entityId;
this.savingsId = savingsId;
this.guaranteeAmount = guaranteeAmount;
this.guarantorTypeId = GUARANTOR_TYPE_CUSTOMER;
return this;
}
public GuarantorTestBuilder existingCustomerWithoutGuaranteeAmount(final String entityId) {
this.entityId = entityId;
this.savingsId = null;
this.guaranteeAmount = null;
this.guarantorTypeId = GUARANTOR_TYPE_CUSTOMER;
return this;
}
public GuarantorTestBuilder externalCustomer() {
this.guarantorTypeId = GUARANTOR_TYPE_EXTERNAL;
return this;
}
}
@@ -7,10 +7,22 @@ package org.mifosplatform.portfolio.common.service;
import org.springframework.data.jpa.domain.AbstractPersistable;
/**
* The interface to be implemented by classes that want to be informed when a
* Business Event executes. example: on completion of loan approval event need
* to block guarantor funds
*
*/
public interface BusinessEventListner {
/**
* Implement this method for notifications before executing Business Event
*/
public void businessEventToBeExecuted(AbstractPersistable<Long> businessEventEntity);
/**
* Implement this method for notifications after executing Business Event
*/
public void businessEventWasExecuted(AbstractPersistable<Long> businessEventEntity);
}
@@ -8,14 +8,35 @@ package org.mifosplatform.portfolio.common.service;
import org.mifosplatform.portfolio.common.BusinessEventNotificationConstants.BUSINESS_EVENTS;
import org.springframework.data.jpa.domain.AbstractPersistable;
/**
* Implemented class is responsible for notifying the business event to
* registered listeners.
*
*/
public interface BusinessEventNotifierService {
/**
* Method should be called to notify listeners before Business event
* execution for any pre-processing of event
*/
public void notifyBusinessEventToBeExecuted(BUSINESS_EVENTS businessEvent, AbstractPersistable<Long> businessEventEntity);
/**
* Method should be called to notify listeners after Business event
* execution for any post-processing of event
*/
public void notifyBusinessEventWasExecuted(BUSINESS_EVENTS businessEvent, AbstractPersistable<Long> businessEventEntity);
/**
* Method is to register a class as listener for pre-processing of any
* Business event
*/
public void addBusinessEventPreListners(BUSINESS_EVENTS businessEvent, BusinessEventListner businessEventListner);
/**
* Method is to register a class as listener for post-processing of any
* Business event
*/
public void addBusinessEventPostListners(BUSINESS_EVENTS businessEvent, BusinessEventListner businessEventListner);
}
@@ -20,6 +20,16 @@ public class BusinessEventNotifierServiceImpl implements BusinessEventNotifierSe
private final Map<BUSINESS_EVENTS, List<BusinessEventListner>> preListners = new HashMap<>(5);
private final Map<BUSINESS_EVENTS, List<BusinessEventListner>> postListners = new HashMap<>(5);
/*
* (non-Javadoc)
*
* @see
* org.mifosplatform.portfolio.common.service.BusinessEventNotifierService
* #notifyBusinessEventToBeExecuted
* (org.mifosplatform.portfolio.common.BusinessEventNotificationConstants
* .BUSINESS_EVENTS,
* org.springframework.data.jpa.domain.AbstractPersistable)
*/
@Override
public void notifyBusinessEventToBeExecuted(BUSINESS_EVENTS businessEvent, AbstractPersistable<Long> businessEventEntity) {
List<BusinessEventListner> businessEventListners = this.preListners.get(businessEvent);
@@ -30,6 +40,16 @@ public class BusinessEventNotifierServiceImpl implements BusinessEventNotifierSe
}
}
/*
* (non-Javadoc)
*
* @see
* org.mifosplatform.portfolio.common.service.BusinessEventNotifierService
* #notifyBusinessEventWasExecuted
* (org.mifosplatform.portfolio.common.BusinessEventNotificationConstants
* .BUSINESS_EVENTS,
* org.springframework.data.jpa.domain.AbstractPersistable)
*/
@Override
public void notifyBusinessEventWasExecuted(BUSINESS_EVENTS businessEvent, AbstractPersistable<Long> businessEventEntity) {
List<BusinessEventListner> businessEventListners = this.postListners.get(businessEvent);
@@ -40,11 +60,31 @@ public class BusinessEventNotifierServiceImpl implements BusinessEventNotifierSe
}
}
/*
* (non-Javadoc)
*
* @see
* org.mifosplatform.portfolio.common.service.BusinessEventNotifierService
* #addBusinessEventPreListners
* (org.mifosplatform.portfolio.common.BusinessEventNotificationConstants
* .BUSINESS_EVENTS,
* org.mifosplatform.portfolio.common.service.BusinessEventListner)
*/
@Override
public void addBusinessEventPreListners(BUSINESS_EVENTS businessEvent, BusinessEventListner businessEventListner) {
addBusinessEventListners(businessEvent, businessEventListner, preListners);
}
/*
* (non-Javadoc)
*
* @see
* org.mifosplatform.portfolio.common.service.BusinessEventNotifierService
* #addBusinessEventPostListners
* (org.mifosplatform.portfolio.common.BusinessEventNotificationConstants
* .BUSINESS_EVENTS,
* org.mifosplatform.portfolio.common.service.BusinessEventListner)
*/
@Override
public void addBusinessEventPostListners(BUSINESS_EVENTS businessEvent, BusinessEventListner businessEventListner) {
addBusinessEventListners(businessEvent, businessEventListner, postListners);
@@ -146,6 +146,10 @@ public class GuarantorDomainServiceImpl implements GuarantorDomainService {
}
/**
* Method assigns a guarantor to loan and blocks the funds on guarantor's
* account
*/
@Override
public void assignGuarantor(final GuarantorFundingDetails guarantorFundingDetails, final LocalDate transactionDate) {
if (guarantorFundingDetails.getStatus().isActive()) {
@@ -168,6 +172,10 @@ public class GuarantorDomainServiceImpl implements GuarantorDomainService {
}
}
/**
* Method releases(withdraw) a guarantor from loan and unblocks the funds on
* guarantor's account
*/
@Override
public void releaseGuarantor(final GuarantorFundingDetails guarantorFundingDetails, final LocalDate transactionDate) {
BigDecimal amoutForWithdraw = guarantorFundingDetails.getAmountRemaining();
@@ -187,6 +195,11 @@ public class GuarantorDomainServiceImpl implements GuarantorDomainService {
}
}
/**
* Method is to recover funds from guarantor's in case loan is unpaid.
* (Transfers guarantee amount from guarantor's account to loan account and
* releases guarantor)
*/
@Override
public void transaferFundsFromGuarantor(final Loan loan) {
if (loan.getGuaranteeAmount().compareTo(BigDecimal.ZERO) != 1) { return; }
@@ -254,6 +267,11 @@ public class GuarantorDomainServiceImpl implements GuarantorDomainService {
}
}
/**
* Method reverses all blocked fund(both hold and release) transactions.
* example: reverses all transactions on undo approval of loan account.
*
*/
private void reverseAllFundTransaction(final Loan loan) {
if (loan.getGuaranteeAmount().compareTo(BigDecimal.ZERO) == 1) {
@@ -274,6 +292,11 @@ public class GuarantorDomainServiceImpl implements GuarantorDomainService {
}
}
/**
* Method holds all guarantor's guarantee amount for a loan account.
* example: hold funds on approval of loan account.
*
*/
private void holdGuarantorFunds(final Loan loan) {
if (loan.loanProduct().isHoldGuaranteeFundsEnabled()) {
final List<Guarantor> existGuarantorList = this.guarantorRepository.findByLoan(loan);
@@ -318,6 +341,13 @@ public class GuarantorDomainServiceImpl implements GuarantorDomainService {
}
}
/**
* Method releases all guarantor's guarantee amount(first external guarantee
* and then self guarantee) for a loan account in the portion of guarantee
* percentage on a paid principal. example: releases funds on repayments of
* loan account.
*
*/
private void releaseGuarantorFunds(final LoanTransaction loanTransaction) {
final Loan loan = loanTransaction.getLoan();
if (loan.getGuaranteeAmount().compareTo(BigDecimal.ZERO) == 1) {
@@ -364,6 +394,11 @@ public class GuarantorDomainServiceImpl implements GuarantorDomainService {
}
/**
* Method releases all guarantor's guarantee amount. example: releases funds
* on write-off of a loan account.
*
*/
private void releaseAllGuarantors(final LoanTransaction loanTransaction) {
Loan loan = loanTransaction.getLoan();
if (loan.getGuaranteeAmount().compareTo(BigDecimal.ZERO) == 1) {
@@ -398,6 +433,11 @@ public class GuarantorDomainServiceImpl implements GuarantorDomainService {
}
}
/**
* Method releases guarantor's guarantee amount on transferring guarantee
* amount to loan account. example: on recovery of guarantee funds from
* guarantor's.
*/
private void completeGuarantorFund(final LoanTransaction loanTransaction) {
Loan loan = loanTransaction.getLoan();
GuarantorFundingDetails guarantorFundingDetails = this.guarantorFundingRepository.findOne(releaseLoanIds.get(loan.getId()));
@@ -437,6 +477,10 @@ public class GuarantorDomainServiceImpl implements GuarantorDomainService {
return amountLeft;
}
/**
* Method reverses the fund release transactions in case of loan transaction
* reversed
*/
private void reverseTransaction(final List<Long> loanTransactionIds) {
List<GuarantorFundingTransaction> fundingTransactions = this.guarantorFundingTransactionRepository
@@ -123,7 +123,7 @@ public class GuarantorWritePlatformServiceJpaRepositoryIImpl implements Guaranto
final Integer guarantorTypeId = guarantorCommand.getGuarantorTypeId();
Guarantor guarantor = null;
for (final Guarantor avilableGuarantor : existGuarantorList) {
if (entityId != null && avilableGuarantor.getEntityId() == entityId
if (entityId != null && avilableGuarantor.getEntityId() != null && avilableGuarantor.getEntityId().equals(entityId)
&& avilableGuarantor.getGurantorType() == guarantorTypeId && avilableGuarantor.isActive()) {
if (guarantorCommand.getSavingsId() == null || avilableGuarantor.hasGuarantor(guarantorCommand.getSavingsId())) {
/** Get the right guarantor based on guarantorType **/
@@ -251,15 +251,7 @@ public class GuarantorWritePlatformServiceJpaRepositoryIImpl implements Guaranto
GuarantorFundingDetails guarantorFundingDetails = guarantorForDelete.getGuarantorFundingDetail(guarantorFundingId);
if (guarantorFundingDetails == null) { throw new GuarantorNotFoundException(loanId, guarantorForDelete.getId(),
guarantorFundingId); }
if (!guarantorFundingDetails.getStatus().isActive()) {
baseDataValidator.failWithCodeNoParameterAddedToErrorCode(GuarantorConstants.GUARANTOR_NOT_ACTIVE_ERROR);
}
GuarantorFundStatusType fundStatusType = GuarantorFundStatusType.DELETED;
if (guarantorForDelete.getLoan().isDisbursed() || guarantorForDelete.getLoan().isApproved()) {
fundStatusType = GuarantorFundStatusType.WITHDRAWN;
this.guarantorDomainService.releaseGuarantor(guarantorFundingDetails, LocalDate.now());
}
guarantorForDelete.updateStatus(guarantorFundingDetails, fundStatusType);
removeguarantorFundDetails(guarantorForDelete, baseDataValidator, guarantorFundingDetails);
}
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
@@ -274,6 +266,19 @@ public class GuarantorWritePlatformServiceJpaRepositoryIImpl implements Guaranto
return commandProcessingResultBuilder.build();
}
private void removeguarantorFundDetails(final Guarantor guarantorForDelete, final DataValidatorBuilder baseDataValidator,
GuarantorFundingDetails guarantorFundingDetails) {
if (!guarantorFundingDetails.getStatus().isActive()) {
baseDataValidator.failWithCodeNoParameterAddedToErrorCode(GuarantorConstants.GUARANTOR_NOT_ACTIVE_ERROR);
}
GuarantorFundStatusType fundStatusType = GuarantorFundStatusType.DELETED;
if (guarantorForDelete.getLoan().isDisbursed() || guarantorForDelete.getLoan().isApproved()) {
fundStatusType = GuarantorFundStatusType.WITHDRAWN;
this.guarantorDomainService.releaseGuarantor(guarantorFundingDetails, LocalDate.now());
}
guarantorForDelete.updateStatus(guarantorFundingDetails, fundStatusType);
}
private void validateGuarantorBusinessRules(final Guarantor guarantor) {
// validate guarantor conditions
if (guarantor.isExistingCustomer()) {