corrected early payment related issues

This commit is contained in:
Pramod Nuthakki
2014-09-23 16:42:37 +05:30
parent ad51032aec
commit 4266e5d705
4 changed files with 73 additions and 31 deletions
@@ -3204,6 +3204,7 @@ public class ClientLoanIntegrationTest {
addRepaymentValues(expectedvalues, todaysDate, 1, "1771.88", "16.39", "0.0", "0.0");
addRepaymentValues(expectedvalues, todaysDate, 1, "1780.05", "8.22", "0.0", "0.0");
verifyLoanRepaymentSchedule(loanSchedule, expectedvalues);
HashMap prepayDetail = this.loanTransactionHelper.getPrepayAmount(this.requestSpec, this.responseSpec, loanID);
String prepayAmount = String.valueOf(prepayDetail.get("amount"));
todaysDate = Calendar.getInstance();
@@ -3266,6 +3267,15 @@ public class ClientLoanIntegrationTest {
verifyLoanRepaymentSchedule(loanSchedule, expectedvalues);
loanSchedule = this.loanTransactionHelper.getLoanFutureRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
expectedvalues = new ArrayList<>();
todaysDate = Calendar.getInstance();
addRepaymentValues(expectedvalues, todaysDate, 0, "4965.31", "92.51", "0.0", "0.0");
addRepaymentValues(expectedvalues, todaysDate, 1, "2505.67", "23.24", "0.0", "0.0");
addRepaymentValues(expectedvalues, todaysDate, 1, "2529.02", "11.67", "0.0", "0.0");
verifyLoanRepaymentSchedule(loanSchedule, expectedvalues,0);
todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -7);
final String LOAN_FIRST_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
@@ -3302,6 +3312,14 @@ public class ClientLoanIntegrationTest {
addRepaymentValues(expectedvalues, todaysDate, 1, "1009.87", "4.66", "0.0", "0.0");
verifyLoanRepaymentSchedule(loanSchedule, expectedvalues);
HashMap prepayDetail = this.loanTransactionHelper.getPrepayAmount(this.requestSpec, this.responseSpec, loanID);
String prepayAmount = String.valueOf(prepayDetail.get("amount"));
todaysDate = Calendar.getInstance();
String LOAN_REPAYMENT_DATE = dateFormat.format(todaysDate.getTime());
this.loanTransactionHelper.makeRepayment(LOAN_REPAYMENT_DATE, new Float(prepayAmount), loanID);
loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
LoanStatusChecker.verifyLoanAccountIsClosed(loanStatusHashMap);
}
@Test
@@ -3313,6 +3331,7 @@ public class ClientLoanIntegrationTest {
Calendar todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.DAY_OF_MONTH, -14);
final String LOAN_DISBURSEMENT_DATE = dateFormat.format(todaysDate.getTime());
todaysDate.add(Calendar.DAY_OF_MONTH, -2);
final String REST_START_DATE = dateFormat.format(todaysDate.getTime());
todaysDate = Calendar.getInstance();
@@ -3366,9 +3385,9 @@ public class ClientLoanIntegrationTest {
expectedvalues = new ArrayList<>();
todaysDate = Calendar.getInstance();
addRepaymentValues(expectedvalues, todaysDate, -1, "2482.76", "46.15", "100.0", "0.0");
addRepaymentValues(expectedvalues, todaysDate, 1, "2482.09", "46.82", "0.0", "0.0");
addRepaymentValues(expectedvalues, todaysDate, 1, "2505.67", "23.24", "12.79", "0.0");
addRepaymentValues(expectedvalues, todaysDate, 1, "2529.48", "11.67", "0.0", "0.0");
addRepaymentValues(expectedvalues, todaysDate, 1, "2490.75", "38.16", "0.0", "0.0");
addRepaymentValues(expectedvalues, todaysDate, 1, "2505.71", "23.2", "11.91", "0.0");
addRepaymentValues(expectedvalues, todaysDate, 1, "2520.78", "11.63", "0.0", "0.0");
verifyLoanRepaymentSchedule(loanSchedule, expectedvalues);
@@ -3397,9 +3416,9 @@ public class ClientLoanIntegrationTest {
expectedvalues = new ArrayList<>();
todaysDate = Calendar.getInstance();
addRepaymentValues(expectedvalues, todaysDate, -1, "2482.76", "46.15", "100.0", "0.0");
addRepaymentValues(expectedvalues, todaysDate, 1, "5065.31", "34.69", "0.0", "0.0");
addRepaymentValues(expectedvalues, todaysDate, 1, "0", "11.32", "10.35", "0.0");
addRepaymentValues(expectedvalues, todaysDate, 1, "2451.93", "11.32", "0.0", "0.0");
addRepaymentValues(expectedvalues, todaysDate, 1, "5100", "27.96", "0.0", "0.0");
addRepaymentValues(expectedvalues, todaysDate, 1, "0", "11.16", "9.64", "0.0");
addRepaymentValues(expectedvalues, todaysDate, 1, "2417.24", "11.16", "0.0", "0.0");
verifyLoanRepaymentSchedule(loanSchedule, expectedvalues);
HashMap prepayDetail = this.loanTransactionHelper.getPrepayAmount(this.requestSpec, this.responseSpec, loanID);
@@ -3481,20 +3500,24 @@ public class ClientLoanIntegrationTest {
}
private void verifyLoanRepaymentSchedule(final ArrayList<HashMap> loanSchedule, List<Map<String, Object>> expectedvalues) {
System.out.println("--------------------VERIFYING THE PRINCIPAL DUES,INTEREST DUE AND DUE DATE--------------------------");
int i = 1;
for (Map<String, Object> values : expectedvalues) {
assertEquals("Checking for Due Date for Month " + i, values.get("dueDate"), loanSchedule.get(i).get("dueDate"));
validateNumberForEqualWithMsg("Checking for Principal Due for Month " + i, String.valueOf(values.get("principalDue")),
String.valueOf(loanSchedule.get(i).get("principalDue")));
validateNumberForEqualWithMsg("Checking for Interest Due for Month " + i, String.valueOf(values.get("interestDue")),
String.valueOf(loanSchedule.get(i).get("interestDue")));
validateNumberForEqualWithMsg("Checking for Fee charge Due for Month " + i, String.valueOf(values.get("feeChargesDue")),
String.valueOf(loanSchedule.get(i).get("feeChargesDue")));
validateNumberForEqualWithMsg("Checking for Penalty charge Due for Month " + i,
String.valueOf(values.get("penaltyChargesDue")), String.valueOf(loanSchedule.get(i).get("penaltyChargesDue")));
i++;
}
int index = 1;
verifyLoanRepaymentSchedule(loanSchedule, expectedvalues, index);
}
private void verifyLoanRepaymentSchedule(final ArrayList<HashMap> loanSchedule, List<Map<String, Object>> expectedvalues, int index) {
System.out.println("--------------------VERIFYING THE PRINCIPAL DUES,INTEREST DUE AND DUE DATE--------------------------");
for (Map<String, Object> values : expectedvalues) {
assertEquals("Checking for Due Date for installment " + index, values.get("dueDate"), loanSchedule.get(index).get("dueDate"));
validateNumberForEqualWithMsg("Checking for Principal Due for installment " + index,
String.valueOf(values.get("principalDue")), String.valueOf(loanSchedule.get(index).get("principalDue")));
validateNumberForEqualWithMsg("Checking for Interest Due for installment " + index, String.valueOf(values.get("interestDue")),
String.valueOf(loanSchedule.get(index).get("interestDue")));
validateNumberForEqualWithMsg("Checking for Fee charge Due for installment " + index,
String.valueOf(values.get("feeChargesDue")), String.valueOf(loanSchedule.get(index).get("feeChargesDue")));
validateNumberForEqualWithMsg("Checking for Penalty charge Due for installment " + index,
String.valueOf(values.get("penaltyChargesDue")), String.valueOf(loanSchedule.get(index).get("penaltyChargesDue")));
index++;
}
}
}
@@ -63,7 +63,7 @@ public class LoanTransactionHelper {
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");
}
@@ -444,6 +444,13 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
final LoanTransaction preCloseTransaction) {
List<RecalculationDetail> earlypaymentDetail = new ArrayList<>();
Money currentInstallmentOutstanding = installment.getTotalOutstanding(currency);
LocalDate maxTransactionDate = null;
Set<LocalDate> transaDates = recalculationDates.keySet();
for (LocalDate transactionDate : transaDates) {
if (maxTransactionDate == null || transactionDate.isAfter(maxTransactionDate)) {
maxTransactionDate = transactionDate;
}
}
for (final LoanTransaction loanTransaction : transactionsPostDisbursement) {
Money amountToProcess = null;
LocalDate transactionDate = loanTransaction.getTransactionDate();
@@ -454,10 +461,14 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
if (newLoanTransaction.isRepayment() || newLoanTransaction.isInterestWaiver() || newLoanTransaction.isRecoveryRepayment()) {
newLoanTransaction.resetDerivedComponents();
}
Money unProcessed = processTransaction(newLoanTransaction, currency, installments, amountToProcess);
if (transactionDate.isAfter(installment.getFromDate()) && transactionDate.isBefore(installment.getDueDate())) {
if (loanTransaction.getTransactionDate().isEqual(maxTransactionDate) && transactionDate.isAfter(installment.getFromDate())
&& transactionDate.isBefore(installment.getDueDate())) {
Money earlyPayment = currentInstallmentOutstanding.minus(installment.getTotalOutstanding(currency));
if (earlyPayment.isGreaterThanZero() && (newLoanTransaction.isRepayment() || newLoanTransaction.isInterestWaiver() || newLoanTransaction.isRecoveryRepayment())) {
if (earlyPayment.isGreaterThanZero()
&& (newLoanTransaction.isRepayment() || newLoanTransaction.isInterestWaiver() || newLoanTransaction
.isRecoveryRepayment())) {
earlypaymentDetail.add(new RecalculationDetail(false, transactionDate, null, earlyPayment, false));
}
currentInstallmentOutstanding = installment.getTotalOutstanding(currency);
@@ -405,6 +405,10 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
outstandingBalance = outstandingBalance.zero();
}
}
if (fixedEmiAmount.isZero() && !recalculatedInterestComponent) {
fixedEmiAmount = principalForThisPeriod.plus(interestForThisinstallment);
}
reducePrincipal = reducePrincipal.minus(reducePrincipalForCurrentInstallment);
if (principalForThisPeriod.isGreaterThan(reducePrincipalForCurrentInstallment)) {
@@ -436,10 +440,6 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
reducePrincipal = reducePrincipal.plus(reducePrincipalForCurrentInstallment);
if (fixedEmiAmount.isZero() && !recalculatedInterestComponent) {
fixedEmiAmount = principalForThisPeriod.plus(interestForThisinstallment);
}
actualOutstandingbalance = actualOutstandingbalance.minus(reducePrincipal);
if (actualOutstandingbalance.isLessThanZero()) {
actualOutstandingbalance = actualOutstandingbalance.zero();
@@ -1292,9 +1292,13 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
}
}
if (installment.isRecalculatedInterestComponent() && installment.getPrincipal(currency).isGreaterThanZero()) {
diffAmt.add(new RecalculationDetail(false, installment.getDueDate(), null, installment.getPrincipal(currency), false));
}
/*
* if (installment.isRecalculatedInterestComponent() &&
* installment.getPrincipal(currency).isGreaterThanZero()) {
* diffAmt.add(new RecalculationDetail(false,
* installment.getDueDate(), null,
* installment.getPrincipal(currency), false)); }
*/
List<RecalculationDetail> earlypaymentDetail = loanRepaymentScheduleTransactionProcessor.handleRepaymentSchedule(
transactionsForInstallment, currency, processinstallmets, installment, recalculationDates, preCloseTransaction);
@@ -1648,18 +1652,22 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
List<LoanRepaymentScheduleInstallment> installments, MonetaryCurrency currency, final LoanApplicationTerms applicationTerms,
MathContext mc, final Set<LoanCharge> loanCharges) {
LoanTransaction precloseTransaction = null;
Money collectedPrincipal = Money.zero(currency);
for (LoanTransaction loanTransaction : loanTransactions) {
if (precloseTransaction == null
|| (!precloseTransaction.getTransactionDate().isAfter(loanTransaction.getTransactionDate()) && (loanTransaction.getId() == null || (precloseTransaction
.getId() != null && loanTransaction.getId().compareTo(precloseTransaction.getId()) == 1)))) {
precloseTransaction = loanTransaction;
}
collectedPrincipal = collectedPrincipal.plus(loanTransaction.getPrincipalPortion());
}
if (precloseTransaction != null) {
LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment = calculatePrepaymentAmount(installments, currency,
precloseTransaction.getTransactionDate(), applicationTerms.getInterestChargedFromLocalDate(), applicationTerms, mc,
loanCharges);
if (precloseTransaction.getAmount(currency).isLessThan(loanRepaymentScheduleInstallment.getTotalOutstanding(currency))) {
Money pendingPrinciapl = applicationTerms.getPrincipal().minus(collectedPrincipal).plus(precloseTransaction.getPrincipalPortion());
if (pendingPrinciapl.isGreaterThan(loanRepaymentScheduleInstallment.getPrincipal(currency))
|| precloseTransaction.getAmount(currency).isLessThan(loanRepaymentScheduleInstallment.getTotalOutstanding(currency))) {
precloseTransaction = null;
}
}