Merge branch 'FINERACT-491' into develop

This commit is contained in:
Nazeer Hussain Shaik
2017-11-20 16:01:35 +05:30
4 changed files with 78 additions and 43 deletions
@@ -320,7 +320,7 @@ public class FixedDepositAccount extends SavingsAccount {
final PostingPeriod postingPeriod = PostingPeriod.createFrom(periodInterval, periodStartingBalance, transactions, final PostingPeriod postingPeriod = PostingPeriod.createFrom(periodInterval, periodStartingBalance, transactions,
this.currency, compoundingPeriodType, interestCalculationType, interestRateAsFraction, daysInYearType.getValue(), this.currency, compoundingPeriodType, interestCalculationType, interestRateAsFraction, daysInYearType.getValue(),
maturityDate, interestPostTransactions, isInterestTransfer, minBalanceForInterestCalculation, maturityDate, interestPostTransactions, isInterestTransfer, minBalanceForInterestCalculation,
isSavingsInterestPostingAtCurrentPeriodEnd, isUserPosting); isSavingsInterestPostingAtCurrentPeriodEnd, isUserPosting, financialYearBeginningMonth);
periodStartingBalance = postingPeriod.closingBalance(); periodStartingBalance = postingPeriod.closingBalance();
@@ -352,7 +352,7 @@ public class RecurringDepositAccount extends SavingsAccount {
final PostingPeriod postingPeriod = PostingPeriod.createFrom(periodInterval, periodStartingBalance, transactions, final PostingPeriod postingPeriod = PostingPeriod.createFrom(periodInterval, periodStartingBalance, transactions,
this.currency, compoundingPeriodType, interestCalculationType, interestRateAsFraction, daysInYearType.getValue(), this.currency, compoundingPeriodType, interestCalculationType, interestRateAsFraction, daysInYearType.getValue(),
maturityDate, interestPostTransactions, isInterestTransfer, minBalanceForInterestCalculation, maturityDate, interestPostTransactions, isInterestTransfer, minBalanceForInterestCalculation,
isSavingsInterestPostingAtCurrentPeriodEnd, isUserPosting); isSavingsInterestPostingAtCurrentPeriodEnd, isUserPosting, financialYearBeginningMonth);
periodStartingBalance = postingPeriod.closingBalance(); periodStartingBalance = postingPeriod.closingBalance();
@@ -749,7 +749,7 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
retreiveOrderedNonInterestPostingTransactions(), this.currency, compoundingPeriodType, interestCalculationType, retreiveOrderedNonInterestPostingTransactions(), this.currency, compoundingPeriodType, interestCalculationType,
interestRateAsFraction, daysInYearType.getValue(), upToInterestCalculationDate, interestPostTransactions, interestRateAsFraction, daysInYearType.getValue(), upToInterestCalculationDate, interestPostTransactions,
isInterestTransfer, minBalanceForInterestCalculation, isSavingsInterestPostingAtCurrentPeriodEnd, isInterestTransfer, minBalanceForInterestCalculation, isSavingsInterestPostingAtCurrentPeriodEnd,
overdraftInterestRateAsFraction, minOverdraftForInterestCalculation, isUserPosting); overdraftInterestRateAsFraction, minOverdraftForInterestCalculation, isUserPosting, financialYearBeginningMonth);
periodStartingBalance = postingPeriod.closingBalance(); periodStartingBalance = postingPeriod.closingBalance();
@@ -22,8 +22,10 @@ import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.TreeSet;
import org.apache.fineract.infrastructure.core.domain.LocalDateInterval; import org.apache.fineract.infrastructure.core.domain.LocalDateInterval;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
import org.apache.fineract.organisation.monetary.domain.Money; import org.apache.fineract.organisation.monetary.domain.Money;
import org.apache.fineract.portfolio.savings.SavingsCompoundingInterestPeriodType; import org.apache.fineract.portfolio.savings.SavingsCompoundingInterestPeriodType;
@@ -33,8 +35,7 @@ import org.joda.time.DateTime;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
public class PostingPeriod { public class PostingPeriod {
@SuppressWarnings("unused")
private final LocalDateInterval periodInterval; private final LocalDateInterval periodInterval;
private final MonetaryCurrency currency; private final MonetaryCurrency currency;
private final SavingsCompoundingInterestPeriodType interestCompoundingType; private final SavingsCompoundingInterestPeriodType interestCompoundingType;
@@ -60,13 +61,15 @@ public class PostingPeriod {
private final Money minBalanceForInterestCalculation; private final Money minBalanceForInterestCalculation;
private BigDecimal overdraftInterestRateAsFraction; private BigDecimal overdraftInterestRateAsFraction;
private Money minOverdraftForInterestCalculation; private Money minOverdraftForInterestCalculation;
private Integer financialYearBeginningMonth;
public static PostingPeriod createFrom(final LocalDateInterval periodInterval, final Money periodStartingBalance, public static PostingPeriod createFrom(final LocalDateInterval periodInterval, final Money periodStartingBalance,
final List<SavingsAccountTransaction> orderedListOfTransactions, final MonetaryCurrency currency, final List<SavingsAccountTransaction> orderedListOfTransactions, final MonetaryCurrency currency,
final SavingsCompoundingInterestPeriodType interestCompoundingPeriodType, final SavingsCompoundingInterestPeriodType interestCompoundingPeriodType,
final SavingsInterestCalculationType interestCalculationType, final BigDecimal interestRateAsFraction, final long daysInYear, final SavingsInterestCalculationType interestCalculationType, final BigDecimal interestRateAsFraction, final long daysInYear,
final LocalDate upToInterestCalculationDate, Collection<Long> interestPostTransactions, boolean isInterestTransfer, final LocalDate upToInterestCalculationDate, Collection<Long> interestPostTransactions, boolean isInterestTransfer,
final Money minBalanceForInterestCalculation, final boolean isSavingsInterestPostingAtCurrentPeriodEnd,final boolean isUserPosting) { final Money minBalanceForInterestCalculation, final boolean isSavingsInterestPostingAtCurrentPeriodEnd,final boolean isUserPosting, Integer financialYearBeginningMonth) {
final BigDecimal overdraftInterestRateAsFraction = BigDecimal.ZERO; final BigDecimal overdraftInterestRateAsFraction = BigDecimal.ZERO;
final Money minOverdraftForInterestCalculation = Money.zero(currency); final Money minOverdraftForInterestCalculation = Money.zero(currency);
@@ -75,7 +78,7 @@ public class PostingPeriod {
interestCompoundingPeriodType, interestCalculationType, interestRateAsFraction, daysInYear, interestCompoundingPeriodType, interestCalculationType, interestRateAsFraction, daysInYear,
upToInterestCalculationDate, interestPostTransactions, isInterestTransfer, upToInterestCalculationDate, interestPostTransactions, isInterestTransfer,
minBalanceForInterestCalculation, isSavingsInterestPostingAtCurrentPeriodEnd, minBalanceForInterestCalculation, isSavingsInterestPostingAtCurrentPeriodEnd,
overdraftInterestRateAsFraction, minOverdraftForInterestCalculation, isUserPosting); overdraftInterestRateAsFraction, minOverdraftForInterestCalculation, isUserPosting, financialYearBeginningMonth);
} }
// isInterestTransfer boolean is to identify newly created transaction is // isInterestTransfer boolean is to identify newly created transaction is
@@ -86,7 +89,7 @@ public class PostingPeriod {
final SavingsInterestCalculationType interestCalculationType, final BigDecimal interestRateAsFraction, final long daysInYear, final SavingsInterestCalculationType interestCalculationType, final BigDecimal interestRateAsFraction, final long daysInYear,
final LocalDate upToInterestCalculationDate, Collection<Long> interestPostTransactions, boolean isInterestTransfer, final LocalDate upToInterestCalculationDate, Collection<Long> interestPostTransactions, boolean isInterestTransfer,
final Money minBalanceForInterestCalculation, final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Money minBalanceForInterestCalculation, final boolean isSavingsInterestPostingAtCurrentPeriodEnd,
final BigDecimal overdraftInterestRateAsFraction, final Money minOverdraftForInterestCalculation, boolean isUserPosting) { final BigDecimal overdraftInterestRateAsFraction, final Money minOverdraftForInterestCalculation, boolean isUserPosting, int financialYearBeginningMonth) {
final List<EndOfDayBalance> accountEndOfDayBalances = new ArrayList<>(); final List<EndOfDayBalance> accountEndOfDayBalances = new ArrayList<>();
boolean interestTransfered = false; boolean interestTransfered = false;
@@ -143,12 +146,12 @@ public class PostingPeriod {
} }
final List<CompoundingPeriod> compoundingPeriods = compoundingPeriodsInPostingPeriod(periodInterval, interestCompoundingPeriodType, final List<CompoundingPeriod> compoundingPeriods = compoundingPeriodsInPostingPeriod(periodInterval, interestCompoundingPeriodType,
accountEndOfDayBalances, upToInterestCalculationDate); accountEndOfDayBalances, upToInterestCalculationDate, financialYearBeginningMonth);
return new PostingPeriod(periodInterval, currency, periodStartingBalance, openingDayBalance, interestCompoundingPeriodType, return new PostingPeriod(periodInterval, currency, periodStartingBalance, openingDayBalance, interestCompoundingPeriodType,
interestCalculationType, interestRateAsFraction, daysInYear, compoundingPeriods, interestTransfered, interestCalculationType, interestRateAsFraction, daysInYear, compoundingPeriods, interestTransfered,
minBalanceForInterestCalculation, isSavingsInterestPostingAtCurrentPeriodEnd, minBalanceForInterestCalculation, isSavingsInterestPostingAtCurrentPeriodEnd,
overdraftInterestRateAsFraction, minOverdraftForInterestCalculation, isUserPosting); overdraftInterestRateAsFraction, minOverdraftForInterestCalculation, isUserPosting, financialYearBeginningMonth);
} }
private PostingPeriod(final LocalDateInterval periodInterval, final MonetaryCurrency currency, final Money openingBalance, private PostingPeriod(final LocalDateInterval periodInterval, final MonetaryCurrency currency, final Money openingBalance,
@@ -156,7 +159,7 @@ public class PostingPeriod {
final SavingsInterestCalculationType interestCalculationType, final BigDecimal interestRateAsFraction, final long daysInYear, final SavingsInterestCalculationType interestCalculationType, final BigDecimal interestRateAsFraction, final long daysInYear,
final List<CompoundingPeriod> compoundingPeriods, boolean interestTransfered, final Money minBalanceForInterestCalculation, final List<CompoundingPeriod> compoundingPeriods, boolean interestTransfered, final Money minBalanceForInterestCalculation,
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final BigDecimal overdraftInterestRateAsFraction, final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final BigDecimal overdraftInterestRateAsFraction,
final Money minOverdraftForInterestCalculation, boolean isUserPosting) { final Money minOverdraftForInterestCalculation, boolean isUserPosting, Integer financialYearBeginningMonth) {
this.periodInterval = periodInterval; this.periodInterval = periodInterval;
this.currency = currency; this.currency = currency;
this.openingBalance = openingBalance; this.openingBalance = openingBalance;
@@ -176,6 +179,7 @@ public class PostingPeriod {
this.overdraftInterestRateAsFraction = overdraftInterestRateAsFraction; this.overdraftInterestRateAsFraction = overdraftInterestRateAsFraction;
this.minOverdraftForInterestCalculation = minOverdraftForInterestCalculation; this.minOverdraftForInterestCalculation = minOverdraftForInterestCalculation;
this.isUserPosting = isUserPosting; this.isUserPosting = isUserPosting;
this.financialYearBeginningMonth = financialYearBeginningMonth;
} }
public Money interest() { public Money interest() {
@@ -211,7 +215,7 @@ public class PostingPeriod {
if (!SavingsCompoundingInterestPeriodType.DAILY.equals(this.interestCompoundingType)) { if (!SavingsCompoundingInterestPeriodType.DAILY.equals(this.interestCompoundingType)) {
compoundingPeriodEndDate = determineInterestPeriodEndDateFrom( compoundingPeriodEndDate = determineInterestPeriodEndDateFrom(
compoundingPeriod.getPeriodInterval().startDate(), this.interestCompoundingType, compoundingPeriod.getPeriodInterval().startDate(), this.interestCompoundingType,
compoundingPeriod.getPeriodInterval().endDate()); compoundingPeriod.getPeriodInterval().endDate(), this.getFinancialYearBeginningMonth());
} }
if (compoundingPeriodEndDate.equals(compoundingPeriod.getPeriodInterval().endDate())) { if (compoundingPeriodEndDate.equals(compoundingPeriod.getPeriodInterval().endDate())) {
@@ -235,7 +239,7 @@ public class PostingPeriod {
private static List<CompoundingPeriod> compoundingPeriodsInPostingPeriod(final LocalDateInterval postingPeriodInterval, private static List<CompoundingPeriod> compoundingPeriodsInPostingPeriod(final LocalDateInterval postingPeriodInterval,
final SavingsCompoundingInterestPeriodType interestPeriodType, final List<EndOfDayBalance> allEndOfDayBalances, final SavingsCompoundingInterestPeriodType interestPeriodType, final List<EndOfDayBalance> allEndOfDayBalances,
final LocalDate upToInterestCalculationDate) { final LocalDate upToInterestCalculationDate, int financialYearBeginningMonth) {
final List<CompoundingPeriod> compoundingPeriods = new ArrayList<>(); final List<CompoundingPeriod> compoundingPeriods = new ArrayList<>();
@@ -256,7 +260,7 @@ public class PostingPeriod {
while (!periodStartDate.isAfter(postingPeriodEndDate) && !periodEndDate.isAfter(postingPeriodEndDate)) { while (!periodStartDate.isAfter(postingPeriodEndDate) && !periodEndDate.isAfter(postingPeriodEndDate)) {
periodEndDate = determineInterestPeriodEndDateFrom(periodStartDate, interestPeriodType, upToInterestCalculationDate); periodEndDate = determineInterestPeriodEndDateFrom(periodStartDate, interestPeriodType, upToInterestCalculationDate, financialYearBeginningMonth);
if (periodEndDate.isAfter(postingPeriodEndDate)) { if (periodEndDate.isAfter(postingPeriodEndDate)) {
periodEndDate = postingPeriodEndDate; periodEndDate = postingPeriodEndDate;
} }
@@ -285,7 +289,7 @@ public class PostingPeriod {
while (!periodStartDate.isAfter(qPostingPeriodEndDate) && !periodEndDate.isAfter(qPostingPeriodEndDate)) { while (!periodStartDate.isAfter(qPostingPeriodEndDate) && !periodEndDate.isAfter(qPostingPeriodEndDate)) {
periodEndDate = determineInterestPeriodEndDateFrom(periodStartDate, interestPeriodType, upToInterestCalculationDate); periodEndDate = determineInterestPeriodEndDateFrom(periodStartDate, interestPeriodType, upToInterestCalculationDate, financialYearBeginningMonth);
if (periodEndDate.isAfter(qPostingPeriodEndDate)) { if (periodEndDate.isAfter(qPostingPeriodEndDate)) {
periodEndDate = qPostingPeriodEndDate; periodEndDate = qPostingPeriodEndDate;
} }
@@ -310,7 +314,7 @@ public class PostingPeriod {
while (!periodStartDate.isAfter(bPostingPeriodEndDate) && !periodEndDate.isAfter(bPostingPeriodEndDate)) { while (!periodStartDate.isAfter(bPostingPeriodEndDate) && !periodEndDate.isAfter(bPostingPeriodEndDate)) {
periodEndDate = determineInterestPeriodEndDateFrom(periodStartDate, interestPeriodType, upToInterestCalculationDate); periodEndDate = determineInterestPeriodEndDateFrom(periodStartDate, interestPeriodType, upToInterestCalculationDate, financialYearBeginningMonth);
if (periodEndDate.isAfter(bPostingPeriodEndDate)) { if (periodEndDate.isAfter(bPostingPeriodEndDate)) {
periodEndDate = bPostingPeriodEndDate; periodEndDate = bPostingPeriodEndDate;
} }
@@ -335,7 +339,7 @@ public class PostingPeriod {
while (!periodStartDate.isAfter(aPostingPeriodEndDate) && !periodEndDate.isAfter(aPostingPeriodEndDate)) { while (!periodStartDate.isAfter(aPostingPeriodEndDate) && !periodEndDate.isAfter(aPostingPeriodEndDate)) {
periodEndDate = determineInterestPeriodEndDateFrom(periodStartDate, interestPeriodType, upToInterestCalculationDate); periodEndDate = determineInterestPeriodEndDateFrom(periodStartDate, interestPeriodType, upToInterestCalculationDate, financialYearBeginningMonth);
if (periodEndDate.isAfter(aPostingPeriodEndDate)) { if (periodEndDate.isAfter(aPostingPeriodEndDate)) {
periodEndDate = aPostingPeriodEndDate; periodEndDate = aPostingPeriodEndDate;
} }
@@ -360,10 +364,14 @@ public class PostingPeriod {
} }
private static LocalDate determineInterestPeriodEndDateFrom(final LocalDate periodStartDate, private static LocalDate determineInterestPeriodEndDateFrom(final LocalDate periodStartDate,
final SavingsCompoundingInterestPeriodType interestPeriodType, final LocalDate upToInterestCalculationDate) { final SavingsCompoundingInterestPeriodType interestPeriodType, final LocalDate upToInterestCalculationDate, int financialYearBeginningMonth) {
LocalDate periodEndDate = upToInterestCalculationDate; LocalDate periodEndDate = upToInterestCalculationDate;
int previousMonth = financialYearBeginningMonth-1;
if(previousMonth==0){
previousMonth = 12;
}
int periodsInMonth = 1;
switch (interestPeriodType) { switch (interestPeriodType) {
case INVALID: case INVALID:
break; break;
@@ -383,34 +391,20 @@ public class PostingPeriod {
periodEndDate = periodStartDate.dayOfMonth().withMaximumValue(); periodEndDate = periodStartDate.dayOfMonth().withMaximumValue();
break; break;
case QUATERLY: case QUATERLY:
// // jan 1st to mar 31st, 1st apr to jun 30, jul 1st to sept periodsInMonth = 4;
// 30, periodEndDate = getPeriodEndDate(periodEndDate, previousMonth, periodsInMonth, periodStartDate);
// // oct 1st to dec 31
int year = periodStartDate.getYearOfEra();
int monthofYear = periodStartDate.getMonthOfYear();
if (monthofYear <= 3) {
periodEndDate = new DateTime().withDate(year, 3, 31).toLocalDate();
} else if (monthofYear <= 6) {
periodEndDate = new DateTime().withDate(year, 6, 30).toLocalDate();
} else if (monthofYear <= 9) {
periodEndDate = new DateTime().withDate(year, 9, 30).toLocalDate();
} else if (monthofYear <= 12) {
periodEndDate = new DateTime().withDate(year, 12, 31).toLocalDate();
}
break; break;
case BI_ANNUAL: case BI_ANNUAL:
// // jan 1st to 30, jul 1st to dec 31 periodsInMonth = 2;
year = periodStartDate.getYearOfEra(); periodEndDate = getPeriodEndDate(periodEndDate, previousMonth, periodsInMonth, periodStartDate);
monthofYear = periodStartDate.getMonthOfYear();
if (monthofYear <= 6) {
periodEndDate = new DateTime().withDate(year, 6, 30).toLocalDate();
} else if (monthofYear <= 12) {
periodEndDate = new DateTime().withDate(year, 12, 31).toLocalDate();
}
break; break;
case ANNUAL: case ANNUAL:
periodEndDate = periodStartDate.monthOfYear().withMaximumValue(); periodEndDate = periodStartDate.withMonthOfYear(previousMonth);
periodEndDate = periodEndDate.dayOfMonth().withMaximumValue(); periodEndDate = periodEndDate.dayOfMonth().withMaximumValue();
if(periodEndDate.isBefore(periodStartDate)){
periodEndDate = periodEndDate.plusYears(1);
}
break; break;
// case NO_COMPOUNDING_SIMPLE_INTEREST: // case NO_COMPOUNDING_SIMPLE_INTEREST:
@@ -422,6 +416,40 @@ public class PostingPeriod {
return periodEndDate; return periodEndDate;
} }
private static LocalDate getPeriodEndDate(LocalDate periodEndDate, int previousMonth, int periodsInMonth, LocalDate periodStartDate) {
int year = periodStartDate.getYearOfEra();
int monthofYear = periodStartDate.getMonthOfYear();
LocalDate date = DateUtils.getLocalDateOfTenant();
TreeSet<Integer> monthSet = new TreeSet<>();
date = date.withMonthOfYear(previousMonth);
monthSet.add(date.getMonthOfYear());
int count =0;
while(count<(periodsInMonth-1)){
date = date.plusMonths((12/periodsInMonth));
monthSet.add(date.getMonthOfYear());
count++;
}
boolean notInRange = true;
/*
* if strt date is 2016-10-05
* if financial year set to 4 then applicable month will be march and september that is (3,9)
* if start date fall in month of oct,nov or dec then month will be 10, 11 or 12
* so period end date should be taken from next year for march month
*/
for (Integer month : monthSet) {
if(monthofYear<=month.intValue()){
periodEndDate = new DateTime().withDate(year, month, DateUtils.getLocalDateOfTenant().withMonthOfYear(month).dayOfMonth().withMaximumValue().getDayOfMonth()).toLocalDate();
notInRange = false;
break;
}
}
if(notInRange){
periodEndDate = new DateTime().withDate(year+1, monthSet.first(), DateUtils.getLocalDateOfTenant().withMonthOfYear(monthSet.first()).dayOfMonth().withMaximumValue().getDayOfMonth()).toLocalDate();
}
return periodEndDate;
}
public boolean isInterestTransfered() { public boolean isInterestTransfered() {
return this.interestTransfered; return this.interestTransfered;
} }
@@ -433,4 +461,11 @@ public class PostingPeriod {
public boolean isUserPosting() { public boolean isUserPosting() {
return this.isUserPosting; return this.isUserPosting;
} }
public Integer getFinancialYearBeginningMonth() {
return this.financialYearBeginningMonth;
}
} }