Merge pull request #1494 from pramodn02/develop
MIFOSX-2123 : added fix to change the principal amount
This commit is contained in:
+5
-2
@@ -520,7 +520,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
BigDecimal fixedEmiAmount = loanApplicationTerms.getFixedEmiAmount();
|
BigDecimal fixedEmiAmount = loanApplicationTerms.getFixedEmiAmount();
|
||||||
reducePrincipal = applyEarlyPaymentStrategy(loanApplicationTerms, reducePrincipal, totalCumulativePrincipal,
|
reducePrincipal = applyEarlyPaymentStrategy(loanApplicationTerms, reducePrincipal, totalCumulativePrincipal,
|
||||||
periodNumber + 1, mc, holidayDetailDTO);
|
periodNumber + 1, mc, holidayDetailDTO);
|
||||||
if (fixedEmiAmount.compareTo(loanApplicationTerms.getFixedEmiAmount()) != 0) {
|
if (loanApplicationTerms.getAmortizationMethod().isEqualInstallment() && fixedEmiAmount.compareTo(loanApplicationTerms.getFixedEmiAmount()) != 0) {
|
||||||
isEmiAmountChanged = true;
|
isEmiAmountChanged = true;
|
||||||
}
|
}
|
||||||
principalForThisPeriod = principalForThisPeriod.plus(earlyPaidAmount);
|
principalForThisPeriod = principalForThisPeriod.plus(earlyPaidAmount);
|
||||||
@@ -643,7 +643,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
reducePrincipal = applyEarlyPaymentStrategy(loanApplicationTerms, reducePrincipal,
|
reducePrincipal = applyEarlyPaymentStrategy(loanApplicationTerms, reducePrincipal,
|
||||||
totalCumulativePrincipal.plus(principalForThisPeriod.minus(principalProcessed)), periodNumber + 1, mc,
|
totalCumulativePrincipal.plus(principalForThisPeriod.minus(principalProcessed)), periodNumber + 1, mc,
|
||||||
holidayDetailDTO);
|
holidayDetailDTO);
|
||||||
if (fixedEmiAmount.compareTo(loanApplicationTerms.getFixedEmiAmount()) != 0) {
|
if (loanApplicationTerms.getAmortizationMethod().isEqualInstallment() && fixedEmiAmount.compareTo(loanApplicationTerms.getFixedEmiAmount()) != 0) {
|
||||||
isEmiAmountChanged = true;
|
isEmiAmountChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -943,6 +943,9 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
updateFixedInstallmentAmount(mc, loanApplicationTerms, loanApplicationTerms.getExpectedDisbursementDate(),
|
updateFixedInstallmentAmount(mc, loanApplicationTerms, loanApplicationTerms.getExpectedDisbursementDate(),
|
||||||
periodNumber, loanApplicationTerms.getPrincipal().minus(totalCumulativePrincipal), holidayDetailDTO);
|
periodNumber, loanApplicationTerms.getPrincipal().minus(totalCumulativePrincipal), holidayDetailDTO);
|
||||||
}
|
}
|
||||||
|
if(loanApplicationTerms.getAmortizationMethod().isEqualPrincipal()){
|
||||||
|
loanApplicationTerms.updateFixedPrincipalAmount(mc, periodNumber, loanApplicationTerms.getPrincipal().minus(totalCumulativePrincipal));
|
||||||
|
}
|
||||||
reducePrincipal = reducePrincipal.zero();
|
reducePrincipal = reducePrincipal.zero();
|
||||||
break;
|
break;
|
||||||
case REDUCE_NUMBER_OF_INSTALLMENTS:
|
case REDUCE_NUMBER_OF_INSTALLMENTS:
|
||||||
|
|||||||
+34
-20
@@ -7,7 +7,6 @@ package org.mifosplatform.portfolio.loanaccount.loanschedule.domain;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.MathContext;
|
import java.math.MathContext;
|
||||||
import java.math.RoundingMode;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -117,6 +116,8 @@ public final class LoanApplicationTerms {
|
|||||||
|
|
||||||
private BigDecimal fixedEmiAmount;
|
private BigDecimal fixedEmiAmount;
|
||||||
|
|
||||||
|
private BigDecimal fixedPrincipalAmount;
|
||||||
|
|
||||||
private final BigDecimal actualFixedEmiAmount;
|
private final BigDecimal actualFixedEmiAmount;
|
||||||
|
|
||||||
private final BigDecimal maxOutstandingBalance;
|
private final BigDecimal maxOutstandingBalance;
|
||||||
@@ -148,7 +149,7 @@ public final class LoanApplicationTerms {
|
|||||||
|
|
||||||
private final LoanPreClosureInterestCalculationStrategy preClosureInterestCalculationStrategy;
|
private final LoanPreClosureInterestCalculationStrategy preClosureInterestCalculationStrategy;
|
||||||
|
|
||||||
private Money approvedPrincipal = null ;
|
private Money approvedPrincipal = null;
|
||||||
|
|
||||||
public static LoanApplicationTerms assembleFrom(final ApplicationCurrency currency, final Integer loanTermFrequency,
|
public static LoanApplicationTerms assembleFrom(final ApplicationCurrency currency, final Integer loanTermFrequency,
|
||||||
final PeriodFrequencyType loanTermPeriodFrequencyType, final Integer numberOfRepayments, final Integer repaymentEvery,
|
final PeriodFrequencyType loanTermPeriodFrequencyType, final Integer numberOfRepayments, final Integer repaymentEvery,
|
||||||
@@ -166,7 +167,8 @@ public final class LoanApplicationTerms {
|
|||||||
final RecalculationFrequencyType recalculationFrequencyType, final CalendarInstance restCalendarInstance,
|
final RecalculationFrequencyType recalculationFrequencyType, final CalendarInstance restCalendarInstance,
|
||||||
final CalendarInstance compoundingCalendarInstance, final RecalculationFrequencyType compoundingFrequencyType,
|
final CalendarInstance compoundingCalendarInstance, final RecalculationFrequencyType compoundingFrequencyType,
|
||||||
final BigDecimal principalThresholdForLastInstalment, final Integer installmentAmountInMultiplesOf,
|
final BigDecimal principalThresholdForLastInstalment, final Integer installmentAmountInMultiplesOf,
|
||||||
final LoanPreClosureInterestCalculationStrategy preClosureInterestCalculationStrategy, final Calendar loanCalendar, BigDecimal approvedAmount) {
|
final LoanPreClosureInterestCalculationStrategy preClosureInterestCalculationStrategy, final Calendar loanCalendar,
|
||||||
|
BigDecimal approvedAmount) {
|
||||||
|
|
||||||
final LoanRescheduleStrategyMethod rescheduleStrategyMethod = null;
|
final LoanRescheduleStrategyMethod rescheduleStrategyMethod = null;
|
||||||
final InterestRecalculationCompoundingMethod interestRecalculationCompoundingMethod = null;
|
final InterestRecalculationCompoundingMethod interestRecalculationCompoundingMethod = null;
|
||||||
@@ -341,7 +343,8 @@ public final class LoanApplicationTerms {
|
|||||||
final CalendarInstance restCalendarInstance, final RecalculationFrequencyType recalculationFrequencyType,
|
final CalendarInstance restCalendarInstance, final RecalculationFrequencyType recalculationFrequencyType,
|
||||||
final CalendarInstance compoundingCalendarInstance, final RecalculationFrequencyType compoundingFrequencyType,
|
final CalendarInstance compoundingCalendarInstance, final RecalculationFrequencyType compoundingFrequencyType,
|
||||||
final BigDecimal principalThresholdForLastInstalment, final Integer installmentAmountInMultiplesOf,
|
final BigDecimal principalThresholdForLastInstalment, final Integer installmentAmountInMultiplesOf,
|
||||||
final LoanPreClosureInterestCalculationStrategy preClosureInterestCalculationStrategy, final Calendar loanCalendar, BigDecimal approvedAmount) {
|
final LoanPreClosureInterestCalculationStrategy preClosureInterestCalculationStrategy, final Calendar loanCalendar,
|
||||||
|
BigDecimal approvedAmount) {
|
||||||
this.currency = currency;
|
this.currency = currency;
|
||||||
this.loanTermFrequency = loanTermFrequency;
|
this.loanTermFrequency = loanTermFrequency;
|
||||||
this.loanTermPeriodFrequencyType = loanTermPeriodFrequencyType;
|
this.loanTermPeriodFrequencyType = loanTermPeriodFrequencyType;
|
||||||
@@ -390,7 +393,7 @@ public final class LoanApplicationTerms {
|
|||||||
this.preClosureInterestCalculationStrategy = preClosureInterestCalculationStrategy;
|
this.preClosureInterestCalculationStrategy = preClosureInterestCalculationStrategy;
|
||||||
|
|
||||||
this.loanCalendar = loanCalendar;
|
this.loanCalendar = loanCalendar;
|
||||||
this.approvedPrincipal = Money.of(principal.getCurrency(), approvedAmount) ;
|
this.approvedPrincipal = Money.of(principal.getCurrency(), approvedAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Money adjustPrincipalIfLastRepaymentPeriod(final Money principalForPeriod, final Money totalCumulativePrincipalToDate,
|
public Money adjustPrincipalIfLastRepaymentPeriod(final Money principalForPeriod, final Money totalCumulativePrincipalToDate,
|
||||||
@@ -490,8 +493,7 @@ public final class LoanApplicationTerms {
|
|||||||
case DECLINING_BALANCE:
|
case DECLINING_BALANCE:
|
||||||
switch (this.amortizationMethod) {
|
switch (this.amortizationMethod) {
|
||||||
case EQUAL_INSTALLMENTS:
|
case EQUAL_INSTALLMENTS:
|
||||||
Money totalPmtForThisInstallment = pmtForInstallment(calculator, daysInPeriod, outstandingBalance, periodNumber,
|
Money totalPmtForThisInstallment = pmtForInstallment(calculator, daysInPeriod, outstandingBalance, periodNumber, mc);
|
||||||
mc);
|
|
||||||
principalForInstallment = calculatePrincipalDueForInstallment(periodNumber, totalPmtForThisInstallment,
|
principalForInstallment = calculatePrincipalDueForInstallment(periodNumber, totalPmtForThisInstallment,
|
||||||
interestForThisInstallment);
|
interestForThisInstallment);
|
||||||
break;
|
break;
|
||||||
@@ -556,9 +558,9 @@ public final class LoanApplicationTerms {
|
|||||||
final Money interestForThisInstallmentBeforeGrace = calculateDecliningInterestDueForInstallmentBeforeApplyingGrace(
|
final Money interestForThisInstallmentBeforeGrace = calculateDecliningInterestDueForInstallmentBeforeApplyingGrace(
|
||||||
calculator, mc, daysInPeriodApplicableForInterest, outstandingBalance);
|
calculator, mc, daysInPeriodApplicableForInterest, outstandingBalance);
|
||||||
|
|
||||||
final Money interestForThisInstallmentAfterGrace = calculateDecliningInterestDueForInstallmentAfterApplyingGrace(calculator,
|
final Money interestForThisInstallmentAfterGrace = calculateDecliningInterestDueForInstallmentAfterApplyingGrace(
|
||||||
interestCalculationGraceOnRepaymentPeriodFraction, mc, daysInPeriodApplicableForInterest, outstandingBalance,
|
calculator, interestCalculationGraceOnRepaymentPeriodFraction, mc, daysInPeriodApplicableForInterest,
|
||||||
periodNumber);
|
outstandingBalance, periodNumber);
|
||||||
|
|
||||||
interestForInstallment = interestForThisInstallmentAfterGrace;
|
interestForInstallment = interestForThisInstallmentAfterGrace;
|
||||||
if (interestForThisInstallmentAfterGrace.isGreaterThanZero()) {
|
if (interestForThisInstallmentAfterGrace.isGreaterThanZero()) {
|
||||||
@@ -651,8 +653,7 @@ public final class LoanApplicationTerms {
|
|||||||
this.loanEndDate = loanEndDate;
|
this.loanEndDate = loanEndDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Money calculateTotalInterestPerInstallmentWithoutGrace(final PaymentPeriodsInOneYearCalculator calculator,
|
private Money calculateTotalInterestPerInstallmentWithoutGrace(final PaymentPeriodsInOneYearCalculator calculator, final MathContext mc) {
|
||||||
final MathContext mc) {
|
|
||||||
|
|
||||||
final Money totalInterestForLoanTerm = calculateTotalFlatInterestDueWithoutGrace(calculator, mc);
|
final Money totalInterestForLoanTerm = calculateTotalFlatInterestDueWithoutGrace(calculator, mc);
|
||||||
|
|
||||||
@@ -709,8 +710,8 @@ public final class LoanApplicationTerms {
|
|||||||
|
|
||||||
final Integer interestPaymentDuePeriods = calculateNumberOfRepaymentPeriodsWhereInterestPaymentIsDue(this.numberOfRepayments);
|
final Integer interestPaymentDuePeriods = calculateNumberOfRepaymentPeriodsWhereInterestPaymentIsDue(this.numberOfRepayments);
|
||||||
|
|
||||||
interestForInstallment = realTotalInterestForLoan.dividedBy(BigDecimal.valueOf(interestPaymentDuePeriods),
|
interestForInstallment = realTotalInterestForLoan
|
||||||
mc.getRoundingMode());
|
.dividedBy(BigDecimal.valueOf(interestPaymentDuePeriods), mc.getRoundingMode());
|
||||||
}
|
}
|
||||||
|
|
||||||
return interestForInstallment;
|
return interestForInstallment;
|
||||||
@@ -792,8 +793,8 @@ public final class LoanApplicationTerms {
|
|||||||
|
|
||||||
final BigDecimal divisor = BigDecimal.valueOf(Double.valueOf("100.0"));
|
final BigDecimal divisor = BigDecimal.valueOf(Double.valueOf("100.0"));
|
||||||
final BigDecimal loanTermPeriodsInYearBigDecimal = BigDecimal.valueOf(loanTermPeriodsInOneYear);
|
final BigDecimal loanTermPeriodsInYearBigDecimal = BigDecimal.valueOf(loanTermPeriodsInOneYear);
|
||||||
final BigDecimal oneDayOfYearInterestRate = this.annualNominalInterestRate.divide(loanTermPeriodsInYearBigDecimal, mc)
|
final BigDecimal oneDayOfYearInterestRate = this.annualNominalInterestRate.divide(loanTermPeriodsInYearBigDecimal, mc).divide(
|
||||||
.divide(divisor, mc);
|
divisor, mc);
|
||||||
BigDecimal interestRate = oneDayOfYearInterestRate.multiply(BigDecimal.valueOf(repaymentEvery), mc);
|
BigDecimal interestRate = oneDayOfYearInterestRate.multiply(BigDecimal.valueOf(repaymentEvery), mc);
|
||||||
return outstandingBalance.getAmount().multiply(interestRate, mc);
|
return outstandingBalance.getAmount().multiply(interestRate, mc);
|
||||||
}
|
}
|
||||||
@@ -936,16 +937,27 @@ public final class LoanApplicationTerms {
|
|||||||
private Money calculateEqualPrincipalDueForInstallment(final MathContext mc, final int periodNumber) {
|
private Money calculateEqualPrincipalDueForInstallment(final MathContext mc, final int periodNumber) {
|
||||||
|
|
||||||
final Integer numberOfPrincipalPaymentPeriods = calculateNumberOfPrincipalPaymentPeriods(this.numberOfRepayments);
|
final Integer numberOfPrincipalPaymentPeriods = calculateNumberOfPrincipalPaymentPeriods(this.numberOfRepayments);
|
||||||
|
Money principal = this.principal;
|
||||||
|
if (this.fixedPrincipalAmount == null) {
|
||||||
|
principal = this.principal.dividedBy(numberOfPrincipalPaymentPeriods, mc.getRoundingMode());
|
||||||
|
this.fixedPrincipalAmount = principal.getAmount();
|
||||||
|
} else {
|
||||||
|
principal = Money.of(getCurrency(), this.fixedPrincipalAmount);
|
||||||
|
}
|
||||||
|
|
||||||
Money principal = this.principal.dividedBy(numberOfPrincipalPaymentPeriods, mc.getRoundingMode());
|
|
||||||
if (isPrincipalGraceApplicableForThisPeriod(periodNumber)) {
|
if (isPrincipalGraceApplicableForThisPeriod(periodNumber)) {
|
||||||
principal = principal.zero();
|
principal = principal.zero();
|
||||||
}
|
}
|
||||||
return principal;
|
return principal;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Money calculatePrincipalDueForInstallment(final int periodNumber, final Money totalDuePerInstallment,
|
public void updateFixedPrincipalAmount(final MathContext mc, final int periodNumber, final Money outstandingAmount) {
|
||||||
final Money periodInterest) {
|
final Integer numberOfPrincipalPaymentPeriods = calculateNumberOfPrincipalPaymentPeriods(this.numberOfRepayments);
|
||||||
|
Money principal = outstandingAmount.dividedBy(numberOfPrincipalPaymentPeriods - periodNumber + 1, mc.getRoundingMode());
|
||||||
|
this.fixedPrincipalAmount = principal.getAmount();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Money calculatePrincipalDueForInstallment(final int periodNumber, final Money totalDuePerInstallment, final Money periodInterest) {
|
||||||
|
|
||||||
Money principal = totalDuePerInstallment.minus(periodInterest);
|
Money principal = totalDuePerInstallment.minus(periodInterest);
|
||||||
if (isPrincipalGraceApplicableForThisPeriod(periodNumber)) {
|
if (isPrincipalGraceApplicableForThisPeriod(periodNumber)) {
|
||||||
@@ -1047,8 +1059,9 @@ public final class LoanApplicationTerms {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Money getApprovedPrincipal() {
|
public Money getApprovedPrincipal() {
|
||||||
return this.approvedPrincipal ;
|
return this.approvedPrincipal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<DisbursementData> getDisbursementDatas() {
|
public List<DisbursementData> getDisbursementDatas() {
|
||||||
return this.disbursementDatas;
|
return this.disbursementDatas;
|
||||||
}
|
}
|
||||||
@@ -1256,4 +1269,5 @@ public final class LoanApplicationTerms {
|
|||||||
public Calendar getLoanCalendar() {
|
public Calendar getLoanCalendar() {
|
||||||
return loanCalendar;
|
return loanCalendar;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+4
@@ -48,4 +48,8 @@ public enum AmortizationMethod {
|
|||||||
public boolean isEqualInstallment() {
|
public boolean isEqualInstallment() {
|
||||||
return this.value.equals(AmortizationMethod.EQUAL_INSTALLMENTS.getValue());
|
return this.value.equals(AmortizationMethod.EQUAL_INSTALLMENTS.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isEqualPrincipal() {
|
||||||
|
return this.value.equals(AmortizationMethod.EQUAL_PRINCIPAL.getValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user