http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/580840c3/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java index bc97a67..46b875a 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java @@ -235,6 +235,7 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> { @Column(name = "interest_calculation_type_enum", nullable = false) protected Integer interestCalculationType; + /** * A value from the {@link SavingsInterestCalculationDaysInYearType} * enumeration. @@ -462,13 +463,10 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> { public boolean isClosed() { 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 isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,final boolean postInterestAsOn) { final List<PostingPeriod> postingPeriods = calculateInterestUsing(mc, interestPostingUpToDate, isInterestTransfer, - isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); - + isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, postInterestAsOn); Money interestPostedToDate = Money.zero(this.currency); boolean recalucateDailyBalanceDetails = false; @@ -477,23 +475,23 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> { withholdTransactions.addAll(findWithHoldTransactions()); for (final PostingPeriod interestPostingPeriod : postingPeriods) { - + final LocalDate interestPostingTransactionDate = interestPostingPeriod.dateOfPostingTransaction(); final Money interestEarnedToBePostedForPeriod = interestPostingPeriod.getInterestEarned(); - + if (!interestPostingTransactionDate.isAfter(interestPostingUpToDate)) { - interestPostedToDate = interestPostedToDate.plus(interestEarnedToBePostedForPeriod); final SavingsAccountTransaction postingTransaction = findInterestPostingTransactionFor(interestPostingTransactionDate); if (postingTransaction == null) { SavingsAccountTransaction newPostingTransaction; if (interestEarnedToBePostedForPeriod.isGreaterThanOrEqualTo(Money.zero(currency))) { + newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(), interestPostingTransactionDate, - interestEarnedToBePostedForPeriod); + interestEarnedToBePostedForPeriod, interestPostingPeriod.isUserPosting()); } else { newPostingTransaction = SavingsAccountTransaction.overdraftInterest(this, office(), interestPostingTransactionDate, - interestEarnedToBePostedForPeriod.negated()); + interestEarnedToBePostedForPeriod.negated(), interestPostingPeriod.isUserPosting()); } addTransaction(newPostingTransaction); if (applyWithHoldTax) { @@ -519,10 +517,12 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> { SavingsAccountTransaction newPostingTransaction; if (interestEarnedToBePostedForPeriod.isGreaterThanOrEqualTo(Money.zero(currency))) { newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(), - interestPostingTransactionDate, interestEarnedToBePostedForPeriod); + interestPostingTransactionDate, interestEarnedToBePostedForPeriod, + interestPostingPeriod.isUserPosting()); } else { newPostingTransaction = SavingsAccountTransaction.overdraftInterest(this, office(), - interestPostingTransactionDate, interestEarnedToBePostedForPeriod.negated()); + interestPostingTransactionDate, interestEarnedToBePostedForPeriod.negated(), + interestPostingPeriod.isUserPosting()); } addTransaction(newPostingTransaction); if (applyWithHoldTaxForOldTransaction) { @@ -641,6 +641,16 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> { return savingsTransaction; } + public List<LocalDate> getManualPostingDates() { + List<LocalDate> transactions = new ArrayList<>(); + for (SavingsAccountTransaction trans : this.transactions) { + if (trans.isManualTransaction()) { + transactions.add(trans.getTransactionLocalDate()); + } + } + return transactions; + } + /** * All interest calculation based on END-OF-DAY-BALANCE. * @@ -657,9 +667,10 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> { * * @param isInterestTransfer * TODO - */ + */ + public List<PostingPeriod> calculateInterestUsing(final MathContext mc, final LocalDate upToInterestCalculationDate, - boolean isInterestTransfer, final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth) { + boolean isInterestTransfer, final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,final boolean postInterestAsOn) { // no openingBalance concept supported yet but probably will to allow // for migrations. @@ -680,10 +691,14 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> { .fromInt(this.interestCompoundingPeriodType); final SavingsInterestCalculationDaysInYearType daysInYearType = SavingsInterestCalculationDaysInYearType - .fromInt(this.interestCalculationDaysInYearType); - + .fromInt(this.interestCalculationDaysInYearType); + List<LocalDate> postedAsOnDates= getManualPostingDates(); + if(postInterestAsOn){ + postedAsOnDates.add(upToInterestCalculationDate); + } final List<LocalDateInterval> postingPeriodIntervals = this.savingsHelper.determineInterestPostingPeriods( - getStartInterestCalculationDate(), upToInterestCalculationDate, postingPeriodType, financialYearBeginningMonth); + getStartInterestCalculationDate(), upToInterestCalculationDate, postingPeriodType, financialYearBeginningMonth, + postedAsOnDates); final List<PostingPeriod> allPostingPeriods = new ArrayList<>(); @@ -719,12 +734,17 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> { final Money minOverdraftForInterestCalculation = Money.of(getCurrency(), this.minOverdraftForInterestCalculation); for (final LocalDateInterval periodInterval : postingPeriodIntervals) { + + boolean isUserPosting = false; + if(postedAsOnDates.contains(periodInterval.endDate().plusDays(1))){ + isUserPosting = true; + } final PostingPeriod postingPeriod = PostingPeriod.createFrom(periodInterval, periodStartingBalance, retreiveOrderedNonInterestPostingTransactions(), this.currency, compoundingPeriodType, interestCalculationType, interestRateAsFraction, daysInYearType.getValue(), upToInterestCalculationDate, interestPostTransactions, isInterestTransfer, minBalanceForInterestCalculation, isSavingsInterestPostingAtCurrentPeriodEnd, - overdraftInterestRateAsFraction, minOverdraftForInterestCalculation); + overdraftInterestRateAsFraction, minOverdraftForInterestCalculation, isUserPosting); periodStartingBalance = postingPeriod.closingBalance(); @@ -2133,13 +2153,15 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> { if (isSavingsChargeApplied) { final MathContext mc = MathContext.DECIMAL64; boolean isInterestTransfer = false; + boolean postInterestAsOnDate = false; if (this.isBeforeLastPostingPeriod(getActivationLocalDate())) { final LocalDate today = DateUtils.getLocalDateOfTenant(); - this.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); + this.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, + postInterestAsOnDate); } else { final LocalDate today = DateUtils.getLocalDateOfTenant(); this.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, - financialYearBeginningMonth); + financialYearBeginningMonth, postInterestAsOnDate); } } } @@ -2781,10 +2803,10 @@ public class SavingsAccount extends AbstractPersistableCustom<Long> { this.sub_status = SavingsAccountSubStatusEnum.ESCHEAT.getValue(); this.closedOnDate = DateUtils.getDateOfTenant(); this.closedBy = appUser; - + boolean postInterestAsOnDate = false; LocalDate transactionDate = DateUtils.getLocalDateOfTenant(); if(this.getSummary().getAccountBalance(this.getCurrency()).isGreaterThanZero()){ - SavingsAccountTransaction transaction = SavingsAccountTransaction.escheat(this, transactionDate, appUser); + SavingsAccountTransaction transaction = SavingsAccountTransaction.escheat(this, transactionDate, appUser, postInterestAsOnDate); this.transactions.add(transaction); } recalculateDailyBalances(Money.zero(this.currency), transactionDate);
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/580840c3/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountDomainServiceJpa.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountDomainServiceJpa.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountDomainServiceJpa.java index 53141c2..6426026 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountDomainServiceJpa.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountDomainServiceJpa.java @@ -86,6 +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 Set<Long> existingReversedTransactionIds = new HashSet<>(); updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds); final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount, @@ -96,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); + financialYearBeginningMonth, interestPostAsOn); } else { final LocalDate today = DateUtils.getLocalDateOfTenant(); account.calculateInterestUsing(mc, today, transactionBooleanValues.isInterestTransfer(), - isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); + isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, interestPostAsOn); } List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null; if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) { @@ -154,15 +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 MathContext mc = MathContext.DECIMAL64; if (account.isBeforeLastPostingPeriod(transactionDate)) { final LocalDate today = DateUtils.getLocalDateOfTenant(); - account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); + account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, + interestPostAsOn); } else { final LocalDate today = DateUtils.getLocalDateOfTenant(); account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, - financialYearBeginningMonth); + financialYearBeginningMonth, interestPostAsOn); } saveTransactionToGenerateTransactionId(deposit); http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/580840c3/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountTransaction.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountTransaction.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountTransaction.java index 166f6ed..56e6485 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountTransaction.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountTransaction.java @@ -114,6 +114,9 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom<L @ManyToOne @JoinColumn(name = "appuser_id", nullable = true) private AppUser appUser; + + @Column(name = "is_manual", length = 1, nullable = true) + private boolean isManualTransaction; @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch=FetchType.EAGER) @JoinColumn(name = "savings_transaction_id", referencedColumnName = "id", nullable = false) @@ -126,112 +129,123 @@ 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 PaymentDetail paymentDetail, final LocalDate date, final Money amount, Date createdDate, final AppUser appUser, + final boolean isManualTransaction) { final boolean isReversed = false; return new SavingsAccountTransaction(savingsAccount, office, paymentDetail, SavingsAccountTransactionType.DEPOSIT.getValue(), date, - createdDate, amount, isReversed, appUser); + createdDate, amount, isReversed, appUser, isManualTransaction); } 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 SavingsAccountTransactionType savingsAccountTransactionType) { final boolean isReversed = false; + final boolean isManualTransaction = false; return new SavingsAccountTransaction(savingsAccount, office, paymentDetail, savingsAccountTransactionType.getValue(), date, - createdDate, amount, isReversed, appUser); + createdDate, amount, isReversed, appUser,isManualTransaction); } public static SavingsAccountTransaction withdrawal(final SavingsAccount savingsAccount, final Office office, 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.WITHDRAWAL.getValue(), - date, createdDate, amount, isReversed, appUser); + date, createdDate, amount, isReversed, appUser, isManualTransaction); } public static SavingsAccountTransaction interestPosting(final SavingsAccount savingsAccount, final Office office, final LocalDate date, - final Money amount) { + final Money amount,final boolean isManualTransaction) { final boolean isReversed = false; return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.INTEREST_POSTING.getValue(), date, - amount, isReversed, null); + amount, isReversed, null, isManualTransaction); } public static SavingsAccountTransaction overdraftInterest(final SavingsAccount savingsAccount, final Office office, - final LocalDate date, final Money amount) { + final LocalDate date, final Money amount,final boolean isManualTransaction) { final boolean isReversed = false; return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.OVERDRAFT_INTEREST.getValue(), date, - amount, isReversed, null); + amount, isReversed, null, isManualTransaction); } public static SavingsAccountTransaction withdrawalFee(final SavingsAccount savingsAccount, final Office office, final LocalDate date, final Money amount, final AppUser appUser) { final boolean isReversed = false; + final boolean isManualTransaction = false; return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.WITHDRAWAL_FEE.getValue(), date, amount, - isReversed, appUser); + isReversed, appUser, isManualTransaction); } public static SavingsAccountTransaction annualFee(final SavingsAccount savingsAccount, final Office office, final LocalDate date, final Money amount, final AppUser appUser) { final boolean isReversed = false; + final boolean isManualTransaction = false; return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.ANNUAL_FEE.getValue(), date, amount, - isReversed, appUser); + isReversed, appUser, isManualTransaction); } public static SavingsAccountTransaction charge(final SavingsAccount savingsAccount, final Office office, final LocalDate date, final Money amount, final AppUser appUser) { final boolean isReversed = false; + final boolean isManualTransaction = false; return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.PAY_CHARGE.getValue(), date, amount, - isReversed, appUser); + isReversed, appUser, isManualTransaction); } public static SavingsAccountTransaction waiver(final SavingsAccount savingsAccount, final Office office, final LocalDate date, final Money amount, final AppUser appUser) { final boolean isReversed = false; + final boolean isManualTransaction = false; return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.WAIVE_CHARGES.getValue(), date, amount, - isReversed, appUser); + isReversed, appUser, isManualTransaction); } public static SavingsAccountTransaction initiateTransfer(final SavingsAccount savingsAccount, final Office office, final LocalDate date, final AppUser appUser) { final boolean isReversed = false; + final boolean isManualTransaction = false; final PaymentDetail paymentDetail = null; return new SavingsAccountTransaction(savingsAccount, office, paymentDetail, SavingsAccountTransactionType.INITIATE_TRANSFER.getValue(), date, new Date(), savingsAccount.getSummary() - .getAccountBalance(), isReversed, appUser); + .getAccountBalance(), isReversed, appUser, isManualTransaction); } public static SavingsAccountTransaction approveTransfer(final SavingsAccount savingsAccount, final Office office, final LocalDate date, final AppUser appUser) { final boolean isReversed = false; + final boolean isManualTransaction = false; final PaymentDetail paymentDetail = null; return new SavingsAccountTransaction(savingsAccount, office, paymentDetail, SavingsAccountTransactionType.APPROVE_TRANSFER.getValue(), date, new Date(), savingsAccount.getSummary() - .getAccountBalance(), isReversed, appUser); + .getAccountBalance(), isReversed, appUser, isManualTransaction); } public static SavingsAccountTransaction withdrawTransfer(final SavingsAccount savingsAccount, final Office office, final LocalDate date, final AppUser appUser) { final boolean isReversed = false; + final boolean isManualTransaction = false; final PaymentDetail paymentDetail = null; return new SavingsAccountTransaction(savingsAccount, office, paymentDetail, SavingsAccountTransactionType.WITHDRAW_TRANSFER.getValue(), date, new Date(), savingsAccount.getSummary() - .getAccountBalance(), isReversed, appUser); + .getAccountBalance(), isReversed, appUser, isManualTransaction); } public static SavingsAccountTransaction withHoldTax(final SavingsAccount savingsAccount, final Office office, final LocalDate date, final Money amount, final Map<TaxComponent, BigDecimal> taxDetails) { final boolean isReversed = false; + final boolean isManualTransaction = false; SavingsAccountTransaction accountTransaction = new SavingsAccountTransaction(savingsAccount, office, - SavingsAccountTransactionType.WITHHOLD_TAX.getValue(), date, amount, isReversed, null); + SavingsAccountTransactionType.WITHHOLD_TAX.getValue(), date, amount, isReversed, null, isManualTransaction); updateTaxDetails(taxDetails, accountTransaction); return accountTransaction; } public static SavingsAccountTransaction escheat(final SavingsAccount savingsAccount, final LocalDate date, - final AppUser appUser) { + final AppUser appUser,final boolean accountTransaction) { final boolean isReversed = false; final PaymentDetail paymentDetail = null; return new SavingsAccountTransaction(savingsAccount, savingsAccount.office(), paymentDetail, SavingsAccountTransactionType.ESCHEAT.getValue(), date, new Date(), savingsAccount.getSummary() - .getAccountBalance(), isReversed, appUser); + .getAccountBalance(), isReversed, appUser,accountTransaction); } public static void updateTaxDetails(final Map<TaxComponent, BigDecimal> taxDetails, final SavingsAccountTransaction accountTransaction) { @@ -245,23 +259,25 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom<L public static SavingsAccountTransaction copyTransaction(SavingsAccountTransaction accountTransaction) { return new SavingsAccountTransaction(accountTransaction.savingsAccount, accountTransaction.office, accountTransaction.paymentDetail, accountTransaction.typeOf, accountTransaction.transactionLocalDate(), - accountTransaction.createdDate, accountTransaction.amount, accountTransaction.reversed, accountTransaction.appUser); + accountTransaction.createdDate, accountTransaction.amount, accountTransaction.reversed, accountTransaction.appUser, + accountTransaction.isManualTransaction); } private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Office office, final Integer typeOf, - final LocalDate transactionLocalDate, final Money amount, final boolean isReversed, final AppUser appUser) { - this(savingsAccount, office, null, typeOf, transactionLocalDate, new Date(), amount, isReversed, appUser); + final LocalDate transactionLocalDate, final Money amount, final boolean isReversed, final AppUser appUser,final boolean isManualTransaction) { + this(savingsAccount, office, null, typeOf, transactionLocalDate, new Date(), amount, isReversed, appUser, isManualTransaction); } private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Office office, final PaymentDetail paymentDetail, final Integer typeOf, final LocalDate transactionLocalDate, final Date createdDate, final Money amount, - final boolean isReversed, final AppUser appUser) { - this(savingsAccount, office, paymentDetail, typeOf, transactionLocalDate, createdDate, amount.getAmount(), isReversed, appUser); + final boolean isReversed, final AppUser appUser, final boolean isManualTransaction) { + this(savingsAccount, office, paymentDetail, typeOf, transactionLocalDate, createdDate, amount.getAmount(), isReversed, appUser, + isManualTransaction); } private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Office office, final PaymentDetail paymentDetail, final Integer typeOf, final LocalDate transactionLocalDate, final Date createdDate, final BigDecimal amount, - final boolean isReversed, final AppUser appUser) { + final boolean isReversed, final AppUser appUser, final boolean isManualTransaction) { this.savingsAccount = savingsAccount; this.office = office; this.typeOf = typeOf; @@ -271,6 +287,7 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom<L this.paymentDetail = paymentDetail; this.createdDate = createdDate; this.appUser = appUser; + this.isManualTransaction = isManualTransaction; } public LocalDate transactionLocalDate() { @@ -389,7 +406,7 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom<L this.cumulativeBalance = Money.of(currency, this.runningBalance).multipliedBy(this.balanceNumberOfDays).getAmount(); } - private LocalDate getTransactionLocalDate() { + public LocalDate getTransactionLocalDate() { return new LocalDate(this.dateOf); } @@ -470,6 +487,14 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom<L public boolean isAfter(final LocalDate transactionDate) { return getTransactionLocalDate().isAfter(transactionDate); } + + public boolean isManualTransaction() { + return this.isManualTransaction; + } + + public void setPostInterestAsOn(boolean isManualTransaction) { + this.isManualTransaction = isManualTransaction; + } public EndOfDayBalance toEndOfDayBalance(final LocalDateInterval periodInterval, final MonetaryCurrency currency) { @@ -704,5 +729,22 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom<L public void updateAmount(final Money amount) { this.amount = amount.getAmount(); } + + public Integer getTypeOf() { + return this.typeOf; + } + + public SavingsAccount getSavingsAccount() { + return this.savingsAccount; + } + + + public void setSavingsAccount(SavingsAccount savingsAccount) { + this.savingsAccount = savingsAccount; + } + + public Date getDateOf() { + return this.dateOf; + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/580840c3/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsHelper.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsHelper.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsHelper.java index 09b7219..555ee24 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsHelper.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsHelper.java @@ -33,9 +33,9 @@ import org.apache.fineract.portfolio.savings.domain.interest.PostingPeriod; import org.joda.time.LocalDate; public final class SavingsHelper { - + AccountTransfersReadPlatformService accountTransfersReadPlatformService = null; - + public SavingsHelper(AccountTransfersReadPlatformService accountTransfersReadPlatformService) { this.accountTransfersReadPlatformService = accountTransfersReadPlatformService; } @@ -44,30 +44,49 @@ public final class SavingsHelper { public List<LocalDateInterval> determineInterestPostingPeriods(final LocalDate startInterestCalculationLocalDate, final LocalDate interestPostingUpToDate, final SavingsPostingInterestPeriodType postingPeriodType, - final Integer financialYearBeginningMonth) { + final Integer financialYearBeginningMonth,List<LocalDate> postInterestAsOn) { final List<LocalDateInterval> postingPeriods = new ArrayList<>(); - LocalDate periodStartDate = startInterestCalculationLocalDate; LocalDate periodEndDate = periodStartDate; - + LocalDate actualPeriodStartDate = periodStartDate; + while (!periodStartDate.isAfter(interestPostingUpToDate) && !periodEndDate.isAfter(interestPostingUpToDate)) { - - final LocalDate interestPostingLocalDate = determineInterestPostingPeriodEndDateFrom(periodStartDate, postingPeriodType, + + final LocalDate interestPostingLocalDate = determineInterestPostingPeriodEndDateFrom(periodStartDate, postingPeriodType, interestPostingUpToDate, financialYearBeginningMonth); + periodEndDate = interestPostingLocalDate.minusDays(1); - + + if (!postInterestAsOn.isEmpty()) { + for (LocalDate transactiondate : postInterestAsOn) { + if (periodStartDate.isBefore(transactiondate) + && (periodEndDate.isAfter(transactiondate) || periodEndDate + .isEqual(transactiondate))) { + periodEndDate = transactiondate.minusDays(1); + actualPeriodStartDate = periodEndDate; + break; + } + } + } + postingPeriods.add(LocalDateInterval.create(periodStartDate, periodEndDate)); - + + if (actualPeriodStartDate.isEqual(periodEndDate)) + { + periodEndDate = actualPeriodStartDate.plusDays(1); + periodStartDate = actualPeriodStartDate.plusDays(1); + }else{ periodEndDate = interestPostingLocalDate; periodStartDate = interestPostingLocalDate; + } } return postingPeriods; } private LocalDate determineInterestPostingPeriodEndDateFrom(final LocalDate periodStartDate, - final SavingsPostingInterestPeriodType interestPostingPeriodType, final LocalDate interestPostingUpToDate, + final SavingsPostingInterestPeriodType interestPostingPeriodType, final LocalDate interestPostingUpToDate, Integer financialYearBeginningMonth) { LocalDate periodEndDate = interestPostingUpToDate; @@ -90,7 +109,6 @@ public final class SavingsHelper { biannualDates.add(periodStartDate.withMonthOfYear(financialYearBeginningMonth).plusMonths(6).withYear(periodStartDate.getYear()) .dayOfMonth().withMaximumValue()); Collections.sort(biannualDates); - boolean isEndDateSet = false; switch (interestPostingPeriodType) { @@ -131,11 +149,9 @@ public final class SavingsHelper { } periodEndDate = periodEndDate.dayOfMonth().withMaximumValue(); break; - } - + } // interest posting always occurs on next day after the period end date. - periodEndDate = periodEndDate.plusDays(1); - + periodEndDate = periodEndDate.plusDays(1); return periodEndDate; } http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/580840c3/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/interest/PostingPeriod.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/interest/PostingPeriod.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/interest/PostingPeriod.java index 26b7310..2d9f560 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/interest/PostingPeriod.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/interest/PostingPeriod.java @@ -54,6 +54,7 @@ public class PostingPeriod { // include in compounding interest private boolean interestTransfered = false; + private boolean isUserPosting = false; // minimum balance for interest calculation private final Money minBalanceForInterestCalculation; @@ -65,7 +66,7 @@ public class PostingPeriod { final SavingsCompoundingInterestPeriodType interestCompoundingPeriodType, final SavingsInterestCalculationType interestCalculationType, final BigDecimal interestRateAsFraction, final long daysInYear, final LocalDate upToInterestCalculationDate, Collection<Long> interestPostTransactions, boolean isInterestTransfer, - final Money minBalanceForInterestCalculation, final boolean isSavingsInterestPostingAtCurrentPeriodEnd) { + final Money minBalanceForInterestCalculation, final boolean isSavingsInterestPostingAtCurrentPeriodEnd,final boolean isUserPosting) { final BigDecimal overdraftInterestRateAsFraction = BigDecimal.ZERO; final Money minOverdraftForInterestCalculation = Money.zero(currency); @@ -74,7 +75,7 @@ public class PostingPeriod { interestCompoundingPeriodType, interestCalculationType, interestRateAsFraction, daysInYear, upToInterestCalculationDate, interestPostTransactions, isInterestTransfer, minBalanceForInterestCalculation, isSavingsInterestPostingAtCurrentPeriodEnd, - overdraftInterestRateAsFraction, minOverdraftForInterestCalculation); + overdraftInterestRateAsFraction, minOverdraftForInterestCalculation, isUserPosting); } // isInterestTransfer boolean is to identify newly created transaction is @@ -85,7 +86,7 @@ public class PostingPeriod { final SavingsInterestCalculationType interestCalculationType, final BigDecimal interestRateAsFraction, final long daysInYear, final LocalDate upToInterestCalculationDate, Collection<Long> interestPostTransactions, boolean isInterestTransfer, final Money minBalanceForInterestCalculation, final boolean isSavingsInterestPostingAtCurrentPeriodEnd, - final BigDecimal overdraftInterestRateAsFraction, final Money minOverdraftForInterestCalculation) { + final BigDecimal overdraftInterestRateAsFraction, final Money minOverdraftForInterestCalculation, boolean isUserPosting) { final List<EndOfDayBalance> accountEndOfDayBalances = new ArrayList<>(); boolean interestTransfered = false; @@ -147,7 +148,7 @@ public class PostingPeriod { return new PostingPeriod(periodInterval, currency, periodStartingBalance, openingDayBalance, interestCompoundingPeriodType, interestCalculationType, interestRateAsFraction, daysInYear, compoundingPeriods, interestTransfered, minBalanceForInterestCalculation, isSavingsInterestPostingAtCurrentPeriodEnd, - overdraftInterestRateAsFraction, minOverdraftForInterestCalculation); + overdraftInterestRateAsFraction, minOverdraftForInterestCalculation, isUserPosting); } private PostingPeriod(final LocalDateInterval periodInterval, final MonetaryCurrency currency, final Money openingBalance, @@ -155,7 +156,7 @@ public class PostingPeriod { final SavingsInterestCalculationType interestCalculationType, final BigDecimal interestRateAsFraction, final long daysInYear, final List<CompoundingPeriod> compoundingPeriods, boolean interestTransfered, final Money minBalanceForInterestCalculation, final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final BigDecimal overdraftInterestRateAsFraction, - final Money minOverdraftForInterestCalculation) { + final Money minOverdraftForInterestCalculation, boolean isUserPosting) { this.periodInterval = periodInterval; this.currency = currency; this.openingBalance = openingBalance; @@ -174,6 +175,7 @@ public class PostingPeriod { this.minBalanceForInterestCalculation = minBalanceForInterestCalculation; this.overdraftInterestRateAsFraction = overdraftInterestRateAsFraction; this.minOverdraftForInterestCalculation = minOverdraftForInterestCalculation; + this.isUserPosting = isUserPosting; } public Money interest() { @@ -410,4 +412,12 @@ public class PostingPeriod { public boolean isInterestTransfered() { return this.interestTransfered; } + + public LocalDateInterval getPeriodInterval() { + return this.periodInterval; + } + + public boolean isUserPosting() { + return this.isUserPosting; + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/580840c3/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/exception/PostInterestAsOnDateException.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/exception/PostInterestAsOnDateException.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/exception/PostInterestAsOnDateException.java new file mode 100644 index 0000000..7630368 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/exception/PostInterestAsOnDateException.java @@ -0,0 +1,61 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.portfolio.savings.exception; + + +import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException; + + +public class PostInterestAsOnDateException extends AbstractPlatformDomainRuleException{ + public static enum PostInterestAsOnException_TYPE { + FUTURE_DATE, VALID_DATE, ACTIVATION_DATE, LAST_TRANSACTION_DATE; + public String errorMessage() { + if (name().toString().equalsIgnoreCase("FUTURE_DATE")) { + return "Cannot Post Interest in future Dates"; + } else if (name().toString().equalsIgnoreCase("VALID_DATE")) { + return "Please Pass a valid date"; + } else if (name().toString().equalsIgnoreCase("ACTIVATION_DATE")) { + return "Post Interest Date must be after the Activation date"; + } else if (name().toString().equalsIgnoreCase("LAST_TRANSACTION_DATE")) { + return "Cannot Post Interest before last transaction date"; + } + return name().toString(); + } + + public String errorCode() { + if (name().toString().equalsIgnoreCase("FUTURE_DATE")) { + return "error.msg.futureDate"; + } else if (name().toString().equalsIgnoreCase("VALID_DATE")) { + return "error.msg.nullDatePassed"; + } else if (name().toString().equalsIgnoreCase("ACTIVATION_DATE")) { + return "error.msg.before activation date"; + } else if (name().toString().equalsIgnoreCase("LAST_TRANSACTION_DATE")) { + return "error.msg.countInterest"; + } + return name().toString(); + } + } + + + public PostInterestAsOnDateException(final PostInterestAsOnException_TYPE reason) { + super(reason.errorCode(), reason.errorMessage()); + } + + +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/580840c3/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/exception/PostInterestClosingDateException.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/exception/PostInterestClosingDateException.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/exception/PostInterestClosingDateException.java new file mode 100644 index 0000000..24a11de --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/exception/PostInterestClosingDateException.java @@ -0,0 +1,28 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.portfolio.savings.exception; + +import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException; + +public class PostInterestClosingDateException extends AbstractPlatformDomainRuleException { + + public PostInterestClosingDateException() { + super("error.msg.postInterest.notDone", "Please do a post interest on the closing date"); + } +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/580840c3/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/PostInterestSavingsAccountCommandHandler.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/PostInterestSavingsAccountCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/PostInterestSavingsAccountCommandHandler.java index b48b215..7ff81d0 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/PostInterestSavingsAccountCommandHandler.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/PostInterestSavingsAccountCommandHandler.java @@ -41,6 +41,6 @@ public class PostInterestSavingsAccountCommandHandler implements NewCommandSourc @Transactional @Override public CommandProcessingResult processCommand(final JsonCommand command) { - return this.writePlatformService.postInterest(command.getSavingsId()); + return this.writePlatformService.postInterest(command); } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/580840c3/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/PostSavingsAccountInterestAsOnDateCommandHandler.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/PostSavingsAccountInterestAsOnDateCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/PostSavingsAccountInterestAsOnDateCommandHandler.java new file mode 100644 index 0000000..dc61644 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/handler/PostSavingsAccountInterestAsOnDateCommandHandler.java @@ -0,0 +1,47 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.portfolio.savings.handler; + +import org.apache.fineract.commands.annotation.CommandType; +import org.apache.fineract.commands.handler.NewCommandSourceHandler; +import org.apache.fineract.infrastructure.core.api.JsonCommand; +import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; +import org.apache.fineract.portfolio.savings.service.SavingsAccountWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@CommandType(entity = "SAVINGSACCOUNT", action = "POSTINTERESTASONDATE") +public class PostSavingsAccountInterestAsOnDateCommandHandler implements NewCommandSourceHandler { + + private final SavingsAccountWritePlatformService writePlatformService; + + @Autowired + public PostSavingsAccountInterestAsOnDateCommandHandler(final SavingsAccountWritePlatformService writePlatformService) { + this.writePlatformService = writePlatformService; + } + + @Transactional + @Override + public CommandProcessingResult processCommand(final JsonCommand command) { + return this.writePlatformService.postInterest(command); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/580840c3/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountReadPlatformServiceImpl.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountReadPlatformServiceImpl.java index 5853ddb..cf9496b 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountReadPlatformServiceImpl.java @@ -1049,9 +1049,9 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead transfer = AccountTransferData.transferBasicDetails(toTransferId, currency, toTransferAmount, toTransferDate, toTransferDescription, toTransferReversed); } - + final boolean postInterestAsOn = false; return SavingsAccountTransactionData.create(id, transactionType, paymentDetailData, savingsId, accountNo, date, currency, - amount, runningBalance, reversed, transfer); + amount, runningBalance, reversed, transfer, postInterestAsOn); } } @@ -1437,9 +1437,9 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead final PaymentDetailData paymentDetailData = null; final AccountTransferData transfer = null; final BigDecimal runningBalance = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "runningBalance"); - ; + final boolean postInterestAsOn = false; return SavingsAccountTransactionData.create(savingsId, transactionType, paymentDetailData, savingsId, accountNo, duedate, - currency, dueamount, runningBalance, false, transfer); + currency, dueamount, runningBalance, false, transfer, postInterestAsOn); } } http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/580840c3/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java index 51ffb4f..d9f8b4e 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java @@ -143,7 +143,6 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo private final WorkingDaysRepositoryWrapper workingDaysRepository; private final DepositAccountOnHoldTransactionRepository depositAccountOnHoldTransactionRepository; - @Autowired public DepositAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final SavingsAccountRepositoryWrapper savingAccountRepositoryWrapper, @@ -185,7 +184,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo this.depositAccountReadPlatformService = depositAccountReadPlatformService; this.calendarInstanceRepository = calendarInstanceRepository; this.configurationDomainService = configurationDomainService; - this.depositAccountOnHoldTransactionRepository =depositAccountOnHoldTransactionRepository; + this.depositAccountOnHoldTransactionRepository = depositAccountOnHoldTransactionRepository; } @Transactional @@ -235,14 +234,15 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO); } final boolean isInterestTransfer = false; + final boolean postInterestAsOn = false; if (account.isBeforeLastPostingPeriod(account.getActivationLocalDate())) { final LocalDate today = DateUtils.getLocalDateOfTenant(); account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, - financialYearBeginningMonth); + financialYearBeginningMonth, postInterestAsOn); } else { final LocalDate today = DateUtils.getLocalDateOfTenant(); account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, - financialYearBeginningMonth); + financialYearBeginningMonth, postInterestAsOn); } updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds); @@ -252,10 +252,12 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo account.updateMaturityDateAndAmount(mc, isPreMatureClosure, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null; - if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){ - depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account); + if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) { + depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository + .findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account); } - account.validateAccountBalanceDoesNotBecomeNegative(SavingsAccountTransactionType.PAY_CHARGE.name(),depositAccountOnHoldTransactions); + account.validateAccountBalanceDoesNotBecomeNegative(SavingsAccountTransactionType.PAY_CHARGE.name(), + depositAccountOnHoldTransactions); this.savingAccountRepositoryWrapper.saveAndFlush(account); } @@ -338,21 +340,24 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo final LocalDate overdueUptoDate = DateUtils.getLocalDateOfTenant(); account.updateOverduePayments(overdueUptoDate); final boolean isInterestTransfer = false; + final boolean postInterestAsOn = false; if (account.isBeforeLastPostingPeriod(account.getActivationLocalDate())) { final LocalDate today = DateUtils.getLocalDateOfTenant(); account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, - financialYearBeginningMonth); + financialYearBeginningMonth, postInterestAsOn); } else { final LocalDate today = DateUtils.getLocalDateOfTenant(); account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, - financialYearBeginningMonth); + financialYearBeginningMonth, postInterestAsOn); } List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null; - if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){ - depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account); + if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) { + depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository + .findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account); } - account.validateAccountBalanceDoesNotBecomeNegative(SavingsAccountTransactionType.PAY_CHARGE.name(),depositAccountOnHoldTransactions); + account.validateAccountBalanceDoesNotBecomeNegative(SavingsAccountTransactionType.PAY_CHARGE.name(), + depositAccountOnHoldTransactions); this.savingAccountRepositoryWrapper.saveAndFlush(account); } @@ -391,8 +396,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo final LocalDate depositAmountUpdateEffectiveFromDate = command .localDateValueOfParameterNamed(DepositsApiConstants.effectiveDateParamName); - final RecurringDepositAccount recurringDepositAccount = (RecurringDepositAccount) this.depositAccountAssembler - .assembleFrom(savingsId, DepositAccountType.RECURRING_DEPOSIT); + final RecurringDepositAccount recurringDepositAccount = (RecurringDepositAccount) this.depositAccountAssembler.assembleFrom( + savingsId, DepositAccountType.RECURRING_DEPOSIT); DepositAccountRecurringDetail recurringDetail = recurringDepositAccount.getRecurringDetail(); Map<String, Object> changes = recurringDetail.updateMandatoryRecommendedDepositAmount(mandatoryRecommendedDepositAmount, depositAmountUpdateEffectiveFromDate, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); @@ -446,8 +451,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo @Transactional @Override - public CommandProcessingResult withdrawal(final Long savingsId, final JsonCommand command, - final DepositAccountType depositAccountType) { + public CommandProcessingResult withdrawal(final Long savingsId, final JsonCommand command, final DepositAccountType depositAccountType) { boolean isRegularTransaction = true; @@ -493,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; account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, - financialYearBeginningMonth); + financialYearBeginningMonth, postInterestAsOn); this.savingAccountRepositoryWrapper.save(account); @@ -537,7 +541,9 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo final LocalDate today = DateUtils.getLocalDateOfTenant(); final MathContext mc = new MathContext(10, MoneyHelper.getRoundingMode()); boolean isInterestTransfer = false; - account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); + boolean postInterestAsOn = false; + account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, + postInterestAsOn); this.savingAccountRepositoryWrapper.saveAndFlush(account); postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds); @@ -588,11 +594,10 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo .findOneByIdAndSavingsAccountId(transactionId, savingsId); if (savingsAccountTransaction == null) { throw new SavingsAccountTransactionNotFoundException(savingsId, transactionId); } - if (!allowAccountTransferModification && this.accountTransfersReadPlatformService.isAccountTransfer(transactionId, - PortfolioAccountType.SAVINGS)) { throw new PlatformServiceUnavailableException( - "error.msg.recurring.deposit.account.transfer.transaction.update.not.allowed", - "Recurring deposit account transaction:" + transactionId + " update not allowed as it involves in account transfer", - transactionId); } + if (!allowAccountTransferModification + && this.accountTransfersReadPlatformService.isAccountTransfer(transactionId, PortfolioAccountType.SAVINGS)) { throw new PlatformServiceUnavailableException( + "error.msg.recurring.deposit.account.transfer.transaction.update.not.allowed", "Recurring deposit account transaction:" + + transactionId + " update not allowed as it involves in account transfer", transactionId); } final LocalDate today = DateUtils.getLocalDateOfTenant(); final MathContext mc = MathContext.DECIMAL64; @@ -602,24 +607,26 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo } account.undoTransaction(transactionId); boolean isInterestTransfer = false; + boolean postInterestAsOn = false; checkClientOrGroupActive(account); if (savingsAccountTransaction.isPostInterestCalculationRequired() && account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) { - account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); + account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, + postInterestAsOn); } else { account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, - financialYearBeginningMonth); + financialYearBeginningMonth, postInterestAsOn); } List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null; - if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){ - depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account); + if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) { + depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository + .findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account); } - account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.undoTransactionAction,depositAccountOnHoldTransactions); + account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.undoTransactionAction, depositAccountOnHoldTransactions); // account.activateAccountBasedOnBalance(); final boolean isPreMatureClosure = false; - account.updateMaturityDateAndAmount(mc, isPreMatureClosure, isSavingsInterestPostingAtCurrentPeriodEnd, - financialYearBeginningMonth); + account.updateMaturityDateAndAmount(mc, isPreMatureClosure, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); final LocalDate overdueUptoDate = DateUtils.getLocalDateOfTenant(); @@ -663,14 +670,12 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo .findOneByIdAndSavingsAccountId(transactionId, savingsId); if (savingsAccountTransaction == null) { throw new SavingsAccountTransactionNotFoundException(savingsId, transactionId); } - if (!(savingsAccountTransaction.isDeposit() || savingsAccountTransaction.isWithdrawal()) - || savingsAccountTransaction.isReversed()) { throw new TransactionUpdateNotAllowedException(savingsId, transactionId); } + if (!(savingsAccountTransaction.isDeposit() || savingsAccountTransaction.isWithdrawal()) || savingsAccountTransaction.isReversed()) { throw new TransactionUpdateNotAllowedException( + savingsId, transactionId); } - if (this.accountTransfersReadPlatformService.isAccountTransfer(transactionId, - PortfolioAccountType.SAVINGS)) { throw new PlatformServiceUnavailableException( - "error.msg.saving.account.transfer.transaction.update.not.allowed", - "Deposit account transaction:" + transactionId + " update not allowed as it involves in account transfer", - transactionId); } + if (this.accountTransfersReadPlatformService.isAccountTransfer(transactionId, PortfolioAccountType.SAVINGS)) { throw new PlatformServiceUnavailableException( + "error.msg.saving.account.transfer.transaction.update.not.allowed", "Deposit account transaction:" + transactionId + + " update not allowed as it involves in account transfer", transactionId); } final LocalDate today = DateUtils.getLocalDateOfTenant(); @@ -705,19 +710,22 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo } final Long newtransactionId = saveTransactionToGenerateTransactionId(transaction); boolean isInterestTransfer = false; + final boolean postInterestAsOn = false; if (account.isBeforeLastPostingPeriod(transactionDate) || account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate())) { - account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); + account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, + postInterestAsOn); } else { account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, - financialYearBeginningMonth); + financialYearBeginningMonth, postInterestAsOn); } List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null; - if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){ - depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account); + if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) { + depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository + .findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account); } - account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.adjustTransactionAction,depositAccountOnHoldTransactions); + account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.adjustTransactionAction, depositAccountOnHoldTransactions); account.activateAccountBasedOnBalance(); if (savingsAccountTransaction.isDeposit()) { @@ -913,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 Set<Long> existingTransactionIds = new HashSet<>(); final Set<Long> existingReversedTransactionIds = new HashSet<>(); updateExistingTransactionsDetails(savingsAccount, existingTransactionIds, existingReversedTransactionIds); @@ -925,7 +933,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo final MathContext mc = MathContext.DECIMAL64; boolean isInterestTransfer = false; savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, - financialYearBeginningMonth); + financialYearBeginningMonth, postInterestAsOn); this.savingsAccountTransactionRepository.save(newTransferTransaction); this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount); @@ -957,8 +965,9 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue()); final MathContext mc = MathContext.DECIMAL64; boolean isInterestTransfer = false; + boolean postInterestAsOn = false; savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, - financialYearBeginningMonth); + financialYearBeginningMonth, postInterestAsOn); this.savingsAccountTransactionRepository.save(withdrawtransferTransaction); this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount); @@ -999,9 +1008,10 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo savingsAccount.reassignSavingsOfficer(fieldOfficer, transferDate); } boolean isInterestTransfer = false; + boolean postInterestAsOn = false; final MathContext mc = MathContext.DECIMAL64; savingsAccount.calculateInterestUsing(mc, transferDate, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, - financialYearBeginningMonth); + financialYearBeginningMonth, postInterestAsOn); this.savingsAccountTransactionRepository.save(acceptTransferTransaction); this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount); @@ -1131,8 +1141,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo .isSavingsInterestPostingAtCurrentPeriodEnd(); final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth(); - final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository - .findOneWithNotFoundDetection(savingsAccountChargeId, savingsAccountId); + final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection( + savingsAccountChargeId, savingsAccountId); // Get Savings account from savings charge final SavingsAccount account = savingsAccountCharge.savingsAccount(); @@ -1144,21 +1154,25 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo account.waiveCharge(savingsAccountChargeId, user); boolean isInterestTransfer = false; + boolean postInterestAsOn = false; final MathContext mc = MathContext.DECIMAL64; if (account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueLocalDate())) { final LocalDate today = DateUtils.getLocalDateOfTenant(); - account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); + account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, + postInterestAsOn); } else { final LocalDate today = DateUtils.getLocalDateOfTenant(); account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, - financialYearBeginningMonth); + financialYearBeginningMonth, postInterestAsOn); } List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null; - if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){ - depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account); + if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) { + depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository + .findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account); } - account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.waiveChargeTransactionAction,depositAccountOnHoldTransactions); + account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.waiveChargeTransactionAction, + depositAccountOnHoldTransactions); this.savingAccountRepositoryWrapper.saveAndFlush(account); @@ -1181,8 +1195,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo final SavingsAccount savingsAccount = this.depositAccountAssembler.assembleFrom(savingsAccountId, depositAccountType); checkClientOrGroupActive(savingsAccount); - final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository - .findOneWithNotFoundDetection(savingsAccountChargeId, savingsAccountId); + final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection( + savingsAccountChargeId, savingsAccountId); savingsAccount.removeCharge(savingsAccountCharge); this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount); @@ -1208,8 +1222,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo final BigDecimal amountPaid = command.bigDecimalValueOfParameterNamed(amountParamName); final LocalDate transactionDate = command.localDateValueOfParameterNamed(dueAsOfDateParamName); - final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository - .findOneWithNotFoundDetection(savingsAccountChargeId, savingsAccountId); + final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection( + savingsAccountChargeId, savingsAccountId); final List<ApiParameterError> dataValidationErrors = new ArrayList<>(); final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors) @@ -1247,8 +1261,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo @SuppressWarnings("unused") final DepositAccountType depositAccountType) { // always use current date as transaction date for batch job final LocalDate transactionDate = DateUtils.getLocalDateOfTenant(); - final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository - .findOneWithNotFoundDetection(savingsAccountChargeId, accountId); + final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection( + savingsAccountChargeId, accountId); final DateTimeFormatter fmt = DateTimeFormat.forPattern("dd MM yyyy"); @@ -1275,21 +1289,25 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds); account.payCharge(savingsAccountCharge, amountPaid, transactionDate, formatter, user); boolean isInterestTransfer = false; + boolean postInterestAsOn = false; final MathContext mc = MathContext.DECIMAL64; if (account.isBeforeLastPostingPeriod(transactionDate)) { final LocalDate today = DateUtils.getLocalDateOfTenant(); - account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); + account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, + postInterestAsOn); } else { final LocalDate today = DateUtils.getLocalDateOfTenant(); account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, - financialYearBeginningMonth); + financialYearBeginningMonth, postInterestAsOn); } List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions = null; - if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){ - depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account); + if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1) { + depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository + .findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account); } - account.validateAccountBalanceDoesNotBecomeNegative("." + SavingsAccountTransactionType.PAY_CHARGE.getCode(),depositAccountOnHoldTransactions); + account.validateAccountBalanceDoesNotBecomeNegative("." + SavingsAccountTransactionType.PAY_CHARGE.getCode(), + depositAccountOnHoldTransactions); this.savingAccountRepositoryWrapper.saveAndFlush(account); @@ -1340,8 +1358,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo @Override public SavingsAccountTransaction mandatorySavingsAccountDeposit(final SavingsAccountTransactionDTO accountTransactionDTO) { boolean isRegularTransaction = false; - final RecurringDepositAccount account = (RecurringDepositAccount) this.depositAccountAssembler - .assembleFrom(accountTransactionDTO.getSavingsAccountId(), DepositAccountType.RECURRING_DEPOSIT); + final RecurringDepositAccount account = (RecurringDepositAccount) this.depositAccountAssembler.assembleFrom( + accountTransactionDTO.getSavingsAccountId(), DepositAccountType.RECURRING_DEPOSIT); final PaymentDetail paymentDetail = accountTransactionDTO.getPaymentDetail(); if (paymentDetail != null && paymentDetail.getId() == null) { this.paymentDetailWritePlatformService.persistPaymentDetail(paymentDetail); http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/580840c3/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java index fc6c5cb..38099d1 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java @@ -767,7 +767,8 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead .append("sa.currency_code as currencyCode, sa.currency_digits as currencyDigits, sa.currency_multiplesof as inMultiplesOf, "); sqlBuilder.append("curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, "); sqlBuilder.append("curr.display_symbol as currencyDisplaySymbol, "); - sqlBuilder.append("pt.value as paymentTypeName "); + sqlBuilder.append("pt.value as paymentTypeName, "); + sqlBuilder.append("tr.is_manual as postInterestAsOn "); sqlBuilder.append("from m_savings_account sa "); sqlBuilder.append("join m_savings_account_transaction tr on tr.savings_account_id = sa.id "); sqlBuilder.append("join m_currency curr on curr.code = sa.currency_code "); @@ -797,6 +798,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead final Long savingsId = rs.getLong("savingsId"); final String accountNo = rs.getString("accountNo"); + final boolean postInterestAsOn = rs.getBoolean("postInterestAsOn"); PaymentDetailData paymentDetailData = null; if (transactionType.isDepositOrWithdrawal()) { @@ -840,12 +842,14 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead final boolean toTransferReversed = rs.getBoolean("toTransferReversed"); final String toTransferDescription = rs.getString("toTransferDescription"); + + transfer = AccountTransferData.transferBasicDetails(toTransferId, currency, toTransferAmount, toTransferDate, toTransferDescription, toTransferReversed); } return SavingsAccountTransactionData.create(id, transactionType, paymentDetailData, savingsId, accountNo, date, currency, - amount, runningBalance, reversed, transfer, submittedOnDate); + amount, runningBalance, reversed, transfer, submittedOnDate, postInterestAsOn); } } http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/580840c3/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformService.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformService.java index c8bf578..51e5383 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformService.java @@ -41,8 +41,6 @@ public interface SavingsAccountWritePlatformService { CommandProcessingResult calculateInterest(Long savingsId); - CommandProcessingResult postInterest(Long savingsId); - CommandProcessingResult undoTransaction(Long savingsId, Long transactionId, boolean allowAccountTransferModification); CommandProcessingResult adjustSavingsTransaction(Long savingsId, Long transactionId, JsonCommand command); @@ -78,7 +76,6 @@ public interface SavingsAccountWritePlatformService { void processPostActiveActions(SavingsAccount account, DateTimeFormatter fmt, Set<Long> existingTransactionIds, Set<Long> existingReversedTransactionIds); - void postInterest(SavingsAccount account); CommandProcessingResult modifyWithHoldTax(Long savingsAccountId, JsonCommand command); @@ -87,4 +84,8 @@ public interface SavingsAccountWritePlatformService { void setSubStatusDormant(Long savingsId); void escheat(Long savingsId); + + CommandProcessingResult postInterest(JsonCommand command); + + void postInterest(SavingsAccount account, boolean postInterestAs, LocalDate transactionDate); } \ No newline at end of file