This is an automated email from the ASF dual-hosted git repository.
adamsaghy 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 4f2400ca3 FINERACT-2011: Savings Account - transaction order is
incorrectly mixed after certain activities
4f2400ca3 is described below
commit 4f2400ca3e63f58901fb68cebfae80a86a590c4b
Author: jmarta <[email protected]>
AuthorDate: Fri Nov 17 01:46:58 2023 +0100
FINERACT-2011: Savings Account - transaction order is incorrectly mixed
after certain activities
---
.../infrastructure/core/api/JsonCommand.java | 60 +-----
.../domain/GlobalConfigurationProperty.java | 5 +-
.../portfolio/savings/domain/SavingsAccount.java | 182 ++++++++--------
...countWritePlatformServiceJpaRepositoryImpl.java | 5 +-
.../ClientSavingsIntegrationTest.java | 50 -----
.../SavingsAccountRecalculateBalanceTest.java | 230 +++++++++++++++++++++
.../common/savings/SavingsAccountHelper.java | 34 ++-
.../savings/SavingsApplicationTestBuilder.java | 6 +-
8 files changed, 361 insertions(+), 211 deletions(-)
diff --git
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/api/JsonCommand.java
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/api/JsonCommand.java
index 07c6f0023..9d560ad83 100644
---
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/api/JsonCommand.java
+++
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/api/JsonCommand.java
@@ -32,11 +32,13 @@ import java.time.temporal.TemporalAccessor;
import java.util.Arrays;
import java.util.Locale;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.infrastructure.core.domain.ExternalId;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.infrastructure.core.service.MathUtil;
import
org.apache.fineract.infrastructure.security.domain.BasicPasswordEncodablePlatformUser;
import org.apache.fineract.infrastructure.security.domain.PlatformUser;
import
org.apache.fineract.infrastructure.security.service.PlatformPasswordEncoder;
@@ -268,27 +270,11 @@ public final class JsonCommand {
}
private boolean differenceExists(final TemporalAccessor baseValue, final
TemporalAccessor workingCopyValue) {
- boolean differenceExists = false;
-
- if (baseValue != null) {
- differenceExists = !baseValue.equals(workingCopyValue);
- } else {
- differenceExists = workingCopyValue != null;
- }
-
- return differenceExists;
+ return !Objects.equals(baseValue, workingCopyValue);
}
private boolean differenceExists(final String baseValue, final String
workingCopyValue) {
- boolean differenceExists = false;
-
- if (StringUtils.isNotBlank(baseValue)) {
- differenceExists = !baseValue.equals(workingCopyValue);
- } else {
- differenceExists = StringUtils.isNotBlank(workingCopyValue);
- }
-
- return differenceExists;
+ return !Objects.equals(baseValue, workingCopyValue);
}
private boolean differenceExists(final String[] baseValue, final String[]
workingCopyValue) {
@@ -298,47 +284,15 @@ public final class JsonCommand {
}
private boolean differenceExists(final Number baseValue, final Number
workingCopyValue) {
- boolean differenceExists = false;
-
- if (baseValue != null) {
- if (workingCopyValue != null) {
- differenceExists = !baseValue.equals(workingCopyValue);
- } else {
- differenceExists = true;
- }
- } else {
- differenceExists = workingCopyValue != null;
- }
-
- return differenceExists;
+ return !Objects.equals(baseValue, workingCopyValue);
}
private boolean differenceExists(final BigDecimal baseValue, final
BigDecimal workingCopyValue) {
- boolean differenceExists = false;
-
- if (baseValue != null) {
- if (workingCopyValue != null) {
- differenceExists = baseValue.compareTo(workingCopyValue) != 0;
- } else {
- differenceExists = true;
- }
- } else {
- differenceExists = workingCopyValue != null;
- }
-
- return differenceExists;
+ return !MathUtil.isEqualTo(baseValue, workingCopyValue);
}
private boolean differenceExists(final Boolean baseValue, final Boolean
workingCopyValue) {
- boolean differenceExists = false;
-
- if (baseValue != null) {
- differenceExists = !baseValue.equals(workingCopyValue);
- } else {
- differenceExists = workingCopyValue != null;
- }
-
- return differenceExists;
+ return !Objects.equals(baseValue, workingCopyValue);
}
public boolean parameterExists(final String parameterName) {
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/GlobalConfigurationProperty.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/GlobalConfigurationProperty.java
index 6b884573a..a38401d24 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/GlobalConfigurationProperty.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/GlobalConfigurationProperty.java
@@ -64,10 +64,9 @@ public class GlobalConfigurationProperty extends
AbstractPersistableCustom {
private boolean isTrapDoor;
public Map<String, Object> update(final JsonCommand command) {
-
final Map<String, Object> actualChanges = new LinkedHashMap<>(7);
- if (this.isTrapDoor == true) {
+ if (this.isTrapDoor) {
throw new GlobalConfigurationPropertyCannotBeModfied(this.getId());
}
@@ -109,7 +108,6 @@ public class GlobalConfigurationProperty extends
AbstractPersistableCustom {
}
return actualChanges;
-
}
public static GlobalConfigurationProperty newSurveyConfiguration(final
String name) {
@@ -120,6 +118,5 @@ public class GlobalConfigurationProperty extends
AbstractPersistableCustom {
return new
GlobalConfigurationPropertyData().setName(getName()).setEnabled(isEnabled()).setValue(getValue())
.setDateValue(getDateValue()).setStringValue(getStringValue()).setId(this.getId()).setDescription(this.description)
.setTrapDoor(this.isTrapDoor);
-
}
}
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 5abf3857e..61a067910 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
@@ -83,6 +83,7 @@ import
org.apache.fineract.infrastructure.core.domain.LocalDateInterval;
import
org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
+import org.apache.fineract.infrastructure.core.service.MathUtil;
import
org.apache.fineract.infrastructure.security.service.RandomPasswordGenerator;
import org.apache.fineract.interoperation.domain.InteropIdentifier;
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
@@ -510,6 +511,9 @@ public class SavingsAccount extends
AbstractAuditableWithUTCDateTimeCustom {
final List<PostingPeriod> postingPeriods = calculateInterestUsing(mc,
interestPostingUpToDate, isInterestTransfer,
isSavingsInterestPostingAtCurrentPeriodEnd,
financialYearBeginningMonth, postInterestOnDate, backdatedTxnsAllowedTill,
postReversals);
+ if (postingPeriods.isEmpty()) {
+ return;
+ }
Money interestPostedToDate = Money.zero(this.currency);
@@ -811,108 +815,102 @@ public class SavingsAccount extends
AbstractAuditableWithUTCDateTimeCustom {
boolean isInterestTransfer, final boolean
isSavingsInterestPostingAtCurrentPeriodEnd, final Integer
financialYearBeginningMonth,
final LocalDate postInterestOnDate, final boolean
backdatedTxnsAllowedTill, final boolean postReversals) {
- // no openingBalance concept supported yet but probably will to allow
- // for migrations.
- Money openingAccountBalance = null;
-
+ // no openingBalance concept supported yet but probably will to allow
for migrations.
// Check global configurations and 'pivot' date is null
- if (backdatedTxnsAllowedTill) {
- openingAccountBalance = Money.of(this.currency,
this.summary.getRunningBalanceOnPivotDate());
- } else {
- openingAccountBalance = Money.zero(this.currency);
- }
-
- // update existing transactions so derived balance fields are
- // correct.
+ Money openingAccountBalance = backdatedTxnsAllowedTill ?
Money.of(this.currency, this.summary.getRunningBalanceOnPivotDate())
+ : Money.zero(this.currency);
+ // update existing transactions so derived balance fields are correct.
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
- // that period
-
- // A generate list of EndOfDayBalances (not including interest
postings)
- final SavingsPostingInterestPeriodType postingPeriodType =
SavingsPostingInterestPeriodType.fromInt(this.interestPostingPeriodType);
-
- final SavingsCompoundingInterestPeriodType compoundingPeriodType =
SavingsCompoundingInterestPeriodType
- .fromInt(this.interestCompoundingPeriodType);
+ final List<PostingPeriod> allPostingPeriods = new ArrayList<>();
+ if (hasInterestCalculation() || hasOverdraftInterestCalculation()) {
+ // 1. default to calculate interest based on entire history OR
+ // 2. determine latest 'posting period' and find interest credited
to that period
- final SavingsInterestCalculationDaysInYearType daysInYearType =
SavingsInterestCalculationDaysInYearType
- .fromInt(this.interestCalculationDaysInYearType);
- List<LocalDate> postedAsOnDates = null;
- if (backdatedTxnsAllowedTill) {
- postedAsOnDates = getManualPostingDatesWithPivotConfig();
- } else {
- postedAsOnDates = getManualPostingDates();
- }
- if (postInterestOnDate != null) {
- postedAsOnDates.add(postInterestOnDate);
- }
- final List<LocalDateInterval> postingPeriodIntervals =
this.savingsHelper.determineInterestPostingPeriods(
- getStartInterestCalculationDate(),
upToInterestCalculationDate, postingPeriodType, financialYearBeginningMonth,
- postedAsOnDates);
+ // A generate list of EndOfDayBalances (not including interest
postings)
+ final SavingsPostingInterestPeriodType postingPeriodType =
SavingsPostingInterestPeriodType
+ .fromInt(this.interestPostingPeriodType);
- final List<PostingPeriod> allPostingPeriods = new ArrayList<>();
+ final SavingsCompoundingInterestPeriodType compoundingPeriodType =
SavingsCompoundingInterestPeriodType
+ .fromInt(this.interestCompoundingPeriodType);
- Money periodStartingBalance;
- if (this.startInterestCalculationDate != null &&
!this.getStartInterestCalculationDate().equals(this.getActivationDate())) {
- LocalDate startInterestCalculationDate =
this.startInterestCalculationDate;
- SavingsAccountTransaction transaction = null;
+ final SavingsInterestCalculationDaysInYearType daysInYearType =
SavingsInterestCalculationDaysInYearType
+ .fromInt(this.interestCalculationDaysInYearType);
+ List<LocalDate> postedAsOnDates = null;
if (backdatedTxnsAllowedTill) {
- transaction =
findLastFilteredTransactionWithPivotConfig(startInterestCalculationDate);
+ postedAsOnDates = getManualPostingDatesWithPivotConfig();
} else {
- transaction =
findLastTransaction(startInterestCalculationDate);
+ postedAsOnDates = getManualPostingDates();
+ }
+ if (postInterestOnDate != null) {
+ postedAsOnDates.add(postInterestOnDate);
}
+ final List<LocalDateInterval> postingPeriodIntervals =
this.savingsHelper.determineInterestPostingPeriods(
+ getStartInterestCalculationDate(),
upToInterestCalculationDate, postingPeriodType, financialYearBeginningMonth,
+ postedAsOnDates);
- if (transaction == null) {
- periodStartingBalance = Money.zero(this.currency);
+ Money periodStartingBalance;
+ if (this.startInterestCalculationDate != null &&
!this.getStartInterestCalculationDate().equals(this.getActivationDate())) {
+ LocalDate startInterestCalculationDate =
this.startInterestCalculationDate;
+ SavingsAccountTransaction transaction = null;
+ if (backdatedTxnsAllowedTill) {
+ transaction =
findLastFilteredTransactionWithPivotConfig(startInterestCalculationDate);
+ } else {
+ transaction =
findLastTransaction(startInterestCalculationDate);
+ }
+
+ if (transaction == null) {
+ periodStartingBalance = Money.zero(this.currency);
+ } else {
+ periodStartingBalance = Money.of(this.currency,
this.summary.getRunningBalanceOnPivotDate());
+ }
} else {
- periodStartingBalance = Money.of(this.currency,
this.summary.getRunningBalanceOnPivotDate());
+ periodStartingBalance = Money.zero(this.currency);
}
- } else {
- periodStartingBalance = Money.zero(this.currency);
- }
- final SavingsInterestCalculationType interestCalculationType =
SavingsInterestCalculationType.fromInt(this.interestCalculationType);
- final BigDecimal interestRateAsFraction =
getEffectiveInterestRateAsFraction(mc, upToInterestCalculationDate);
- final BigDecimal overdraftInterestRateAsFraction =
getEffectiveOverdraftInterestRateAsFraction(mc);
- final Collection<Long> interestPostTransactions =
this.savingsHelper.fetchPostInterestTransactionIds(getId());
- final Money minBalanceForInterestCalculation = Money.of(getCurrency(),
minBalanceForInterestCalculation());
- final Money minOverdraftForInterestCalculation =
Money.of(getCurrency(), this.minOverdraftForInterestCalculation);
+ final SavingsInterestCalculationType interestCalculationType =
SavingsInterestCalculationType
+ .fromInt(this.interestCalculationType);
+ final BigDecimal interestRateAsFraction =
getEffectiveInterestRateAsFraction(mc, upToInterestCalculationDate);
+ final BigDecimal overdraftInterestRateAsFraction =
getEffectiveOverdraftInterestRateAsFraction(mc);
+ final Collection<Long> interestPostTransactions =
this.savingsHelper.fetchPostInterestTransactionIds(getId());
+ final Money minBalanceForInterestCalculation =
Money.of(getCurrency(), minBalanceForInterestCalculation());
+ final Money minOverdraftForInterestCalculation =
Money.of(getCurrency(), this.minOverdraftForInterestCalculation);
- for (final LocalDateInterval periodInterval : postingPeriodIntervals) {
+ for (final LocalDateInterval periodInterval :
postingPeriodIntervals) {
- boolean isUserPosting = false;
- if
(postedAsOnDates.contains(periodInterval.endDate().plusDays(1))) {
- isUserPosting = true;
- }
+ boolean isUserPosting = false;
+ if
(postedAsOnDates.contains(periodInterval.endDate().plusDays(1))) {
+ isUserPosting = true;
+ }
- PostingPeriod postingPeriod = null;
- List<SavingsAccountTransaction>
orderedNonInterestPostingTransactions = null;
- if (backdatedTxnsAllowedTill) {
- orderedNonInterestPostingTransactions =
retreiveOrderedNonInterestPostingSavingsTransactionsWithPivotConfig();
- } else {
- orderedNonInterestPostingTransactions =
retreiveOrderedNonInterestPostingTransactions();
- }
+ PostingPeriod postingPeriod = null;
+ List<SavingsAccountTransaction>
orderedNonInterestPostingTransactions = null;
+ if (backdatedTxnsAllowedTill) {
+ orderedNonInterestPostingTransactions =
retreiveOrderedNonInterestPostingSavingsTransactionsWithPivotConfig();
+ } else {
+ orderedNonInterestPostingTransactions =
retreiveOrderedNonInterestPostingTransactions();
+ }
- List<SavingsAccountTransactionDetailsForPostingPeriod>
savingsAccountTransactionDetailsForPostingPeriod =
toSavingsAccountTransactionDetailsForPostingPeriodList(
- orderedNonInterestPostingTransactions);
+ List<SavingsAccountTransactionDetailsForPostingPeriod>
savingsAccountTransactionDetailsForPostingPeriod =
toSavingsAccountTransactionDetailsForPostingPeriodList(
+ orderedNonInterestPostingTransactions);
- postingPeriod = PostingPeriod.createFrom(periodInterval,
periodStartingBalance,
- savingsAccountTransactionDetailsForPostingPeriod,
this.currency, compoundingPeriodType, interestCalculationType,
- interestRateAsFraction, daysInYearType.getValue(),
upToInterestCalculationDate, interestPostTransactions,
- isInterestTransfer, minBalanceForInterestCalculation,
isSavingsInterestPostingAtCurrentPeriodEnd,
- overdraftInterestRateAsFraction,
minOverdraftForInterestCalculation, isUserPosting, financialYearBeginningMonth);
+ postingPeriod = PostingPeriod.createFrom(periodInterval,
periodStartingBalance,
+ savingsAccountTransactionDetailsForPostingPeriod,
this.currency, compoundingPeriodType, interestCalculationType,
+ interestRateAsFraction, daysInYearType.getValue(),
upToInterestCalculationDate, interestPostTransactions,
+ isInterestTransfer, minBalanceForInterestCalculation,
isSavingsInterestPostingAtCurrentPeriodEnd,
+ overdraftInterestRateAsFraction,
minOverdraftForInterestCalculation, isUserPosting, financialYearBeginningMonth);
- periodStartingBalance = postingPeriod.closingBalance();
+ periodStartingBalance = postingPeriod.closingBalance();
- allPostingPeriods.add(postingPeriod);
- }
+ allPostingPeriods.add(postingPeriod);
+ }
-
this.savingsHelper.calculateInterestForAllPostingPeriods(this.currency,
allPostingPeriods, getLockedInUntilDate(),
- isTransferInterestToOtherAccount());
+
this.savingsHelper.calculateInterestForAllPostingPeriods(this.currency,
allPostingPeriods, getLockedInUntilDate(),
+ isTransferInterestToOtherAccount());
- this.summary.updateFromInterestPeriodSummaries(this.currency,
allPostingPeriods);
+ this.summary.updateFromInterestPeriodSummaries(this.currency,
allPostingPeriods);
+ }
if (backdatedTxnsAllowedTill) {
this.summary.updateSummaryWithPivotConfig(this.currency,
this.savingsAccountTransactionSummaryWrapper, null,
@@ -933,6 +931,14 @@ public class SavingsAccount extends
AbstractAuditableWithUTCDateTimeCustom {
return this.nominalAnnualInterestRate.divide(BigDecimal.valueOf(100L),
mc);
}
+ private boolean hasInterestCalculation() {
+ return !MathUtil.isEmpty(nominalAnnualInterestRate);
+ }
+
+ private boolean hasOverdraftInterestCalculation() {
+ return isAllowOverdraft() && !MathUtil.isEmpty(getOverdraftLimit()) &&
!MathUtil.isEmpty(nominalAnnualInterestRateOverdraft);
+ }
+
protected List<SavingsAccountTransaction>
retreiveOrderedNonInterestPostingTransactions() {
final List<SavingsAccountTransaction> listOfTransactionsSorted =
retrieveListOfTransactions();
@@ -982,7 +988,8 @@ public class SavingsAccount extends
AbstractAuditableWithUTCDateTimeCustom {
protected void recalculateDailyBalances(final Money openingAccountBalance,
final LocalDate interestPostingUpToDate,
final boolean backdatedTxnsAllowedTill, boolean postReversals) {
- Money runningBalance = openingAccountBalance.copy();
+ Money runningBalance = openingAccountBalance;
+ boolean calculateInterest = hasInterestCalculation() ||
hasOverdraftInterestCalculation();
List<SavingsAccountTransaction> accountTransactionsSorted = null;
@@ -1017,15 +1024,14 @@ public class SavingsAccount extends
AbstractAuditableWithUTCDateTimeCustom {
}
runningBalance = runningBalance.plus(transactionAmount);
- if
(!transaction.getRunningBalance(this.currency).isEqualTo(transactionAmount)) {
- transaction.setRunningBalance(runningBalance);
- }
- if (overdraftAmount.isZero() &&
runningBalance.isLessThanZero() && !transaction.isAmountOnHold()) {
- overdraftAmount =
overdraftAmount.plus(runningBalance.getAmount().negate());
+ transaction.setRunningBalance(runningBalance);
+
+ if (MathUtil.isEmpty(overdraftAmount) &&
runningBalance.isLessThanZero() && !transaction.isAmountOnHold()) {
+ overdraftAmount = runningBalance.negated();
}
- if (transaction.getId() == null &&
overdraftAmount.isGreaterThanZero()) {
+ if (!calculateInterest || transaction.getId() == null) {
transaction.setOverdraftAmount(overdraftAmount);
- } else if
(overdraftAmount.isNotEqualTo(transaction.getOverdraftAmount(this.currency))) {
+ } else if (!MathUtil.isEqualTo(overdraftAmount,
transaction.getOverdraftAmount(this.currency))) {
SavingsAccountTransaction accountTransaction =
SavingsAccountTransaction.copyTransaction(transaction);
if (transaction.isChargeTransaction()) {
Set<SavingsAccountChargePaidBy> chargesPaidBy =
transaction.getSavingsAccountChargesPaid();
@@ -1039,7 +1045,7 @@ public class SavingsAccount extends
AbstractAuditableWithUTCDateTimeCustom {
if (postReversals) {
reversal =
SavingsAccountTransaction.reversal(transaction);
}
- if (overdraftAmount.isGreaterThanZero()) {
+ if (MathUtil.isGreaterThanZero(overdraftAmount)) {
accountTransaction.setOverdraftAmount(overdraftAmount);
}
accountTransaction.setRunningBalance(runningBalance);
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 7f126fe38..ca47a7f62 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
@@ -63,6 +63,7 @@ import
org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidati
import
org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
import
org.apache.fineract.infrastructure.core.exception.PlatformServiceUnavailableException;
import org.apache.fineract.infrastructure.core.service.DateUtils;
+import org.apache.fineract.infrastructure.core.service.MathUtil;
import org.apache.fineract.infrastructure.dataqueries.data.EntityTables;
import org.apache.fineract.infrastructure.dataqueries.data.StatusEnum;
import
org.apache.fineract.infrastructure.dataqueries.service.EntityDatatableChecksWritePlatformService;
@@ -579,8 +580,8 @@ public class
SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
.isSavingsInterestPostingAtCurrentPeriodEnd();
final Integer financialYearBeginningMonth =
this.configurationDomainService.retrieveFinancialYearBeginningMonth();
- if
(savingsAccountData.getNominalAnnualInterestRate().compareTo(BigDecimal.ZERO) >
0 || (savingsAccountData.isAllowOverdraft()
- &&
savingsAccountData.getNominalAnnualInterestRateOverdraft().compareTo(BigDecimal.ZERO)
> 0)) {
+ if
(MathUtil.isGreaterThanZero(savingsAccountData.getNominalAnnualInterestRate())
|| (savingsAccountData.isAllowOverdraft()
+ &&
MathUtil.isGreaterThanZero(savingsAccountData.getNominalAnnualInterestRateOverdraft())))
{
final Set<Long> existingTransactionIds = new HashSet<>();
final Set<Long> existingReversedTransactionIds = new HashSet<>();
updateExistingTransactionsDetails(savingsAccountData,
existingTransactionIds, existingReversedTransactionIds);
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 ab52ce6da..5f9be5a8a 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
@@ -3162,56 +3162,6 @@ public class ClientSavingsIntegrationTest {
error.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
}
- @Test
- public void testSavingsAccountDepositAfterNegativeHoldAmount() {
- this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec,
this.responseSpec);
-
- final Integer clientID = ClientHelper.createClient(this.requestSpec,
this.responseSpec);
- ClientHelper.verifyClientCreatedOnServer(this.requestSpec,
this.responseSpec, clientID);
-
- final Integer savingsProductID =
createSavingsProduct(this.requestSpec, this.responseSpec, "0", null, false,
true, false);
- Assertions.assertNotNull(savingsProductID);
-
- final Integer savingsId =
this.savingsAccountHelper.applyForSavingsApplication(clientID,
savingsProductID, ACCOUNT_TYPE_INDIVIDUAL);
- this.savingsAccountHelper.approveSavings(savingsId);
- HashMap savingsStatusHashMap =
this.savingsAccountHelper.activateSavings(savingsId);
- SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
-
- float balance = 0F;
- float transactionAmount = 100F;
- Integer depositTransactionId = (Integer)
this.savingsAccountHelper.depositToSavingsAccount(savingsId,
- String.valueOf(transactionAmount),
SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
- Assertions.assertNotNull(depositTransactionId);
- balance = balance + transactionAmount;
- HashMap summary =
this.savingsAccountHelper.getSavingsSummary(savingsId);
- assertEquals(balance, summary.get("availableBalance"), "Verifying
Balance after deposit");
- Integer withdrawalTransactionId = (Integer)
this.savingsAccountHelper.withdrawalFromSavingsAccount(savingsId,
- String.valueOf(transactionAmount),
SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
- Assertions.assertNotNull(withdrawalTransactionId);
- balance = balance - transactionAmount;
- summary = this.savingsAccountHelper.getSavingsSummary(savingsId);
- assertEquals(balance, summary.get("availableBalance"), "Verifying
Balance after withdrawal");
-
- float holdAmount = 50F;
- Integer holdTransactionId = (Integer)
this.savingsAccountHelper.holdAmountInSavingsAccount(savingsId,
String.valueOf(holdAmount),
- false, SavingsAccountHelper.TRANSACTION_DATE,
CommonConstants.RESPONSE_RESOURCE_ID);
- Assertions.assertNotNull(holdTransactionId);
- balance = balance - holdAmount;
- summary = this.savingsAccountHelper.getSavingsSummary(savingsId);
- assertEquals(balance, summary.get("availableBalance"), "Verifying
Balance after hold amount");
- this.savingsAccountHelper.releaseAmount(savingsId, holdTransactionId);
- balance = balance + holdAmount;
- summary = this.savingsAccountHelper.getSavingsSummary(savingsId);
- assertEquals(balance, summary.get("availableBalance"), "Verifying
Balance after release amount");
-
- depositTransactionId = (Integer)
this.savingsAccountHelper.depositToSavingsAccount(savingsId,
String.valueOf(transactionAmount),
- SavingsAccountHelper.TRANSACTION_DATE,
CommonConstants.RESPONSE_RESOURCE_ID);
- Assertions.assertNotNull(depositTransactionId);
- balance = balance + transactionAmount;
- summary = this.savingsAccountHelper.getSavingsSummary(savingsId);
- assertEquals(balance, summary.get("availableBalance"), "Verifying
Balance after hold-release-deposit");
- }
-
private Integer createSavingsAccountDailyPostingOverdraft(final Integer
clientID, final String startDate) {
final Integer savingsProductID =
createSavingsProductDailyPostingOverdraft();
Assertions.assertNotNull(savingsProductID);
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/SavingsAccountRecalculateBalanceTest.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/SavingsAccountRecalculateBalanceTest.java
new file mode 100644
index 000000000..4ae61978b
--- /dev/null
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/SavingsAccountRecalculateBalanceTest.java
@@ -0,0 +1,230 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.integrationtests;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+import io.restassured.builder.RequestSpecBuilder;
+import io.restassured.builder.ResponseSpecBuilder;
+import io.restassured.http.ContentType;
+import io.restassured.specification.RequestSpecification;
+import io.restassured.specification.ResponseSpecification;
+import java.math.BigDecimal;
+import java.util.HashMap;
+import org.apache.fineract.integrationtests.common.ClientHelper;
+import org.apache.fineract.integrationtests.common.CommonConstants;
+import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper;
+import org.apache.fineract.integrationtests.common.PaymentTypeHelper;
+import org.apache.fineract.integrationtests.common.SchedulerJobHelper;
+import org.apache.fineract.integrationtests.common.Utils;
+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.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Client Savings Integration Test for checking Savings Application.
+ */
+@SuppressWarnings({ "rawtypes" })
+@Order(2)
+public class SavingsAccountRecalculateBalanceTest {
+
+ private static final Logger LOG =
LoggerFactory.getLogger(SavingsAccountRecalculateBalanceTest.class);
+ public static final String DEPOSIT_AMOUNT = "2000";
+ public static final String WITHDRAW_AMOUNT = "1000";
+ public static final String WITHDRAW_AMOUNT_ADJUSTED = "500";
+ public static final String MINIMUM_OPENING_BALANCE = "1000.0";
+ public static final String ACCOUNT_TYPE_INDIVIDUAL = "INDIVIDUAL";
+ public static final String DATE_FORMAT = "dd MMMM yyyy";
+
+ private ResponseSpecification responseSpec;
+ private RequestSpecification requestSpec;
+ private SavingsAccountHelper savingsAccountHelper;
+ private SavingsProductHelper savingsProductHelper;
+ private SchedulerJobHelper scheduleJobHelper;
+ private PaymentTypeHelper paymentTypeHelper;
+
+ @BeforeEach
+ public void setup() {
+ Utils.initializeRESTAssured();
+ this.requestSpec = new
RequestSpecBuilder().setContentType(ContentType.JSON).build();
+ this.requestSpec.header("Authorization", "Basic " +
Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
+ this.requestSpec.header("Fineract-Platform-TenantId", "default");
+ this.responseSpec = new
ResponseSpecBuilder().expectStatusCode(200).build();
+ this.paymentTypeHelper = new PaymentTypeHelper();
+ }
+
+ @Test
+ public void testSavingsAccountDepositAfterNegativeHoldAmount() {
+ this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec,
this.responseSpec);
+
+ final Integer clientID = ClientHelper.createClient(this.requestSpec,
this.responseSpec);
+ ClientHelper.verifyClientCreatedOnServer(this.requestSpec,
this.responseSpec, clientID);
+
+ final Integer savingsProductID =
createSavingsProduct(this.requestSpec, this.responseSpec, "0", null, false,
true, false, null);
+ Assertions.assertNotNull(savingsProductID);
+
+ final Integer savingsId =
this.savingsAccountHelper.applyForSavingsApplication(clientID,
savingsProductID, ACCOUNT_TYPE_INDIVIDUAL);
+ this.savingsAccountHelper.approveSavings(savingsId);
+ HashMap savingsStatusHashMap =
this.savingsAccountHelper.activateSavings(savingsId);
+ SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
+
+ float balance = 0F;
+ float transactionAmount = 100F;
+ Integer depositTransactionId = (Integer)
this.savingsAccountHelper.depositToSavingsAccount(savingsId,
+ String.valueOf(transactionAmount),
SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
+ Assertions.assertNotNull(depositTransactionId);
+ balance = balance + transactionAmount;
+ HashMap summary =
this.savingsAccountHelper.getSavingsSummary(savingsId);
+ assertEquals(balance, summary.get("availableBalance"), "Verifying
Balance after deposit");
+ Integer withdrawalTransactionId = (Integer)
this.savingsAccountHelper.withdrawalFromSavingsAccount(savingsId,
+ String.valueOf(transactionAmount),
SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
+ Assertions.assertNotNull(withdrawalTransactionId);
+ balance = balance - transactionAmount;
+ summary = this.savingsAccountHelper.getSavingsSummary(savingsId);
+ assertEquals(balance, summary.get("availableBalance"), "Verifying
Balance after withdrawal");
+
+ float holdAmount = 50F;
+ Integer holdTransactionId = (Integer)
this.savingsAccountHelper.holdAmountInSavingsAccount(savingsId,
String.valueOf(holdAmount),
+ false, SavingsAccountHelper.TRANSACTION_DATE,
CommonConstants.RESPONSE_RESOURCE_ID);
+ Assertions.assertNotNull(holdTransactionId);
+ balance = balance - holdAmount;
+ summary = this.savingsAccountHelper.getSavingsSummary(savingsId);
+ assertEquals(balance, summary.get("availableBalance"), "Verifying
Balance after hold amount");
+ this.savingsAccountHelper.releaseAmount(savingsId, holdTransactionId);
+ balance = balance + holdAmount;
+ summary = this.savingsAccountHelper.getSavingsSummary(savingsId);
+ assertEquals(balance, summary.get("availableBalance"), "Verifying
Balance after release amount");
+
+ depositTransactionId = (Integer)
this.savingsAccountHelper.depositToSavingsAccount(savingsId,
String.valueOf(transactionAmount),
+ SavingsAccountHelper.TRANSACTION_DATE,
CommonConstants.RESPONSE_RESOURCE_ID);
+ Assertions.assertNotNull(depositTransactionId);
+ balance = balance + transactionAmount;
+ summary = this.savingsAccountHelper.getSavingsSummary(savingsId);
+ assertEquals(balance, summary.get("availableBalance"), "Verifying
Balance after hold-release-deposit");
+ }
+
+ @Test
+ public void testSavingsAccountDepositAfterNegativeHoldAmountNoInterest() {
+ this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec,
this.responseSpec);
+
+ final Integer clientID = ClientHelper.createClient(this.requestSpec,
this.responseSpec);
+ ClientHelper.verifyClientCreatedOnServer(this.requestSpec,
this.responseSpec, clientID);
+
+ final Integer savingsProductID =
createSavingsProduct(this.requestSpec, this.responseSpec, "0", null, false,
true, false,
+ BigDecimal.ZERO);
+ Assertions.assertNotNull(savingsProductID);
+
+ final Integer savingsId =
this.savingsAccountHelper.applyForSavingsApplication(clientID,
savingsProductID, ACCOUNT_TYPE_INDIVIDUAL);
+ this.savingsAccountHelper.approveSavings(savingsId);
+ HashMap savingsStatusHashMap =
this.savingsAccountHelper.activateSavings(savingsId);
+ SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
+
+ float balance = 0F;
+ float transactionAmount = 100F;
+ Integer depositTransactionId = (Integer)
this.savingsAccountHelper.depositToSavingsAccount(savingsId,
+ String.valueOf(transactionAmount),
SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
+ Assertions.assertNotNull(depositTransactionId);
+ balance = balance + transactionAmount;
+ HashMap summary =
this.savingsAccountHelper.getSavingsSummary(savingsId);
+ assertEquals(balance, summary.get("availableBalance"), "Verifying
Balance after deposit");
+ HashMap depositTransaction =
savingsAccountHelper.getTransactionDetails(savingsId, depositTransactionId);
+ assertEquals(balance, depositTransaction.get("runningBalance"),
"Verifying Running Balance of deposit");
+ Integer withdrawalTransactionId = (Integer)
this.savingsAccountHelper.withdrawalFromSavingsAccount(savingsId,
+ String.valueOf(transactionAmount),
SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
+ Assertions.assertNotNull(withdrawalTransactionId);
+ balance = balance - transactionAmount;
+ summary = this.savingsAccountHelper.getSavingsSummary(savingsId);
+ assertEquals(balance, summary.get("availableBalance"), "Verifying
Balance after withdrawal");
+ HashMap withdrawalTransaction =
savingsAccountHelper.getTransactionDetails(savingsId, withdrawalTransactionId);
+ assertEquals(balance, withdrawalTransaction.get("runningBalance"),
"Verifying Running Balance of withdraw");
+
+ float holdAmount = 50F;
+ Integer holdTransactionId = (Integer)
this.savingsAccountHelper.holdAmountInSavingsAccount(savingsId,
String.valueOf(holdAmount),
+ false, SavingsAccountHelper.TRANSACTION_DATE,
CommonConstants.RESPONSE_RESOURCE_ID);
+ Assertions.assertNotNull(holdTransactionId);
+ balance = balance - holdAmount;
+ summary = this.savingsAccountHelper.getSavingsSummary(savingsId);
+ assertEquals(balance, summary.get("availableBalance"), "Verifying
Balance after hold amount");
+ Integer releaseTransactionId =
this.savingsAccountHelper.releaseAmount(savingsId, holdTransactionId);
+ Assertions.assertNotNull(releaseTransactionId);
+ balance = balance + holdAmount;
+ summary = this.savingsAccountHelper.getSavingsSummary(savingsId);
+ assertEquals(balance, summary.get("availableBalance"), "Verifying
Balance after release amount");
+
+ depositTransactionId = (Integer)
this.savingsAccountHelper.depositToSavingsAccount(savingsId,
String.valueOf(transactionAmount),
+ SavingsAccountHelper.TRANSACTION_DATE,
CommonConstants.RESPONSE_RESOURCE_ID);
+ Assertions.assertNotNull(depositTransactionId);
+ balance = balance + transactionAmount;
+ summary = this.savingsAccountHelper.getSavingsSummary(savingsId);
+ assertEquals(balance, summary.get("availableBalance"), "Verifying
Balance after hold-release-deposit");
+ depositTransaction =
savingsAccountHelper.getTransactionDetails(savingsId, depositTransactionId);
+ // this is a backdated transaction and so listed before the release
transaction
+ assertEquals(balance - holdAmount,
depositTransaction.get("runningBalance"),
+ "Verifying Running Balance of deposit negative balance");
+
+ HashMap releaseTransaction =
savingsAccountHelper.getTransactionDetails(savingsId, releaseTransactionId);
+ assertFalse((Boolean) releaseTransaction.get("reversed"), "Verifying
release transaction with overdraft is not reversed");
+ assertEquals(balance, releaseTransaction.get("runningBalance"),
"Verifying Running Balance");
+ }
+
+ // LienAtProductLevel
+ private Integer createSavingsProduct(final RequestSpecification
requestSpec, final ResponseSpecification responseSpec,
+ final String minOpenningBalance, String
minBalanceForInterestCalculation, final boolean enforceMinRequiredBalance,
+ final boolean allowOverDraft, final boolean lienAllowed,
BigDecimal interestRate) {
+
+ LOG.info("------------------------------CREATING NEW SAVINGS PRODUCT
WITH LIEN---------------------------------------");
+ SavingsProductHelper savingsProductHelper = new SavingsProductHelper();
+ if (lienAllowed) {
+ final String maxAllowedLienLimit = "2000.0";
+ savingsProductHelper.withLienAllowed(maxAllowedLienLimit);
+ }
+ if (enforceMinRequiredBalance) {
+ final String minRequiredBalance = "100.0";
+ savingsProductHelper.withMinRequiredBalance(minRequiredBalance);
+ savingsProductHelper.withEnforceMinRequiredBalance("true");
+ }
+ if (allowOverDraft) {
+ final String overDraftLimit = "500.0";
+ savingsProductHelper.withOverDraft(overDraftLimit);
+ }
+ if (interestRate != null) {
+ savingsProductHelper.withNominalAnnualInterestRate(interestRate);
+ }
+ final String savingsProductJSON =
savingsProductHelper.withInterestCompoundingPeriodTypeAsDaily()
+
.withInterestPostingPeriodTypeAsMonthly().withInterestCalculationPeriodTypeAsDailyBalance()
+
.withMinBalanceForInterestCalculation(minBalanceForInterestCalculation).withMinimumOpenningBalance(minOpenningBalance)
+ .build();
+
+ return SavingsProductHelper.createSavingsProduct(savingsProductJSON,
requestSpec, responseSpec);
+ }
+
+ @AfterEach
+ public void tearDown() {
+
GlobalConfigurationHelper.resetAllDefaultGlobalConfigurations(this.requestSpec,
this.responseSpec);
+
GlobalConfigurationHelper.verifyAllDefaultGlobalConfigurations(this.requestSpec,
this.responseSpec);
+ }
+}
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/SavingsAccountHelper.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/SavingsAccountHelper.java
index 0c14c2672..a0b7d9cff 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/SavingsAccountHelper.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/SavingsAccountHelper.java
@@ -122,30 +122,35 @@ public class SavingsAccountHelper extends IntegrationTest
{
return sdf.format(calendar.getTime());
}
- public Integer applyForSavingsApplication(final Integer id, final Integer
savingsProductID, final String accountType) {
- return applyForSavingsApplicationOnDate(id, savingsProductID,
accountType, CREATED_DATE);
+ public Integer applyForSavingsApplication(final Integer clientOrGroupId,
final Integer savingsProductID, final String accountType) {
+ return applyForSavingsApplicationOnDate(clientOrGroupId,
savingsProductID, accountType, CREATED_DATE);
}
- public Integer applyForSavingsApplicationOnDate(final Integer id, final
Integer savingsProductID, final String accountType,
+ public Integer applyForSavingsApplicationOnDate(final Integer
clientOrGroupId, final Integer savingsProductID, final String accountType,
final String submittedOnDate) {
- return applyForSavingsApplicationOnDate(id, savingsProductID,
accountType, null, false, submittedOnDate);
+ return applyForSavingsApplicationOnDate(clientOrGroupId,
savingsProductID, accountType, null, false, submittedOnDate);
}
- public Integer applyForSavingsApplicationWithExternalId(final Integer id,
final Integer savingsProductID, final String accountType,
- String externalId, boolean withdrawalFeeForTransfers) {
- return applyForSavingsApplicationOnDate(id, savingsProductID,
accountType, externalId, withdrawalFeeForTransfers, CREATED_DATE);
+ public Integer applyForSavingsApplicationWithExternalId(final Integer
clientOrGroupId, final Integer savingsProductID,
+ final String accountType, String externalId, boolean
withdrawalFeeForTransfers) {
+ return applyForSavingsApplicationOnDate(clientOrGroupId,
savingsProductID, accountType, externalId, withdrawalFeeForTransfers,
+ CREATED_DATE);
}
- public Integer applyForSavingsApplicationOnDate(final Integer id, final
Integer savingsProductID, final String accountType,
+ public Integer applyForSavingsApplicationOnDate(final Integer
clientOrGroupId, final Integer savingsProductID, final String accountType,
String externalId, boolean withdrawalFeeForTransfers, final String
submittedOnDate) {
- LOG.info("--------------------------------APPLYING FOR SAVINGS
APPLICATION--------------------------------");
final String savingsApplicationJSON = new
SavingsApplicationTestBuilder() //
.withExternalId(externalId) //
.withWithdrawalFeeForTransfers(withdrawalFeeForTransfers) //
.withSubmittedOnDate(submittedOnDate) //
- .build(id.toString(), savingsProductID.toString(),
accountType);
+ .build(clientOrGroupId.toString(),
savingsProductID.toString(), accountType);
+ return applyForSavingsApplicationOnDate(savingsApplicationJSON);
+ }
+
+ public Integer applyForSavingsApplicationOnDate(String
savingsApplicationJson) {
+ LOG.info("--------------------------------APPLYING FOR SAVINGS
APPLICATION--------------------------------");
return Utils.performServerPost(this.requestSpec, this.responseSpec,
SAVINGS_ACCOUNT_URL + "?" + Utils.TENANT_IDENTIFIER,
- savingsApplicationJSON, "savingsId");
+ savingsApplicationJson, "savingsId");
}
public Integer applyForSavingsApplicationWithDatatables(final Integer id,
final Integer savingsProductID, final String accountType,
@@ -923,4 +928,11 @@ public class SavingsAccountHelper extends IntegrationTest {
updateGsimJSON(clientID.toString(), groupID.toString(),
productID.toString()), "");
}
+ public HashMap getTransactionDetails(Integer savingsId, Integer
transactionId) {
+ LOG.info("--------------------------------- GET savings transaction
details -------------------------------");
+ final String url = "/fineract-provider/api/v1/savingsaccounts/" +
savingsId + "/transactions/" + transactionId + "?"
+ + Utils.TENANT_IDENTIFIER;
+ return Utils.performServerGet(requestSpec, responseSpec, url, "");
+ }
+
}
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/SavingsApplicationTestBuilder.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/SavingsApplicationTestBuilder.java
index 6666da98e..3faf31929 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/SavingsApplicationTestBuilder.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/SavingsApplicationTestBuilder.java
@@ -43,14 +43,14 @@ public class SavingsApplicationTestBuilder {
private List<Map<String, Object>> clientArray = null;
private List<Map<String, Object>> savingsArray = null;
- public String build(final String id, final String savingsProductId, final
String accountType) {
+ public String build(final String clientOrGroupId, final String
savingsProductId, final String accountType) {
final HashMap<String, Object> map = new HashMap<>();
map.put("dateFormat", "dd MMMM yyyy");
if (accountType.equals("GROUP")) {
- map.put("groupId", id);
+ map.put("groupId", clientOrGroupId);
} else {
- map.put("clientId", id);
+ map.put("clientId", clientOrGroupId);
}
map.put("productId", savingsProductId);
map.put("locale", LOCALE);