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()); return this.value.equals(SavingsAccountTransactionType.INTEREST_POSTING.getValue());
} }
public boolean isOverDraftInterestPosting() {
return this.value.equals(SavingsAccountTransactionType.OVERDRAFT_INTEREST.getValue());
}
public boolean isWithHoldTax() { public boolean isWithHoldTax() {
return this.value.equals(SavingsAccountTransactionType.WITHHOLD_TAX.getValue()); 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, public void updateMaturityDateAndAmountBeforeAccountActivation(final MathContext mc, final boolean isPreMatureClosure,
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth) { final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth) {
List<SavingsAccountTransaction> allTransactions = new ArrayList<>(); List<SavingsAccountTransaction> allTransactions = new ArrayList<>();
final boolean postInterestAsOn = false;
final Money transactionAmountMoney = Money.of(getCurrency(), this.accountTermAndPreClosure.depositAmount()); final Money transactionAmountMoney = Money.of(getCurrency(), this.accountTermAndPreClosure.depositAmount());
final SavingsAccountTransaction transaction = SavingsAccountTransaction.deposit(null, office(), null, final SavingsAccountTransaction transaction = SavingsAccountTransaction.deposit(null, office(), null,
this.accountSubmittedOrActivationDate(), transactionAmountMoney, new Date(), null, postInterestAsOn); // TODO: this.accountSubmittedOrActivationDate(), transactionAmountMoney, new Date(), null); // TODO:
// verify // verify
// if // if
// it // it
@@ -496,9 +495,9 @@ public class FixedDepositAccount extends SavingsAccount {
final LocalDate interestPostingUpToDate = maturityDate(); final LocalDate interestPostingUpToDate = maturityDate();
final MathContext mc = MathContext.DECIMAL64; final MathContext mc = MathContext.DECIMAL64;
final boolean isInterestTransfer = false; final boolean isInterestTransfer = false;
final boolean postInterestAsOn = false; final LocalDate postInterestOnDate = null;
final List<PostingPeriod> postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate, isInterestTransfer, final List<PostingPeriod> postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, postInterestAsOn); isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, postInterestOnDate);
Money interestPostedToDate = Money.zero(this.currency); Money interestPostedToDate = Money.zero(this.currency);
@@ -518,7 +517,7 @@ public class FixedDepositAccount extends SavingsAccount {
final SavingsAccountTransaction postingTransaction = findInterestPostingTransactionFor(interestPostingTransactionDate); final SavingsAccountTransaction postingTransaction = findInterestPostingTransactionFor(interestPostingTransactionDate);
if (postingTransaction == null) { if (postingTransaction == null) {
final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(), final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(),
interestPostingTransactionDate, interestEarnedToBePostedForPeriod, postInterestAsOn); interestPostingTransactionDate, interestEarnedToBePostedForPeriod, interestPostingPeriod.isUserPosting());
this.transactions.add(newPostingTransaction); this.transactions.add(newPostingTransaction);
recalucateDailyBalanceDetails = true; recalucateDailyBalanceDetails = true;
} else { } else {
@@ -526,7 +525,7 @@ public class FixedDepositAccount extends SavingsAccount {
if (correctionRequired) { if (correctionRequired) {
postingTransaction.reverse(); postingTransaction.reverse();
final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(), final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(),
interestPostingTransactionDate, interestEarnedToBePostedForPeriod, postInterestAsOn); interestPostingTransactionDate, interestEarnedToBePostedForPeriod, interestPostingPeriod.isUserPosting());
this.transactions.add(newPostingTransaction); this.transactions.add(newPostingTransaction);
recalucateDailyBalanceDetails = true; recalucateDailyBalanceDetails = true;
} }
@@ -609,17 +608,16 @@ public class FixedDepositAccount extends SavingsAccount {
@Override @Override
public void postInterest(final MathContext mc, final LocalDate postingDate, boolean isInterestTransfer, public void postInterest(final MathContext mc, final LocalDate postingDate, boolean isInterestTransfer,
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth, final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,
final boolean postAsInterestOn) { final LocalDate postInterestOnDate) {
final boolean postInterestAsOn=false;
final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate); final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
super.postInterest(mc, interestPostingUpToDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, super.postInterest(mc, interestPostingUpToDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn); financialYearBeginningMonth, postInterestOnDate);
} }
@Override @Override
public List<PostingPeriod> calculateInterestUsing(final MathContext mc, final LocalDate postingDate, boolean isInterestTransfer, public List<PostingPeriod> calculateInterestUsing(final MathContext mc, final LocalDate postingDate, boolean isInterestTransfer,
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth, final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,
final boolean postAsInterestOn) { final LocalDate postAsInterestOn) {
final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate); final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
return super.calculateInterestUsing(mc, interestPostingUpToDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, return super.calculateInterestUsing(mc, interestPostingUpToDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postAsInterestOn); financialYearBeginningMonth, postAsInterestOn);
@@ -373,10 +373,9 @@ public class RecurringDepositAccount extends SavingsAccount {
if (generateFutureTransactions) { if (generateFutureTransactions) {
for (RecurringDepositScheduleInstallment installment : depositScheduleInstallments()) { for (RecurringDepositScheduleInstallment installment : depositScheduleInstallments()) {
if (installment.isPrincipalNotCompleted(getCurrency())) { if (installment.isPrincipalNotCompleted(getCurrency())) {
boolean postInterestAsOn = false;
final SavingsAccountTransaction transaction = SavingsAccountTransaction.deposit(null, office(), null, final SavingsAccountTransaction transaction = SavingsAccountTransaction.deposit(null, office(), null,
installment.dueDate(), installment.getDepositAmountOutstanding(getCurrency()), installment.dueDate().toDate(), installment.dueDate(), installment.getDepositAmountOutstanding(getCurrency()), installment.dueDate().toDate(),
null, postInterestAsOn); null);
allTransactions.add(transaction); allTransactions.add(transaction);
} }
} }
@@ -603,9 +602,9 @@ public class RecurringDepositAccount extends SavingsAccount {
} }
final MathContext mc = MathContext.DECIMAL64; final MathContext mc = MathContext.DECIMAL64;
boolean isInterestTransfer = false; boolean isInterestTransfer = false;
boolean postInterestAsOn =false; LocalDate postInterestOnDate = null;
final List<PostingPeriod> postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate.minusDays(1), isInterestTransfer, final List<PostingPeriod> postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate.minusDays(1), isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, postInterestAsOn); isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, postInterestOnDate);
Money interestPostedToDate = Money.zero(this.currency); Money interestPostedToDate = Money.zero(this.currency);
@@ -623,7 +622,7 @@ public class RecurringDepositAccount extends SavingsAccount {
final SavingsAccountTransaction postingTransaction = findInterestPostingTransactionFor(interestPostingTransactionDate); final SavingsAccountTransaction postingTransaction = findInterestPostingTransactionFor(interestPostingTransactionDate);
if (postingTransaction == null) { if (postingTransaction == null) {
final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(), final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(),
interestPostingTransactionDate, interestEarnedToBePostedForPeriod, postInterestAsOn); interestPostingTransactionDate, interestEarnedToBePostedForPeriod, interestPostingPeriod.isUserPosting());
addTransaction(newPostingTransaction); addTransaction(newPostingTransaction);
recalucateDailyBalanceDetails = true; recalucateDailyBalanceDetails = true;
} else { } else {
@@ -631,7 +630,7 @@ public class RecurringDepositAccount extends SavingsAccount {
if (correctionRequired) { if (correctionRequired) {
postingTransaction.reverse(); postingTransaction.reverse();
final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(), final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(),
interestPostingTransactionDate, interestEarnedToBePostedForPeriod, postInterestAsOn); interestPostingTransactionDate, interestEarnedToBePostedForPeriod, interestPostingPeriod.isUserPosting());
addTransaction(newPostingTransaction); addTransaction(newPostingTransaction);
recalucateDailyBalanceDetails = true; recalucateDailyBalanceDetails = true;
} }
@@ -714,7 +713,7 @@ public class RecurringDepositAccount extends SavingsAccount {
@Override @Override
public void postInterest(final MathContext mc, final LocalDate postingDate, final boolean isInterestTransfer, 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); final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
super.postInterest(mc, interestPostingUpToDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, super.postInterest(mc, interestPostingUpToDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAson); financialYearBeginningMonth, postInterestAson);
@@ -722,7 +721,7 @@ public class RecurringDepositAccount extends SavingsAccount {
@Override @Override
public List<PostingPeriod> calculateInterestUsing(final MathContext mc, final LocalDate postingDate, boolean isInterestTransfer, 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); final LocalDate interestPostingUpToDate = interestPostingUpToDate(postingDate);
return super.calculateInterestUsing(mc, interestPostingUpToDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, return super.calculateInterestUsing(mc, interestPostingUpToDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postAsInterestOn); financialYearBeginningMonth, postAsInterestOn);
@@ -464,9 +464,9 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
return SavingsAccountStatusType.fromInt(this.status).isClosed(); return SavingsAccountStatusType.fromInt(this.status).isClosed();
} }
public void postInterest(final MathContext mc, final LocalDate interestPostingUpToDate, final boolean isInterestTransfer, 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, final List<PostingPeriod> postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, postInterestAsOn); isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, postInterestOnDate);
Money interestPostedToDate = Money.zero(this.currency); Money interestPostedToDate = Money.zero(this.currency);
boolean recalucateDailyBalanceDetails = false; boolean recalucateDailyBalanceDetails = false;
@@ -644,7 +644,7 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
public List<LocalDate> getManualPostingDates() { public List<LocalDate> getManualPostingDates() {
List<LocalDate> transactions = new ArrayList<>(); List<LocalDate> transactions = new ArrayList<>();
for (SavingsAccountTransaction trans : this.transactions) { for (SavingsAccountTransaction trans : this.transactions) {
if (trans.isManualTransaction()) { if (trans.isInterestPosting() && trans.isNotReversed() && trans.isManualTransaction()) {
transactions.add(trans.getTransactionLocalDate()); transactions.add(trans.getTransactionLocalDate());
} }
} }
@@ -670,7 +670,7 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
*/ */
public List<PostingPeriod> calculateInterestUsing(final MathContext mc, final LocalDate upToInterestCalculationDate, 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 // no openingBalance concept supported yet but probably will to allow
// for migrations. // for migrations.
@@ -693,8 +693,8 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
final SavingsInterestCalculationDaysInYearType daysInYearType = SavingsInterestCalculationDaysInYearType final SavingsInterestCalculationDaysInYearType daysInYearType = SavingsInterestCalculationDaysInYearType
.fromInt(this.interestCalculationDaysInYearType); .fromInt(this.interestCalculationDaysInYearType);
List<LocalDate> postedAsOnDates= getManualPostingDates(); List<LocalDate> postedAsOnDates= getManualPostingDates();
if(postInterestAsOn){ if(postInterestOnDate != null){
postedAsOnDates.add(upToInterestCalculationDate); postedAsOnDates.add(postInterestOnDate);
} }
final List<LocalDateInterval> postingPeriodIntervals = this.savingsHelper.determineInterestPostingPeriods( final List<LocalDateInterval> postingPeriodIntervals = this.savingsHelper.determineInterestPostingPeriods(
getStartInterestCalculationDate(), upToInterestCalculationDate, postingPeriodType, financialYearBeginningMonth, getStartInterestCalculationDate(), upToInterestCalculationDate, postingPeriodType, financialYearBeginningMonth,
@@ -2153,7 +2153,7 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> {
if (isSavingsChargeApplied) { if (isSavingsChargeApplied) {
final MathContext mc = MathContext.DECIMAL64; final MathContext mc = MathContext.DECIMAL64;
boolean isInterestTransfer = false; boolean isInterestTransfer = false;
boolean postInterestAsOnDate = false; LocalDate postInterestAsOnDate = null;
if (this.isBeforeLastPostingPeriod(getActivationLocalDate())) { if (this.isBeforeLastPostingPeriod(getActivationLocalDate())) {
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
this.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, this.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
@@ -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());
@@ -86,7 +86,7 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
if (transactionBooleanValues.isRegularTransaction() && !account.allowWithdrawal()) { throw new DepositAccountTransactionNotAllowedException( if (transactionBooleanValues.isRegularTransaction() && !account.allowWithdrawal()) { throw new DepositAccountTransactionNotAllowedException(
account.getId(), "withdraw", account.depositAccountType()); } account.getId(), "withdraw", account.depositAccountType()); }
final Set<Long> existingTransactionIds = new HashSet<>(); final Set<Long> existingTransactionIds = new HashSet<>();
final boolean interestPostAsOn = false; final LocalDate postInterestOnDate = null;
final Set<Long> existingReversedTransactionIds = new HashSet<>(); final Set<Long> existingReversedTransactionIds = new HashSet<>();
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds); updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount, final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
@@ -97,11 +97,11 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
if (account.isBeforeLastPostingPeriod(transactionDate)) { if (account.isBeforeLastPostingPeriod(transactionDate)) {
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
account.postInterest(mc, today, transactionBooleanValues.isInterestTransfer(), isSavingsInterestPostingAtCurrentPeriodEnd, account.postInterest(mc, today, transactionBooleanValues.isInterestTransfer(), isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, interestPostAsOn); financialYearBeginningMonth, postInterestOnDate);
} else { } else {
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
account.calculateInterestUsing(mc, today, transactionBooleanValues.isInterestTransfer(), account.calculateInterestUsing(mc, today, transactionBooleanValues.isInterestTransfer(),
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, interestPostAsOn); isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, postInterestOnDate);
} }
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null; List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) { if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
@@ -155,16 +155,16 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount, final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
paymentDetail, new Date(), user); paymentDetail, new Date(), user);
final SavingsAccountTransaction deposit = account.deposit(transactionDTO, savingsAccountTransactionType); final SavingsAccountTransaction deposit = account.deposit(transactionDTO, savingsAccountTransactionType);
final boolean interestPostAsOn = false; final LocalDate postInterestOnDate = null;
final MathContext mc = MathContext.DECIMAL64; final MathContext mc = MathContext.DECIMAL64;
if (account.isBeforeLastPostingPeriod(transactionDate)) { if (account.isBeforeLastPostingPeriod(transactionDate)) {
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
interestPostAsOn); postInterestOnDate);
} else { } else {
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, interestPostAsOn); financialYearBeginningMonth, postInterestOnDate);
} }
saveTransactionToGenerateTransactionId(deposit); saveTransactionToGenerateTransactionId(deposit);
@@ -129,9 +129,9 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom<L
} }
public static SavingsAccountTransaction deposit(final SavingsAccount savingsAccount, final Office office, 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 PaymentDetail paymentDetail, final LocalDate date, final Money amount, Date createdDate, final AppUser appUser) {
final boolean isManualTransaction) {
final boolean isReversed = false; final boolean isReversed = false;
final boolean isManualTransaction = false;
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail, SavingsAccountTransactionType.DEPOSIT.getValue(), date, return new SavingsAccountTransaction(savingsAccount, office, paymentDetail, SavingsAccountTransactionType.DEPOSIT.getValue(), date,
createdDate, amount, isReversed, appUser, isManualTransaction); createdDate, amount, isReversed, appUser, isManualTransaction);
} }
@@ -327,13 +327,17 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom<L
} }
public boolean isPostInterestCalculationRequired() { public boolean isPostInterestCalculationRequired() {
return this.isDeposit() || this.isChargeTransaction() || this.isDividendPayout(); return this.isDeposit() || this.isWithdrawal() || this.isChargeTransaction() || this.isDividendPayout() || this.isInterestPosting();
} }
public boolean isInterestPostingAndNotReversed() { public boolean isInterestPostingAndNotReversed() {
return SavingsAccountTransactionType.fromInt(this.typeOf).isInterestPosting() && isNotReversed(); return SavingsAccountTransactionType.fromInt(this.typeOf).isInterestPosting() && isNotReversed();
} }
public boolean isInterestPosting() {
return SavingsAccountTransactionType.fromInt(this.typeOf).isInterestPosting()
|| SavingsAccountTransactionType.fromInt(this.typeOf).isOverDraftInterestPosting();
}
public boolean isWithdrawalFeeAndNotReversed() { public boolean isWithdrawalFeeAndNotReversed() {
return SavingsAccountTransactionType.fromInt(this.typeOf).isWithdrawalFee() && isNotReversed(); return SavingsAccountTransactionType.fromInt(this.typeOf).isWithdrawalFee() && isNotReversed();
} }
@@ -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;
}
} }
@@ -234,15 +234,15 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO); this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
} }
final boolean isInterestTransfer = false; final boolean isInterestTransfer = false;
final boolean postInterestAsOn = false; final LocalDate postInterestOnDate = null;
if (account.isBeforeLastPostingPeriod(account.getActivationLocalDate())) { if (account.isBeforeLastPostingPeriod(account.getActivationLocalDate())) {
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn); financialYearBeginningMonth, postInterestOnDate);
} else { } else {
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn); financialYearBeginningMonth, postInterestOnDate);
} }
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds); updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
@@ -340,15 +340,15 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
final LocalDate overdueUptoDate = DateUtils.getLocalDateOfTenant(); final LocalDate overdueUptoDate = DateUtils.getLocalDateOfTenant();
account.updateOverduePayments(overdueUptoDate); account.updateOverduePayments(overdueUptoDate);
final boolean isInterestTransfer = false; final boolean isInterestTransfer = false;
final boolean postInterestAsOn = false; final LocalDate postInterestOnDate = null;
if (account.isBeforeLastPostingPeriod(account.getActivationLocalDate())) { if (account.isBeforeLastPostingPeriod(account.getActivationLocalDate())) {
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn); financialYearBeginningMonth, postInterestOnDate);
} else { } else {
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn); financialYearBeginningMonth, postInterestOnDate);
} }
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null; List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) { if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
@@ -497,9 +497,9 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
final MathContext mc = new MathContext(15, MoneyHelper.getRoundingMode()); final MathContext mc = new MathContext(15, MoneyHelper.getRoundingMode());
boolean isInterestTransfer = false; boolean isInterestTransfer = false;
boolean postInterestAsOn = false; LocalDate postInterestOnDate = null;
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn); financialYearBeginningMonth, postInterestOnDate);
this.savingAccountRepositoryWrapper.save(account); this.savingAccountRepositoryWrapper.save(account);
@@ -541,9 +541,9 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
final MathContext mc = new MathContext(10, MoneyHelper.getRoundingMode()); final MathContext mc = new MathContext(10, MoneyHelper.getRoundingMode());
boolean isInterestTransfer = false; boolean isInterestTransfer = false;
boolean postInterestAsOn = false; LocalDate postInterestOnDate = null;
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestAsOn); postInterestOnDate);
this.savingAccountRepositoryWrapper.saveAndFlush(account); this.savingAccountRepositoryWrapper.saveAndFlush(account);
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds); postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
@@ -607,15 +607,15 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
} }
account.undoTransaction(transactionId); account.undoTransaction(transactionId);
boolean isInterestTransfer = false; boolean isInterestTransfer = false;
boolean postInterestAsOn = false; LocalDate postInterestOnDate = null;
checkClientOrGroupActive(account); checkClientOrGroupActive(account);
if (savingsAccountTransaction.isPostInterestCalculationRequired() if (savingsAccountTransaction.isPostInterestCalculationRequired()
&& account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) { && account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestAsOn); postInterestOnDate);
} else { } else {
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn); financialYearBeginningMonth, postInterestOnDate);
} }
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null; List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) { if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
@@ -710,14 +710,14 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
} }
final Long newtransactionId = saveTransactionToGenerateTransactionId(transaction); final Long newtransactionId = saveTransactionToGenerateTransactionId(transaction);
boolean isInterestTransfer = false; boolean isInterestTransfer = false;
final boolean postInterestAsOn = false; final LocalDate postInterestOnDate = null;
if (account.isBeforeLastPostingPeriod(transactionDate) if (account.isBeforeLastPostingPeriod(transactionDate)
|| account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) { || account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestAsOn); postInterestOnDate);
} else { } else {
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn); financialYearBeginningMonth, postInterestOnDate);
} }
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null; List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) { if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
@@ -921,7 +921,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth(); final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
final SavingsAccount savingsAccount = this.depositAccountAssembler.assembleFrom(accountId, depositAccountType); 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> existingTransactionIds = new HashSet<>();
final Set<Long> existingReversedTransactionIds = new HashSet<>(); final Set<Long> existingReversedTransactionIds = new HashSet<>();
updateExistingTransactionsDetails(savingsAccount, existingTransactionIds, existingReversedTransactionIds); updateExistingTransactionsDetails(savingsAccount, existingTransactionIds, existingReversedTransactionIds);
@@ -933,7 +933,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
final MathContext mc = MathContext.DECIMAL64; final MathContext mc = MathContext.DECIMAL64;
boolean isInterestTransfer = false; boolean isInterestTransfer = false;
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn); financialYearBeginningMonth, postInterestOnDate);
this.savingsAccountTransactionRepository.save(newTransferTransaction); this.savingsAccountTransactionRepository.save(newTransferTransaction);
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount); this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
@@ -965,9 +965,9 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue()); savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue());
final MathContext mc = MathContext.DECIMAL64; final MathContext mc = MathContext.DECIMAL64;
boolean isInterestTransfer = false; boolean isInterestTransfer = false;
boolean postInterestAsOn = false; LocalDate postInterestOnDate = null;
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn); financialYearBeginningMonth, postInterestOnDate);
this.savingsAccountTransactionRepository.save(withdrawtransferTransaction); this.savingsAccountTransactionRepository.save(withdrawtransferTransaction);
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount); this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
@@ -1008,10 +1008,10 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
savingsAccount.reassignSavingsOfficer(fieldOfficer, transferDate); savingsAccount.reassignSavingsOfficer(fieldOfficer, transferDate);
} }
boolean isInterestTransfer = false; boolean isInterestTransfer = false;
boolean postInterestAsOn = false; LocalDate postInterestOnDate = null;
final MathContext mc = MathContext.DECIMAL64; final MathContext mc = MathContext.DECIMAL64;
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn); financialYearBeginningMonth, postInterestOnDate);
this.savingsAccountTransactionRepository.save(acceptTransferTransaction); this.savingsAccountTransactionRepository.save(acceptTransferTransaction);
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount); this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
@@ -1154,16 +1154,16 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
account.waiveCharge(savingsAccountChargeId, user); account.waiveCharge(savingsAccountChargeId, user);
boolean isInterestTransfer = false; boolean isInterestTransfer = false;
boolean postInterestAsOn = false; LocalDate postInterestOnDate = null;
final MathContext mc = MathContext.DECIMAL64; final MathContext mc = MathContext.DECIMAL64;
if (account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueLocalDate())) { if (account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueLocalDate())) {
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestAsOn); postInterestOnDate);
} else { } else {
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn); financialYearBeginningMonth, postInterestOnDate);
} }
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null; List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) { if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
@@ -1289,16 +1289,16 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds); updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
account.payCharge(savingsAccountCharge, amountPaid, transactionDate, formatter, user); account.payCharge(savingsAccountCharge, amountPaid, transactionDate, formatter, user);
boolean isInterestTransfer = false; boolean isInterestTransfer = false;
boolean postInterestAsOn = false; LocalDate postInterestOnDate = null;
final MathContext mc = MathContext.DECIMAL64; final MathContext mc = MathContext.DECIMAL64;
if (account.isBeforeLastPostingPeriod(transactionDate)) { if (account.isBeforeLastPostingPeriod(transactionDate)) {
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestAsOn); postInterestOnDate);
} else { } else {
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn); financialYearBeginningMonth, postInterestOnDate);
} }
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null; List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) { if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
@@ -361,8 +361,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
final MathContext mc = new MathContext(15, MoneyHelper.getRoundingMode()); final MathContext mc = new MathContext(15, MoneyHelper.getRoundingMode());
boolean isInterestTransfer = false; boolean isInterestTransfer = false;
final LocalDate postInterestOnDate = null;
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth,false); financialYearBeginningMonth,postInterestOnDate);
this.savingAccountRepositoryWrapper.save(account); this.savingAccountRepositoryWrapper.save(account);
@@ -425,12 +426,11 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
final MathContext mc = new MathContext(10, MoneyHelper.getRoundingMode()); final MathContext mc = new MathContext(10, MoneyHelper.getRoundingMode());
boolean isInterestTransfer = false; boolean isInterestTransfer = false;
if(postInterestAs==false){ LocalDate postInterestOnDate = null;
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,postInterestAs); if (postInterestAs) {
} postInterestOnDate = transactionDate;
else{ }
account.postInterest(mc, transactionDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,postInterestAs); account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,postInterestOnDate);
}
// for generating transaction id's // for generating transaction id's
List<SavingsAccountTransaction> transactions = account.getTransactions(); List<SavingsAccountTransaction> transactions = account.getTransactions();
for (SavingsAccountTransaction accountTransaction : transactions) { for (SavingsAccountTransaction accountTransaction : transactions) {
@@ -489,13 +489,14 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
} }
} }
boolean isInterestTransfer = false; boolean isInterestTransfer = false;
LocalDate postInterestOnDate = null;
checkClientOrGroupActive(account); checkClientOrGroupActive(account);
if (savingsAccountTransaction.isPostInterestCalculationRequired() if (savingsAccountTransaction.isPostInterestCalculationRequired()
&& account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) { && account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,false); account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,postInterestOnDate);
} else { } else {
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth,false); financialYearBeginningMonth,postInterestOnDate);
} }
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null; List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) { if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
@@ -578,13 +579,13 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
transaction = account.withdraw(transactionDTO, true); transaction = account.withdraw(transactionDTO, true);
} }
final Long newtransactionId = saveTransactionToGenerateTransactionId(transaction); final Long newtransactionId = saveTransactionToGenerateTransactionId(transaction);
final LocalDate postInterestOnDate = null;
if (account.isBeforeLastPostingPeriod(transactionDate) if (account.isBeforeLastPostingPeriod(transactionDate)
|| account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) { || account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) {
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,false); account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,postInterestOnDate);
} else { } else {
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth,false); financialYearBeginningMonth,postInterestOnDate);
} }
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null; List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) { if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
@@ -655,8 +656,10 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
boolean postInterestOnClosingDate = false; boolean postInterestOnClosingDate = false;
List<SavingsAccountTransaction> savingTransactions = account.getTransactions(); List<SavingsAccountTransaction> savingTransactions = account.getTransactions();
for (SavingsAccountTransaction savingTransaction : savingTransactions) { 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; postInterestOnClosingDate = true;
break;
} }
} }
if (postInterestOnClosingDate == false) { throw new PostInterestClosingDateException(); } if (postInterestOnClosingDate == false) { throw new PostInterestClosingDateException(); }
@@ -730,9 +733,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
savingsAccount.setStatus(SavingsAccountStatusType.TRANSFER_IN_PROGRESS.getValue()); savingsAccount.setStatus(SavingsAccountStatusType.TRANSFER_IN_PROGRESS.getValue());
final MathContext mc = MathContext.DECIMAL64; final MathContext mc = MathContext.DECIMAL64;
boolean isInterestTransfer = false; boolean isInterestTransfer = false;
boolean postInterestAsOn = false; LocalDate postInterestOnDate = null;
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn); financialYearBeginningMonth, postInterestOnDate);
this.savingsAccountTransactionRepository.save(newTransferTransaction); this.savingsAccountTransactionRepository.save(newTransferTransaction);
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount); this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
@@ -761,9 +764,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue()); savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue());
final MathContext mc = MathContext.DECIMAL64; final MathContext mc = MathContext.DECIMAL64;
boolean isInterestTransfer = false; boolean isInterestTransfer = false;
boolean postInterestAsOn =false; LocalDate postInterestOnDate = null;
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn); financialYearBeginningMonth, postInterestOnDate);
this.savingsAccountTransactionRepository.save(withdrawtransferTransaction); this.savingsAccountTransactionRepository.save(withdrawtransferTransaction);
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount); this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
@@ -803,9 +806,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
} }
boolean isInterestTransfer = false; boolean isInterestTransfer = false;
final MathContext mc = MathContext.DECIMAL64; final MathContext mc = MathContext.DECIMAL64;
boolean postInterestAsOn = false; LocalDate postInterestOnDate = null;
savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn); financialYearBeginningMonth, postInterestOnDate);
this.savingsAccountTransactionRepository.save(acceptTransferTransaction); this.savingsAccountTransactionRepository.save(acceptTransferTransaction);
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount); this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
@@ -954,16 +957,16 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
account.waiveCharge(savingsAccountChargeId, user); account.waiveCharge(savingsAccountChargeId, user);
boolean isInterestTransfer = false; boolean isInterestTransfer = false;
boolean postInterestAsOn = false; LocalDate postInterestOnDate = null;
final MathContext mc = MathContext.DECIMAL64; final MathContext mc = MathContext.DECIMAL64;
if (account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueLocalDate())) { if (account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueLocalDate())) {
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestAsOn); postInterestOnDate);
} else { } else {
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn); financialYearBeginningMonth, postInterestOnDate);
} }
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null; List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) { if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {
@@ -1088,16 +1091,16 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds); updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
account.payCharge(savingsAccountCharge, amountPaid, transactionDate, formatter, user); account.payCharge(savingsAccountCharge, amountPaid, transactionDate, formatter, user);
boolean isInterestTransfer = false; boolean isInterestTransfer = false;
boolean postInterestAsOn = false; LocalDate postInterestOnDate = null;
final MathContext mc = MathContext.DECIMAL64; final MathContext mc = MathContext.DECIMAL64;
if (account.isBeforeLastPostingPeriod(transactionDate)) { if (account.isBeforeLastPostingPeriod(transactionDate)) {
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestAsOn); postInterestOnDate);
} else { } else {
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestAsOn); financialYearBeginningMonth, postInterestOnDate);
} }
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null; List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) { if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) {