MIFOSX-2049 and fix failing test cases

This commit is contained in:
Vishwas Babu A J
2015-09-06 00:04:35 +05:30
parent 66ce3b4873
commit 8f1eb39d5d
17 changed files with 707 additions and 669 deletions
+3 -3
View File
@@ -35848,8 +35848,8 @@ Request Body:
<div class="method-description">
<h4>List Client Charges</h4>
<p>The <i>list</i> capability of client charges can support <b>pagination</b> and <b>sorting</b>.</p>
<h5>Mandatory Arguments</h5>
<p>The <i>list</i> capability of client charges supports <b>pagination</b>.</p>
<h5>Optional Arguments</h5>
<dl class="argument-list">
<dt>offset</dt>
<dd>
@@ -35867,7 +35867,7 @@ Request Body:
<dd>
String <span>optional</span>
</dd>
<dd>Only returns those charges which are pending payment (neither paid or waived).</dd>
<dd> Filters charges that are pending payment (neither paid or waived).</dd>
</dl>
<p>Example Requests:</p>
<div class=apiClick>clients/189/charges</div>
@@ -7,6 +7,8 @@ package org.mifosplatform.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;
@@ -32,537 +34,454 @@ 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).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]", 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.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());
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());
}
}
/* 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).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);
}
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).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).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);
}
}
@@ -74,14 +74,15 @@ public class ClientChargesTest {
final String clientChargePaidTransactionId = ClientHelper.payChargesForClients(this.requestSpec, this.responseSpec, clientId,
clientChargeId, ClientHelper.getPayChargeJSON("25 AUGUST 2015", "10"));
Assert.assertNotNull(clientChargePaidTransactionId);
isValidOutstandingAmount(ClientHelper.getClientCharge(requestSpec, responseSpec, clientId.toString()), (float) 190.0);
isValidOutstandingAmount(ClientHelper.getClientCharge(requestSpec, responseSpec, clientId.toString(), clientChargeId.toString()),
(float) 190.0);
/**
* Revert the paid client charge transaction by passing the
* clientChargePaidTransactionId and ensure the same is reverted.
*/
final Integer undoTrxnId = ClientHelper.revertClientChargeTransaction(this.requestSpec, this.responseSpec, clientId.toString(),
clientChargePaidTransactionId);
final Integer undoTrxnId = ClientHelper.revertClientChargeTransaction(this.requestSpec, this.responseSpec,
clientId.toString(), clientChargePaidTransactionId);
Assert.assertNotNull(undoTrxnId);
isReversedTransaction(clientId.toString(), undoTrxnId.toString());
/**
@@ -103,8 +104,8 @@ public class ClientChargesTest {
* waiveOffClientChargeTransactionId and ensured the transaction is
* reversed.
*/
final Integer undoWaiveTrxnId = ClientHelper.revertClientChargeTransaction(this.requestSpec, this.responseSpec,
clientId.toString(), waiveOffClientChargeTransactionId);
final Integer undoWaiveTrxnId = ClientHelper.revertClientChargeTransaction(this.requestSpec, this.responseSpec, clientId.toString(),
waiveOffClientChargeTransactionId);
Assert.assertNotNull(undoWaiveTrxnId);
isReversedTransaction(clientId.toString(), undoWaiveTrxnId.toString());
/**
@@ -130,7 +131,8 @@ public class ClientChargesTest {
clientChargeId, ClientHelper.getPayChargeJSON("25 AUGUST 2015", "100"));
Assert.assertNotNull(chargePaid_responseId);
isValidOutstandingAmount(ClientHelper.getClientCharge(requestSpec, responseSpec, clientId.toString()), (float) 100.0);
isValidOutstandingAmount(ClientHelper.getClientCharge(requestSpec, responseSpec, clientId.toString(), clientChargeId.toString()),
(float) 100.0);
}
@@ -147,8 +149,8 @@ public class ClientChargesTest {
}
/**
* Check whether the outStandingAmount is equal to expected Amount or not after
* paying or after waiving off the client charge.
* Check whether the outStandingAmount is equal to expected Amount or not
* after paying or after waiving off the client charge.
*
* @param outStandingAmount
* @param expectedAmount
@@ -7,7 +7,6 @@ package org.mifosplatform.integrationtests.common;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.HashMap;
import org.mifosplatform.integrationtests.common.system.CodeHelper;
@@ -57,12 +56,12 @@ public class ClientHelper {
"clientId");
}
public static Integer createClientForAccountPreference(final RequestSpecification requestSpec,
final ResponseSpecification responseSpec, final Integer clientType, String jsonAttributeToGetBack) {
public static Integer createClientForAccountPreference(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final Integer clientType, String jsonAttributeToGetBack) {
final String activationDate = "04 March 2011";
final String officeId = "1";
System.out
.println("---------------------------------CREATING A CLIENT BASED ON ACCOUNT PREFERENCE---------------------------------------------");
System.out.println(
"---------------------------------CREATING A CLIENT BASED ON ACCOUNT PREFERENCE---------------------------------------------");
return Utils.performServerPost(requestSpec, responseSpec, CREATE_CLIENT_URL,
getTestClientWithClientTypeAsJSON(activationDate, officeId, clientType.toString()), jsonAttributeToGetBack);
}
@@ -305,7 +304,7 @@ public class ClientHelper {
final Integer clientId, final String request) {
System.out.println("--------------------------------- ADD CHARGES FOR Client --------------------------------");
final String ADD_CHARGES_URL = "/mifosng-provider/api/v1/clients/" + clientId + "/charges?" + Utils.TENANT_IDENTIFIER;
final HashMap response = Utils.performServerPost(requestSpec, responseSpec, ADD_CHARGES_URL, request, "");
final HashMap<?, ?> response = Utils.performServerPost(requestSpec, responseSpec, ADD_CHARGES_URL, request, "");
return (Integer) response.get("resourceId");
}
@@ -314,7 +313,7 @@ public class ClientHelper {
System.out.println("--------------------------------- PAY CHARGES FOR CLIENT --------------------------------");
final String CHARGES_URL = "/mifosng-provider/api/v1/clients/" + clientId + "/charges/" + clientChargeId + "?command=paycharge&"
+ Utils.TENANT_IDENTIFIER;
final HashMap response = Utils.performServerPost(requestSpec, responseSpec, CHARGES_URL, json, "");
final HashMap<?, ?> response = Utils.performServerPost(requestSpec, responseSpec, CHARGES_URL, json, "");
return response.get("transactionId") != null ? response.get("transactionId").toString() : null;
}
@@ -324,7 +323,7 @@ public class ClientHelper {
final String CHARGES_URL = "/mifosng-provider/api/v1/clients/" + clientId + "/charges/" + clientChargeId + "?command=waive&"
+ Utils.TENANT_IDENTIFIER;
final HashMap response = Utils.performServerPost(requestSpec, responseSpec, CHARGES_URL, json, "");
final HashMap<?, ?> response = Utils.performServerPost(requestSpec, responseSpec, CHARGES_URL, json, "");
return response.get("transactionId").toString();
}
@@ -334,17 +333,17 @@ public class ClientHelper {
final String CHARGES_URL = "/mifosng-provider/api/v1/clients/" + clientId + "/transactions/" + clientChargeId + "?command=undo&"
+ Utils.TENANT_IDENTIFIER;
final HashMap response = Utils.performServerPost(requestSpec, responseSpec, CHARGES_URL, "", "");
final HashMap<?, ?> response = Utils.performServerPost(requestSpec, responseSpec, CHARGES_URL, "", "");
return (Integer) response.get("resourceId");
}
public static Object getClientCharge(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final String clientId) {
final String clientId, final String clientChargeId) {
System.out.println("---------------------------------GET CLIENT CHARGE---------------------------------------------");
final String CHARGES_URL = "/mifosng-provider/api/v1/clients/" + clientId + "/charges?paid=false&" + Utils.TENANT_IDENTIFIER;
ArrayList list = Utils.performServerGet(requestSpec, responseSpec, CHARGES_URL, "amountOutstanding");
return list != null && !list.isEmpty() ? list.get(0) : null;
final String CHARGES_URL = "/mifosng-provider/api/v1/clients/" + clientId + "/charges/" + clientChargeId + "?"
+ Utils.TENANT_IDENTIFIER;
return Utils.performServerGet(requestSpec, responseSpec, CHARGES_URL, "amountOutstanding");
}
public static Boolean getClientTransactions(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
@@ -120,6 +120,20 @@ public final class SearchParameters {
loanId, savingsId, orphansOnly);
}
public static SearchParameters forPagination(final Integer offset, final Integer limit) {
final Integer maxLimitAllowed = getCheckedLimit(limit);
final Long staffId = null;
final Long loanId = null;
final Long savingsId = null;
final Boolean orphansOnly = false;
final String orderBy = null;
final String sortOrder = null;
return new SearchParameters(null, null, null, null, null, null, null, offset, maxLimitAllowed, orderBy, sortOrder, staffId, null,
loanId, savingsId, orphansOnly);
}
public static SearchParameters forSavings(final String sqlSearch, final String externalId, final Integer offset, final Integer limit,
final String orderBy, final String sortOrder) {
@@ -171,10 +185,10 @@ public final class SearchParameters {
this.currencyCode = null;
}
public SearchParameters(final String sqlSearch, final Long officeId, final String externalId, final String name,
final String hierarchy, final String firstname, final String lastname, final Integer offset, final Integer limit,
final String orderBy, final String sortOrder, final Long staffId, final String accountNo, final Long loanId,
final Long savingsId, final Boolean orphansOnly, final String currencyCode) {
public SearchParameters(final String sqlSearch, final Long officeId, final String externalId, final String name, final String hierarchy,
final String firstname, final String lastname, final Integer offset, final Integer limit, final String orderBy,
final String sortOrder, final Long staffId, final String accountNo, final Long loanId, final Long savingsId,
final Boolean orphansOnly, final String currencyCode) {
this.sqlSearch = sqlSearch;
this.officeId = officeId;
this.externalId = externalId;
@@ -245,11 +259,11 @@ public final class SearchParameters {
public Long getOfficeId() {
return this.officeId;
}
public String getCurrencyCode(){
public String getCurrencyCode() {
return this.currencyCode;
}
public String getExternalId() {
return this.externalId;
}
@@ -33,6 +33,7 @@ import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamExc
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.core.service.Page;
import org.mifosplatform.infrastructure.core.service.SearchParameters;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.charge.data.ChargeData;
import org.mifosplatform.portfolio.charge.service.ChargeReadPlatformService;
@@ -89,9 +90,10 @@ public class ClientChargesApiResource {
new Object[] { ClientApiConstants.CLIENT_CHARGE_QUERY_PARAM_STATUS_VALUE_ALL,
ClientApiConstants.CLIENT_CHARGE_QUERY_PARAM_STATUS_VALUE_ACTIVE,
ClientApiConstants.CLIENT_CHARGE_QUERY_PARAM_STATUS_VALUE_INACTIVE }); }
final SearchParameters searchParameters = SearchParameters.forPagination(offset, limit);
final Page<ClientChargeData> clientCharges = this.clientChargeReadPlatformService.retrieveClientCharges(clientId, chargeStatus,
pendingPayment, limit, offset);
pendingPayment, searchParameters);
return this.toApiJsonSerializer.serialize(settings, clientCharges, ClientApiConstants.CLIENT_CHARGES_RESPONSE_DATA_PARAMETERS);
}
@@ -26,6 +26,7 @@ import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamExc
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.core.service.Page;
import org.mifosplatform.infrastructure.core.service.SearchParameters;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.data.ClientTransactionData;
import org.mifosplatform.portfolio.client.service.ClientTransactionReadPlatformService;
@@ -61,8 +62,10 @@ public class ClientTransactionsApiResource {
public String retrieveAllClientTransactions(@PathParam("clientId") final Long clientId, @Context final UriInfo uriInfo,
@QueryParam("offset") final Integer offset, @QueryParam("limit") final Integer limit) {
this.context.authenticatedUser().validateHasReadPermission(ClientApiConstants.CLIENT_CHARGES_RESOURCE_NAME);
SearchParameters searchParameters = SearchParameters.forPagination(offset, limit);
final Page<ClientTransactionData> clientTransactions = this.clientTransactionReadPlatformService.retrieveAllTransactions(clientId,
limit, offset);
searchParameters);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, clientTransactions,
@@ -5,6 +5,7 @@
*/
package org.mifosplatform.portfolio.client.domain;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.exception.ClientNotActiveException;
import org.mifosplatform.portfolio.client.exception.ClientNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
@@ -20,10 +21,12 @@ import org.springframework.stereotype.Service;
public class ClientRepositoryWrapper {
private final ClientRepository repository;
private final PlatformSecurityContext context;
@Autowired
public ClientRepositoryWrapper(final ClientRepository repository) {
public ClientRepositoryWrapper(final ClientRepository repository, final PlatformSecurityContext context) {
this.repository = repository;
this.context = context;
}
public Client findOneWithNotFoundDetection(final Long id) {
@@ -44,9 +47,11 @@ public class ClientRepositoryWrapper {
this.repository.delete(client);
}
public Client getActiveClient(Long clientId) {
public Client getActiveClientInUserScope(Long clientId) {
final Client client = this.findOneWithNotFoundDetection(clientId);
if (client.isNotActive()) { throw new ClientNotActiveException(client.getId()); }
this.context.validateAccessRights(client.getOffice().getHierarchy());
return client;
}
}
@@ -6,12 +6,12 @@
package org.mifosplatform.portfolio.client.service;
import org.mifosplatform.infrastructure.core.service.Page;
import org.mifosplatform.infrastructure.core.service.SearchParameters;
import org.mifosplatform.portfolio.client.data.ClientChargeData;
public interface ClientChargeReadPlatformService {
Page<ClientChargeData> retrieveClientCharges(Long clientId, String status, Boolean isPaid, Integer limit, Integer offset);
Page<ClientChargeData> retrieveClientCharges(Long clientId, String status, Boolean pendingPayment, SearchParameters parameters);
ClientChargeData retrieveClientCharge(Long clientId, Long clientChargeId);
@@ -16,6 +16,7 @@ import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
import org.mifosplatform.infrastructure.core.service.Page;
import org.mifosplatform.infrastructure.core.service.PaginationHelper;
import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
import org.mifosplatform.infrastructure.core.service.SearchParameters;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.monetary.data.CurrencyData;
import org.mifosplatform.portfolio.charge.data.ChargeData;
@@ -118,8 +119,8 @@ public class ClientChargeReadPlatformServiceImpl implements ClientChargeReadPlat
}
@Override
public Page<ClientChargeData> retrieveClientCharges(Long clientId, String status, Boolean pendingPayment, Integer limit,
Integer offset) {
public Page<ClientChargeData> retrieveClientCharges(Long clientId, String status, Boolean pendingPayment,
SearchParameters searchParameters) {
final ClientChargeMapper rm = new ClientChargeMapper();
final StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.append("select SQL_CALC_FOUND_ROWS ").append(rm.schema()).append(" where cc.client_id=? ");
@@ -133,13 +134,21 @@ public class ClientChargeReadPlatformServiceImpl implements ClientChargeReadPlat
// filter for paid charges
if (pendingPayment != null && pendingPayment) {
sqlBuilder.append(" and ( cc.is_paid_derived = 0 and cc.waived = 1) ");
sqlBuilder.append(" and ( cc.is_paid_derived = 0 and cc.waived = 0) ");
} else if (pendingPayment != null && !pendingPayment) {
sqlBuilder.append(" and (cc.is_paid_derived = 1 or cc.waived = 0) ");
sqlBuilder.append(" and (cc.is_paid_derived = 1 or cc.waived = 1) ");
}
sqlBuilder.append(" order by cc.charge_time_enum ASC, cc.charge_due_date DESC, cc.is_penalty ASC ");
// apply limit and offsets
if (searchParameters.isLimited()) {
sqlBuilder.append(" limit ").append(searchParameters.getLimit());
if (searchParameters.isOffset()) {
sqlBuilder.append(" offset ").append(searchParameters.getOffset());
}
}
sqlBuilder.append(
" order by cc.charge_time_enum ASC, cc.charge_due_date DESC, cc.is_penalty ASC " + "limit " + limit + " offset " + offset);
final String sqlCountRows = "SELECT FOUND_ROWS()";
return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), new Object[] { clientId },
this.clientChargeMapper);
@@ -23,6 +23,7 @@ import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
import org.mifosplatform.infrastructure.core.service.DateUtils;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.holiday.domain.HolidayRepositoryWrapper;
@@ -43,12 +44,17 @@ import org.mifosplatform.portfolio.client.domain.ClientTransactionRepository;
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
import org.mifosplatform.portfolio.paymentdetail.service.PaymentDetailWritePlatformService;
import org.mifosplatform.useradministration.domain.AppUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
@Service
public class ClientChargeWritePlatformServiceJpaRepositoryImpl implements ClientChargeWritePlatformService {
private final static Logger logger = LoggerFactory.getLogger(ClientChargeWritePlatformServiceJpaRepositoryImpl.class);
private final PlatformSecurityContext context;
private final ChargeRepositoryWrapper chargeRepository;
private final ClientRepositoryWrapper clientRepository;
@@ -84,74 +90,83 @@ public class ClientChargeWritePlatformServiceJpaRepositoryImpl implements Client
@Override
public CommandProcessingResult addCharge(Long clientId, JsonCommand command) {
try {
this.clientChargeDataValidator.validateAdd(command.json());
this.clientChargeDataValidator.validateAdd(command.json());
final Client client = clientRepository.getActiveClientInUserScope(clientId);
final Client client = clientRepository.getActiveClient(clientId);
final Long chargeDefinitionId = command.longValueOfParameterNamed(ClientApiConstants.chargeIdParamName);
final Charge charge = this.chargeRepository.findOneWithNotFoundDetection(chargeDefinitionId);
final Long chargeDefinitionId = command.longValueOfParameterNamed(ClientApiConstants.chargeIdParamName);
final Charge charge = this.chargeRepository.findOneWithNotFoundDetection(chargeDefinitionId);
// validate for client charge
if (!charge.isClientCharge()) {
final String errorMessage = "Charge with identifier " + charge.getId() + " cannot be applied to a Client";
throw new ChargeCannotBeAppliedToException("client", errorMessage, charge.getId());
}
// validate for client charge
if (!charge.isClientCharge()) {
final String errorMessage = "Charge with identifier " + charge.getId() + " cannot be applied to a Client";
throw new ChargeCannotBeAppliedToException("client", errorMessage, charge.getId());
final ClientCharge clientCharge = ClientCharge.createNew(client, charge, command);
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat());
validateDueDateOnWorkingDay(clientCharge, fmt);
this.clientChargeRepository.save(clientCharge);
return new CommandProcessingResultBuilder() //
.withEntityId(clientCharge.getId()) //
.withOfficeId(clientCharge.getClient().getOffice().getId()) //
.withClientId(clientCharge.getClient().getId()) //
.build();
} catch (DataIntegrityViolationException dve) {
handleDataIntegrityIssues(clientId, null, dve);
return CommandProcessingResult.empty();
}
final ClientCharge clientCharge = ClientCharge.createNew(client, charge, command);
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat());
validateDueDateOnWorkingDay(clientCharge, fmt);
this.clientChargeRepository.save(clientCharge);
return new CommandProcessingResultBuilder() //
.withEntityId(clientCharge.getId()) //
.withOfficeId(clientCharge.getClient().getOffice().getId()) //
.withClientId(clientCharge.getClient().getId()) //
.build();
}
@Override
public CommandProcessingResult payCharge(Long clientId, Long clientChargeId, JsonCommand command) {
this.clientChargeDataValidator.validatePayCharge(command.json());
try {
this.clientChargeDataValidator.validatePayCharge(command.json());
final Client client = this.clientRepository.getActiveClient(clientId);
final Client client = this.clientRepository.getActiveClientInUserScope(clientId);
final ClientCharge clientCharge = this.clientChargeRepository.findOneWithNotFoundDetection(clientChargeId);
final ClientCharge clientCharge = this.clientChargeRepository.findOneWithNotFoundDetection(clientChargeId);
final Locale locale = command.extractLocale();
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
final LocalDate transactionDate = command.localDateValueOfParameterNamed(ClientApiConstants.transactionDateParamName);
final BigDecimal amountPaid = command.bigDecimalValueOfParameterNamed(ClientApiConstants.amountParamName);
final Money chargePaid = Money.of(clientCharge.getCurrency(), amountPaid);
final Locale locale = command.extractLocale();
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
final LocalDate transactionDate = command.localDateValueOfParameterNamed(ClientApiConstants.transactionDateParamName);
final BigDecimal amountPaid = command.bigDecimalValueOfParameterNamed(ClientApiConstants.amountParamName);
final Money chargePaid = Money.of(clientCharge.getCurrency(), amountPaid);
// Validate business rules for payment
validatePaymentTransaction(client, clientCharge, fmt, transactionDate, amountPaid);
// Validate business rules for payment
validatePaymentTransaction(client, clientCharge, fmt, transactionDate, amountPaid);
// pay the charge
clientCharge.pay(chargePaid);
// pay the charge
clientCharge.pay(chargePaid);
// create Payment Transaction
final Map<String, Object> changes = new LinkedHashMap<>();
final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes);
// create Payment Transaction
final Map<String, Object> changes = new LinkedHashMap<>();
final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes);
ClientTransaction clientTransaction = ClientTransaction.payCharge(client, client.getOffice(), paymentDetail, transactionDate,
chargePaid, clientCharge.getCurrency().getCode(), getAppUserIfPresent());
this.clientTransactionRepository.saveAndFlush(clientTransaction);
ClientTransaction clientTransaction = ClientTransaction.payCharge(client, client.getOffice(), paymentDetail, transactionDate,
chargePaid, clientCharge.getCurrency().getCode(), getAppUserIfPresent());
this.clientTransactionRepository.saveAndFlush(clientTransaction);
// update charge paid by associations
final ClientChargePaidBy chargePaidBy = ClientChargePaidBy.instance(clientTransaction, clientCharge, amountPaid);
clientTransaction.getClientChargePaidByCollection().add(chargePaidBy);
// update charge paid by associations
final ClientChargePaidBy chargePaidBy = ClientChargePaidBy.instance(clientTransaction, clientCharge, amountPaid);
clientTransaction.getClientChargePaidByCollection().add(chargePaidBy);
// generate accounting entries
generateAccountingEntries(clientTransaction);
// generate accounting entries
generateAccountingEntries(clientTransaction);
return new CommandProcessingResultBuilder() //
.withTransactionId(clientTransaction.getId().toString())//
.withEntityId(clientCharge.getId()) //
.withOfficeId(clientCharge.getClient().getOffice().getId()) //
.withClientId(clientCharge.getClient().getId()).build();
return new CommandProcessingResultBuilder() //
.withTransactionId(clientTransaction.getId().toString())//
.withEntityId(clientCharge.getId()) //
.withOfficeId(clientCharge.getClient().getOffice().getId()) //
.withClientId(clientCharge.getClient().getId()).build();
} catch (DataIntegrityViolationException dve) {
handleDataIntegrityIssues(clientId, clientChargeId, dve);
return CommandProcessingResult.empty();
}
}
@@ -162,54 +177,65 @@ public class ClientChargeWritePlatformServiceJpaRepositoryImpl implements Client
@Override
public CommandProcessingResult waiveCharge(Long clientId, Long clientChargeId) {
final Client client = this.clientRepository.getActiveClient(clientId);
final ClientCharge clientCharge = this.clientChargeRepository.findOneWithNotFoundDetection(clientChargeId);
final LocalDate transactionDate = DateUtils.getLocalDateOfTenant();
try {
final Client client = this.clientRepository.getActiveClientInUserScope(clientId);
final ClientCharge clientCharge = this.clientChargeRepository.findOneWithNotFoundDetection(clientChargeId);
final LocalDate transactionDate = DateUtils.getLocalDateOfTenant();
// Validate business rules for payment
validateWaiverTransaction(client, clientCharge);
// Validate business rules for payment
validateWaiverTransaction(client, clientCharge);
// waive the charge
Money waivedAmount = clientCharge.waive();
// waive the charge
Money waivedAmount = clientCharge.waive();
// create Waiver Transaction
ClientTransaction clientTransaction = ClientTransaction.waiver(client, client.getOffice(), transactionDate, waivedAmount,
clientCharge.getCurrency().getCode(), getAppUserIfPresent());
this.clientTransactionRepository.save(clientTransaction);
// create Waiver Transaction
ClientTransaction clientTransaction = ClientTransaction.waiver(client, client.getOffice(), transactionDate, waivedAmount,
clientCharge.getCurrency().getCode(), getAppUserIfPresent());
this.clientTransactionRepository.save(clientTransaction);
// update charge paid by associations
final ClientChargePaidBy chargePaidBy = ClientChargePaidBy.instance(clientTransaction, clientCharge, waivedAmount.getAmount());
clientTransaction.getClientChargePaidByCollection().add(chargePaidBy);
// update charge paid by associations
final ClientChargePaidBy chargePaidBy = ClientChargePaidBy.instance(clientTransaction, clientCharge, waivedAmount.getAmount());
clientTransaction.getClientChargePaidByCollection().add(chargePaidBy);
return new CommandProcessingResultBuilder().withTransactionId(clientTransaction.getId().toString())//
.withEntityId(clientCharge.getId()) //
.withOfficeId(clientCharge.getClient().getOffice().getId()) //
.withClientId(clientCharge.getClient().getId()) //
.build();
return new CommandProcessingResultBuilder().withTransactionId(clientTransaction.getId().toString())//
.withEntityId(clientCharge.getId()) //
.withOfficeId(clientCharge.getClient().getOffice().getId()) //
.withClientId(clientCharge.getClient().getId()) //
.build();
} catch (DataIntegrityViolationException dve) {
handleDataIntegrityIssues(clientId, clientChargeId, dve);
return CommandProcessingResult.empty();
}
}
@Override
public CommandProcessingResult deleteCharge(Long clientId, Long clientChargeId) {
final Client client = this.clientRepository.getActiveClient(clientId);
final ClientCharge clientCharge = this.clientChargeRepository.findOneWithNotFoundDetection(clientChargeId);
try {
final Client client = this.clientRepository.getActiveClientInUserScope(clientId);
final ClientCharge clientCharge = this.clientChargeRepository.findOneWithNotFoundDetection(clientChargeId);
// Validate business rules for charge deletion
validateChargeDeletion(client, clientCharge);
// Validate business rules for charge deletion
validateChargeDeletion(client, clientCharge);
// delete the charge
clientChargeRepository.delete(clientCharge);
// delete the charge
clientChargeRepository.delete(clientCharge);
return new CommandProcessingResultBuilder() //
.withEntityId(clientCharge.getId()) //
.withOfficeId(clientCharge.getClient().getOffice().getId()) //
.withClientId(clientCharge.getClient().getId()) //
.build();
return new CommandProcessingResultBuilder() //
.withEntityId(clientCharge.getId()) //
.withOfficeId(clientCharge.getClient().getOffice().getId()) //
.withClientId(clientCharge.getClient().getId()) //
.build();
} catch (DataIntegrityViolationException dve) {
handleDataIntegrityIssues(clientId, clientChargeId, dve);
return CommandProcessingResult.empty();
}
}
/**
* Validates transaction to ensure that <br>
* charge is active <br>
* transaction date is valid (between client activation and todays date) <br>
* transaction date is valid (between client activation and todays date)
* <br>
* charge is not already paid or waived <br>
* amount is not more than total due
*
@@ -304,14 +330,16 @@ public class ClientChargeWritePlatformServiceJpaRepositoryImpl implements Client
* @return
*/
@Override
public CommandProcessingResult updateCharge(Long clientId, JsonCommand command) {
// this.clientChargeDataValidator.validateAdd(command.json());
public CommandProcessingResult updateCharge(@SuppressWarnings("unused") Long clientId,
@SuppressWarnings("unused") JsonCommand command) {
// functionality not yet supported
return null;
}
@Override
@SuppressWarnings("unused")
public CommandProcessingResult inactivateCharge(Long clientId, Long clientChargeId) {
// TODO Auto-generated method stub
// functionality not yet supported
return null;
}
@@ -378,4 +406,19 @@ public class ClientChargeWritePlatformServiceJpaRepositoryImpl implements Client
return user;
}
private void handleDataIntegrityIssues(@SuppressWarnings("unused") final Long clientId, final Long clientChargeId,
final DataIntegrityViolationException dve) {
final Throwable realCause = dve.getMostSpecificCause();
if (realCause.getMessage().contains("FK_m_client_charge_paid_by_m_client_charge")) {
throw new PlatformDataIntegrityException("error.msg.client.charge.cannot.be.deleted",
"Client charge with id `" + clientChargeId + "` cannot be deleted as transactions have been made on the same",
"clientChargeId", clientChargeId); }
logger.error(dve.getMessage(), dve);
throw new PlatformDataIntegrityException("error.msg.client.charges.unknown.data.integrity.issue",
"Unknown data integrity issue with resource.");
}
}
@@ -8,13 +8,14 @@ package org.mifosplatform.portfolio.client.service;
import java.util.Collection;
import org.mifosplatform.infrastructure.core.service.Page;
import org.mifosplatform.infrastructure.core.service.SearchParameters;
import org.mifosplatform.portfolio.client.data.ClientTransactionData;
import org.springframework.transaction.annotation.Transactional;
public interface ClientTransactionReadPlatformService {
@Transactional(readOnly = true)
public Page<ClientTransactionData> retrieveAllTransactions(Long clientId, Integer limit, Integer offset);
public Page<ClientTransactionData> retrieveAllTransactions(Long clientId, SearchParameters parameters);
@Transactional(readOnly = true)
public Collection<ClientTransactionData> retrieveAllTransactions(final Long clientId, final Long chargeId);
@@ -16,6 +16,7 @@ import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
import org.mifosplatform.infrastructure.core.service.Page;
import org.mifosplatform.infrastructure.core.service.PaginationHelper;
import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
import org.mifosplatform.infrastructure.core.service.SearchParameters;
import org.mifosplatform.organisation.monetary.data.CurrencyData;
import org.mifosplatform.portfolio.client.data.ClientTransactionData;
import org.mifosplatform.portfolio.client.domain.ClientEnumerations;
@@ -121,13 +122,24 @@ public class ClientTransactionReadPlatformServiceImpl implements ClientTransacti
}
@Override
public Page<ClientTransactionData> retrieveAllTransactions(Long clientId, Integer limit, Integer offset) {
public Page<ClientTransactionData> retrieveAllTransactions(Long clientId, SearchParameters searchParameters) {
Object[] parameters = new Object[1];
String sql = "select SQL_CALC_FOUND_ROWS " + this.clientTransactionMapper.schema() + " where c.id = ? ";
final StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.append("select SQL_CALC_FOUND_ROWS ").append(this.clientTransactionMapper.schema()).append(" where c.id = ? ");
parameters[0] = clientId;
final String sqlCountRows = "SELECT FOUND_ROWS()";
sql = sql + " order by tr.transaction_date DESC, tr.created_date DESC, tr.id DESC limit " + limit + " offset " + offset;
return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sql, parameters, this.clientTransactionMapper);
sqlBuilder.append(" order by tr.transaction_date DESC, tr.created_date DESC, tr.id DESC ");
// apply limit and offsets
if (searchParameters.isLimited()) {
sqlBuilder.append(" limit ").append(searchParameters.getLimit());
if (searchParameters.isOffset()) {
sqlBuilder.append(" offset ").append(searchParameters.getOffset());
}
}
return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), parameters,
this.clientTransactionMapper);
}
@Override
@@ -45,7 +45,7 @@ public class ClientTransactionWritePlatformServiceJpaRepositoryImpl implements C
@Override
public CommandProcessingResult undo(Long clientId, Long transactionId) {
final Client client = this.clientRepository.getActiveClient(clientId);
final Client client = this.clientRepository.getActiveClientInUserScope(clientId);
final ClientTransaction clientTransaction = this.clientTransactionRepository.findOneWithNotFoundDetection(clientId, transactionId);
@@ -19,6 +19,7 @@ public class DisbursementData implements Comparable<DisbursementData> {
private final LocalDate expectedDisbursementDate;
private final LocalDate actualDisbursementDate;
private final BigDecimal principal;
@SuppressWarnings("unused")
private final String loanChargeId;
private final BigDecimal chargeAmount;
@@ -43,11 +44,11 @@ public class DisbursementData implements Comparable<DisbursementData> {
public BigDecimal amount() {
return this.principal;
}
public BigDecimal getChargeAmount(){
return this.chargeAmount;
public BigDecimal getChargeAmount() {
return this.chargeAmount;
}
public boolean isDisbursed() {
return this.actualDisbursementDate != null;
}
@@ -373,6 +373,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
this.summary = new SavingsAccountSummary();
this.allowOverdraft = allowOverdraft;
this.overdraftLimit = overdraftLimit;
esnureOverdraftLimitsSetForOverdraftAccounts();
this.enforceMinRequiredBalance = enforceMinRequiredBalance;
this.minRequiredBalance = minRequiredBalance;
@@ -1110,7 +1111,20 @@ public class SavingsAccount extends AbstractPersistable<Long> {
}
validateLockinDetails(baseDataValidator);
esnureOverdraftLimitsSetForOverdraftAccounts();
}
/**
* If overdrafts are allowed and the overdraft limit is not set, set the
* same to Zero
**/
private void esnureOverdraftLimitsSetForOverdraftAccounts() {
if (this.allowOverdraft && this.overdraftLimit == null) {
this.overdraftLimit = BigDecimal.ZERO;
}
}
private void validateLockinDetails(final DataValidatorBuilder baseDataValidator) {
@@ -141,7 +141,7 @@ public class SavingsProduct extends AbstractPersistable<Long> {
protected boolean withdrawalFeeApplicableForTransfer;
@ManyToMany
@JoinTable(name = "m_savings_product_charge", joinColumns = @JoinColumn(name = "savings_product_id"), inverseJoinColumns = @JoinColumn(name = "charge_id"))
@JoinTable(name = "m_savings_product_charge", joinColumns = @JoinColumn(name = "savings_product_id") , inverseJoinColumns = @JoinColumn(name = "charge_id") )
protected Set<Charge> charges;
@Column(name = "allow_overdraft")
@@ -236,11 +236,24 @@ public class SavingsProduct extends AbstractPersistable<Long> {
this.allowOverdraft = allowOverdraft;
this.overdraftLimit = overdraftLimit;
esnureOverdraftLimitsSetForOverdraftAccounts();
this.enforceMinRequiredBalance = enforceMinRequiredBalance;
this.minRequiredBalance = minRequiredBalance;
this.minBalanceForInterestCalculation = minBalanceForInterestCalculation;
}
/**
* If overdrafts are allowed and the overdraft limit is not set, set the
* same to Zero
**/
private void esnureOverdraftLimitsSetForOverdraftAccounts() {
if (this.allowOverdraft && this.overdraftLimit() == null) {
this.overdraftLimit = BigDecimal.ZERO;
}
}
public MonetaryCurrency currency() {
return this.currency.copy();
}
@@ -448,6 +461,7 @@ public class SavingsProduct extends AbstractPersistable<Long> {
}
validateLockinDetails();
esnureOverdraftLimitsSetForOverdraftAccounts();
return actualChanges;
}