fineract-1646 and fineract-1638 combined fix (#2457)

authored-by: Dhaval Maniyar <dhavalmaniyar@Dhavals-MacBook-Pro.local>
This commit is contained in:
logoutdhaval
2022-07-28 14:00:15 +05:30
committed by GitHub
parent 0b334b563e
commit a80f589ad4
9 changed files with 38 additions and 48 deletions
@@ -366,10 +366,6 @@ public final class SavingsAccountData implements Serializable {
return this.glAccountIdForInterestOnSavings;
}
public SavingsAccountSummaryData getSavingsAccountSummaryData() {
return this.savingsAccountSummaryData;
}
public List<SavingsAccountTransactionData> getSavingsAccountTransactionData() {
return this.savingsAccountTransactionData;
}
@@ -417,7 +413,7 @@ public final class SavingsAccountData implements Serializable {
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;
}
@@ -152,7 +152,10 @@ public class SavingsAccountSummaryData implements Serializable {
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:
@@ -245,7 +245,8 @@ public final class SavingsAccountTransactionData implements Serializable {
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();
@@ -263,7 +264,7 @@ public final class SavingsAccountTransactionData implements Serializable {
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);
@@ -1168,8 +1168,8 @@ public class SavingsAccount extends AbstractPersistableCustom {
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(
@@ -164,7 +164,7 @@ public final class PostingPeriod {
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;
@@ -182,7 +182,8 @@ public final class PostingPeriod {
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();
@@ -29,9 +29,7 @@ import java.util.List;
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;
@@ -72,7 +70,7 @@ public class SavingsAccountInterestPostingServiceImpl implements SavingsAccountI
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);
}
@@ -251,21 +249,12 @@ public class SavingsAccountInterestPostingServiceImpl implements SavingsAccountI
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());
}
@@ -292,7 +281,7 @@ public class SavingsAccountInterestPostingServiceImpl implements SavingsAccountI
interestCalculationType, interestRateAsFraction, daysInYearType.getValue(), upToInterestCalculationDate,
interestPostTransactions, isInterestTransfer, minBalanceForInterestCalculation,
isSavingsInterestPostingAtCurrentPeriodEnd, overdraftInterestRateAsFraction, minOverdraftForInterestCalculation,
isUserPosting, financialYearBeginningMonth);
isUserPosting, financialYearBeginningMonth, savingsAccountData.isAllowOverdraft());
periodStartingBalance = postingPeriod.closingBalance();
@@ -322,7 +311,7 @@ public class SavingsAccountInterestPostingServiceImpl implements SavingsAccountI
for (final SavingsAccountTransactionData transaction : listOfTransactionsSorted) {
if (!(transaction.isInterestPostingAndNotReversed() || transaction.isOverdraftInterestAndNotReversed())
&& transaction.isNotReversed()) {
&& transaction.isNotReversed() && !transaction.isReversalTransaction()) {
orderedNonInterestPostingTransactions.add(transaction);
}
}
@@ -331,10 +320,6 @@ public class SavingsAccountInterestPostingServiceImpl implements SavingsAccountI
}
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());
@@ -405,7 +390,7 @@ public class SavingsAccountInterestPostingServiceImpl implements SavingsAccountI
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());
}
}
@@ -444,7 +429,10 @@ public class SavingsAccountInterestPostingServiceImpl implements SavingsAccountI
}
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());
}
@@ -522,7 +510,7 @@ public class SavingsAccountInterestPostingServiceImpl implements SavingsAccountI
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;
}
@@ -536,7 +524,7 @@ public class SavingsAccountInterestPostingServiceImpl implements SavingsAccountI
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);
@@ -340,7 +340,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
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, ");
@@ -825,7 +825,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
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, ");
@@ -1684,7 +1684,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
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 ");
@@ -1708,7 +1708,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
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 ");
@@ -1732,7 +1732,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
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 ");
@@ -22,6 +22,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
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;
@@ -270,6 +271,7 @@ public class SavingsSchedularInterestPoster implements Callable<Void> {
.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) {
@@ -284,10 +286,9 @@ public class SavingsSchedularInterestPoster implements Callable<Void> {
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,
@@ -76,7 +76,7 @@ public class SavingsSchedularServiceImpl implements SavingsSchedularService {
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();