FINERACT-2359: Wrong Days in Year configuration used for calculating interest
This commit is contained in:
committed by
Arnold Gálovics
parent
e0e4415727
commit
8e3de2b72a
+5
-3
@@ -20,6 +20,7 @@ package org.apache.fineract.portfolio.loanaccount.loanschedule.domain;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
|
import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
|
||||||
|
import org.apache.fineract.portfolio.common.domain.DaysInYearType;
|
||||||
import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
|
import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@@ -27,11 +28,12 @@ import org.springframework.stereotype.Component;
|
|||||||
public class AprCalculator {
|
public class AprCalculator {
|
||||||
|
|
||||||
public BigDecimal calculateFrom(final PeriodFrequencyType interestPeriodFrequencyType, final BigDecimal interestRatePerPeriod,
|
public BigDecimal calculateFrom(final PeriodFrequencyType interestPeriodFrequencyType, final BigDecimal interestRatePerPeriod,
|
||||||
final Integer numberOfRepayments, final Integer repaymentEvery, final PeriodFrequencyType repaymentPeriodFrequencyType) {
|
final Integer numberOfRepayments, final Integer repaymentEvery, final PeriodFrequencyType repaymentPeriodFrequencyType,
|
||||||
|
final DaysInYearType daysInYearType) {
|
||||||
BigDecimal defaultAnnualNominalInterestRate = BigDecimal.ZERO;
|
BigDecimal defaultAnnualNominalInterestRate = BigDecimal.ZERO;
|
||||||
switch (interestPeriodFrequencyType) {
|
switch (interestPeriodFrequencyType) {
|
||||||
case DAYS:
|
case DAYS:
|
||||||
defaultAnnualNominalInterestRate = interestRatePerPeriod.multiply(BigDecimal.valueOf(365));
|
defaultAnnualNominalInterestRate = interestRatePerPeriod.multiply(BigDecimal.valueOf(daysInYearType.getValue()));
|
||||||
break;
|
break;
|
||||||
case WEEKS:
|
case WEEKS:
|
||||||
defaultAnnualNominalInterestRate = interestRatePerPeriod.multiply(BigDecimal.valueOf(52));
|
defaultAnnualNominalInterestRate = interestRatePerPeriod.multiply(BigDecimal.valueOf(52));
|
||||||
@@ -48,7 +50,7 @@ public class AprCalculator {
|
|||||||
|
|
||||||
switch (repaymentPeriodFrequencyType) {
|
switch (repaymentPeriodFrequencyType) {
|
||||||
case DAYS:
|
case DAYS:
|
||||||
defaultAnnualNominalInterestRate = ratePerPeriod.multiply(BigDecimal.valueOf(365));
|
defaultAnnualNominalInterestRate = ratePerPeriod.multiply(BigDecimal.valueOf(daysInYearType.getValue()));
|
||||||
break;
|
break;
|
||||||
case WEEKS:
|
case WEEKS:
|
||||||
defaultAnnualNominalInterestRate = ratePerPeriod.multiply(BigDecimal.valueOf(52));
|
defaultAnnualNominalInterestRate = ratePerPeriod.multiply(BigDecimal.valueOf(52));
|
||||||
|
|||||||
+15
-15
@@ -219,6 +219,20 @@ public class LoanScheduleAssembler {
|
|||||||
BigDecimal fixedPrincipalPercentagePerInstallment = this.fromApiJsonHelper
|
BigDecimal fixedPrincipalPercentagePerInstallment = this.fromApiJsonHelper
|
||||||
.extractBigDecimalWithLocaleNamed(LoanApiConstants.fixedPrincipalPercentagePerInstallmentParamName, element);
|
.extractBigDecimalWithLocaleNamed(LoanApiConstants.fixedPrincipalPercentagePerInstallmentParamName, element);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interest recalculation settings copy from product definition
|
||||||
|
*/
|
||||||
|
final DaysInMonthType daysInMonthType = loanProduct.fetchDaysInMonthType();
|
||||||
|
|
||||||
|
DaysInYearType daysInYearType = null;
|
||||||
|
final Integer daysInYearTypeIntFromApplication = this.fromApiJsonHelper
|
||||||
|
.extractIntegerNamed(LoanApiConstants.daysInYearTypeParameterName, element, Locale.getDefault());
|
||||||
|
if (daysInYearTypeIntFromApplication != null) {
|
||||||
|
daysInYearType = DaysInYearType.fromInt(daysInYearTypeIntFromApplication);
|
||||||
|
} else {
|
||||||
|
daysInYearType = loanProduct.fetchDaysInYearType();
|
||||||
|
}
|
||||||
|
|
||||||
// interest terms
|
// interest terms
|
||||||
final Integer interestType = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("interestType", element);
|
final Integer interestType = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("interestType", element);
|
||||||
final InterestMethod interestMethod = allowOverridingInterestMethod ? InterestMethod.fromInt(interestType)
|
final InterestMethod interestMethod = allowOverridingInterestMethod ? InterestMethod.fromInt(interestType)
|
||||||
@@ -246,7 +260,7 @@ public class LoanScheduleAssembler {
|
|||||||
BigDecimal annualNominalInterestRate = BigDecimal.ZERO;
|
BigDecimal annualNominalInterestRate = BigDecimal.ZERO;
|
||||||
if (interestRatePerPeriod != null) {
|
if (interestRatePerPeriod != null) {
|
||||||
annualNominalInterestRate = this.aprCalculator.calculateFrom(interestRatePeriodFrequencyType, interestRatePerPeriod,
|
annualNominalInterestRate = this.aprCalculator.calculateFrom(interestRatePeriodFrequencyType, interestRatePerPeriod,
|
||||||
numberOfRepayments, repaymentEvery, repaymentPeriodFrequencyType);
|
numberOfRepayments, repaymentEvery, repaymentPeriodFrequencyType, daysInYearType);
|
||||||
}
|
}
|
||||||
|
|
||||||
// disbursement details
|
// disbursement details
|
||||||
@@ -365,20 +379,6 @@ public class LoanScheduleAssembler {
|
|||||||
|
|
||||||
final List<DisbursementData> disbursementDatas = fetchDisbursementData(element.getAsJsonObject());
|
final List<DisbursementData> disbursementDatas = fetchDisbursementData(element.getAsJsonObject());
|
||||||
|
|
||||||
/**
|
|
||||||
* Interest recalculation settings copy from product definition
|
|
||||||
*/
|
|
||||||
final DaysInMonthType daysInMonthType = loanProduct.fetchDaysInMonthType();
|
|
||||||
|
|
||||||
DaysInYearType daysInYearType = null;
|
|
||||||
final Integer daysInYearTypeIntFromApplication = this.fromApiJsonHelper
|
|
||||||
.extractIntegerNamed(LoanApiConstants.daysInYearTypeParameterName, element, Locale.getDefault());
|
|
||||||
if (daysInYearTypeIntFromApplication != null) {
|
|
||||||
daysInYearType = DaysInYearType.fromInt(daysInYearTypeIntFromApplication);
|
|
||||||
} else {
|
|
||||||
daysInYearType = loanProduct.fetchDaysInYearType();
|
|
||||||
}
|
|
||||||
|
|
||||||
final boolean isInterestRecalculationEnabled = loanProduct.isInterestRecalculationEnabled();
|
final boolean isInterestRecalculationEnabled = loanProduct.isInterestRecalculationEnabled();
|
||||||
RecalculationFrequencyType recalculationFrequencyType = null;
|
RecalculationFrequencyType recalculationFrequencyType = null;
|
||||||
CalendarInstance restCalendarInstance = null;
|
CalendarInstance restCalendarInstance = null;
|
||||||
|
|||||||
+5
-4
@@ -113,6 +113,10 @@ public class LoanProductAssembler {
|
|||||||
Integer minimumGapBetweenInstallments = null;
|
Integer minimumGapBetweenInstallments = null;
|
||||||
Integer maximumGapBetweenInstallments = null;
|
Integer maximumGapBetweenInstallments = null;
|
||||||
|
|
||||||
|
// Declaring this variable here to be used throughout the file
|
||||||
|
final DaysInYearType daysInYearType = DaysInYearType
|
||||||
|
.fromInt(command.integerValueOfParameterNamed(LoanProductConstants.DAYS_IN_YEAR_TYPE_PARAMETER_NAME));
|
||||||
|
|
||||||
final Integer repaymentEvery = command.integerValueOfParameterNamed("repaymentEvery");
|
final Integer repaymentEvery = command.integerValueOfParameterNamed("repaymentEvery");
|
||||||
final Integer numberOfRepayments = command.integerValueOfParameterNamed("numberOfRepayments");
|
final Integer numberOfRepayments = command.integerValueOfParameterNamed("numberOfRepayments");
|
||||||
final Boolean isLinkedToFloatingInterestRates = command.booleanObjectValueOfParameterNamed("isLinkedToFloatingInterestRates");
|
final Boolean isLinkedToFloatingInterestRates = command.booleanObjectValueOfParameterNamed("isLinkedToFloatingInterestRates");
|
||||||
@@ -129,7 +133,7 @@ public class LoanProductAssembler {
|
|||||||
minInterestRatePerPeriod = command.bigDecimalValueOfParameterNamed("minInterestRatePerPeriod");
|
minInterestRatePerPeriod = command.bigDecimalValueOfParameterNamed("minInterestRatePerPeriod");
|
||||||
maxInterestRatePerPeriod = command.bigDecimalValueOfParameterNamed("maxInterestRatePerPeriod");
|
maxInterestRatePerPeriod = command.bigDecimalValueOfParameterNamed("maxInterestRatePerPeriod");
|
||||||
annualInterestRate = aprCalculator.calculateFrom(interestFrequencyType, interestRatePerPeriod, numberOfRepayments,
|
annualInterestRate = aprCalculator.calculateFrom(interestFrequencyType, interestRatePerPeriod, numberOfRepayments,
|
||||||
repaymentEvery, repaymentFrequencyType);
|
repaymentEvery, repaymentFrequencyType, daysInYearType);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,9 +208,6 @@ public class LoanProductAssembler {
|
|||||||
final DaysInMonthType daysInMonthType = DaysInMonthType
|
final DaysInMonthType daysInMonthType = DaysInMonthType
|
||||||
.fromInt(command.integerValueOfParameterNamed(LoanProductConstants.DAYS_IN_MONTH_TYPE_PARAMETER_NAME));
|
.fromInt(command.integerValueOfParameterNamed(LoanProductConstants.DAYS_IN_MONTH_TYPE_PARAMETER_NAME));
|
||||||
|
|
||||||
final DaysInYearType daysInYearType = DaysInYearType
|
|
||||||
.fromInt(command.integerValueOfParameterNamed(LoanProductConstants.DAYS_IN_YEAR_TYPE_PARAMETER_NAME));
|
|
||||||
|
|
||||||
final DaysInYearCustomStrategyType daysInYearCustomStrategy = command.enumValueOfParameterNamed(
|
final DaysInYearCustomStrategyType daysInYearCustomStrategy = command.enumValueOfParameterNamed(
|
||||||
LoanProductConstants.DAYS_IN_YEAR_CUSTOM_STRATEGY_TYPE_PARAMETER_NAME, DaysInYearCustomStrategyType.class);
|
LoanProductConstants.DAYS_IN_YEAR_CUSTOM_STRATEGY_TYPE_PARAMETER_NAME, DaysInYearCustomStrategyType.class);
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -373,7 +373,8 @@ public class LoanProductRelatedDetailUpdateUtil {
|
|||||||
final AprCalculator aprCalculator) {
|
final AprCalculator aprCalculator) {
|
||||||
BigDecimal annualNominalInterestRate = aprCalculator.calculateFrom(loanRepaymentScheduleDetail.getInterestPeriodFrequencyType(),
|
BigDecimal annualNominalInterestRate = aprCalculator.calculateFrom(loanRepaymentScheduleDetail.getInterestPeriodFrequencyType(),
|
||||||
loanRepaymentScheduleDetail.getNominalInterestRatePerPeriod(), loanRepaymentScheduleDetail.getNumberOfRepayments(),
|
loanRepaymentScheduleDetail.getNominalInterestRatePerPeriod(), loanRepaymentScheduleDetail.getNumberOfRepayments(),
|
||||||
loanRepaymentScheduleDetail.getRepayEvery(), loanRepaymentScheduleDetail.getRepaymentPeriodFrequencyType());
|
loanRepaymentScheduleDetail.getRepayEvery(), loanRepaymentScheduleDetail.getRepaymentPeriodFrequencyType(),
|
||||||
|
loanRepaymentScheduleDetail.fetchDaysInYearType());
|
||||||
loanRepaymentScheduleDetail.setAnnualNominalInterestRate(annualNominalInterestRate);
|
loanRepaymentScheduleDetail.setAnnualNominalInterestRate(annualNominalInterestRate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user