MIFOSX-1272 : added recalculation of charges for diff disburse amount

This commit is contained in:
Pramod Nuthakki
2014-06-18 13:19:15 +05:30
parent 9aa9473c8c
commit 9c9c91b44a
3 changed files with 117 additions and 47 deletions
@@ -188,6 +188,65 @@ public class ClientLoanIntegrationTest {
validateNumberForEqual("0.0", String.valueOf(disbursementDetail.get("feeChargesDue")));
}
@Test
public void testLoanCharges_DISBURSEMENT_FEE_WITH_AMOUNT_CHANGE() {
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec);
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID);
final Integer loanProductID = createLoanProduct(false, NONE);
List<HashMap> charges = new ArrayList<HashMap>();
Integer amountPercentage = ChargesHelper.createCharges(requestSpec, responseSpec,
ChargesHelper.getLoanDisbursementJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT, "1"));
addCharges(charges, amountPercentage, "1", null);
Integer amountPlusInterestPercentage = ChargesHelper.createCharges(requestSpec, responseSpec,
ChargesHelper.getLoanDisbursementJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT_AND_INTEREST, "1"));
addCharges(charges, amountPlusInterestPercentage, "1", null);
Integer interestPercentage = ChargesHelper.createCharges(requestSpec, responseSpec,
ChargesHelper.getLoanDisbursementJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_INTEREST, "1"));
addCharges(charges, interestPercentage, "1", null);
final Integer loanID = applyForLoanApplication(clientID, loanProductID, charges, null, "12,000.00");
Assert.assertNotNull(loanID);
HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID);
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
ArrayList<HashMap> loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
HashMap disbursementDetail = loanSchedule.get(0);
List<HashMap> loanCharges = this.loanTransactionHelper.getLoanCharges(loanID);
validateCharge(amountPercentage, loanCharges, "1.0", "120.0", "0.0", "0.0");
validateCharge(interestPercentage, loanCharges, "1.0", "6.06", "0.0", "0.0");
validateCharge(amountPlusInterestPercentage, loanCharges, "1.0", "126.06", "0.0", "0.0");
validateNumberForEqual("252.12", String.valueOf(disbursementDetail.get("feeChargesDue")));
System.out.println("-----------------------------------APPROVE LOAN-----------------------------------------");
loanStatusHashMap = this.loanTransactionHelper.approveLoan("20 September 2011", loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
// DISBURSE
loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID,"10000");
System.out.println("DISBURSE " + loanStatusHashMap);
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
loanCharges = this.loanTransactionHelper.getLoanCharges(loanID);
loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
disbursementDetail = loanSchedule.get(0);
validateCharge(amountPercentage, loanCharges, "1.0", "0.0", "100.0", "0.0");
validateCharge(interestPercentage, loanCharges, "1.0", "0.0", "5.05", "0.0");
validateCharge(amountPlusInterestPercentage, loanCharges, "1.0", "0.0", "105.05", "0.0");
validateNumberForEqual("210.1", String.valueOf(disbursementDetail.get("feeChargesDue")));
}
@Test
public void testLoanCharges_SPECIFIED_DUE_DATE_FEE() {
@@ -83,11 +83,15 @@ public class LoanTransactionHelper {
}
public HashMap disburseLoan(final String date, final Integer loanID) {
return performLoanTransaction(createLoanOperationURL(DISBURSE_LOAN_COMMAND, loanID), getDisburseLoanAsJSON(date));
return performLoanTransaction(createLoanOperationURL(DISBURSE_LOAN_COMMAND, loanID), getDisburseLoanAsJSON(date, null));
}
public HashMap disburseLoan(final String date, final Integer loanID, final String disburseAmt) {
return performLoanTransaction(createLoanOperationURL(DISBURSE_LOAN_COMMAND, loanID), getDisburseLoanAsJSON(date, disburseAmt));
}
public HashMap disburseLoanToSavings(final String date, final Integer loanID) {
return performLoanTransaction(createLoanOperationURL(DISBURSE_LOAN_TO_SAVINGS_COMMAND, loanID), getDisburseLoanAsJSON(date));
return performLoanTransaction(createLoanOperationURL(DISBURSE_LOAN_TO_SAVINGS_COMMAND, loanID), getDisburseLoanAsJSON(date, null));
}
public HashMap undoDisbursal(final Integer loanID) {
@@ -105,11 +109,11 @@ public class LoanTransactionHelper {
public HashMap waiveInterest(final String date, final String amountToBeWaived, final Integer loanID) {
return performLoanTransaction(createLoanTransactionURL(WAIVE_INTEREST_COMMAND, loanID), getWaiveBodyAsJSON(date, amountToBeWaived));
}
public Integer waiveInterestAndReturnTransactionId(final String date, final String amountToBeWaived, final Integer loanID) {
Integer resourceId = Utils.performServerPost(this.requestSpec, this.responseSpec, createLoanTransactionURL(WAIVE_INTEREST_COMMAND, loanID),
getWaiveBodyAsJSON(date, amountToBeWaived), "resourceId");
return resourceId;
Integer resourceId = Utils.performServerPost(this.requestSpec, this.responseSpec,
createLoanTransactionURL(WAIVE_INTEREST_COMMAND, loanID), getWaiveBodyAsJSON(date, amountToBeWaived), "resourceId");
return resourceId;
}
public HashMap makeRepayment(final String date, final Float amountToBePaid, final Integer loanID) {
@@ -161,12 +165,15 @@ public class LoanTransactionHelper {
return (Integer) response.get("resourceId");
}
private String getDisburseLoanAsJSON(final String actualDisbursementDate) {
private String getDisburseLoanAsJSON(final String actualDisbursementDate, final String transactionAmount) {
final HashMap<String, String> map = new HashMap<String, String>();
map.put("locale", "en");
map.put("dateFormat", "dd MMMM yyyy");
map.put("actualDisbursementDate", actualDisbursementDate);
map.put("note", "DISBURSE NOTE");
if (transactionAmount != null) {
map.put("transactionAmount", transactionAmount);
}
return new Gson().toJson(map);
}
@@ -1200,23 +1200,7 @@ public class Loan extends AbstractPersistable<Long> {
actualChanges.put("recalculateLoanSchedule", true);
for (final LoanCharge loanCharge : possiblyModifedLoanCharges) {
final BigDecimal amount = calculateAmountPercentageAppliedTo(loanCharge);
BigDecimal chargeAmt = BigDecimal.ZERO;
BigDecimal totalChargeAmt = BigDecimal.ZERO;
if (loanCharge.getChargeCalculation().isPercentageBased()) {
chargeAmt = loanCharge.getPercentage();
if (loanCharge.isInstalmentFee()) {
totalChargeAmt = calculatePerInstallmentChargeAmount(loanCharge);
}
} else {
chargeAmt = loanCharge.amount();
if (loanCharge.isInstalmentFee()) {
chargeAmt = chargeAmt.divide(BigDecimal.valueOf(repaymentScheduleDetail().getNumberOfRepayments()));
}
}
loanCharge.update(chargeAmt, loanCharge.getDueLocalDate(), amount, repaymentScheduleDetail().getNumberOfRepayments(),
totalChargeAmt);
validateChargeHasValidSpecifiedDateIfApplicable(loanCharge, getDisbursementDate(), getLastRepaymentPeriodDueDate());
recalculateLoanCharge(loanCharge);
}
}
@@ -1276,6 +1260,26 @@ public class Loan extends AbstractPersistable<Long> {
return actualChanges;
}
private void recalculateLoanCharge(final LoanCharge loanCharge) {
final BigDecimal amount = calculateAmountPercentageAppliedTo(loanCharge);
BigDecimal chargeAmt = BigDecimal.ZERO;
BigDecimal totalChargeAmt = BigDecimal.ZERO;
if (loanCharge.getChargeCalculation().isPercentageBased()) {
chargeAmt = loanCharge.getPercentage();
if (loanCharge.isInstalmentFee()) {
totalChargeAmt = calculatePerInstallmentChargeAmount(loanCharge);
}
} else {
chargeAmt = loanCharge.amount();
if (loanCharge.isInstalmentFee()) {
chargeAmt = chargeAmt.divide(BigDecimal.valueOf(repaymentScheduleDetail().getNumberOfRepayments()));
}
}
loanCharge.update(chargeAmt, loanCharge.getDueLocalDate(), amount, repaymentScheduleDetail().getNumberOfRepayments(),
totalChargeAmt);
validateChargeHasValidSpecifiedDateIfApplicable(loanCharge, getDisbursementDate(), getLastRepaymentPeriodDueDate());
}
private void updateDisbursementDetails(final JsonCommand command, final Map<String, Object> actualChanges) {
List<Long> list = fetchDisbursementIds();
@@ -1470,23 +1474,7 @@ public class Loan extends AbstractPersistable<Long> {
// charges are optional
for (final LoanCharge loanCharge : charges()) {
final BigDecimal amount = calculateAmountPercentageAppliedTo(loanCharge);
BigDecimal chargeAmt = BigDecimal.ZERO;
BigDecimal totalChargeAmt = BigDecimal.ZERO;
if (loanCharge.getChargeCalculation().isPercentageBased()) {
chargeAmt = loanCharge.getPercentage();
if (loanCharge.isInstalmentFee()) {
totalChargeAmt = calculatePerInstallmentChargeAmount(loanCharge);
}
} else {
chargeAmt = loanCharge.amount();
if (loanCharge.isInstalmentFee()) {
chargeAmt = chargeAmt.divide(BigDecimal.valueOf(repaymentScheduleDetail().getNumberOfRepayments()));
}
}
loanCharge.update(chargeAmt, loanCharge.getDueLocalDate(), amount, repaymentScheduleDetail().getNumberOfRepayments(),
totalChargeAmt);
validateChargeHasValidSpecifiedDateIfApplicable(loanCharge, getDisbursementDate(), getLastRepaymentPeriodDueDate());
recalculateLoanCharge(loanCharge);
}
updateSummaryWithTotalFeeChargesDueAtDisbursement(deriveSumTotalOfChargesDueAtDisbursement());
@@ -1722,7 +1710,6 @@ public class Loan extends AbstractPersistable<Long> {
validateDisbursementDateIsOnNonWorkingDay(workingDays, allowTransactionsOnNonWorkingDay);
validateDisbursementDateIsOnHoliday(allowTransactionsOnHoliday, holidays);
handleDisbursementTransaction(actualDisbursementDate);
BigDecimal emiAmount = command.bigDecimalValueOfParameterNamed(LoanApiConstants.emiAmountParameterName);
boolean isEmiAmountChanged = false;
if (this.loanProduct.isMultiDisburseLoan() && emiAmount != null && emiAmount.compareTo(retriveLastEmiAmount()) != 0) {
@@ -1734,11 +1721,17 @@ public class Loan extends AbstractPersistable<Long> {
if (isRepaymentScheduleRegenerationRequiredForDisbursement(actualDisbursementDate) || recalculateSchedule || isEmiAmountChanged) {
regenerateRepaymentSchedule(loanScheduleFactory, currency, calculatedRepaymentsStartingFromDate, isHolidayEnabled, holidays,
workingDays);
updateLoanRepaymentPeriodsDerivedFields(actualDisbursementDate);
} else {
updateLoanRepaymentPeriodsDerivedFields(actualDisbursementDate);
updateLoanSummaryDerivedFields();
if (recalculateSchedule) {
Set<LoanCharge> charges = this.charges();
for (LoanCharge loanCharge : charges) {
recalculateLoanCharge(loanCharge);
}
updateSummaryWithTotalFeeChargesDueAtDisbursement(deriveSumTotalOfChargesDueAtDisbursement());
}
}
updateLoanRepaymentPeriodsDerivedFields(actualDisbursementDate);
updateLoanSummaryDerivedFields();
handleDisbursementTransaction(actualDisbursementDate);
final Money interestApplied = Money.of(getCurrency(), this.summary.getTotalInterestCharged());
@@ -2104,6 +2097,13 @@ public class Loan extends AbstractPersistable<Long> {
regenerateRepaymentSchedule(loanScheduleFactory, applicationCurrency, calculatedRepaymentsStartingFromDate,
isHolidayEnabled, holidays, workingDays);
if(isDisbueseAmtChanged){
Set<LoanCharge> charges = charges();
for (LoanCharge loanCharge : charges) {
recalculateLoanCharge(loanCharge);
}
updateSummaryWithTotalFeeChargesDueAtDisbursement(deriveSumTotalOfChargesDueAtDisbursement());
}
}
actualChanges.put("actualDisbursementDate", "");
@@ -3843,4 +3843,8 @@ public class Loan extends AbstractPersistable<Long> {
return installment;
}
public BigDecimal getApprovedPrincipal() {
return this.approvedPrincipal;
}
}