Merge branch 'PR236' into develop

This commit is contained in:
Adi Narayana Raju
2016-11-14 18:11:36 +05:30
17 changed files with 185 additions and 102 deletions
@@ -129,6 +129,10 @@ public enum SavingsAccountTransactionType {
return this.value.equals(SavingsAccountTransactionType.INTEREST_POSTING.getValue());
}
public boolean isOverDraftInterestPosting() {
return this.value.equals(SavingsAccountTransactionType.OVERDRAFT_INTEREST.getValue());
}
public boolean isWithHoldTax() {
return this.value.equals(SavingsAccountTransactionType.WITHHOLD_TAX.getValue());
}
@@ -190,10 +190,9 @@ public class FixedDepositAccount extends SavingsAccount {
public void updateMaturityDateAndAmountBeforeAccountActivation(final MathContext mc, final boolean isPreMatureClosure,
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth) {
List<SavingsAccountTransaction> allTransactions = new ArrayList<>();
final boolean postInterestAsOn = false;
final Money transactionAmountMoney = Money.of(getCurrency(), this.accountTermAndPreClosure.depositAmount());
final SavingsAccountTransaction transaction = SavingsAccountTransaction.deposit(null, office(), null,
this.accountSubmittedOrActivationDate(), transactionAmountMoney, new Date(), null, postInterestAsOn); // TODO:
this.accountSubmittedOrActivationDate(), transactionAmountMoney, new Date(), null); // TODO:
// verify
// if
// it
@@ -496,9 +495,9 @@ public class FixedDepositAccount extends SavingsAccount {
final LocalDate interestPostingUpToDate = maturityDate();
final MathContext mc = MathContext.DECIMAL64;
final boolean isInterestTransfer = false;
final boolean postInterestAsOn = false;
final LocalDate postInterestOnDate = null;
final List<PostingPeriod> postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, postInterestAsOn);
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, postInterestOnDate);
Money interestPostedToDate = Money.zero(this.currency);
@@ -518,7 +517,7 @@ public class FixedDepositAccount extends SavingsAccount {
final SavingsAccountTransaction postingTransaction = findInterestPostingTransactionFor(interestPostingTransactionDate);
if (postingTransaction == null) {
final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(),
interestPostingTransactionDate, interestEarnedToBePostedForPeriod, postInterestAsOn);
interestPostingTransactionDate, interestEarnedToBePostedForPeriod, interestPostingPeriod.isUserPosting());
this.transactions.add(newPostingTransaction);
recalucateDailyBalanceDetails = true;
} else {
@@ -526,7 +525,7 @@ public class FixedDepositAccount extends SavingsAccount {
if (correctionRequired) {
postingTransaction.reverse();
final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(),
interestPostingTransactionDate, interestEarnedToBePostedForPeriod, postInterestAsOn);
interestPostingTransactionDate, interestEarnedToBePostedForPeriod, interestPostingPeriod.isUserPosting());
this.transactions.add(newPostingTransaction);
recalucateDailyBalanceDetails = true;
}
@@ -609,17 +608,16 @@ public class FixedDepositAccount extends SavingsAccount {
@Override
public void postInterest(final MathContext mc, final LocalDate postingDate, boolean isInterestTransfer,
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,
final boolean postAsInterestOn) {
final boolean postInterestAsOn=false;
final LocalDate postInterestOnDate) {
final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
super.postInterest(mc, interestPostingUpToDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn);
financialYearBeginningMonth, postInterestOnDate);
}
@Override
public List<PostingPeriod> calculateInterestUsing(final MathContext mc, final LocalDate postingDate, boolean isInterestTransfer,
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,
final boolean postAsInterestOn) {
final LocalDate postAsInterestOn) {
final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
return super.calculateInterestUsing(mc, interestPostingUpToDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postAsInterestOn);
@@ -373,10 +373,9 @@ public class RecurringDepositAccount extends SavingsAccount {
if (generateFutureTransactions) {
for (RecurringDepositScheduleInstallment installment : depositScheduleInstallments()) {
if (installment.isPrincipalNotCompleted(getCurrency())) {
boolean postInterestAsOn = false;
final SavingsAccountTransaction transaction = SavingsAccountTransaction.deposit(null, office(), null,
installment.dueDate(), installment.getDepositAmountOutstanding(getCurrency()), installment.dueDate().toDate(),
null, postInterestAsOn);
null);
allTransactions.add(transaction);
}
}
@@ -603,9 +602,9 @@ public class RecurringDepositAccount extends SavingsAccount {
}
final MathContext mc = MathContext.DECIMAL64;
boolean isInterestTransfer = false;
boolean postInterestAsOn =false;
LocalDate postInterestOnDate = null;
final List<PostingPeriod> postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate.minusDays(1), isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, postInterestAsOn);
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, postInterestOnDate);
Money interestPostedToDate = Money.zero(this.currency);
@@ -623,7 +622,7 @@ public class RecurringDepositAccount extends SavingsAccount {
final SavingsAccountTransaction postingTransaction = findInterestPostingTransactionFor(interestPostingTransactionDate);
if (postingTransaction == null) {
final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(),
interestPostingTransactionDate, interestEarnedToBePostedForPeriod, postInterestAsOn);
interestPostingTransactionDate, interestEarnedToBePostedForPeriod, interestPostingPeriod.isUserPosting());
addTransaction(newPostingTransaction);
recalucateDailyBalanceDetails = true;
} else {
@@ -631,7 +630,7 @@ public class RecurringDepositAccount extends SavingsAccount {
if (correctionRequired) {
postingTransaction.reverse();
final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(),
interestPostingTransactionDate, interestEarnedToBePostedForPeriod, postInterestAsOn);
interestPostingTransactionDate, interestEarnedToBePostedForPeriod, interestPostingPeriod.isUserPosting());
addTransaction(newPostingTransaction);
recalucateDailyBalanceDetails = true;
}
@@ -714,7 +713,7 @@ public class RecurringDepositAccount extends SavingsAccount {
@Override
public void postInterest(final MathContext mc, final LocalDate postingDate, final boolean isInterestTransfer,
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,final boolean postInterestAson) {
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,final LocalDate postInterestAson) {
final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
super.postInterest(mc, interestPostingUpToDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAson);
@@ -722,7 +721,7 @@ public class RecurringDepositAccount extends SavingsAccount {
@Override
public List<PostingPeriod> calculateInterestUsing(final MathContext mc, final LocalDate postingDate, boolean isInterestTransfer,
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,final boolean postAsInterestOn) {
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,final LocalDate postAsInterestOn) {
final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
return super.calculateInterestUsing(mc, interestPostingUpToDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postAsInterestOn);
@@ -464,9 +464,9 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
return SavingsAccountStatusType.fromInt(this.status).isClosed();
}
public void postInterest(final MathContext mc, final LocalDate interestPostingUpToDate, final boolean isInterestTransfer,
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,final boolean postInterestAsOn) {
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,final LocalDate postInterestOnDate) {
final List<PostingPeriod> postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, postInterestAsOn);
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, postInterestOnDate);
Money interestPostedToDate = Money.zero(this.currency);
boolean recalucateDailyBalanceDetails = false;
@@ -644,7 +644,7 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
public List<LocalDate> getManualPostingDates() {
List<LocalDate> transactions = new ArrayList<>();
for (SavingsAccountTransaction trans : this.transactions) {
if (trans.isManualTransaction()) {
if (trans.isInterestPosting() && trans.isNotReversed() && trans.isManualTransaction()) {
transactions.add(trans.getTransactionLocalDate());
}
}
@@ -670,7 +670,7 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
*/
public List<PostingPeriod> calculateInterestUsing(final MathContext mc, final LocalDate upToInterestCalculationDate,
boolean isInterestTransfer, final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,final boolean postInterestAsOn) {
boolean isInterestTransfer, final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,final LocalDate postInterestOnDate) {
// no openingBalance concept supported yet but probably will to allow
// for migrations.
@@ -693,8 +693,8 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
final SavingsInterestCalculationDaysInYearType daysInYearType = SavingsInterestCalculationDaysInYearType
.fromInt(this.interestCalculationDaysInYearType);
List<LocalDate> postedAsOnDates= getManualPostingDates();
if(postInterestAsOn){
postedAsOnDates.add(upToInterestCalculationDate);
if(postInterestOnDate != null){
postedAsOnDates.add(postInterestOnDate);
}
final List<LocalDateInterval> postingPeriodIntervals = this.savingsHelper.determineInterestPostingPeriods(
getStartInterestCalculationDate(), upToInterestCalculationDate, postingPeriodType, financialYearBeginningMonth,
@@ -2153,7 +2153,7 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
if (isSavingsChargeApplied) {
final MathContext mc = MathContext.DECIMAL64;
boolean isInterestTransfer = false;
boolean postInterestAsOnDate = false;
LocalDate postInterestAsOnDate = null;
if (this.isBeforeLastPostingPeriod(getActivationLocalDate())) {
final LocalDate today = DateUtils.getLocalDateOfTenant();
this.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
@@ -2666,8 +2666,7 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
SavingsCompoundingInterestPeriodType savingsCompoundingInterestPeriodType = SavingsCompoundingInterestPeriodType
.fromInt(interestCompoundingPeriodType);
if (postingtoCompoundMap.get(savingsPostingInterestPeriodType) == null
|| !postingtoCompoundMap.get(savingsPostingInterestPeriodType).contains(savingsCompoundingInterestPeriodType)) {
if (postingtoCompoundMap.get(savingsPostingInterestPeriodType) == null) {
baseDataValidator.failWithCodeNoParameterAddedToErrorCode("posting.period.type.is.less.than.compound.period.type",
savingsPostingInterestPeriodType.name(), savingsCompoundingInterestPeriodType.name());
@@ -86,7 +86,7 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
if (transactionBooleanValues.isRegularTransaction() && !account.allowWithdrawal()) { throw new DepositAccountTransactionNotAllowedException(
account.getId(), "withdraw", account.depositAccountType()); }
final Set<Long> existingTransactionIds = new HashSet<>();
final boolean interestPostAsOn = false;
final LocalDate postInterestOnDate = null;
final Set<Long> existingReversedTransactionIds = new HashSet<>();
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
@@ -97,11 +97,11 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
if (account.isBeforeLastPostingPeriod(transactionDate)) {
final LocalDate today = DateUtils.getLocalDateOfTenant();
account.postInterest(mc, today, transactionBooleanValues.isInterestTransfer(), isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, interestPostAsOn);
financialYearBeginningMonth, postInterestOnDate);
} else {
final LocalDate today = DateUtils.getLocalDateOfTenant();
account.calculateInterestUsing(mc, today, transactionBooleanValues.isInterestTransfer(),
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, interestPostAsOn);
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, postInterestOnDate);
}
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
@@ -155,16 +155,16 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
paymentDetail, new Date(), user);
final SavingsAccountTransaction deposit = account.deposit(transactionDTO, savingsAccountTransactionType);
final boolean interestPostAsOn = false;
final LocalDate postInterestOnDate = null;
final MathContext mc = MathContext.DECIMAL64;
if (account.isBeforeLastPostingPeriod(transactionDate)) {
final LocalDate today = DateUtils.getLocalDateOfTenant();
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
interestPostAsOn);
postInterestOnDate);
} else {
final LocalDate today = DateUtils.getLocalDateOfTenant();
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, interestPostAsOn);
financialYearBeginningMonth, postInterestOnDate);
}
saveTransactionToGenerateTransactionId(deposit);
@@ -129,9 +129,9 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom<L
}
public static SavingsAccountTransaction deposit(final SavingsAccount savingsAccount, final Office office,
final PaymentDetail paymentDetail, final LocalDate date, final Money amount, Date createdDate, final AppUser appUser,
final boolean isManualTransaction) {
final PaymentDetail paymentDetail, final LocalDate date, final Money amount, Date createdDate, final AppUser appUser) {
final boolean isReversed = false;
final boolean isManualTransaction = false;
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail, SavingsAccountTransactionType.DEPOSIT.getValue(), date,
createdDate, amount, isReversed, appUser, isManualTransaction);
}
@@ -327,13 +327,17 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom<L
}
public boolean isPostInterestCalculationRequired() {
return this.isDeposit() || this.isChargeTransaction() || this.isDividendPayout();
return this.isDeposit() || this.isWithdrawal() || this.isChargeTransaction() || this.isDividendPayout() || this.isInterestPosting();
}
public boolean isInterestPostingAndNotReversed() {
return SavingsAccountTransactionType.fromInt(this.typeOf).isInterestPosting() && isNotReversed();
}
public boolean isInterestPosting() {
return SavingsAccountTransactionType.fromInt(this.typeOf).isInterestPosting()
|| SavingsAccountTransactionType.fromInt(this.typeOf).isOverDraftInterestPosting();
}
public boolean isWithdrawalFeeAndNotReversed() {
return SavingsAccountTransactionType.fromInt(this.typeOf).isWithdrawalFee() && isNotReversed();
}
@@ -178,4 +178,9 @@ public class AnnualCompoundingPeriod implements CompoundingPeriod {
this.periodInterval = periodInterval;
this.endOfDayBalances = endOfDayBalances;
}
@Override
public LocalDateInterval getPeriodInterval() {
return this.periodInterval;
}
}
@@ -178,4 +178,9 @@ public class BiAnnualCompoundingPeriod implements CompoundingPeriod {
this.periodInterval = periodInterval;
this.endOfDayBalances = endOfDayBalances;
}
@Override
public LocalDateInterval getPeriodInterval() {
return this.periodInterval;
}
}
@@ -46,10 +46,13 @@ public class CompoundInterestHelper {
Money interestEarned = Money.zero(currency);
// 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) {
final BigDecimal interestEarnedThisPeriod = postingPeriod.calculateInterest(interestEarnedButNotPosted);
final BigDecimal interestEarnedThisPeriod = postingPeriod.calculateInterest(compoundInterestValues);
final Money moneyToBePostedForPeriod = Money.of(currency, interestEarnedThisPeriod);
@@ -58,9 +61,9 @@ public class CompoundInterestHelper {
// interest for accounts which has post interest to linked savings
// account and if already transfered then it includes in interest
// calculation.
if (postingPeriod.isInterestTransfered() || !interestTransferEnabled
|| (lockUntil != null && !postingPeriod.dateOfPostingTransaction().isAfter(lockUntil))) {
interestEarnedButNotPosted = interestEarnedButNotPosted.add(moneyToBePostedForPeriod.getAmount());
if (!(postingPeriod.isInterestTransfered() || !interestTransferEnabled
|| (lockUntil != null && !postingPeriod.dateOfPostingTransaction().isAfter(lockUntil)))) {
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 org.apache.fineract.infrastructure.core.domain.LocalDateInterval;
import org.apache.fineract.portfolio.savings.SavingsCompoundingInterestPeriodType;
import org.apache.fineract.portfolio.savings.SavingsInterestCalculationType;
@@ -29,4 +30,5 @@ public interface CompoundingPeriod {
SavingsInterestCalculationType interestCalculationType, BigDecimal interestFromPreviousPostingPeriod,
BigDecimal interestRateAsFraction, long daysInYear, BigDecimal minBalanceForInterestCalculation,
BigDecimal overdraftInterestRateAsFraction, BigDecimal minOverdraftForInterestCalculation);
LocalDateInterval getPeriodInterval();
}
@@ -30,7 +30,6 @@ import org.joda.time.LocalDate;
public class DailyCompoundingPeriod implements CompoundingPeriod {
@SuppressWarnings("unused")
private final LocalDateInterval periodInterval;
private final List<EndOfDayBalance> endOfDayBalances;
@@ -77,8 +76,8 @@ public class DailyCompoundingPeriod implements CompoundingPeriod {
@Override
public BigDecimal calculateInterest(
@SuppressWarnings("unused") final SavingsCompoundingInterestPeriodType compoundingInterestPeriodType,
@SuppressWarnings("unused") final SavingsInterestCalculationType interestCalculationType,
final SavingsCompoundingInterestPeriodType compoundingInterestPeriodType,
final SavingsInterestCalculationType interestCalculationType,
final BigDecimal interestFromPreviousPostingPeriod, final BigDecimal interestRateAsFraction, final long daysInYear,
final BigDecimal minBalanceForInterestCalculation,
final BigDecimal overdraftInterestRateAsFraction, final BigDecimal minOverdraftForInterestCalculation) {
@@ -97,4 +96,9 @@ public class DailyCompoundingPeriod implements CompoundingPeriod {
return interestEarned;
}
@Override
public LocalDateInterval getPeriodInterval() {
return this.periodInterval;
}
}
@@ -174,4 +174,9 @@ public class MonthlyCompoundingPeriod implements CompoundingPeriod {
this.periodInterval = periodInterval;
this.endOfDayBalances = endOfDayBalances;
}
@Override
public LocalDateInterval getPeriodInterval() {
return this.periodInterval;
}
}
@@ -194,19 +194,32 @@ public class PostingPeriod {
return this.openingBalance;
}
public BigDecimal calculateInterest(final BigDecimal interestFromPreviousPostingPeriod) {
public BigDecimal calculateInterest(final CompoundInterestValues compoundInterestValues) {
BigDecimal interestEarned = BigDecimal.ZERO;
// for each compounding period accumulate the amount of interest
// to be applied to the balanced for interest calculation
BigDecimal interestCompounded = interestFromPreviousPostingPeriod;
for (final CompoundingPeriod compoundingPeriod : this.compoundingPeriods) {
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.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);
}
@@ -31,7 +31,6 @@ import org.joda.time.LocalDate;
public class QuarterlyCompoundingPeriod implements CompoundingPeriod {
@SuppressWarnings("unused")
private final LocalDateInterval periodInterval;
private final List<EndOfDayBalance> endOfDayBalances;
@@ -178,4 +177,9 @@ public class QuarterlyCompoundingPeriod implements CompoundingPeriod {
this.periodInterval = periodInterval;
this.endOfDayBalances = endOfDayBalances;
}
@Override
public LocalDateInterval getPeriodInterval() {
return this.periodInterval;
}
}
@@ -234,15 +234,15 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
}
final boolean isInterestTransfer = false;
final boolean postInterestAsOn = false;
final LocalDate postInterestOnDate = null;
if (account.isBeforeLastPostingPeriod(account.getActivationLocalDate())) {
final LocalDate today = DateUtils.getLocalDateOfTenant();
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn);
financialYearBeginningMonth, postInterestOnDate);
} else {
final LocalDate today = DateUtils.getLocalDateOfTenant();
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn);
financialYearBeginningMonth, postInterestOnDate);
}
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
@@ -340,15 +340,15 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
final LocalDate overdueUptoDate = DateUtils.getLocalDateOfTenant();
account.updateOverduePayments(overdueUptoDate);
final boolean isInterestTransfer = false;
final boolean postInterestAsOn = false;
final LocalDate postInterestOnDate = null;
if (account.isBeforeLastPostingPeriod(account.getActivationLocalDate())) {
final LocalDate today = DateUtils.getLocalDateOfTenant();
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn);
financialYearBeginningMonth, postInterestOnDate);
} else {
final LocalDate today = DateUtils.getLocalDateOfTenant();
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn);
financialYearBeginningMonth, postInterestOnDate);
}
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
@@ -497,9 +497,9 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
final LocalDate today = DateUtils.getLocalDateOfTenant();
final MathContext mc = new MathContext(15, MoneyHelper.getRoundingMode());
boolean isInterestTransfer = false;
boolean postInterestAsOn = false;
LocalDate postInterestOnDate = null;
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn);
financialYearBeginningMonth, postInterestOnDate);
this.savingAccountRepositoryWrapper.save(account);
@@ -541,9 +541,9 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
final LocalDate today = DateUtils.getLocalDateOfTenant();
final MathContext mc = new MathContext(10, MoneyHelper.getRoundingMode());
boolean isInterestTransfer = false;
boolean postInterestAsOn = false;
LocalDate postInterestOnDate = null;
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestAsOn);
postInterestOnDate);
this.savingAccountRepositoryWrapper.saveAndFlush(account);
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
@@ -607,15 +607,15 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
}
account.undoTransaction(transactionId);
boolean isInterestTransfer = false;
boolean postInterestAsOn = false;
LocalDate postInterestOnDate = null;
checkClientOrGroupActive(account);
if (savingsAccountTransaction.isPostInterestCalculationRequired()
&& account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestAsOn);
postInterestOnDate);
} else {
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn);
financialYearBeginningMonth, postInterestOnDate);
}
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
@@ -710,14 +710,14 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
}
final Long newtransactionId = saveTransactionToGenerateTransactionId(transaction);
boolean isInterestTransfer = false;
final boolean postInterestAsOn = false;
final LocalDate postInterestOnDate = null;
if (account.isBeforeLastPostingPeriod(transactionDate)
|| account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestAsOn);
postInterestOnDate);
} else {
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn);
financialYearBeginningMonth, postInterestOnDate);
}
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
@@ -921,7 +921,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
final SavingsAccount savingsAccount = this.depositAccountAssembler.assembleFrom(accountId, depositAccountType);
final boolean postInterestAsOn = false;
final LocalDate postInterestOnDate = null;
final Set<Long> existingTransactionIds = new HashSet<>();
final Set<Long> existingReversedTransactionIds = new HashSet<>();
updateExistingTransactionsDetails(savingsAccount, existingTransactionIds, existingReversedTransactionIds);
@@ -933,7 +933,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
final MathContext mc = MathContext.DECIMAL64;
boolean isInterestTransfer = false;
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn);
financialYearBeginningMonth, postInterestOnDate);
this.savingsAccountTransactionRepository.save(newTransferTransaction);
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
@@ -965,9 +965,9 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue());
final MathContext mc = MathContext.DECIMAL64;
boolean isInterestTransfer = false;
boolean postInterestAsOn = false;
LocalDate postInterestOnDate = null;
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn);
financialYearBeginningMonth, postInterestOnDate);
this.savingsAccountTransactionRepository.save(withdrawtransferTransaction);
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
@@ -1008,10 +1008,10 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
savingsAccount.reassignSavingsOfficer(fieldOfficer, transferDate);
}
boolean isInterestTransfer = false;
boolean postInterestAsOn = false;
LocalDate postInterestOnDate = null;
final MathContext mc = MathContext.DECIMAL64;
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn);
financialYearBeginningMonth, postInterestOnDate);
this.savingsAccountTransactionRepository.save(acceptTransferTransaction);
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
@@ -1154,16 +1154,16 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
account.waiveCharge(savingsAccountChargeId, user);
boolean isInterestTransfer = false;
boolean postInterestAsOn = false;
LocalDate postInterestOnDate = null;
final MathContext mc = MathContext.DECIMAL64;
if (account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueLocalDate())) {
final LocalDate today = DateUtils.getLocalDateOfTenant();
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestAsOn);
postInterestOnDate);
} else {
final LocalDate today = DateUtils.getLocalDateOfTenant();
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn);
financialYearBeginningMonth, postInterestOnDate);
}
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
@@ -1289,16 +1289,16 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
account.payCharge(savingsAccountCharge, amountPaid, transactionDate, formatter, user);
boolean isInterestTransfer = false;
boolean postInterestAsOn = false;
LocalDate postInterestOnDate = null;
final MathContext mc = MathContext.DECIMAL64;
if (account.isBeforeLastPostingPeriod(transactionDate)) {
final LocalDate today = DateUtils.getLocalDateOfTenant();
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestAsOn);
postInterestOnDate);
} else {
final LocalDate today = DateUtils.getLocalDateOfTenant();
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn);
financialYearBeginningMonth, postInterestOnDate);
}
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
@@ -361,8 +361,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final LocalDate today = DateUtils.getLocalDateOfTenant();
final MathContext mc = new MathContext(15, MoneyHelper.getRoundingMode());
boolean isInterestTransfer = false;
final LocalDate postInterestOnDate = null;
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth,false);
financialYearBeginningMonth,postInterestOnDate);
this.savingAccountRepositoryWrapper.save(account);
@@ -425,12 +426,11 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final LocalDate today = DateUtils.getLocalDateOfTenant();
final MathContext mc = new MathContext(10, MoneyHelper.getRoundingMode());
boolean isInterestTransfer = false;
if(postInterestAs==false){
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,postInterestAs);
}
else{
account.postInterest(mc, transactionDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,postInterestAs);
}
LocalDate postInterestOnDate = null;
if (postInterestAs) {
postInterestOnDate = transactionDate;
}
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,postInterestOnDate);
// for generating transaction id's
List<SavingsAccountTransaction> transactions = account.getTransactions();
for (SavingsAccountTransaction accountTransaction : transactions) {
@@ -489,13 +489,14 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
}
}
boolean isInterestTransfer = false;
LocalDate postInterestOnDate = null;
checkClientOrGroupActive(account);
if (savingsAccountTransaction.isPostInterestCalculationRequired()
&& account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,false);
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,postInterestOnDate);
} else {
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth,false);
financialYearBeginningMonth,postInterestOnDate);
}
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
@@ -578,13 +579,13 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
transaction = account.withdraw(transactionDTO, true);
}
final Long newtransactionId = saveTransactionToGenerateTransactionId(transaction);
final LocalDate postInterestOnDate = null;
if (account.isBeforeLastPostingPeriod(transactionDate)
|| account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,false);
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,postInterestOnDate);
} else {
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth,false);
financialYearBeginningMonth,postInterestOnDate);
}
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
@@ -655,8 +656,10 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
boolean postInterestOnClosingDate = false;
List<SavingsAccountTransaction> savingTransactions = account.getTransactions();
for (SavingsAccountTransaction savingTransaction : savingTransactions) {
if (closedDate.toDate().equals(savingTransaction.getDateOf())) if (savingTransaction.getTypeOf() == SavingsAccountTransactionType.OVERDRAFT_INTEREST.getValue()) {
if (savingTransaction.isInterestPosting() && savingTransaction.isNotReversed()
&& closedDate.isEqual(savingTransaction.getTransactionLocalDate())) {
postInterestOnClosingDate = true;
break;
}
}
if (postInterestOnClosingDate == false) { throw new PostInterestClosingDateException(); }
@@ -730,9 +733,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
savingsAccount.setStatus(SavingsAccountStatusType.TRANSFER_IN_PROGRESS.getValue());
final MathContext mc = MathContext.DECIMAL64;
boolean isInterestTransfer = false;
boolean postInterestAsOn = false;
LocalDate postInterestOnDate = null;
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn);
financialYearBeginningMonth, postInterestOnDate);
this.savingsAccountTransactionRepository.save(newTransferTransaction);
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
@@ -761,9 +764,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue());
final MathContext mc = MathContext.DECIMAL64;
boolean isInterestTransfer = false;
boolean postInterestAsOn =false;
LocalDate postInterestOnDate = null;
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn);
financialYearBeginningMonth, postInterestOnDate);
this.savingsAccountTransactionRepository.save(withdrawtransferTransaction);
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
@@ -803,9 +806,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
}
boolean isInterestTransfer = false;
final MathContext mc = MathContext.DECIMAL64;
boolean postInterestAsOn = false;
LocalDate postInterestOnDate = null;
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn);
financialYearBeginningMonth, postInterestOnDate);
this.savingsAccountTransactionRepository.save(acceptTransferTransaction);
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
@@ -954,16 +957,16 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
account.waiveCharge(savingsAccountChargeId, user);
boolean isInterestTransfer = false;
boolean postInterestAsOn = false;
LocalDate postInterestOnDate = null;
final MathContext mc = MathContext.DECIMAL64;
if (account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueLocalDate())) {
final LocalDate today = DateUtils.getLocalDateOfTenant();
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestAsOn);
postInterestOnDate);
} else {
final LocalDate today = DateUtils.getLocalDateOfTenant();
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn);
financialYearBeginningMonth, postInterestOnDate);
}
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
@@ -1088,16 +1091,16 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
account.payCharge(savingsAccountCharge, amountPaid, transactionDate, formatter, user);
boolean isInterestTransfer = false;
boolean postInterestAsOn = false;
LocalDate postInterestOnDate = null;
final MathContext mc = MathContext.DECIMAL64;
if (account.isBeforeLastPostingPeriod(transactionDate)) {
final LocalDate today = DateUtils.getLocalDateOfTenant();
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestAsOn);
postInterestOnDate);
} else {
final LocalDate today = DateUtils.getLocalDateOfTenant();
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn);
financialYearBeginningMonth, postInterestOnDate);
}
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {