This is an automated email from the ASF dual-hosted git repository.
manojvm pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
The following commit(s) were added to refs/heads/develop by this push:
new e4eb8afdf fineract-1652: Account Balance and Transaction running
balance is wrong
new d1c77a5e4 Merge pull request #2396 from logoutdhaval/fineract-1652
e4eb8afdf is described below
commit e4eb8afdf41422834ebee955d9164ad6dc5ecbdd
Author: Dhaval Maniyar <[email protected]>
AuthorDate: Thu Jun 30 21:43:21 2022 +0530
fineract-1652: Account Balance and Transaction running balance is wrong
---
.../savings/data/SavingsAccountSummaryData.java | 37 +++++++++----
.../savings/domain/FixedDepositAccount.java | 37 +++++++------
.../savings/domain/RecurringDepositAccount.java | 28 ++++++----
.../portfolio/savings/domain/SavingsAccount.java | 62 ++++++++++++++--------
.../savings/domain/SavingsAccountAssembler.java | 17 ++++--
.../domain/SavingsAccountDomainServiceJpa.java | 19 ++++---
.../savings/domain/SavingsAccountSummary.java | 52 +++++++++++++-----
.../savings/domain/SavingsAccountTransaction.java | 7 ++-
...countWritePlatformServiceJpaRepositoryImpl.java | 34 +++++++-----
.../SavingsAccountInterestPostingServiceImpl.java | 3 +-
...countWritePlatformServiceJpaRepositoryImpl.java | 33 ++++++------
.../service/SavingsSchedularInterestPoster.java | 24 +++++----
.../ClientSavingsIntegrationTest.java | 56 +++++++++++++++++++
13 files changed, 281 insertions(+), 128 deletions(-)
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountSummaryData.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountSummaryData.java
index e92edaefd..145f3e19f 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountSummaryData.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountSummaryData.java
@@ -78,7 +78,7 @@ public class SavingsAccountSummaryData implements
Serializable {
this.interestNotPosted = interestNotPosted;
this.lastInterestCalculationDate = lastInterestCalculationDate;
this.availableBalance = availableBalance;
- this.interestPostedTillDate = interestPostedTillDate == null ?
lastInterestCalculationDate : interestPostedTillDate;
+ this.interestPostedTillDate = interestPostedTillDate;
}
public void setPrevInterestPostedTillDate(LocalDate
interestPostedTillDate) {
@@ -152,7 +152,7 @@ public class SavingsAccountSummaryData implements
Serializable {
public void updateSummaryWithPivotConfig(final CurrencyData currency,
final SavingsAccountTransactionSummaryWrapper wrapper,
final SavingsAccountTransaction transaction, final
List<SavingsAccountTransactionData> savingsAccountTransactions) {
- if (transaction != null) {
+ if (transaction != null && !transaction.isReversalTransaction()) {
Money transactionAmount = Money.of(currency,
transaction.getAmount());
switch
(SavingsAccountTransactionType.fromInt(transaction.getTypeOf())) {
case DEPOSIT:
@@ -219,15 +219,17 @@ public class SavingsAccountSummaryData implements
Serializable {
// boolean isUpdated = false;
Money interestTotal = Money.of(currency, this.totalInterestPosted);
Money withHoldTaxTotal = Money.of(currency, this.totalWithholdTax);
-
+ Money overdraftInterestTotal = Money.of(currency,
this.totalOverdraftInterestDerived);
final HashMap<String, Money> map =
updateRunningBalanceAndPivotDate(true, savingsAccountTransactions,
interestTotal,
- withHoldTaxTotal, currency);
+ overdraftInterestTotal, withHoldTaxTotal, currency);
interestTotal = map.get("interestTotal");
withHoldTaxTotal = map.get("withHoldTax");
+ overdraftInterestTotal = map.get("overdraftInterestTotal");
this.totalInterestPosted =
interestTotal.getAmountDefaultedToNullIfZero();
this.totalWithholdTax =
withHoldTaxTotal.getAmountDefaultedToNullIfZero();
+ this.totalOverdraftInterestDerived =
overdraftInterestTotal.getAmountDefaultedToNullIfZero();
this.accountBalance = Money.of(currency,
this.accountBalance).plus(this.totalInterestPosted).minus(this.totalWithholdTax)
- .getAmount();
+ .minus(this.totalOverdraftInterestDerived).getAmount();
}
}
@@ -246,13 +248,23 @@ public class SavingsAccountSummaryData implements
Serializable {
@SuppressWarnings("unchecked")
private HashMap<String, Money> updateRunningBalanceAndPivotDate(final
boolean backdatedTxnsAllowedTill,
- final List<SavingsAccountTransactionData>
savingsAccountTransactions, Money interestTotal, Money withHoldTaxTotal,
- CurrencyData currency) {
+ final List<SavingsAccountTransactionData>
savingsAccountTransactions, Money interestTotal, Money overdraftInterestTotal,
+ Money withHoldTaxTotal, CurrencyData currency) {
boolean isUpdated = false;
HashMap<String, Money> map = new HashMap<>();
for (int i = savingsAccountTransactions.size() - 1; i >= 0; i--) {
final SavingsAccountTransactionData savingsAccountTransaction =
savingsAccountTransactions.get(i);
- if (savingsAccountTransaction.isInterestPostingAndNotReversed() &&
savingsAccountTransaction.isNotReversed() && !isUpdated) {
+ if (savingsAccountTransaction.isInterestPostingAndNotReversed() &&
!savingsAccountTransaction.isReversalTransaction()
+ && !isUpdated) {
+
setRunningBalanceOnPivotDate(savingsAccountTransaction.getRunningBalance(currency).getAmount());
+
setInterestPostedTillDate(savingsAccountTransaction.getTransactionDate());
+ isUpdated = true;
+ if (!backdatedTxnsAllowedTill) {
+ break;
+ }
+ }
+ if (savingsAccountTransaction.isOverdraftInterestAndNotReversed()
&& !savingsAccountTransaction.isReversalTransaction()
+ && !isUpdated) {
setRunningBalanceOnPivotDate(savingsAccountTransaction.getRunningBalance(currency).getAmount());
setInterestPostedTillDate(savingsAccountTransaction.getTransactionDate());
isUpdated = true;
@@ -261,10 +273,12 @@ public class SavingsAccountSummaryData implements
Serializable {
}
}
if (backdatedTxnsAllowedTill) {
- if
(savingsAccountTransaction.isInterestPostingAndNotReversed() &&
savingsAccountTransaction.isNotReversed()) {
+ if
(savingsAccountTransaction.isInterestPostingAndNotReversed()) {
interestTotal =
interestTotal.plus(savingsAccountTransaction.getAmount());
}
-
+ if
(savingsAccountTransaction.isOverdraftInterestAndNotReversed()) {
+ overdraftInterestTotal =
overdraftInterestTotal.plus(savingsAccountTransaction.getAmount());
+ }
if (savingsAccountTransaction.isWithHoldTaxAndNotReversed()) {
withHoldTaxTotal =
withHoldTaxTotal.plus(savingsAccountTransaction.getAmount());
}
@@ -273,6 +287,7 @@ public class SavingsAccountSummaryData implements
Serializable {
if (backdatedTxnsAllowedTill) {
map.put("interestTotal", interestTotal);
map.put("withHoldTax", withHoldTaxTotal);
+ map.put("overdraftInterestTotal", overdraftInterestTotal);
}
return map;
}
@@ -293,7 +308,7 @@ public class SavingsAccountSummaryData implements
Serializable {
this.totalWithholdTax =
wrapper.calculateTotalWithholdTaxWithdrawal(currency, transactions);
// boolean isUpdated = false;
- updateRunningBalanceAndPivotDate(false, transactions, null, null,
currency);
+ updateRunningBalanceAndPivotDate(false, transactions, null, null,
null, currency);
this.accountBalance = Money.of(currency,
this.totalDeposits).plus(this.totalInterestPosted).minus(this.totalWithdrawals)
.minus(this.totalWithdrawalFees).minus(this.totalAnnualFees).minus(this.totalFeeCharge).minus(this.totalPenaltyCharge)
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/FixedDepositAccount.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/FixedDepositAccount.java
index 9dff82f57..c03c8f957 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/FixedDepositAccount.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/FixedDepositAccount.java
@@ -191,19 +191,20 @@ public class FixedDepositAccount extends SavingsAccount {
public void updateMaturityDateAndAmountBeforeAccountActivation(final
MathContext mc, final boolean isPreMatureClosure,
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final
Integer financialYearBeginningMonth) {
List<SavingsAccountTransaction> allTransactions = new ArrayList<>();
+ String refNo = null;
final Money transactionAmountMoney = Money.of(getCurrency(),
this.accountTermAndPreClosure.depositAmount());
final SavingsAccountTransaction transaction =
SavingsAccountTransaction.deposit(null, office(), null,
- this.accountSubmittedOrActivationDate(),
transactionAmountMoney, new Date(), null); // TODO:
-
// verify
-
// if
-
// it
-
// is
-
// ok
-
// to
-
// pass
-
// null
-
// for
-
// AppUser
+ this.accountSubmittedOrActivationDate(),
transactionAmountMoney, new Date(), null, refNo); // TODO:
+ // verify
+ // if
+ // it
+ // is
+ // ok
+ // to
+ // pass
+ // null
+ // for
+ // AppUser
transaction.updateRunningBalance(transactionAmountMoney);
transaction.updateCumulativeBalanceAndDates(this.getCurrency(),
interestCalculatedUpto());
allTransactions.add(transaction);
@@ -528,8 +529,10 @@ public class FixedDepositAccount extends SavingsAccount {
final boolean isInterestTransfer = false;
final LocalDate postInterestOnDate = null;
final boolean backdatedTxnsAllowedTill = false;
+ boolean postReversals = false;
final List<PostingPeriod> postingPeriods = calculateInterestUsing(mc,
interestPostingUpToDate, isInterestTransfer,
- isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestOnDate, backdatedTxnsAllowedTill);
+ isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestOnDate, backdatedTxnsAllowedTill,
+ postReversals);
Money interestPostedToDate = Money.zero(this.currency);
@@ -568,7 +571,7 @@ public class FixedDepositAccount extends SavingsAccount {
if (recalucateDailyBalanceDetails) {
// update existing transactions so derived balance fields are
// correct.
- recalculateDailyBalances(Money.zero(this.currency),
interestPostingUpToDate, backdatedTxnsAllowedTill);
+ recalculateDailyBalances(Money.zero(this.currency),
interestPostingUpToDate, backdatedTxnsAllowedTill, postReversals);
}
this.summary.updateSummary(this.currency,
this.savingsAccountTransactionSummaryWrapper, this.transactions);
@@ -597,11 +600,11 @@ public class FixedDepositAccount extends SavingsAccount {
}
recalucateDailyBalance =
applyWithholdTaxForDepositAccounts(accountCloseDate, recalucateDailyBalance,
backdatedTxnsAllowedTill);
-
+ boolean postReversals = false;
if (recalucateDailyBalance) {
// update existing transactions so derived balance fields are
// correct.
- recalculateDailyBalances(Money.zero(this.currency),
accountCloseDate, backdatedTxnsAllowedTill);
+ recalculateDailyBalances(Money.zero(this.currency),
accountCloseDate, backdatedTxnsAllowedTill, postReversals);
}
this.summary.updateSummary(this.currency,
this.savingsAccountTransactionSummaryWrapper, this.transactions);
this.accountTermAndPreClosure.updateMaturityDetails(this.getAccountBalance(),
accountCloseDate);
@@ -651,10 +654,10 @@ public class FixedDepositAccount extends SavingsAccount {
@Override
public List<PostingPeriod> calculateInterestUsing(final MathContext mc,
final LocalDate postingDate, boolean isInterestTransfer,
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final
Integer financialYearBeginningMonth,
- final LocalDate postAsInterestOn, final boolean
backdatedTxnsAllowedTill) {
+ final LocalDate postAsInterestOn, final boolean
backdatedTxnsAllowedTill, final boolean postReversals) {
final LocalDate interestPostingUpToDate =
interestPostingUpToDate(postingDate);
return super.calculateInterestUsing(mc, interestPostingUpToDate,
isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
- financialYearBeginningMonth, postAsInterestOn,
backdatedTxnsAllowedTill);
+ financialYearBeginningMonth, postAsInterestOn,
backdatedTxnsAllowedTill, postReversals);
}
private LocalDate interestPostingUpToDate(final LocalDate
interestPostingDate) {
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/RecurringDepositAccount.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/RecurringDepositAccount.java
index 6d87fee26..cd28932d4 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/RecurringDepositAccount.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/RecurringDepositAccount.java
@@ -382,6 +382,7 @@ public class RecurringDepositAccount extends SavingsAccount
{
latestTransactionDate = installment.getTransactionLocalDate();
}
}
+ String refNo = null;
if (generateFutureTransactions) {
for (RecurringDepositScheduleInstallment installment :
depositScheduleInstallments()) {
if (installment.isPrincipalNotCompleted(getCurrency())) {
@@ -391,7 +392,7 @@ public class RecurringDepositAccount extends SavingsAccount
{
}
final SavingsAccountTransaction transaction =
SavingsAccountTransaction.deposit(null, office(), null, dueDate,
installment.getDepositAmountOutstanding(getCurrency()),
-
Date.from(installment.dueDate().atStartOfDay(ZoneId.systemDefault()).toInstant()),
null);
+
Date.from(installment.dueDate().atStartOfDay(ZoneId.systemDefault()).toInstant()),
null, refNo);
allTransactions.add(transaction);
}
}
@@ -542,14 +543,16 @@ public class RecurringDepositAccount extends
SavingsAccount {
protected void processAccountUponActivation(final DateTimeFormatter fmt,
final AppUser user) {
final Money minRequiredOpeningBalance = Money.of(this.currency,
this.minRequiredOpeningBalance);
final boolean backdatedTxnsAllowedTill = false;
+ String refNo = null;
if (minRequiredOpeningBalance.isGreaterThanZero()) {
final SavingsAccountTransactionDTO transactionDTO = new
SavingsAccountTransactionDTO(fmt, getActivationLocalDate(),
minRequiredOpeningBalance.getAmount(), null, new Date(),
user, accountType);
- deposit(transactionDTO, backdatedTxnsAllowedTill);
+ deposit(transactionDTO, backdatedTxnsAllowedTill, refNo);
// update existing transactions so derived balance fields are
// correct.
- recalculateDailyBalances(Money.zero(this.currency),
DateUtils.getBusinessLocalDate(), backdatedTxnsAllowedTill);
+ boolean postReversals = false;
+ recalculateDailyBalances(Money.zero(this.currency),
DateUtils.getBusinessLocalDate(), backdatedTxnsAllowedTill, postReversals);
}
}
@@ -644,8 +647,10 @@ public class RecurringDepositAccount extends
SavingsAccount {
boolean isInterestTransfer = false;
LocalDate postInterestOnDate = null;
final boolean backdatedTxnsAllowedTill = false;
+ boolean postReversals = false;
final List<PostingPeriod> postingPeriods = calculateInterestUsing(mc,
interestPostingUpToDate.minusDays(1), isInterestTransfer,
- isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestOnDate, backdatedTxnsAllowedTill);
+ isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestOnDate, backdatedTxnsAllowedTill,
+ postReversals);
Money interestPostedToDate = Money.zero(this.currency);
@@ -681,7 +686,7 @@ public class RecurringDepositAccount extends SavingsAccount
{
if (recalucateDailyBalanceDetails) {
// update existing transactions so derived balance fields are
// correct.
- recalculateDailyBalances(Money.zero(this.currency),
interestPostingUpToDate, backdatedTxnsAllowedTill);
+ recalculateDailyBalances(Money.zero(this.currency),
interestPostingUpToDate, backdatedTxnsAllowedTill, postReversals);
}
this.summary.updateSummary(this.currency,
this.savingsAccountTransactionSummaryWrapper, this.transactions);
}
@@ -710,11 +715,11 @@ public class RecurringDepositAccount extends
SavingsAccount {
}
applyWithholdTaxForDepositAccounts(accountCloseDate,
recalucateDailyBalance, backdatedTxnsAllowedTill);
-
+ boolean postReversals = false;
if (recalucateDailyBalance) {
// update existing transactions so derived balance fields are
// correct.
- recalculateDailyBalances(Money.zero(this.currency),
accountCloseDate, backdatedTxnsAllowedTill);
+ recalculateDailyBalances(Money.zero(this.currency),
accountCloseDate, backdatedTxnsAllowedTill, postReversals);
}
this.summary.updateSummary(this.currency,
this.savingsAccountTransactionSummaryWrapper, this.transactions);
@@ -764,10 +769,10 @@ public class RecurringDepositAccount extends
SavingsAccount {
@Override
public List<PostingPeriod> calculateInterestUsing(final MathContext mc,
final LocalDate postingDate, boolean isInterestTransfer,
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final
Integer financialYearBeginningMonth,
- final LocalDate postAsInterestOn, final boolean
backdatedTxnsAllowedTill) {
+ final LocalDate postAsInterestOn, final boolean
backdatedTxnsAllowedTill, final boolean postReversals) {
final LocalDate interestPostingUpToDate =
interestPostingUpToDate(postingDate);
return super.calculateInterestUsing(mc, interestPostingUpToDate,
isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
- financialYearBeginningMonth, postAsInterestOn,
backdatedTxnsAllowedTill);
+ financialYearBeginningMonth, postAsInterestOn,
backdatedTxnsAllowedTill, postReversals);
}
private LocalDate interestPostingUpToDate(final LocalDate
interestPostingDate) {
@@ -839,7 +844,8 @@ public class RecurringDepositAccount extends SavingsAccount
{
}
@Override
- public SavingsAccountTransaction deposit(final
SavingsAccountTransactionDTO transactionDTO, final boolean
backdatedTxnsAllowedTill) {
+ public SavingsAccountTransaction deposit(final
SavingsAccountTransactionDTO transactionDTO, final boolean
backdatedTxnsAllowedTill,
+ final String refNo) {
if (isAccountMatured()) {
final String defaultUserMessage = "Transaction is not allowed.
Account is matured.";
@@ -877,7 +883,7 @@ public class RecurringDepositAccount extends SavingsAccount
{
throw new PlatformApiDataValidationException(dataValidationErrors);
}
- final SavingsAccountTransaction transaction =
super.deposit(transactionDTO, backdatedTxnsAllowedTill);
+ final SavingsAccountTransaction transaction =
super.deposit(transactionDTO, backdatedTxnsAllowedTill, refNo);
return transaction;
}
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 625f998f3..864840876 100644
---
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
@@ -514,7 +514,8 @@ public class SavingsAccount extends
AbstractPersistableCustom {
final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final
Integer financialYearBeginningMonth,
final LocalDate postInterestOnDate, final boolean
backdatedTxnsAllowedTill, final boolean postReversals) {
final List<PostingPeriod> postingPeriods = calculateInterestUsing(mc,
interestPostingUpToDate, isInterestTransfer,
- isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestOnDate, backdatedTxnsAllowedTill);
+ isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestOnDate, backdatedTxnsAllowedTill,
+ postReversals);
Money interestPostedToDate = Money.zero(this.currency);
@@ -628,7 +629,7 @@ public class SavingsAccount extends
AbstractPersistableCustom {
// update existing transactions so derived balance fields are
// correct.
- recalculateDailyBalances(openingAccountBalance,
interestPostingUpToDate, backdatedTxnsAllowedTill);
+ recalculateDailyBalances(openingAccountBalance,
interestPostingUpToDate, backdatedTxnsAllowedTill, postReversals);
}
if (!backdatedTxnsAllowedTill) {
@@ -654,7 +655,7 @@ public class SavingsAccount extends
AbstractPersistableCustom {
final List<SavingsAccountTransaction> withholdTransactions = new
ArrayList<>();
List<SavingsAccountTransaction> trans =
getSavingsAccountTransactionsWithPivotConfig();
for (final SavingsAccountTransaction transaction : trans) {
- if (transaction.isWithHoldTaxAndNotReversed()) {
+ if (transaction.isWithHoldTaxAndNotReversed() &&
!transaction.isReversalTransaction()) {
withholdTransactions.add(transaction);
}
}
@@ -670,7 +671,7 @@ public class SavingsAccount extends
AbstractPersistableCustom {
List<SavingsAccountTransaction> trans = getTransactions();
for (final SavingsAccountTransaction transaction : trans) {
if ((transaction.isInterestPostingAndNotReversed() ||
transaction.isOverdraftInterestAndNotReversed())
- && transaction.occursOn(postingDate)) {
+ && transaction.occursOn(postingDate) &&
!transaction.isReversalTransaction()) {
postingTransation = transaction;
break;
}
@@ -683,7 +684,7 @@ public class SavingsAccount extends
AbstractPersistableCustom {
List<SavingsAccountTransaction> trans =
getSavingsAccountTransactionsWithPivotConfig();
for (final SavingsAccountTransaction transaction : trans) {
if ((transaction.isInterestPostingAndNotReversed() ||
transaction.isOverdraftInterestAndNotReversed())
- && transaction.occursOn(postingDate)) {
+ && transaction.occursOn(postingDate) &&
!transaction.isReversalTransaction()) {
postingTransation = transaction;
break;
}
@@ -810,7 +811,7 @@ public class SavingsAccount extends
AbstractPersistableCustom {
public List<PostingPeriod> calculateInterestUsing(final MathContext mc,
final LocalDate upToInterestCalculationDate,
boolean isInterestTransfer, final boolean
isSavingsInterestPostingAtCurrentPeriodEnd, final Integer
financialYearBeginningMonth,
- final LocalDate postInterestOnDate, final boolean
backdatedTxnsAllowedTill) {
+ final LocalDate postInterestOnDate, final boolean
backdatedTxnsAllowedTill, final boolean postReversals) {
// no openingBalance concept supported yet but probably will to allow
// for migrations.
@@ -825,7 +826,8 @@ public class SavingsAccount extends
AbstractPersistableCustom {
// update existing transactions so derived balance fields are
// correct.
- recalculateDailyBalances(openingAccountBalance,
upToInterestCalculationDate, backdatedTxnsAllowedTill);
+
+ recalculateDailyBalances(openingAccountBalance,
upToInterestCalculationDate, backdatedTxnsAllowedTill, postReversals);
// 1. default to calculate interest based on entire history OR
// 2. determine latest 'posting period' and find interest credited to
@@ -931,7 +933,7 @@ public class SavingsAccount extends
AbstractPersistableCustom {
for (final SavingsAccountTransaction transaction :
listOfTransactionsSorted) {
if (!(transaction.isInterestPostingAndNotReversed() ||
transaction.isOverdraftInterestAndNotReversed())
- && transaction.isNotReversed()) {
+ && transaction.isNotReversed() &&
!transaction.isReversalTransaction()) {
orderedNonInterestPostingTransactions.add(transaction);
}
}
@@ -946,7 +948,7 @@ public class SavingsAccount extends
AbstractPersistableCustom {
for (final SavingsAccountTransaction transaction :
listOfTransactionsSorted) {
if (!(transaction.isInterestPostingAndNotReversed() ||
transaction.isOverdraftInterestAndNotReversed())
- && transaction.isNotReversed()) {
+ && transaction.isNotReversed() &&
!transaction.isReversalTransaction()) {
orderedNonInterestPostingTransactions.add(transaction);
}
}
@@ -972,7 +974,7 @@ public class SavingsAccount extends
AbstractPersistableCustom {
}
protected void recalculateDailyBalances(final Money openingAccountBalance,
final LocalDate interestPostingUpToDate,
- final boolean backdatedTxnsAllowedTill) {
+ final boolean backdatedTxnsAllowedTill, boolean postReversals) {
Money runningBalance = openingAccountBalance.copy();
@@ -1026,15 +1028,25 @@ public class SavingsAccount extends
AbstractPersistableCustom {
.add(SavingsAccountChargePaidBy.instance(accountTransaction,
x.getSavingsAccountCharge(), x.getAmount())));
accountTransaction.getSavingsAccountChargesPaid().addAll(newChargePaidBy);
}
+ SavingsAccountTransaction reversal = null;
transaction.reverse();
+ if (postReversals) {
+ reversal =
SavingsAccountTransaction.reversal(transaction);
+ }
if (overdraftAmount.isGreaterThanZero()) {
accountTransaction.updateOverdraftAmount(overdraftAmount.getAmount());
}
// accountTransaction.updateRunningBalance(runningBalance);
if (backdatedTxnsAllowedTill) {
addTransactionToExisting(accountTransaction);
+ if (reversal != null) {
+ addTransactionToExisting(reversal);
+ }
} else {
addTransaction(accountTransaction);
+ if (reversal != null) {
+ addTransaction(reversal);
+ }
}
isTransactionsModified = true;
}
@@ -1058,7 +1070,7 @@ public class SavingsAccount extends
AbstractPersistableCustom {
LocalDate endOfBalanceDate = interestPostingUpToDate;
for (int i = accountTransactionsSorted.size() - 1; i >= 0; i--) {
final SavingsAccountTransaction transaction =
accountTransactionsSorted.get(i);
- if (transaction.isNotReversed()
+ if (transaction.isNotReversed() &&
!transaction.isReversalTransaction()
&& !(transaction.isInterestPostingAndNotReversed() ||
transaction.isOverdraftInterestAndNotReversed())) {
transaction.updateCumulativeBalanceAndDates(this.currency,
endOfBalanceDate);
// this transactions transaction date is end of balance date
for
@@ -1068,17 +1080,19 @@ public class SavingsAccount extends
AbstractPersistableCustom {
}
}
- public SavingsAccountTransaction deposit(final
SavingsAccountTransactionDTO transactionDTO, final boolean
backdatedTxnsAllowedTill) {
- return deposit(transactionDTO, SavingsAccountTransactionType.DEPOSIT,
backdatedTxnsAllowedTill);
+ public SavingsAccountTransaction deposit(final
SavingsAccountTransactionDTO transactionDTO, final boolean
backdatedTxnsAllowedTill,
+ final String refNo) {
+ return deposit(transactionDTO, SavingsAccountTransactionType.DEPOSIT,
backdatedTxnsAllowedTill, refNo);
}
public SavingsAccountTransaction dividendPayout(final
SavingsAccountTransactionDTO transactionDTO,
final boolean backdatedTxnsAllowedTill) {
- return deposit(transactionDTO,
SavingsAccountTransactionType.DIVIDEND_PAYOUT, backdatedTxnsAllowedTill);
+ String refNo = null;
+ return deposit(transactionDTO,
SavingsAccountTransactionType.DIVIDEND_PAYOUT, backdatedTxnsAllowedTill, refNo);
}
public SavingsAccountTransaction deposit(final
SavingsAccountTransactionDTO transactionDTO,
- final SavingsAccountTransactionType savingsAccountTransactionType,
final boolean backdatedTxnsAllowedTill) {
+ final SavingsAccountTransactionType savingsAccountTransactionType,
final boolean backdatedTxnsAllowedTill, final String refNo) {
final String resourceTypeName = depositAccountType().resourceName();
if (isNotActive()) {
final String defaultUserMessage = "Transaction is not allowed.
Account is not active.";
@@ -1122,7 +1136,7 @@ public class SavingsAccount extends
AbstractPersistableCustom {
final SavingsAccountTransaction transaction =
SavingsAccountTransaction.deposit(this, office(),
transactionDTO.getPaymentDetail(),
transactionDTO.getTransactionDate(), amount,
transactionDTO.getCreatedDate(), transactionDTO.getAppUser(),
- savingsAccountTransactionType);
+ savingsAccountTransactionType, refNo);
if (backdatedTxnsAllowedTill) {
addTransactionToExisting(transaction);
@@ -1251,6 +1265,10 @@ public class SavingsAccount extends
AbstractPersistableCustom {
||
this.sub_status.equals(SavingsAccountSubStatusEnum.DORMANT.getValue())) {
this.sub_status = SavingsAccountSubStatusEnum.NONE.getValue();
}
+ if (backdatedTxnsAllowedTill) {
+ this.summary.updateSummaryWithPivotConfig(this.currency,
this.savingsAccountTransactionSummaryWrapper, transaction,
+ this.savingsAccountTransactions);
+ }
return transaction;
}
@@ -1375,7 +1393,7 @@ public class SavingsAccount extends
AbstractPersistableCustom {
if (!backdatedTxnsAllowedTill) {
for (final SavingsAccountTransaction transaction :
retreiveListOfTransactions()) {
if ((transaction.isInterestPostingAndNotReversed() ||
transaction.isOverdraftInterestAndNotReversed())
- && transaction.isAfter(transactionDate)) {
+ && transaction.isAfter(transactionDate) &&
!transaction.isReversalTransaction()) {
transactionBeforeLastInterestPosting = true;
break;
}
@@ -2760,15 +2778,15 @@ public class SavingsAccount extends
AbstractPersistableCustom {
final MathContext mc = MathContext.DECIMAL64;
boolean isInterestTransfer = false;
LocalDate postInterestAsOnDate = null;
+ boolean postReversals = false;
if (this.isBeforeLastPostingPeriod(getActivationLocalDate(),
backdatedTxnsAllowedTill)) {
final LocalDate today = DateUtils.getBusinessLocalDate();
- boolean postReversals = false;
this.postInterest(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestAsOnDate, backdatedTxnsAllowedTill,
postReversals);
} else {
final LocalDate today = DateUtils.getBusinessLocalDate();
this.calculateInterestUsing(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd,
- financialYearBeginningMonth, postInterestAsOnDate,
backdatedTxnsAllowedTill);
+ financialYearBeginningMonth, postInterestAsOnDate,
backdatedTxnsAllowedTill, postReversals);
}
}
}
@@ -3513,7 +3531,8 @@ public class SavingsAccount extends
AbstractPersistableCustom {
refNo.toString());
}
}
- recalculateDailyBalances(Money.zero(this.currency), transactionDate,
backdatedTxnsAllowedTill);
+ boolean postReversals = false;
+ recalculateDailyBalances(Money.zero(this.currency), transactionDate,
backdatedTxnsAllowedTill, postReversals);
this.summary.updateSummary(this.currency,
this.savingsAccountTransactionSummaryWrapper, this.transactions);
}
@@ -3532,7 +3551,8 @@ public class SavingsAccount extends
AbstractPersistableCustom {
SavingsAccountTransaction transaction =
SavingsAccountTransaction.escheat(this, transactionDate, appUser,
postInterestAsOnDate);
this.transactions.add(transaction);
}
- recalculateDailyBalances(Money.zero(this.currency), transactionDate,
false);
+ boolean postReversals = false;
+ recalculateDailyBalances(Money.zero(this.currency), transactionDate,
false, postReversals);
this.summary.updateSummary(this.currency,
this.savingsAccountTransactionSummaryWrapper, this.transactions);
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountAssembler.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountAssembler.java
index de98a78e3..f5418f3a9 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountAssembler.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountAssembler.java
@@ -361,6 +361,11 @@ public class SavingsAccountAssembler {
// Update transient variable
account.setSavingsAccountTransactions(savingsAccountTransactions);
}
+ // Update last running balance on account level
+ if (savingsAccountTransactions != null &&
!savingsAccountTransactions.isEmpty()) {
+
account.getSummary().setRunningBalanceOnPivotDate(savingsAccountTransactions.get(savingsAccountTransactions.size()
- 1)
+
.getRunningBalance(account.getCurrency()).getAmount());
+ }
} else {
savingsAccountTransactions =
this.savingsAccountRepository.findAllTransactions(account);
account.setSavingsAccountTransactions(savingsAccountTransactions);
@@ -368,10 +373,11 @@ public class SavingsAccountAssembler {
}
// Update last running balance on account level
- if (savingsAccountTransactions != null) {
-
account.getSummary().setRunningBalanceOnPivotDate(savingsAccountTransactions.get(savingsAccountTransactions.size()
- 1)
- .getRunningBalance(account.getCurrency()).getAmount());
- }
+ // if (savingsAccountTransactions != null &&
!savingsAccountTransactions.isEmpty()) {
+ //
account.getSummary().setRunningBalanceOnPivotDate(savingsAccountTransactions.get(savingsAccountTransactions.size()
+ // - 1)
+ // .getRunningBalance(account.getCurrency()).getAmount());
+ // }
account.setHelpers(this.savingsAccountTransactionSummaryWrapper,
this.savingsHelper);
return account;
@@ -380,7 +386,8 @@ public class SavingsAccountAssembler {
public SavingsAccountData assembleSavings(final SavingsAccountData
account) {
// Update last running balance on account level
- if (account.getTransactions() != null &&
account.getTransactions().size() != 0) {
+ if (account.getTransactions() != null &&
account.getTransactions().size() != 0
+ && account.getSummary().getInterestPostedTillDate() != null) {
account.getSummary().setRunningBalanceOnPivotDate(account.getTransactions().get(account.getTransactions().size()
- 1)
.getRunningBalance(account.getCurrency()).getAmount());
}
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 29dbc4ce7..142605ee1 100644
---
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
@@ -115,13 +115,14 @@ public class SavingsAccountDomainServiceJpa implements
SavingsAccountDomainServi
final MathContext mc = MathContext.DECIMAL64;
final LocalDate today = DateUtils.getBusinessLocalDate();
+ boolean postReversals = false;
if (account.isBeforeLastPostingPeriod(transactionDate,
backdatedTxnsAllowedTill)) {
- boolean postReversals = false;
account.postInterest(mc, today,
transactionBooleanValues.isInterestTransfer(),
isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestOnDate,
backdatedTxnsAllowedTill, postReversals);
} else {
account.calculateInterestUsing(mc, today,
transactionBooleanValues.isInterestTransfer(),
- isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestOnDate, backdatedTxnsAllowedTill);
+ isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestOnDate, backdatedTxnsAllowedTill,
+ postReversals);
}
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions
= null;
@@ -191,18 +192,20 @@ public class SavingsAccountDomainServiceJpa implements
SavingsAccountDomainServi
Integer accountType = null;
final SavingsAccountTransactionDTO transactionDTO = new
SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
paymentDetail, new Date(), user, accountType);
- final SavingsAccountTransaction deposit =
account.deposit(transactionDTO, savingsAccountTransactionType,
backdatedTxnsAllowedTill);
+ UUID refNo = UUID.randomUUID();
+ final SavingsAccountTransaction deposit =
account.deposit(transactionDTO, savingsAccountTransactionType,
backdatedTxnsAllowedTill,
+ refNo.toString());
final LocalDate postInterestOnDate = null;
final MathContext mc = MathContext.DECIMAL64;
final LocalDate today = DateUtils.getBusinessLocalDate();
+ boolean postReversals = false;
if (account.isBeforeLastPostingPeriod(transactionDate,
backdatedTxnsAllowedTill)) {
- boolean postReversals = false;
account.postInterest(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestOnDate, backdatedTxnsAllowedTill,
postReversals);
} else {
account.calculateInterestUsing(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd,
- financialYearBeginningMonth, postInterestOnDate,
backdatedTxnsAllowedTill);
+ financialYearBeginningMonth, postInterestOnDate,
backdatedTxnsAllowedTill, postReversals);
}
saveTransactionToGenerateTransactionId(deposit);
@@ -316,20 +319,22 @@ public class SavingsAccountDomainServiceJpa implements
SavingsAccountDomainServi
final LocalDate today = DateUtils.getBusinessLocalDate();
final MathContext mc = new MathContext(15,
MoneyHelper.getRoundingMode());
for (SavingsAccountTransaction savingsAccountTransaction :
savingsAccountTransactions) {
+ boolean postReversals = true;
if (savingsAccountTransaction.isPostInterestCalculationRequired()
&&
account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate(),
backdatedTxnsAllowedTill)) {
- boolean postReversals = true;
+
account.postInterest(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestOnDate, backdatedTxnsAllowedTill,
postReversals);
} else {
account.calculateInterestUsing(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd,
- financialYearBeginningMonth, postInterestOnDate,
backdatedTxnsAllowedTill);
+ financialYearBeginningMonth, postInterestOnDate,
backdatedTxnsAllowedTill, postReversals);
}
account.validateAccountBalanceDoesNotBecomeNegativeMinimal(savingsAccountTransaction.getAmount(),
false);
account.activateAccountBasedOnBalance();
}
this.savingsAccountRepository.save(account);
+
newTransactions.addAll(account.getSavingsAccountTransactionsWithPivotConfig());
this.savingsAccountTransactionRepository.saveAll(newTransactions);
postJournalEntries(account, existingTransactionIds,
existingReversedTransactionIds, false, backdatedTxnsAllowedTill);
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountSummary.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountSummary.java
index 82d105de1..a234186b6 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountSummary.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountSummary.java
@@ -113,7 +113,7 @@ public final class SavingsAccountSummary {
this.totalWithholdTax =
wrapper.calculateTotalWithholdTaxWithdrawal(currency, transactions);
// boolean isUpdated = false;
- updateRunningBalanceAndPivotDate(false, transactions, null, null,
currency);
+ updateRunningBalanceAndPivotDate(false, transactions, null, null,
null, currency);
this.accountBalance = Money.of(currency,
this.totalDeposits).plus(this.totalInterestPosted).minus(this.totalWithdrawals)
.minus(this.totalWithdrawalFees).minus(this.totalAnnualFees).minus(this.totalFeeCharge).minus(this.totalPenaltyCharge)
@@ -189,30 +189,53 @@ public final class SavingsAccountSummary {
}
} else {
// boolean isUpdated = false;
- Money interestTotal = Money.of(currency, this.totalInterestPosted);
- Money withHoldTaxTotal = Money.of(currency, this.totalWithholdTax);
-
+ Money interestTotal = Money.zero(currency);
+ Money withHoldTaxTotal = Money.zero(currency);
+ Money overdraftInterestTotal = Money.zero(currency);
+ this.totalDeposits = wrapper.calculateTotalDeposits(currency,
savingsAccountTransactions);
+ this.totalWithdrawals =
wrapper.calculateTotalWithdrawals(currency, savingsAccountTransactions);
+ this.totalWithdrawalFees =
wrapper.calculateTotalWithdrawalFees(currency, savingsAccountTransactions);
+ this.totalAnnualFees = wrapper.calculateTotalAnnualFees(currency,
savingsAccountTransactions);
+ this.totalFeeCharge = wrapper.calculateTotalFeesCharge(currency,
savingsAccountTransactions);
+ this.totalPenaltyCharge =
wrapper.calculateTotalPenaltyCharge(currency, savingsAccountTransactions);
+ this.totalFeeChargesWaived =
wrapper.calculateTotalFeesChargeWaived(currency, savingsAccountTransactions);
+ this.totalPenaltyChargesWaived =
wrapper.calculateTotalPenaltyChargeWaived(currency, savingsAccountTransactions);
final HashMap<String, Money> map =
updateRunningBalanceAndPivotDate(true, savingsAccountTransactions,
interestTotal,
- withHoldTaxTotal, currency);
+ overdraftInterestTotal, withHoldTaxTotal, currency);
interestTotal = map.get("interestTotal");
withHoldTaxTotal = map.get("withHoldTax");
+ overdraftInterestTotal = map.get("overdraftInterestTotal");
this.totalInterestPosted =
interestTotal.getAmountDefaultedToNullIfZero();
+ this.totalOverdraftInterestDerived =
overdraftInterestTotal.getAmountDefaultedToNullIfZero();
this.totalWithholdTax =
withHoldTaxTotal.getAmountDefaultedToNullIfZero();
- this.accountBalance = Money.of(currency,
this.accountBalance).plus(this.totalInterestPosted).minus(this.totalWithholdTax)
- .getAmount();
+ this.accountBalance = Money.of(currency,
this.totalDeposits).plus(this.totalInterestPosted).minus(this.totalWithdrawals)
+
.minus(this.totalWithdrawalFees).minus(this.totalAnnualFees).minus(this.totalFeeCharge).minus(this.totalPenaltyCharge)
+
.minus(this.totalOverdraftInterestDerived).minus(totalWithholdTax).getAmount();
+ // this.accountBalance = Money.of(currency,
+ //
this.accountBalance).plus(this.totalInterestPosted).minus(this.totalWithholdTax)
+ // .getAmount();
}
}
@SuppressWarnings("unchecked")
private HashMap<String, Money> updateRunningBalanceAndPivotDate(final
boolean backdatedTxnsAllowedTill,
- final List<SavingsAccountTransaction> savingsAccountTransactions,
Money interestTotal, Money withHoldTaxTotal,
- MonetaryCurrency currency) {
+ final List<SavingsAccountTransaction> savingsAccountTransactions,
Money interestTotal, Money overdraftInterestTotal,
+ Money withHoldTaxTotal, MonetaryCurrency currency) {
boolean isUpdated = false;
HashMap<String, Money> map = new HashMap<>();
for (int i = savingsAccountTransactions.size() - 1; i >= 0; i--) {
final SavingsAccountTransaction savingsAccountTransaction =
savingsAccountTransactions.get(i);
- if (savingsAccountTransaction.isInterestPostingAndNotReversed() &&
savingsAccountTransaction.isNotReversed()
- && !savingsAccountTransaction.isReversalTransaction() &&
!isUpdated) {
+ if (savingsAccountTransaction.isInterestPostingAndNotReversed() &&
!savingsAccountTransaction.isReversalTransaction()
+ && !isUpdated) {
+
setRunningBalanceOnPivotDate(savingsAccountTransaction.getRunningBalance(currency).getAmount());
+
setInterestPostedTillDate(savingsAccountTransaction.getLastTransactionDate());
+ isUpdated = true;
+ if (!backdatedTxnsAllowedTill) {
+ break;
+ }
+ }
+ if (savingsAccountTransaction.isOverdraftInterestAndNotReversed()
&& !savingsAccountTransaction.isReversalTransaction()
+ && !isUpdated) {
setRunningBalanceOnPivotDate(savingsAccountTransaction.getRunningBalance(currency).getAmount());
setInterestPostedTillDate(savingsAccountTransaction.getLastTransactionDate());
isUpdated = true;
@@ -225,8 +248,10 @@ public final class SavingsAccountSummary {
&& !savingsAccountTransaction.isReversalTransaction())
{
interestTotal =
interestTotal.plus(savingsAccountTransaction.getAmount(currency));
}
-
- if (savingsAccountTransaction.isWithHoldTaxAndNotReversed()) {
+ if
(savingsAccountTransaction.isOverdraftInterestAndNotReversed() &&
!savingsAccountTransaction.isReversalTransaction()) {
+ overdraftInterestTotal =
overdraftInterestTotal.plus(savingsAccountTransaction.getAmount());
+ }
+ if (savingsAccountTransaction.isWithHoldTaxAndNotReversed() &&
!savingsAccountTransaction.isReversalTransaction()) {
withHoldTaxTotal =
withHoldTaxTotal.plus(savingsAccountTransaction.getAmount(currency));
}
}
@@ -234,6 +259,7 @@ public final class SavingsAccountSummary {
if (backdatedTxnsAllowedTill) {
map.put("interestTotal", interestTotal);
map.put("withHoldTax", withHoldTaxTotal);
+ map.put("overdraftInterestTotal", overdraftInterestTotal);
}
return map;
}
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 3362d4ebe..861aa465a 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
@@ -153,22 +153,21 @@ public final class SavingsAccountTransaction extends
AbstractPersistableCustom {
}
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 String refNo) {
final boolean isReversed = false;
final boolean isManualTransaction = false;
final Boolean lienTransaction = false;
- final String refNo = null;
return new SavingsAccountTransaction(savingsAccount, office,
paymentDetail, SavingsAccountTransactionType.DEPOSIT.getValue(), date,
createdDate, amount, isReversed, appUser, isManualTransaction,
lienTransaction, refNo);
}
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 SavingsAccountTransactionType savingsAccountTransactionType,
final String refNo) {
final boolean isReversed = false;
final boolean isManualTransaction = false;
final Boolean lienTransaction = false;
- final String refNo = null;
return new SavingsAccountTransaction(savingsAccount, office,
paymentDetail, savingsAccountTransactionType.getValue(), date,
createdDate, amount, isReversed, appUser, isManualTransaction,
lienTransaction, refNo);
}
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 c7667bb1c..353070900 100644
---
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
@@ -239,6 +239,7 @@ public class
DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
}
final boolean isInterestTransfer = false;
final LocalDate postInterestOnDate = null;
+ final boolean postReversals = false;
if (activationChargeAmount.isGreaterThanZero()) {
payActivationCharge(account, user);
}
@@ -249,7 +250,7 @@ public class
DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
} else {
final LocalDate today = DateUtils.getBusinessLocalDate();
account.calculateInterestUsing(mc, today,
isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
- financialYearBeginningMonth, postInterestOnDate,
false);
+ financialYearBeginningMonth, postInterestOnDate,
false, postReversals);
}
updateExistingTransactionsDetails(account,
existingTransactionIds, existingReversedTransactionIds);
@@ -366,6 +367,7 @@ public class
DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
account.updateOverduePayments(overdueUptoDate);
final boolean isInterestTransfer = false;
final LocalDate postInterestOnDate = null;
+ boolean postReversals = false;
if
(account.isBeforeLastPostingPeriod(account.getActivationLocalDate(), false)) {
final LocalDate today = DateUtils.getBusinessLocalDate();
account.postInterest(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
@@ -373,7 +375,7 @@ public class
DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
} else {
final LocalDate today = DateUtils.getBusinessLocalDate();
account.calculateInterestUsing(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd,
- financialYearBeginningMonth, postInterestOnDate,
false);
+ financialYearBeginningMonth, postInterestOnDate,
false, postReversals);
}
List<DepositAccountOnHoldTransaction>
depositAccountOnHoldTransactions = null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) > 0) {
@@ -521,11 +523,12 @@ public class
DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
checkClientOrGroupActive(account);
final LocalDate today = DateUtils.getBusinessLocalDate();
+ boolean postReversals = false;
final MathContext mc = new MathContext(15,
MoneyHelper.getRoundingMode());
boolean isInterestTransfer = false;
LocalDate postInterestOnDate = null;
account.calculateInterestUsing(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd,
- financialYearBeginningMonth, postInterestOnDate, false);
+ financialYearBeginningMonth, postInterestOnDate, false,
postReversals);
this.savingAccountRepositoryWrapper.save(account);
@@ -643,13 +646,14 @@ public class
DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
boolean isInterestTransfer = false;
LocalDate postInterestOnDate = null;
checkClientOrGroupActive(account);
+ boolean postReversals = false;
if (savingsAccountTransaction.isPostInterestCalculationRequired()
&&
account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate(),
false)) {
account.postInterest(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestOnDate, false);
} else {
account.calculateInterestUsing(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd,
- financialYearBeginningMonth, postInterestOnDate, false);
+ financialYearBeginningMonth, postInterestOnDate, false,
postReversals);
}
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions
= null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) > 0) {
@@ -746,7 +750,7 @@ public class
DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
if (savingsAccountTransaction.isDeposit()) {
final SavingsAccountTransactionDTO transactionDTO = new
SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
paymentDetail, savingsAccountTransaction.createdDate(),
user, accountType);
- transaction = account.deposit(transactionDTO, false);
+ transaction = account.deposit(transactionDTO, false,
refNo.toString());
} else {
final SavingsAccountTransactionDTO transactionDTO = new
SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
paymentDetail, savingsAccountTransaction.createdDate(),
user, accountType);
@@ -755,13 +759,14 @@ public class
DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
final Long newtransactionId =
saveTransactionToGenerateTransactionId(transaction);
boolean isInterestTransfer = false;
final LocalDate postInterestOnDate = null;
+ boolean postReversals = false;
if (account.isBeforeLastPostingPeriod(transactionDate, false)
||
account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate(),
false)) {
account.postInterest(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestOnDate, false);
} else {
account.calculateInterestUsing(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd,
- financialYearBeginningMonth, postInterestOnDate, false);
+ financialYearBeginningMonth, postInterestOnDate, false,
postReversals);
}
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions
= null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) > 0) {
@@ -983,8 +988,9 @@ public class
DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
savingsAccount.setStatus(SavingsAccountStatusType.TRANSFER_IN_PROGRESS.getValue());
final MathContext mc = MathContext.DECIMAL64;
boolean isInterestTransfer = false;
+ boolean postReversals = false;
savingsAccount.calculateInterestUsing(mc, transferDate,
isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
- financialYearBeginningMonth, postInterestOnDate, false);
+ financialYearBeginningMonth, postInterestOnDate, false,
postReversals);
this.savingsAccountTransactionRepository.save(newTransferTransaction);
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
@@ -1014,11 +1020,12 @@ public class
DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
savingsAccount.office(), transferDate, user);
savingsAccount.addTransaction(withdrawtransferTransaction);
savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue());
+ boolean postReversals = false;
final MathContext mc = MathContext.DECIMAL64;
boolean isInterestTransfer = false;
LocalDate postInterestOnDate = null;
savingsAccount.calculateInterestUsing(mc, transferDate,
isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
- financialYearBeginningMonth, postInterestOnDate, false);
+ financialYearBeginningMonth, postInterestOnDate, false,
postReversals);
this.savingsAccountTransactionRepository.save(withdrawtransferTransaction);
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
@@ -1059,10 +1066,11 @@ public class
DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
savingsAccount.reassignSavingsOfficer(fieldOfficer, transferDate);
}
boolean isInterestTransfer = false;
+ boolean postReversals = false;
LocalDate postInterestOnDate = null;
final MathContext mc = MathContext.DECIMAL64;
savingsAccount.calculateInterestUsing(mc, transferDate,
isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
- financialYearBeginningMonth, postInterestOnDate, false);
+ financialYearBeginningMonth, postInterestOnDate, false,
postReversals);
this.savingsAccountTransactionRepository.save(acceptTransferTransaction);
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
@@ -1215,15 +1223,15 @@ public class
DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
boolean isInterestTransfer = false;
LocalDate postInterestOnDate = null;
final MathContext mc = MathContext.DECIMAL64;
+ boolean postReversals = false;
if
(account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueLocalDate(),
false)) {
final LocalDate today = DateUtils.getBusinessLocalDate();
- boolean postReversals = false;
account.postInterest(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestOnDate, false, postReversals);
} else {
final LocalDate today = DateUtils.getBusinessLocalDate();
account.calculateInterestUsing(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd,
- financialYearBeginningMonth, postInterestOnDate, false);
+ financialYearBeginningMonth, postInterestOnDate, false,
postReversals);
}
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions
= null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) > 0) {
@@ -1355,15 +1363,15 @@ public class
DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
boolean isInterestTransfer = false;
LocalDate postInterestOnDate = null;
final MathContext mc = MathContext.DECIMAL64;
+ boolean postReversals = false;
if (account.isBeforeLastPostingPeriod(transactionDate, false)) {
final LocalDate today = DateUtils.getBusinessLocalDate();
- boolean postReversals = false;
account.postInterest(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestOnDate, false, postReversals);
} else {
final LocalDate today = DateUtils.getBusinessLocalDate();
account.calculateInterestUsing(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd,
- financialYearBeginningMonth, postInterestOnDate, false);
+ financialYearBeginningMonth, postInterestOnDate, false,
postReversals);
}
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions
= null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) > 0) {
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountInterestPostingServiceImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountInterestPostingServiceImpl.java
index 74a19d350..eed7393bb 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountInterestPostingServiceImpl.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountInterestPostingServiceImpl.java
@@ -422,11 +422,10 @@ public class SavingsAccountInterestPostingServiceImpl
implements SavingsAccountI
Money runningBalance = openingAccountBalance.copy();
List<SavingsAccountTransactionData> accountTransactionsSorted =
retreiveListOfTransactions(savingsAccountData);
-
boolean isTransactionsModified = false;
for (final SavingsAccountTransactionData transaction :
accountTransactionsSorted) {
- if (transaction.isReversed()) {
+ if (transaction.isReversed() ||
transaction.isReversalTransaction()) {
transaction.zeroBalanceFields();
} else {
Money overdraftAmount =
Money.zero(savingsAccountData.currency());
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java
index 6f9d473fc..d22c85534 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java
@@ -515,9 +515,9 @@ public class
SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final MathContext mc = new MathContext(15,
MoneyHelper.getRoundingMode());
boolean isInterestTransfer = false;
final LocalDate postInterestOnDate = null;
-
+ boolean postReversals = false;
account.calculateInterestUsing(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd,
- financialYearBeginningMonth, postInterestOnDate,
backdatedTxnsAllowedTill);
+ financialYearBeginningMonth, postInterestOnDate,
backdatedTxnsAllowedTill, postReversals);
if (backdatedTxnsAllowedTill) {
this.savingsAccountTransactionRepository.saveAll(account.getSavingsAccountTransactionsWithPivotConfig());
@@ -787,15 +787,15 @@ public class
SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
}
boolean isInterestTransfer = false;
LocalDate postInterestOnDate = null;
+ boolean postReversals = false;
checkClientOrGroupActive(account);
if (savingsAccountTransaction.isPostInterestCalculationRequired()
&&
account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate(),
false)) {
- boolean postReversals = false;
account.postInterest(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestOnDate, false, postReversals);
} else {
account.calculateInterestUsing(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd,
- financialYearBeginningMonth, postInterestOnDate, false);
+ financialYearBeginningMonth, postInterestOnDate, false,
postReversals);
}
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions
= null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) > 0) {
@@ -882,22 +882,22 @@ public class
SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
Integer accountType = null;
final SavingsAccountTransactionDTO transactionDTO = new
SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
paymentDetail, savingsAccountTransaction.createdDate(), user,
accountType);
+ UUID refNo = UUID.randomUUID();
if (savingsAccountTransaction.isDeposit()) {
- transaction = account.deposit(transactionDTO, false);
+ transaction = account.deposit(transactionDTO, false,
refNo.toString());
} else {
- UUID refNo = UUID.randomUUID();
transaction = account.withdraw(transactionDTO, true, false,
refNo.toString());
}
final Long newtransactionId =
saveTransactionToGenerateTransactionId(transaction);
final LocalDate postInterestOnDate = null;
+ boolean postReversals = false;
if (account.isBeforeLastPostingPeriod(transactionDate, false)
||
account.isBeforeLastPostingPeriod(savingsAccountTransaction.transactionLocalDate(),
false)) {
- boolean postReversals = false;
account.postInterest(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestOnDate, false, postReversals);
} else {
account.calculateInterestUsing(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd,
- financialYearBeginningMonth, postInterestOnDate, false);
+ financialYearBeginningMonth, postInterestOnDate, false,
postReversals);
}
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions
= null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) > 0) {
@@ -1079,8 +1079,9 @@ public class
SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final MathContext mc = MathContext.DECIMAL64;
boolean isInterestTransfer = false;
LocalDate postInterestOnDate = null;
+ boolean postReversals = false;
savingsAccount.calculateInterestUsing(mc, transferDate,
isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
- financialYearBeginningMonth, postInterestOnDate, false);
+ financialYearBeginningMonth, postInterestOnDate, false,
postReversals);
this.savingsAccountTransactionRepository.save(newTransferTransaction);
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
@@ -1110,8 +1111,9 @@ public class
SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final MathContext mc = MathContext.DECIMAL64;
boolean isInterestTransfer = false;
LocalDate postInterestOnDate = null;
+ boolean postReversals = false;
savingsAccount.calculateInterestUsing(mc, transferDate,
isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
- financialYearBeginningMonth, postInterestOnDate, false);
+ financialYearBeginningMonth, postInterestOnDate, false,
postReversals);
this.savingsAccountTransactionRepository.save(withdrawtransferTransaction);
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
@@ -1152,8 +1154,9 @@ public class
SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
boolean isInterestTransfer = false;
final MathContext mc = MathContext.DECIMAL64;
LocalDate postInterestOnDate = null;
+ boolean postReversals = false;
savingsAccount.calculateInterestUsing(mc, transferDate,
isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
- financialYearBeginningMonth, postInterestOnDate, false);
+ financialYearBeginningMonth, postInterestOnDate, false,
postReversals);
this.savingsAccountTransactionRepository.save(acceptTransferTransaction);
this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount);
@@ -1322,15 +1325,15 @@ public class
SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
boolean isInterestTransfer = false;
LocalDate postInterestOnDate = null;
final MathContext mc = MathContext.DECIMAL64;
+ boolean postReversals = false;
if
(account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueLocalDate(),
backdatedTxnsAllowedTill)) {
final LocalDate today = DateUtils.getBusinessLocalDate();
- boolean postReversals = false;
account.postInterest(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestOnDate, backdatedTxnsAllowedTill,
postReversals);
} else {
final LocalDate today = DateUtils.getBusinessLocalDate();
account.calculateInterestUsing(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd,
- financialYearBeginningMonth, postInterestOnDate,
backdatedTxnsAllowedTill);
+ financialYearBeginningMonth, postInterestOnDate,
backdatedTxnsAllowedTill, postReversals);
}
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions
= null;
@@ -1475,15 +1478,15 @@ public class
SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
boolean isInterestTransfer = false;
LocalDate postInterestOnDate = null;
final MathContext mc = MathContext.DECIMAL64;
+ boolean postReversals = false;
if (account.isBeforeLastPostingPeriod(transactionDate,
backdatedTxnsAllowedTill)) {
final LocalDate today = DateUtils.getBusinessLocalDate();
- boolean postReversals = false;
account.postInterest(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
postInterestOnDate, isInterestTransfer, postReversals);
} else {
final LocalDate today = DateUtils.getBusinessLocalDate();
account.calculateInterestUsing(mc, today, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd,
- financialYearBeginningMonth, postInterestOnDate,
backdatedTxnsAllowedTill);
+ financialYearBeginningMonth, postInterestOnDate,
backdatedTxnsAllowedTill, postReversals);
}
List<DepositAccountOnHoldTransaction> depositAccountOnHoldTransactions
= null;
if (account.getOnHoldFunds().compareTo(BigDecimal.ZERO) > 0) {
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularInterestPoster.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularInterestPoster.java
index fda525233..57c6797d6 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularInterestPoster.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularInterestPoster.java
@@ -253,14 +253,20 @@ public class SavingsSchedularInterestPoster implements
Callable<Void> {
List<String> transRefNo = new ArrayList<>();
for (SavingsAccountData savingsAccountData : savingsAccountDataList) {
SavingsAccountSummaryData savingsAccountSummaryData =
savingsAccountData.getSummary();
- paramsForSavingsSummary
- .add(new Object[] {
savingsAccountSummaryData.getTotalDeposits(),
savingsAccountSummaryData.getTotalWithdrawals(),
-
savingsAccountSummaryData.getTotalInterestEarned(),
savingsAccountSummaryData.getTotalInterestPosted(),
-
savingsAccountSummaryData.getTotalWithdrawalFees(),
savingsAccountSummaryData.getTotalFeeCharge(),
- savingsAccountSummaryData.getTotalPenaltyCharge(),
savingsAccountSummaryData.getTotalAnnualFees(),
- savingsAccountSummaryData.getAccountBalance(),
savingsAccountSummaryData.getTotalOverdraftInterestDerived(),
- savingsAccountSummaryData.getTotalWithholdTax(),
savingsAccountSummaryData.getLastInterestCalculationDate(),
-
savingsAccountSummaryData.getInterestPostedTillDate(),
savingsAccountData.getId() });
+ paramsForSavingsSummary.add(new Object[] {
savingsAccountSummaryData.getTotalDeposits(),
+ savingsAccountSummaryData.getTotalWithdrawals(),
savingsAccountSummaryData.getTotalInterestEarned(),
+ savingsAccountSummaryData.getTotalInterestPosted(),
savingsAccountSummaryData.getTotalWithdrawalFees(),
+ savingsAccountSummaryData.getTotalFeeCharge(),
savingsAccountSummaryData.getTotalPenaltyCharge(),
+ savingsAccountSummaryData.getTotalAnnualFees(),
savingsAccountSummaryData.getAccountBalance(),
+
savingsAccountSummaryData.getTotalOverdraftInterestDerived(),
savingsAccountSummaryData.getTotalWithholdTax(),
+
Date.from(savingsAccountSummaryData.getLastInterestCalculationDate().atStartOfDay(DateUtils.getDateTimeZoneOfTenant())
+ .toInstant()),
+ savingsAccountSummaryData.getInterestPostedTillDate() !=
null
+ ?
Date.from(savingsAccountSummaryData.getInterestPostedTillDate()
+
.atStartOfDay(DateUtils.getDateTimeZoneOfTenant()).toInstant())
+ :
Date.from(savingsAccountSummaryData.getLastInterestCalculationDate()
+
.atStartOfDay(DateUtils.getDateTimeZoneOfTenant()).toInstant()),
+ savingsAccountData.getId() });
List<SavingsAccountTransactionData>
savingsAccountTransactionDataList =
savingsAccountData.getSavingsAccountTransactionData();
for (SavingsAccountTransactionData savingsAccountTransactionData :
savingsAccountTransactionDataList) {
if (savingsAccountTransactionData.getId() == null) {
@@ -287,7 +293,7 @@ public class SavingsSchedularInterestPoster implements
Callable<Void> {
if (transRefNo.size() > 0) {
this.jdbcTemplate.batchUpdate(queryForSavingsUpdate,
paramsForSavingsSummary);
this.jdbcTemplate.batchUpdate(queryForTransactionInsertion,
paramsForTransactionInsertion);
-
+ LOG.info("`Total No Of Interest Posting:` {}", transRefNo.size());
List<SavingsAccountTransactionData>
savingsAccountTransactionDataList = fetchTransactionsFromIds(transRefNo);
if (savingsAccountDataList != null) {
LOG.info("Fetched Transactions from DB: {}",
savingsAccountTransactionDataList.size());
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientSavingsIntegrationTest.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientSavingsIntegrationTest.java
index 7a85e0a88..f0512f740 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientSavingsIntegrationTest.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientSavingsIntegrationTest.java
@@ -52,6 +52,7 @@ import
org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper;
import
org.apache.fineract.integrationtests.common.savings.SavingsProductHelper;
import
org.apache.fineract.integrationtests.common.savings.SavingsStatusChecker;
import org.apache.fineract.portfolio.charge.domain.ChargeTimeType;
+import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -2815,4 +2816,59 @@ public class ClientSavingsIntegrationTest {
balance = Float.parseFloat("900.0");
assertEquals(balance, summary.get("accountBalance"), "Verifying
account balance is 900");
}
+
+ @Test
+ public void testAccountBalanceAndTransactionRunningBalanceWithConfigOn() {
+ this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec,
this.responseSpec);
+
GlobalConfigurationHelper.updateEnabledFlagForGlobalConfiguration(this.requestSpec,
this.responseSpec, "38", false);
+
GlobalConfigurationHelper.updateEnabledFlagForGlobalConfiguration(this.requestSpec,
this.responseSpec, "39", true);
+
GlobalConfigurationHelper.updateValueForGlobalConfiguration(requestSpec,
responseSpec, "39", "5");
+
+ final Integer clientID = ClientHelper.createClient(this.requestSpec,
this.responseSpec);
+ ClientHelper.verifyClientCreatedOnServer(this.requestSpec,
this.responseSpec, clientID);
+ final String minBalanceForInterestCalculation = null;
+ final String minRequiredBalance = "0";
+ final String enforceMinRequiredBalance = "false";
+ final boolean allowOverdraft = true;
+
+ final Integer savingsProductID =
createSavingsProduct(this.requestSpec, this.responseSpec, "0",
minBalanceForInterestCalculation,
+ minRequiredBalance, enforceMinRequiredBalance, allowOverdraft);
+ Assertions.assertNotNull(savingsProductID);
+
+ final Integer savingsId =
this.savingsAccountHelper.applyForSavingsApplication(clientID,
savingsProductID, ACCOUNT_TYPE_INDIVIDUAL);
+ Assertions.assertNotNull(savingsId);
+
+ HashMap savingsStatusHashMap =
this.savingsAccountHelper.approveSavings(savingsId);
+ SavingsStatusChecker.verifySavingsIsApproved(savingsStatusHashMap);
+
+ savingsStatusHashMap =
this.savingsAccountHelper.activateSavings(savingsId);
+ SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
+
+ // withdrawal transaction 1
+ Integer withdrawalTransactionId = (Integer)
this.savingsAccountHelper.withdrawalFromSavingsAccount(savingsId, "500",
+ SavingsAccountHelper.TRANSACTION_DATE,
CommonConstants.RESPONSE_RESOURCE_ID);
+ HashMap summary =
this.savingsAccountHelper.getSavingsSummary(savingsId);
+ Float balance = Float.parseFloat("-500.0");
+ assertEquals(balance, summary.get("accountBalance"), "Verifying
account balance is -500");
+
+ // withdrawal transaction 2
+ withdrawalTransactionId = (Integer)
this.savingsAccountHelper.withdrawalFromSavingsAccount(savingsId, "500",
+ SavingsAccountHelper.TRANSACTION_DATE,
CommonConstants.RESPONSE_RESOURCE_ID);
+ summary = this.savingsAccountHelper.getSavingsSummary(savingsId);
+ balance = Float.parseFloat("-1000.0");
+ assertEquals(balance, summary.get("accountBalance"), "Verifying
account balance is -1000");
+
+ // Check for last transactions running balance
+ Object transactionObj =
this.savingsAccountHelper.getSavingsDetails(savingsId, "transactions");
+ ArrayList<HashMap<String, Object>> transactions =
(ArrayList<HashMap<String, Object>>) transactionObj;
+ HashMap<String, Object> requestedTransaction =
transactions.get(transactions.size() - 2);
+ balance = Float.parseFloat("-1000.0");
+ assertEquals(balance.toString(),
requestedTransaction.get("runningBalance").toString(), "Equality check for
Balance");
+ }
+
+ @AfterEach
+ public void tearDown() {
+
GlobalConfigurationHelper.resetAllDefaultGlobalConfigurations(this.requestSpec,
this.responseSpec);
+
GlobalConfigurationHelper.verifyAllDefaultGlobalConfigurations(this.requestSpec,
this.responseSpec);
+ }
}