#164_compounding interest is greater than posting inerest
This commit is contained in:
+1
-2
@@ -2666,8 +2666,7 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
|
|||||||
SavingsCompoundingInterestPeriodType savingsCompoundingInterestPeriodType = SavingsCompoundingInterestPeriodType
|
SavingsCompoundingInterestPeriodType savingsCompoundingInterestPeriodType = SavingsCompoundingInterestPeriodType
|
||||||
.fromInt(interestCompoundingPeriodType);
|
.fromInt(interestCompoundingPeriodType);
|
||||||
|
|
||||||
if (postingtoCompoundMap.get(savingsPostingInterestPeriodType) == null
|
if (postingtoCompoundMap.get(savingsPostingInterestPeriodType) == null) {
|
||||||
|| !postingtoCompoundMap.get(savingsPostingInterestPeriodType).contains(savingsCompoundingInterestPeriodType)) {
|
|
||||||
baseDataValidator.failWithCodeNoParameterAddedToErrorCode("posting.period.type.is.less.than.compound.period.type",
|
baseDataValidator.failWithCodeNoParameterAddedToErrorCode("posting.period.type.is.less.than.compound.period.type",
|
||||||
savingsPostingInterestPeriodType.name(), savingsCompoundingInterestPeriodType.name());
|
savingsPostingInterestPeriodType.name(), savingsCompoundingInterestPeriodType.name());
|
||||||
|
|
||||||
|
|||||||
+5
@@ -178,4 +178,9 @@ public class AnnualCompoundingPeriod implements CompoundingPeriod {
|
|||||||
this.periodInterval = periodInterval;
|
this.periodInterval = periodInterval;
|
||||||
this.endOfDayBalances = endOfDayBalances;
|
this.endOfDayBalances = endOfDayBalances;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LocalDateInterval getPeriodInterval() {
|
||||||
|
return this.periodInterval;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+5
@@ -178,4 +178,9 @@ public class BiAnnualCompoundingPeriod implements CompoundingPeriod {
|
|||||||
this.periodInterval = periodInterval;
|
this.periodInterval = periodInterval;
|
||||||
this.endOfDayBalances = endOfDayBalances;
|
this.endOfDayBalances = endOfDayBalances;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LocalDateInterval getPeriodInterval() {
|
||||||
|
return this.periodInterval;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+8
-5
@@ -46,10 +46,13 @@ public class CompoundInterestHelper {
|
|||||||
Money interestEarned = Money.zero(currency);
|
Money interestEarned = Money.zero(currency);
|
||||||
|
|
||||||
// total interest earned in previous periods but not yet recognised
|
// total interest earned in previous periods but not yet recognised
|
||||||
BigDecimal interestEarnedButNotPosted = BigDecimal.ZERO;
|
BigDecimal compoundedInterest = BigDecimal.ZERO;
|
||||||
|
BigDecimal unCompoundedInterest = BigDecimal.ZERO;
|
||||||
|
final CompoundInterestValues compoundInterestValues = new CompoundInterestValues(compoundedInterest,
|
||||||
|
unCompoundedInterest);
|
||||||
for (final PostingPeriod postingPeriod : allPeriods) {
|
for (final PostingPeriod postingPeriod : allPeriods) {
|
||||||
|
|
||||||
final BigDecimal interestEarnedThisPeriod = postingPeriod.calculateInterest(interestEarnedButNotPosted);
|
final BigDecimal interestEarnedThisPeriod = postingPeriod.calculateInterest(compoundInterestValues);
|
||||||
|
|
||||||
final Money moneyToBePostedForPeriod = Money.of(currency, interestEarnedThisPeriod);
|
final Money moneyToBePostedForPeriod = Money.of(currency, interestEarnedThisPeriod);
|
||||||
|
|
||||||
@@ -58,9 +61,9 @@ public class CompoundInterestHelper {
|
|||||||
// interest for accounts which has post interest to linked savings
|
// interest for accounts which has post interest to linked savings
|
||||||
// account and if already transfered then it includes in interest
|
// account and if already transfered then it includes in interest
|
||||||
// calculation.
|
// calculation.
|
||||||
if (postingPeriod.isInterestTransfered() || !interestTransferEnabled
|
if (!(postingPeriod.isInterestTransfered() || !interestTransferEnabled
|
||||||
|| (lockUntil != null && !postingPeriod.dateOfPostingTransaction().isAfter(lockUntil))) {
|
|| (lockUntil != null && !postingPeriod.dateOfPostingTransaction().isAfter(lockUntil)))) {
|
||||||
interestEarnedButNotPosted = interestEarnedButNotPosted.add(moneyToBePostedForPeriod.getAmount());
|
compoundInterestValues.setcompoundedInterest(BigDecimal.ZERO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
package org.apache.fineract.portfolio.savings.domain.interest;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
public class CompoundInterestValues {
|
||||||
|
|
||||||
|
private BigDecimal compoundedInterest;
|
||||||
|
private BigDecimal uncompoundedInterest;
|
||||||
|
|
||||||
|
public CompoundInterestValues(final BigDecimal compoundedInterest, final BigDecimal uncompoundedInterest) {
|
||||||
|
this.compoundedInterest = compoundedInterest;
|
||||||
|
this.uncompoundedInterest = uncompoundedInterest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getcompoundedInterest() {
|
||||||
|
return this.compoundedInterest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getuncompoundedInterest() {
|
||||||
|
return this.uncompoundedInterest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setcompoundedInterest(BigDecimal interestToBeCompounded) {
|
||||||
|
this.compoundedInterest = interestToBeCompounded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setuncompoundedInterest(BigDecimal interestToBeUncompounded) {
|
||||||
|
this.uncompoundedInterest = interestToBeUncompounded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setZeroForInterestToBeUncompounded() {
|
||||||
|
this.uncompoundedInterest = BigDecimal.ZERO;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+2
@@ -20,6 +20,7 @@ package org.apache.fineract.portfolio.savings.domain.interest;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.LocalDateInterval;
|
||||||
import org.apache.fineract.portfolio.savings.SavingsCompoundingInterestPeriodType;
|
import org.apache.fineract.portfolio.savings.SavingsCompoundingInterestPeriodType;
|
||||||
import org.apache.fineract.portfolio.savings.SavingsInterestCalculationType;
|
import org.apache.fineract.portfolio.savings.SavingsInterestCalculationType;
|
||||||
|
|
||||||
@@ -29,4 +30,5 @@ public interface CompoundingPeriod {
|
|||||||
SavingsInterestCalculationType interestCalculationType, BigDecimal interestFromPreviousPostingPeriod,
|
SavingsInterestCalculationType interestCalculationType, BigDecimal interestFromPreviousPostingPeriod,
|
||||||
BigDecimal interestRateAsFraction, long daysInYear, BigDecimal minBalanceForInterestCalculation,
|
BigDecimal interestRateAsFraction, long daysInYear, BigDecimal minBalanceForInterestCalculation,
|
||||||
BigDecimal overdraftInterestRateAsFraction, BigDecimal minOverdraftForInterestCalculation);
|
BigDecimal overdraftInterestRateAsFraction, BigDecimal minOverdraftForInterestCalculation);
|
||||||
|
LocalDateInterval getPeriodInterval();
|
||||||
}
|
}
|
||||||
+7
-3
@@ -30,7 +30,6 @@ import org.joda.time.LocalDate;
|
|||||||
|
|
||||||
public class DailyCompoundingPeriod implements CompoundingPeriod {
|
public class DailyCompoundingPeriod implements CompoundingPeriod {
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final LocalDateInterval periodInterval;
|
private final LocalDateInterval periodInterval;
|
||||||
private final List<EndOfDayBalance> endOfDayBalances;
|
private final List<EndOfDayBalance> endOfDayBalances;
|
||||||
|
|
||||||
@@ -77,8 +76,8 @@ public class DailyCompoundingPeriod implements CompoundingPeriod {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BigDecimal calculateInterest(
|
public BigDecimal calculateInterest(
|
||||||
@SuppressWarnings("unused") final SavingsCompoundingInterestPeriodType compoundingInterestPeriodType,
|
final SavingsCompoundingInterestPeriodType compoundingInterestPeriodType,
|
||||||
@SuppressWarnings("unused") final SavingsInterestCalculationType interestCalculationType,
|
final SavingsInterestCalculationType interestCalculationType,
|
||||||
final BigDecimal interestFromPreviousPostingPeriod, final BigDecimal interestRateAsFraction, final long daysInYear,
|
final BigDecimal interestFromPreviousPostingPeriod, final BigDecimal interestRateAsFraction, final long daysInYear,
|
||||||
final BigDecimal minBalanceForInterestCalculation,
|
final BigDecimal minBalanceForInterestCalculation,
|
||||||
final BigDecimal overdraftInterestRateAsFraction, final BigDecimal minOverdraftForInterestCalculation) {
|
final BigDecimal overdraftInterestRateAsFraction, final BigDecimal minOverdraftForInterestCalculation) {
|
||||||
@@ -97,4 +96,9 @@ public class DailyCompoundingPeriod implements CompoundingPeriod {
|
|||||||
|
|
||||||
return interestEarned;
|
return interestEarned;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LocalDateInterval getPeriodInterval() {
|
||||||
|
return this.periodInterval;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+5
@@ -174,4 +174,9 @@ public class MonthlyCompoundingPeriod implements CompoundingPeriod {
|
|||||||
this.periodInterval = periodInterval;
|
this.periodInterval = periodInterval;
|
||||||
this.endOfDayBalances = endOfDayBalances;
|
this.endOfDayBalances = endOfDayBalances;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LocalDateInterval getPeriodInterval() {
|
||||||
|
return this.periodInterval;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+17
-4
@@ -194,19 +194,32 @@ public class PostingPeriod {
|
|||||||
return this.openingBalance;
|
return this.openingBalance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BigDecimal calculateInterest(final BigDecimal interestFromPreviousPostingPeriod) {
|
public BigDecimal calculateInterest(final CompoundInterestValues compoundInterestValues) {
|
||||||
BigDecimal interestEarned = BigDecimal.ZERO;
|
BigDecimal interestEarned = BigDecimal.ZERO;
|
||||||
|
|
||||||
// for each compounding period accumulate the amount of interest
|
// for each compounding period accumulate the amount of interest
|
||||||
// to be applied to the balanced for interest calculation
|
// to be applied to the balanced for interest calculation
|
||||||
BigDecimal interestCompounded = interestFromPreviousPostingPeriod;
|
|
||||||
for (final CompoundingPeriod compoundingPeriod : this.compoundingPeriods) {
|
for (final CompoundingPeriod compoundingPeriod : this.compoundingPeriods) {
|
||||||
|
|
||||||
final BigDecimal interestUnrounded = compoundingPeriod.calculateInterest(this.interestCompoundingType,
|
final BigDecimal interestUnrounded = compoundingPeriod.calculateInterest(this.interestCompoundingType,
|
||||||
this.interestCalculationType, interestCompounded, this.interestRateAsFraction, this.daysInYear,
|
this.interestCalculationType, compoundInterestValues.getcompoundedInterest(), this.interestRateAsFraction, this.daysInYear,
|
||||||
this.minBalanceForInterestCalculation.getAmount(), this.overdraftInterestRateAsFraction,
|
this.minBalanceForInterestCalculation.getAmount(), this.overdraftInterestRateAsFraction,
|
||||||
this.minOverdraftForInterestCalculation.getAmount());
|
this.minOverdraftForInterestCalculation.getAmount());
|
||||||
interestCompounded = interestCompounded.add(interestUnrounded);
|
BigDecimal unCompoundedInterest = compoundInterestValues.getuncompoundedInterest().add(interestUnrounded);
|
||||||
|
compoundInterestValues.setuncompoundedInterest(unCompoundedInterest);
|
||||||
|
LocalDate compoundingPeriodEndDate = compoundingPeriod.getPeriodInterval().endDate();
|
||||||
|
if (!SavingsCompoundingInterestPeriodType.DAILY.equals(this.interestCompoundingType)) {
|
||||||
|
compoundingPeriodEndDate = determineInterestPeriodEndDateFrom(
|
||||||
|
compoundingPeriod.getPeriodInterval().startDate(), this.interestCompoundingType,
|
||||||
|
compoundingPeriod.getPeriodInterval().endDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compoundingPeriodEndDate.equals(compoundingPeriod.getPeriodInterval().endDate())) {
|
||||||
|
BigDecimal interestCompounded = compoundInterestValues.getcompoundedInterest()
|
||||||
|
.add(unCompoundedInterest);
|
||||||
|
compoundInterestValues.setcompoundedInterest(interestCompounded);
|
||||||
|
compoundInterestValues.setZeroForInterestToBeUncompounded();
|
||||||
|
}
|
||||||
interestEarned = interestEarned.add(interestUnrounded);
|
interestEarned = interestEarned.add(interestUnrounded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-1
@@ -31,7 +31,6 @@ import org.joda.time.LocalDate;
|
|||||||
|
|
||||||
public class QuarterlyCompoundingPeriod implements CompoundingPeriod {
|
public class QuarterlyCompoundingPeriod implements CompoundingPeriod {
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final LocalDateInterval periodInterval;
|
private final LocalDateInterval periodInterval;
|
||||||
private final List<EndOfDayBalance> endOfDayBalances;
|
private final List<EndOfDayBalance> endOfDayBalances;
|
||||||
|
|
||||||
@@ -178,4 +177,9 @@ public class QuarterlyCompoundingPeriod implements CompoundingPeriod {
|
|||||||
this.periodInterval = periodInterval;
|
this.periodInterval = periodInterval;
|
||||||
this.endOfDayBalances = endOfDayBalances;
|
this.endOfDayBalances = endOfDayBalances;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LocalDateInterval getPeriodInterval() {
|
||||||
|
return this.periodInterval;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user