Skip to content

Commit

Permalink
fineract-1646 and fineract-1638 combined fix (#2457)
Browse files Browse the repository at this point in the history
authored-by: Dhaval Maniyar <[email protected]>
  • Loading branch information
logoutdhaval committed Jul 28, 2022
1 parent 0b334b5 commit a80f589
Show file tree
Hide file tree
Showing 9 changed files with 38 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -366,10 +366,6 @@ public Long getGlAccountIdForInterestOnSavings() {
return this.glAccountIdForInterestOnSavings;
}

public SavingsAccountSummaryData getSavingsAccountSummaryData() {
return this.savingsAccountSummaryData;
}

public List<SavingsAccountTransactionData> getSavingsAccountTransactionData() {
return this.savingsAccountTransactionData;
}
Expand Down Expand Up @@ -417,7 +413,7 @@ public SavingsAccountTransactionData findLastTransaction(final LocalDate date) {
SavingsAccountTransactionData savingsTransaction = null;
List<SavingsAccountTransactionData> trans = getTransactions();
for (final SavingsAccountTransactionData transaction : trans) {
if (transaction.isNotReversed() && transaction.occursOn(date)) {
if (transaction.isNotReversed() && !transaction.isReversalTransaction() && transaction.occursOn(date)) {
savingsTransaction = transaction;
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,10 @@ public BigDecimal getRunningBalanceOnPivotDate() {
public void updateSummaryWithPivotConfig(final CurrencyData currency, final SavingsAccountTransactionSummaryWrapper wrapper,
final SavingsAccountTransaction transaction, final List<SavingsAccountTransactionData> savingsAccountTransactions) {

if (transaction != null && !transaction.isReversalTransaction()) {
if (transaction != null) {
if (transaction.isReversalTransaction()) {
return;
}
Money transactionAmount = Money.of(currency, transaction.getAmount());
switch (SavingsAccountTransactionType.fromInt(transaction.getTypeOf())) {
case DEPOSIT:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,8 @@ public LocalDate getTransactionLocalDate() {
return this.transactionDate;
}

public EndOfDayBalance toEndOfDayBalanceBoundedBy(final Money openingBalance, final LocalDateInterval boundedBy) {
public EndOfDayBalance toEndOfDayBalanceBoundedBy(final Money openingBalance, final LocalDateInterval boundedBy,
final boolean isAllowOverdraft) {

final MonetaryCurrency currency = openingBalance.getCurrency();
Money endOfDayBalance = openingBalance.copy();
Expand All @@ -263,7 +264,7 @@ public EndOfDayBalance toEndOfDayBalanceBoundedBy(final Money openingBalance, fi
if (isDeposit() || isDividendPayoutAndNotReversed()) {
endOfDayBalance = endOfDayBalance.plus(getAmount());
} else if (isWithdrawal() || isChargeTransactionAndNotReversed()) {
if (endOfDayBalance.isGreaterThanZero()) {
if (endOfDayBalance.isGreaterThanZero() || isAllowOverdraft) {
endOfDayBalance = endOfDayBalance.minus(getAmount());
} else {
endOfDayBalance = Money.of(currency, this.runningBalance);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1168,8 +1168,8 @@ public SavingsAccountTransaction deposit(final SavingsAccountTransactionDTO tran
public void validatePivotDateTransaction(LocalDate transactionDate, final boolean backdatedTxnsAllowedTill,
final Long relaxingDaysConfigForPivotDate, final String resourceTypeName) {
if (backdatedTxnsAllowedTill) {
if (this.getSummary().getLastInterestCalculationDate() != null && transactionDate
.isBefore(this.getSummary().getLastInterestCalculationDate().minusDays(relaxingDaysConfigForPivotDate))) {
if (this.getSummary().getInterestPostedTillDate() != null
&& transactionDate.isBefore(this.getSummary().getInterestPostedTillDate().minusDays(relaxingDaysConfigForPivotDate))) {
final Object[] defaultUserArgs = Arrays.asList(transactionDate, getActivationLocalDate()).toArray();
final String defaultUserMessage = "Transaction date cannot be before transactions pivot date.";
final ApiParameterError error = ApiParameterError.parameterError(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ public static PostingPeriod createFromDTO(final LocalDateInterval periodInterval
final LocalDate upToInterestCalculationDate, Collection<Long> interestPostTransactions, boolean isInterestTransfer,
final Money minBalanceForInterestCalculation, final boolean isSavingsInterestPostingAtCurrentPeriodEnd,
final BigDecimal overdraftInterestRateAsFraction, final Money minOverdraftForInterestCalculation, boolean isUserPosting,
int financialYearBeginningMonth) {
int financialYearBeginningMonth, final boolean isAllowOverdraft) {

final List<EndOfDayBalance> accountEndOfDayBalances = new ArrayList<>();
boolean interestTransfered = false;
Expand All @@ -182,7 +182,8 @@ public static PostingPeriod createFromDTO(final LocalDateInterval periodInterval
openingDayBalance = endOfDayBalance.closingBalance();

} else if (transaction.spansAnyPortionOf(periodInterval)) {
final EndOfDayBalance endOfDayBalance = transaction.toEndOfDayBalanceBoundedBy(openingDayBalance, periodInterval);
final EndOfDayBalance endOfDayBalance = transaction.toEndOfDayBalanceBoundedBy(openingDayBalance, periodInterval,
isAllowOverdraft);
accountEndOfDayBalances.add(endOfDayBalance);

closeOfDayBalance = endOfDayBalance.closingBalance();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.domain.LocalDateInterval;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
import org.apache.fineract.organisation.monetary.domain.Money;
import org.apache.fineract.portfolio.savings.DepositAccountType;
Expand Down Expand Up @@ -72,7 +70,7 @@ public SavingsAccountData postInterest(final MathContext mc, final LocalDate int
interestPostedToDate = Money.of(savingsAccountData.currency(), savingsAccountData.getSummary().getTotalInterestPosted());
SavingsAccountTransactionData savingsAccountTransactionData = retrieveLastTransactions(savingsAccountData);
LocalDate lastTransactionDate = savingsAccountTransactionData.getLastTransactionDate();
savingsAccountData.setStartInterestCalculationDate(lastTransactionDate);
savingsAccountData.setStartInterestCalculationDate(lastTransactionDate.plusDays(1));
} else {
savingsAccountData.setStartInterestCalculationDate(startInterestDate);
}
Expand Down Expand Up @@ -251,21 +249,12 @@ public List<PostingPeriod> calculateInterestUsing(final MathContext mc, final Lo
final SavingsAccountTransactionData transaction = retrieveLastTransactions(savingsAccountData);

if (transaction == null) {
final String defaultUserMessage = "No transactions were found on the specified date "
+ savingsAccountData.getStartInterestCalculationDate().toString() + " for account number "
+ savingsAccountData.getAccountNo() + " and resource id " + savingsAccountData.getId();

final ApiParameterError error = ApiParameterError.parameterError(
"error.msg.savingsaccount.transaction.incorrect.start.interest.calculation.date", defaultUserMessage,
"transactionDate", savingsAccountData.getStartInterestCalculationDate().toString());

final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
dataValidationErrors.add(error);

throw new PlatformApiDataValidationException(dataValidationErrors);
periodStartingBalance = Money.zero(savingsAccountData.currency());
} else {
periodStartingBalance = Money.of(savingsAccountData.currency(),
savingsAccountData.getSummary().getRunningBalanceOnPivotDate());
}

periodStartingBalance = transaction.getRunningBalance(savingsAccountData.currency());
} else {
periodStartingBalance = Money.zero(savingsAccountData.currency());
}
Expand All @@ -292,7 +281,7 @@ public List<PostingPeriod> calculateInterestUsing(final MathContext mc, final Lo
interestCalculationType, interestRateAsFraction, daysInYearType.getValue(), upToInterestCalculationDate,
interestPostTransactions, isInterestTransfer, minBalanceForInterestCalculation,
isSavingsInterestPostingAtCurrentPeriodEnd, overdraftInterestRateAsFraction, minOverdraftForInterestCalculation,
isUserPosting, financialYearBeginningMonth);
isUserPosting, financialYearBeginningMonth, savingsAccountData.isAllowOverdraft());

periodStartingBalance = postingPeriod.closingBalance();

Expand Down Expand Up @@ -322,7 +311,7 @@ private List<SavingsAccountTransactionData> retreiveOrderedNonInterestPostingTra

for (final SavingsAccountTransactionData transaction : listOfTransactionsSorted) {
if (!(transaction.isInterestPostingAndNotReversed() || transaction.isOverdraftInterestAndNotReversed())
&& transaction.isNotReversed()) {
&& transaction.isNotReversed() && !transaction.isReversalTransaction()) {
orderedNonInterestPostingTransactions.add(transaction);
}
}
Expand All @@ -331,10 +320,6 @@ private List<SavingsAccountTransactionData> retreiveOrderedNonInterestPostingTra
}

private List<SavingsAccountTransactionData> retreiveListOfTransactions(final SavingsAccountData savingsAccountData) {
if (savingsAccountData.getTransactions() != null && savingsAccountData.getTransactions().size() == 1) {
return savingsAccountData.getTransactions();
}

final List<SavingsAccountTransactionData> listOfTransactionsSorted = new ArrayList<>();
listOfTransactionsSorted.addAll(savingsAccountData.getTransactions());

Expand Down Expand Up @@ -405,7 +390,7 @@ public LocalDate getActivationLocalDate(final SavingsAccountData savingsAccountD
public List<LocalDate> getManualPostingDates(final SavingsAccountData savingsAccountData) {
List<LocalDate> transactions = new ArrayList<>();
for (SavingsAccountTransactionData trans : savingsAccountData.getSavingsAccountTransactionData()) {
if (trans.isInterestPosting() && trans.isNotReversed() && trans.isManualTransaction()) {
if (trans.isInterestPosting() && trans.isNotReversed() && !trans.isReversalTransaction() && trans.isManualTransaction()) {
transactions.add(trans.getTransactionLocalDate());
}
}
Expand Down Expand Up @@ -444,7 +429,10 @@ protected void recalculateDailyBalances(final Money openingAccountBalance, final
}

runningBalance = runningBalance.plus(transactionAmount);
transaction.updateRunningBalance(runningBalance);
if (!transaction.getRunningBalance(transactionAmount.getCurrency()).isEqualTo(transactionAmount)) {
transaction.updateRunningBalance(runningBalance);
}
// transaction.updateRunningBalance(runningBalance);
if (overdraftAmount.isZero() && runningBalance.isLessThanZero()) {
overdraftAmount = overdraftAmount.plus(runningBalance.getAmount().negate());
}
Expand Down Expand Up @@ -522,7 +510,7 @@ protected SavingsAccountTransactionData findInterestPostingTransactionFor(final
List<SavingsAccountTransactionData> trans = savingsAccountData.getSavingsAccountTransactionData();
for (final SavingsAccountTransactionData transaction : trans) {
if ((transaction.isInterestPostingAndNotReversed() || transaction.isOverdraftInterestAndNotReversed())
&& transaction.occursOn(postingDate)) {
&& transaction.occursOn(postingDate) && !transaction.isReversalTransaction()) {
postingTransation = transaction;
break;
}
Expand All @@ -536,7 +524,7 @@ protected void resetAccountTransactionsEndOfDayBalances(final List<SavingsAccoun
LocalDate endOfBalanceDate = interestPostingUpToDate;
for (int i = accountTransactionsSorted.size() - 1; i >= 0; i--) {
final SavingsAccountTransactionData transaction = accountTransactionsSorted.get(i);
if (transaction.isNotReversed()
if (transaction.isNotReversed() && !transaction.isReversalTransaction()
&& !(transaction.isInterestPostingAndNotReversed() || transaction.isOverdraftInterestAndNotReversed())) {
transaction.updateCumulativeBalanceAndDates(MonetaryCurrency.fromCurrencyData(savingsAccountData.currency()),
endOfBalanceDate);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ private static final class SavingAccountMapperForInterestPosting implements Resu
sqlBuilder.append("tg.id as taxGroupId, ");
sqlBuilder.append("(select COALESCE(max(sat.transaction_date),sa.activatedon_date) ");
sqlBuilder.append("from m_savings_account_transaction as sat ");
sqlBuilder.append("where sat.is_reversed = false ");
sqlBuilder.append("where sat.is_reversed = false and sat.is_reversal = false ");
sqlBuilder.append("and sat.transaction_type_enum in (1,2) ");
sqlBuilder.append("and sat.savings_account_id = sa.id) as lastActiveTransactionDate, ");
sqlBuilder.append("sp.id as productId, ");
Expand Down Expand Up @@ -825,7 +825,7 @@ private static final class SavingAccountMapper implements RowMapper<SavingsAccou
sqlBuilder.append("tg.id as taxGroupId, tg.name as taxGroupName, ");
sqlBuilder.append("(select COALESCE(max(sat.transaction_date),sa.activatedon_date) ");
sqlBuilder.append("from m_savings_account_transaction as sat ");
sqlBuilder.append("where sat.is_reversed = false ");
sqlBuilder.append("where sat.is_reversed = false and sat.is_reversal = false ");
sqlBuilder.append("and sat.transaction_type_enum in (1,2) ");
sqlBuilder.append("and sat.savings_account_id = sa.id) as lastActiveTransactionDate, ");
sqlBuilder.append("sp.is_dormancy_tracking_active as isDormancyTrackingActive, ");
Expand Down Expand Up @@ -1684,7 +1684,7 @@ public List<Long> retrieveSavingsIdsPendingInactive(LocalDate tenantLocalDate) {
sql.append(" where sa.status_enum = 300 ");
sql.append(" and sa.sub_status_enum = 0 ");
String compareDate = "(select COALESCE(max(sat.transaction_date), sa.activatedon_date) "
+ "from m_savings_account_transaction as sat where sat.is_reversed = false"
+ "from m_savings_account_transaction as sat where sat.is_reversed = false and sat.is_reversal = false"
+ " and sat.transaction_type_enum in (1,2) and sat.savings_account_id = sa.id)";
sql.append(" and ").append(sqlGenerator.dateDiff("?", compareDate)).append(" >= sp.days_to_inactive ");

Expand All @@ -1708,7 +1708,7 @@ public List<Long> retrieveSavingsIdsPendingDormant(LocalDate tenantLocalDate) {
sql.append(" where sa.status_enum = 300 ");
sql.append(" and sa.sub_status_enum = 100 ");
sql.append(" and " + sqlGenerator.dateDiff("?",
"(select COALESCE(max(sat.transaction_date),sa.activatedon_date) from m_savings_account_transaction as sat where sat.is_reversed = false and sat.transaction_type_enum in (1,2) and sat.savings_account_id = sa.id)")
"(select COALESCE(max(sat.transaction_date),sa.activatedon_date) from m_savings_account_transaction as sat where sat.is_reversed = false and sat.is_reversal = false and sat.transaction_type_enum in (1,2) and sat.savings_account_id = sa.id)")
+ " ");
sql.append(" >= sp.days_to_dormancy ");

Expand All @@ -1732,7 +1732,7 @@ public List<Long> retrieveSavingsIdsPendingEscheat(LocalDate tenantLocalDate) {
sql.append(" where sa.status_enum = 300 ");
sql.append(" and sa.sub_status_enum = 200 ");
sql.append(" and " + sqlGenerator.dateDiff("?",
"(select COALESCE(max(sat.transaction_date),sa.activatedon_date) from m_savings_account_transaction as sat where sat.is_reversed = false and sat.transaction_type_enum in (1,2) and sat.savings_account_id = sa.id)")
"(select COALESCE(max(sat.transaction_date),sa.activatedon_date) from m_savings_account_transaction as sat where sat.is_reversed = false and sat.is_reversal = false and sat.transaction_type_enum in (1,2) and sat.savings_account_id = sa.id)")
+ " ");
sql.append(" >= sp.days_to_escheat ");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.math.BigDecimal;
import java.security.SecureRandom;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
Expand Down Expand Up @@ -270,6 +271,7 @@ private void batchUpdate(final List<SavingsAccountData> savingsAccountDataList)
.atStartOfDay(DateUtils.getDateTimeZoneOfTenant()).toInstant()),
savingsAccountData.getId() });
List<SavingsAccountTransactionData> savingsAccountTransactionDataList = savingsAccountData.getSavingsAccountTransactionData();
LocalDateTime currentDate = DateUtils.getLocalDateTimeOfTenant();
for (SavingsAccountTransactionData savingsAccountTransactionData : savingsAccountTransactionDataList) {
Date balanceEndDate = null;
if (savingsAccountTransactionData.getBalanceEndDate() != null) {
Expand All @@ -284,10 +286,9 @@ private void batchUpdate(final List<SavingsAccountData> savingsAccountDataList)
savingsAccountTransactionData.isReversed(), savingsAccountTransactionData.getTransactionType().getId(),
savingsAccountTransactionData.getTransactionDate(), savingsAccountTransactionData.getAmount(), balanceEndDate,
savingsAccountTransactionData.getBalanceNumberOfDays(), savingsAccountTransactionData.getRunningBalance(),
savingsAccountTransactionData.getCumulativeBalance(), savingsAccountTransactionData.getSubmittedOnDate(),
Integer.valueOf(1), savingsAccountTransactionData.isManualTransaction(),
savingsAccountTransactionData.getRefNo(), savingsAccountTransactionData.isReversalTransaction(),
savingsAccountTransactionData.getOverdraftAmount(), });
savingsAccountTransactionData.getCumulativeBalance(), currentDate, Integer.valueOf(1),
savingsAccountTransactionData.isManualTransaction(), savingsAccountTransactionData.getRefNo(),
savingsAccountTransactionData.isReversalTransaction(), savingsAccountTransactionData.getOverdraftAmount(), });
} else {
paramsForTransactionUpdate.add(new Object[] { savingsAccountTransactionData.isReversed(),
savingsAccountTransactionData.getAmount(), savingsAccountTransactionData.getOverdraftAmount(), balanceEndDate,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public void postInterestForAccounts(Map<String, String> jobParameters) throws Jo
Long maxSavingsIdInList = 0L;
// initialise the executor service with fetched configurations
final ExecutorService executorService = Executors.newFixedThreadPool(threadPoolSize);
final boolean backdatedTxnsAllowedTill = this.configurationDomainService.retrievePivotDateConfig();
final boolean backdatedTxnsAllowedTill = false;

long start = System.currentTimeMillis();

Expand Down

0 comments on commit a80f589

Please sign in to comment.