#164_compounding interest is greater than posting inerest

This commit is contained in:
jyothsnag
2016-11-10 21:51:49 +05:30
parent 580840c35e
commit 9195315512
10 changed files with 90 additions and 15 deletions
@@ -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());
@@ -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;
}
} }
@@ -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;
}
} }
@@ -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);
} }
} }
@@ -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;
}
}
@@ -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();
} }
@@ -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;
}
} }
@@ -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;
}
} }
@@ -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);
} }
@@ -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;
}
} }