Skip to content

Commit a80f589

Browse files
authored
fineract-1646 and fineract-1638 combined fix (#2457)
authored-by: Dhaval Maniyar <dhavalmaniyar@Dhavals-MacBook-Pro.local>
1 parent 0b334b5 commit a80f589

9 files changed

Lines changed: 38 additions & 48 deletions

fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountData.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -366,10 +366,6 @@ public Long getGlAccountIdForInterestOnSavings() {
366366
return this.glAccountIdForInterestOnSavings;
367367
}
368368

369-
public SavingsAccountSummaryData getSavingsAccountSummaryData() {
370-
return this.savingsAccountSummaryData;
371-
}
372-
373369
public List<SavingsAccountTransactionData> getSavingsAccountTransactionData() {
374370
return this.savingsAccountTransactionData;
375371
}
@@ -417,7 +413,7 @@ public SavingsAccountTransactionData findLastTransaction(final LocalDate date) {
417413
SavingsAccountTransactionData savingsTransaction = null;
418414
List<SavingsAccountTransactionData> trans = getTransactions();
419415
for (final SavingsAccountTransactionData transaction : trans) {
420-
if (transaction.isNotReversed() && transaction.occursOn(date)) {
416+
if (transaction.isNotReversed() && !transaction.isReversalTransaction() && transaction.occursOn(date)) {
421417
savingsTransaction = transaction;
422418
break;
423419
}

fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountSummaryData.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,10 @@ public BigDecimal getRunningBalanceOnPivotDate() {
152152
public void updateSummaryWithPivotConfig(final CurrencyData currency, final SavingsAccountTransactionSummaryWrapper wrapper,
153153
final SavingsAccountTransaction transaction, final List<SavingsAccountTransactionData> savingsAccountTransactions) {
154154

155-
if (transaction != null && !transaction.isReversalTransaction()) {
155+
if (transaction != null) {
156+
if (transaction.isReversalTransaction()) {
157+
return;
158+
}
156159
Money transactionAmount = Money.of(currency, transaction.getAmount());
157160
switch (SavingsAccountTransactionType.fromInt(transaction.getTypeOf())) {
158161
case DEPOSIT:

fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionData.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,8 @@ public LocalDate getTransactionLocalDate() {
245245
return this.transactionDate;
246246
}
247247

248-
public EndOfDayBalance toEndOfDayBalanceBoundedBy(final Money openingBalance, final LocalDateInterval boundedBy) {
248+
public EndOfDayBalance toEndOfDayBalanceBoundedBy(final Money openingBalance, final LocalDateInterval boundedBy,
249+
final boolean isAllowOverdraft) {
249250

250251
final MonetaryCurrency currency = openingBalance.getCurrency();
251252
Money endOfDayBalance = openingBalance.copy();
@@ -263,7 +264,7 @@ public EndOfDayBalance toEndOfDayBalanceBoundedBy(final Money openingBalance, fi
263264
if (isDeposit() || isDividendPayoutAndNotReversed()) {
264265
endOfDayBalance = endOfDayBalance.plus(getAmount());
265266
} else if (isWithdrawal() || isChargeTransactionAndNotReversed()) {
266-
if (endOfDayBalance.isGreaterThanZero()) {
267+
if (endOfDayBalance.isGreaterThanZero() || isAllowOverdraft) {
267268
endOfDayBalance = endOfDayBalance.minus(getAmount());
268269
} else {
269270
endOfDayBalance = Money.of(currency, this.runningBalance);

fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,8 +1168,8 @@ public SavingsAccountTransaction deposit(final SavingsAccountTransactionDTO tran
11681168
public void validatePivotDateTransaction(LocalDate transactionDate, final boolean backdatedTxnsAllowedTill,
11691169
final Long relaxingDaysConfigForPivotDate, final String resourceTypeName) {
11701170
if (backdatedTxnsAllowedTill) {
1171-
if (this.getSummary().getLastInterestCalculationDate() != null && transactionDate
1172-
.isBefore(this.getSummary().getLastInterestCalculationDate().minusDays(relaxingDaysConfigForPivotDate))) {
1171+
if (this.getSummary().getInterestPostedTillDate() != null
1172+
&& transactionDate.isBefore(this.getSummary().getInterestPostedTillDate().minusDays(relaxingDaysConfigForPivotDate))) {
11731173
final Object[] defaultUserArgs = Arrays.asList(transactionDate, getActivationLocalDate()).toArray();
11741174
final String defaultUserMessage = "Transaction date cannot be before transactions pivot date.";
11751175
final ApiParameterError error = ApiParameterError.parameterError(

fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/interest/PostingPeriod.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ public static PostingPeriod createFromDTO(final LocalDateInterval periodInterval
164164
final LocalDate upToInterestCalculationDate, Collection<Long> interestPostTransactions, boolean isInterestTransfer,
165165
final Money minBalanceForInterestCalculation, final boolean isSavingsInterestPostingAtCurrentPeriodEnd,
166166
final BigDecimal overdraftInterestRateAsFraction, final Money minOverdraftForInterestCalculation, boolean isUserPosting,
167-
int financialYearBeginningMonth) {
167+
int financialYearBeginningMonth, final boolean isAllowOverdraft) {
168168

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

184184
} else if (transaction.spansAnyPortionOf(periodInterval)) {
185-
final EndOfDayBalance endOfDayBalance = transaction.toEndOfDayBalanceBoundedBy(openingDayBalance, periodInterval);
185+
final EndOfDayBalance endOfDayBalance = transaction.toEndOfDayBalanceBoundedBy(openingDayBalance, periodInterval,
186+
isAllowOverdraft);
186187
accountEndOfDayBalances.add(endOfDayBalance);
187188

188189
closeOfDayBalance = endOfDayBalance.closingBalance();

fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountInterestPostingServiceImpl.java

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,7 @@
2929
import java.util.Map;
3030
import java.util.Set;
3131
import java.util.stream.Collectors;
32-
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
3332
import org.apache.fineract.infrastructure.core.domain.LocalDateInterval;
34-
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
3533
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
3634
import org.apache.fineract.organisation.monetary.domain.Money;
3735
import org.apache.fineract.portfolio.savings.DepositAccountType;
@@ -72,7 +70,7 @@ public SavingsAccountData postInterest(final MathContext mc, final LocalDate int
7270
interestPostedToDate = Money.of(savingsAccountData.currency(), savingsAccountData.getSummary().getTotalInterestPosted());
7371
SavingsAccountTransactionData savingsAccountTransactionData = retrieveLastTransactions(savingsAccountData);
7472
LocalDate lastTransactionDate = savingsAccountTransactionData.getLastTransactionDate();
75-
savingsAccountData.setStartInterestCalculationDate(lastTransactionDate);
73+
savingsAccountData.setStartInterestCalculationDate(lastTransactionDate.plusDays(1));
7674
} else {
7775
savingsAccountData.setStartInterestCalculationDate(startInterestDate);
7876
}
@@ -251,21 +249,12 @@ public List<PostingPeriod> calculateInterestUsing(final MathContext mc, final Lo
251249
final SavingsAccountTransactionData transaction = retrieveLastTransactions(savingsAccountData);
252250

253251
if (transaction == null) {
254-
final String defaultUserMessage = "No transactions were found on the specified date "
255-
+ savingsAccountData.getStartInterestCalculationDate().toString() + " for account number "
256-
+ savingsAccountData.getAccountNo() + " and resource id " + savingsAccountData.getId();
257-
258-
final ApiParameterError error = ApiParameterError.parameterError(
259-
"error.msg.savingsaccount.transaction.incorrect.start.interest.calculation.date", defaultUserMessage,
260-
"transactionDate", savingsAccountData.getStartInterestCalculationDate().toString());
261-
262-
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
263-
dataValidationErrors.add(error);
264-
265-
throw new PlatformApiDataValidationException(dataValidationErrors);
252+
periodStartingBalance = Money.zero(savingsAccountData.currency());
253+
} else {
254+
periodStartingBalance = Money.of(savingsAccountData.currency(),
255+
savingsAccountData.getSummary().getRunningBalanceOnPivotDate());
266256
}
267257

268-
periodStartingBalance = transaction.getRunningBalance(savingsAccountData.currency());
269258
} else {
270259
periodStartingBalance = Money.zero(savingsAccountData.currency());
271260
}
@@ -292,7 +281,7 @@ public List<PostingPeriod> calculateInterestUsing(final MathContext mc, final Lo
292281
interestCalculationType, interestRateAsFraction, daysInYearType.getValue(), upToInterestCalculationDate,
293282
interestPostTransactions, isInterestTransfer, minBalanceForInterestCalculation,
294283
isSavingsInterestPostingAtCurrentPeriodEnd, overdraftInterestRateAsFraction, minOverdraftForInterestCalculation,
295-
isUserPosting, financialYearBeginningMonth);
284+
isUserPosting, financialYearBeginningMonth, savingsAccountData.isAllowOverdraft());
296285

297286
periodStartingBalance = postingPeriod.closingBalance();
298287

@@ -322,7 +311,7 @@ private List<SavingsAccountTransactionData> retreiveOrderedNonInterestPostingTra
322311

323312
for (final SavingsAccountTransactionData transaction : listOfTransactionsSorted) {
324313
if (!(transaction.isInterestPostingAndNotReversed() || transaction.isOverdraftInterestAndNotReversed())
325-
&& transaction.isNotReversed()) {
314+
&& transaction.isNotReversed() && !transaction.isReversalTransaction()) {
326315
orderedNonInterestPostingTransactions.add(transaction);
327316
}
328317
}
@@ -331,10 +320,6 @@ private List<SavingsAccountTransactionData> retreiveOrderedNonInterestPostingTra
331320
}
332321

333322
private List<SavingsAccountTransactionData> retreiveListOfTransactions(final SavingsAccountData savingsAccountData) {
334-
if (savingsAccountData.getTransactions() != null && savingsAccountData.getTransactions().size() == 1) {
335-
return savingsAccountData.getTransactions();
336-
}
337-
338323
final List<SavingsAccountTransactionData> listOfTransactionsSorted = new ArrayList<>();
339324
listOfTransactionsSorted.addAll(savingsAccountData.getTransactions());
340325

@@ -405,7 +390,7 @@ public LocalDate getActivationLocalDate(final SavingsAccountData savingsAccountD
405390
public List<LocalDate> getManualPostingDates(final SavingsAccountData savingsAccountData) {
406391
List<LocalDate> transactions = new ArrayList<>();
407392
for (SavingsAccountTransactionData trans : savingsAccountData.getSavingsAccountTransactionData()) {
408-
if (trans.isInterestPosting() && trans.isNotReversed() && trans.isManualTransaction()) {
393+
if (trans.isInterestPosting() && trans.isNotReversed() && !trans.isReversalTransaction() && trans.isManualTransaction()) {
409394
transactions.add(trans.getTransactionLocalDate());
410395
}
411396
}
@@ -444,7 +429,10 @@ protected void recalculateDailyBalances(final Money openingAccountBalance, final
444429
}
445430

446431
runningBalance = runningBalance.plus(transactionAmount);
447-
transaction.updateRunningBalance(runningBalance);
432+
if (!transaction.getRunningBalance(transactionAmount.getCurrency()).isEqualTo(transactionAmount)) {
433+
transaction.updateRunningBalance(runningBalance);
434+
}
435+
// transaction.updateRunningBalance(runningBalance);
448436
if (overdraftAmount.isZero() && runningBalance.isLessThanZero()) {
449437
overdraftAmount = overdraftAmount.plus(runningBalance.getAmount().negate());
450438
}
@@ -522,7 +510,7 @@ protected SavingsAccountTransactionData findInterestPostingTransactionFor(final
522510
List<SavingsAccountTransactionData> trans = savingsAccountData.getSavingsAccountTransactionData();
523511
for (final SavingsAccountTransactionData transaction : trans) {
524512
if ((transaction.isInterestPostingAndNotReversed() || transaction.isOverdraftInterestAndNotReversed())
525-
&& transaction.occursOn(postingDate)) {
513+
&& transaction.occursOn(postingDate) && !transaction.isReversalTransaction()) {
526514
postingTransation = transaction;
527515
break;
528516
}
@@ -536,7 +524,7 @@ protected void resetAccountTransactionsEndOfDayBalances(final List<SavingsAccoun
536524
LocalDate endOfBalanceDate = interestPostingUpToDate;
537525
for (int i = accountTransactionsSorted.size() - 1; i >= 0; i--) {
538526
final SavingsAccountTransactionData transaction = accountTransactionsSorted.get(i);
539-
if (transaction.isNotReversed()
527+
if (transaction.isNotReversed() && !transaction.isReversalTransaction()
540528
&& !(transaction.isInterestPostingAndNotReversed() || transaction.isOverdraftInterestAndNotReversed())) {
541529
transaction.updateCumulativeBalanceAndDates(MonetaryCurrency.fromCurrencyData(savingsAccountData.currency()),
542530
endOfBalanceDate);

fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ private static final class SavingAccountMapperForInterestPosting implements Resu
340340
sqlBuilder.append("tg.id as taxGroupId, ");
341341
sqlBuilder.append("(select COALESCE(max(sat.transaction_date),sa.activatedon_date) ");
342342
sqlBuilder.append("from m_savings_account_transaction as sat ");
343-
sqlBuilder.append("where sat.is_reversed = false ");
343+
sqlBuilder.append("where sat.is_reversed = false and sat.is_reversal = false ");
344344
sqlBuilder.append("and sat.transaction_type_enum in (1,2) ");
345345
sqlBuilder.append("and sat.savings_account_id = sa.id) as lastActiveTransactionDate, ");
346346
sqlBuilder.append("sp.id as productId, ");
@@ -825,7 +825,7 @@ private static final class SavingAccountMapper implements RowMapper<SavingsAccou
825825
sqlBuilder.append("tg.id as taxGroupId, tg.name as taxGroupName, ");
826826
sqlBuilder.append("(select COALESCE(max(sat.transaction_date),sa.activatedon_date) ");
827827
sqlBuilder.append("from m_savings_account_transaction as sat ");
828-
sqlBuilder.append("where sat.is_reversed = false ");
828+
sqlBuilder.append("where sat.is_reversed = false and sat.is_reversal = false ");
829829
sqlBuilder.append("and sat.transaction_type_enum in (1,2) ");
830830
sqlBuilder.append("and sat.savings_account_id = sa.id) as lastActiveTransactionDate, ");
831831
sqlBuilder.append("sp.is_dormancy_tracking_active as isDormancyTrackingActive, ");
@@ -1684,7 +1684,7 @@ public List<Long> retrieveSavingsIdsPendingInactive(LocalDate tenantLocalDate) {
16841684
sql.append(" where sa.status_enum = 300 ");
16851685
sql.append(" and sa.sub_status_enum = 0 ");
16861686
String compareDate = "(select COALESCE(max(sat.transaction_date), sa.activatedon_date) "
1687-
+ "from m_savings_account_transaction as sat where sat.is_reversed = false"
1687+
+ "from m_savings_account_transaction as sat where sat.is_reversed = false and sat.is_reversal = false"
16881688
+ " and sat.transaction_type_enum in (1,2) and sat.savings_account_id = sa.id)";
16891689
sql.append(" and ").append(sqlGenerator.dateDiff("?", compareDate)).append(" >= sp.days_to_inactive ");
16901690

@@ -1708,7 +1708,7 @@ public List<Long> retrieveSavingsIdsPendingDormant(LocalDate tenantLocalDate) {
17081708
sql.append(" where sa.status_enum = 300 ");
17091709
sql.append(" and sa.sub_status_enum = 100 ");
17101710
sql.append(" and " + sqlGenerator.dateDiff("?",
1711-
"(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)")
1711+
"(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)")
17121712
+ " ");
17131713
sql.append(" >= sp.days_to_dormancy ");
17141714

@@ -1732,7 +1732,7 @@ public List<Long> retrieveSavingsIdsPendingEscheat(LocalDate tenantLocalDate) {
17321732
sql.append(" where sa.status_enum = 300 ");
17331733
sql.append(" and sa.sub_status_enum = 200 ");
17341734
sql.append(" and " + sqlGenerator.dateDiff("?",
1735-
"(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)")
1735+
"(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)")
17361736
+ " ");
17371737
sql.append(" >= sp.days_to_escheat ");
17381738

fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularInterestPoster.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.math.BigDecimal;
2323
import java.security.SecureRandom;
2424
import java.time.LocalDate;
25+
import java.time.LocalDateTime;
2526
import java.util.ArrayList;
2627
import java.util.Collection;
2728
import java.util.Date;
@@ -270,6 +271,7 @@ private void batchUpdate(final List<SavingsAccountData> savingsAccountDataList)
270271
.atStartOfDay(DateUtils.getDateTimeZoneOfTenant()).toInstant()),
271272
savingsAccountData.getId() });
272273
List<SavingsAccountTransactionData> savingsAccountTransactionDataList = savingsAccountData.getSavingsAccountTransactionData();
274+
LocalDateTime currentDate = DateUtils.getLocalDateTimeOfTenant();
273275
for (SavingsAccountTransactionData savingsAccountTransactionData : savingsAccountTransactionDataList) {
274276
Date balanceEndDate = null;
275277
if (savingsAccountTransactionData.getBalanceEndDate() != null) {
@@ -284,10 +286,9 @@ private void batchUpdate(final List<SavingsAccountData> savingsAccountDataList)
284286
savingsAccountTransactionData.isReversed(), savingsAccountTransactionData.getTransactionType().getId(),
285287
savingsAccountTransactionData.getTransactionDate(), savingsAccountTransactionData.getAmount(), balanceEndDate,
286288
savingsAccountTransactionData.getBalanceNumberOfDays(), savingsAccountTransactionData.getRunningBalance(),
287-
savingsAccountTransactionData.getCumulativeBalance(), savingsAccountTransactionData.getSubmittedOnDate(),
288-
Integer.valueOf(1), savingsAccountTransactionData.isManualTransaction(),
289-
savingsAccountTransactionData.getRefNo(), savingsAccountTransactionData.isReversalTransaction(),
290-
savingsAccountTransactionData.getOverdraftAmount(), });
289+
savingsAccountTransactionData.getCumulativeBalance(), currentDate, Integer.valueOf(1),
290+
savingsAccountTransactionData.isManualTransaction(), savingsAccountTransactionData.getRefNo(),
291+
savingsAccountTransactionData.isReversalTransaction(), savingsAccountTransactionData.getOverdraftAmount(), });
291292
} else {
292293
paramsForTransactionUpdate.add(new Object[] { savingsAccountTransactionData.isReversed(),
293294
savingsAccountTransactionData.getAmount(), savingsAccountTransactionData.getOverdraftAmount(), balanceEndDate,

fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularServiceImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public void postInterestForAccounts(Map<String, String> jobParameters) throws Jo
7676
Long maxSavingsIdInList = 0L;
7777
// initialise the executor service with fetched configurations
7878
final ExecutorService executorService = Executors.newFixedThreadPool(threadPoolSize);
79-
final boolean backdatedTxnsAllowedTill = this.configurationDomainService.retrievePivotDateConfig();
79+
final boolean backdatedTxnsAllowedTill = false;
8080

8181
long start = System.currentTimeMillis();
8282

0 commit comments

Comments
 (0)