FINERACT-2011: Savings Account - transaction order is incorrectly mixed after certain activities
This commit is contained in:
+7
-53
@@ -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) {
|
||||
|
||||
+1
-4
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+104
-98
@@ -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,109 +815,103 @@ 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 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);
|
||||
|
||||
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
|
||||
|
||||
Money periodStartingBalance;
|
||||
if (this.startInterestCalculationDate != null && !this.getStartInterestCalculationDate().equals(this.getActivationDate())) {
|
||||
LocalDate startInterestCalculationDate = this.startInterestCalculationDate;
|
||||
SavingsAccountTransaction transaction = null;
|
||||
// A generate list of EndOfDayBalances (not including interest postings)
|
||||
final SavingsPostingInterestPeriodType postingPeriodType = SavingsPostingInterestPeriodType
|
||||
.fromInt(this.interestPostingPeriodType);
|
||||
|
||||
final SavingsCompoundingInterestPeriodType compoundingPeriodType = SavingsCompoundingInterestPeriodType
|
||||
.fromInt(this.interestCompoundingPeriodType);
|
||||
|
||||
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) {
|
||||
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.zero(this.currency);
|
||||
} else {
|
||||
periodStartingBalance = Money.of(this.currency, this.summary.getRunningBalanceOnPivotDate());
|
||||
}
|
||||
} 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);
|
||||
|
||||
for (final LocalDateInterval periodInterval : postingPeriodIntervals) {
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
periodStartingBalance = postingPeriod.closingBalance();
|
||||
|
||||
allPostingPeriods.add(postingPeriod);
|
||||
}
|
||||
|
||||
this.savingsHelper.calculateInterestForAllPostingPeriods(this.currency, allPostingPeriods, getLockedInUntilDate(),
|
||||
isTransferInterestToOtherAccount());
|
||||
|
||||
this.summary.updateFromInterestPeriodSummaries(this.currency, allPostingPeriods);
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
periodStartingBalance = postingPeriod.closingBalance();
|
||||
|
||||
allPostingPeriods.add(postingPeriod);
|
||||
}
|
||||
|
||||
this.savingsHelper.calculateInterestForAllPostingPeriods(this.currency, allPostingPeriods, getLockedInUntilDate(),
|
||||
isTransferInterestToOtherAccount());
|
||||
|
||||
this.summary.updateFromInterestPeriodSummaries(this.currency, allPostingPeriods);
|
||||
|
||||
if (backdatedTxnsAllowedTill) {
|
||||
this.summary.updateSummaryWithPivotConfig(this.currency, this.savingsAccountTransactionSummaryWrapper, null,
|
||||
this.savingsAccountTransactions);
|
||||
@@ -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);
|
||||
transaction.setRunningBalance(runningBalance);
|
||||
|
||||
if (MathUtil.isEmpty(overdraftAmount) && runningBalance.isLessThanZero() && !transaction.isAmountOnHold()) {
|
||||
overdraftAmount = runningBalance.negated();
|
||||
}
|
||||
if (overdraftAmount.isZero() && runningBalance.isLessThanZero() && !transaction.isAmountOnHold()) {
|
||||
overdraftAmount = overdraftAmount.plus(runningBalance.getAmount().negate());
|
||||
}
|
||||
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);
|
||||
|
||||
+3
-2
@@ -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);
|
||||
|
||||
-50
@@ -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);
|
||||
|
||||
+230
@@ -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);
|
||||
}
|
||||
}
|
||||
+23
-11
@@ -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, "");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user