FINERACT-1943 Fix submitted on date references

This commit is contained in:
Mkkor
2023-08-07 13:42:54 +02:00
committed by Adam Saghy
parent 5b3d088f7b
commit a04c8da659
7 changed files with 297 additions and 116 deletions
@@ -115,24 +115,26 @@ public final class SavingsAccountTransactionData implements Serializable {
final Money amount, final boolean isManualTransaction) {
final boolean isReversed = false;
final Boolean lienTransaction = false;
final LocalDate submittedOnDate = DateUtils.getBusinessLocalDate();
final SavingsAccountTransactionType savingsAccountTransactionType = SavingsAccountTransactionType.INTEREST_POSTING;
SavingsAccountTransactionEnumData savingsAccountTransactionEnumData = new SavingsAccountTransactionEnumData(
savingsAccountTransactionType.getValue().longValue(), savingsAccountTransactionType.getCode(),
savingsAccountTransactionType.getValue().toString());
return new SavingsAccountTransactionData(amount.getAmount(), date, savingsAccount.getId(), savingsAccountTransactionEnumData,
isReversed, null, isManualTransaction, lienTransaction);
isReversed, null, isManualTransaction, lienTransaction, submittedOnDate);
}
public static SavingsAccountTransactionData overdraftInterest(final SavingsAccountData savingsAccount, final LocalDate date,
final Money amount, final boolean isManualTransaction) {
final boolean isReversed = false;
final Boolean lienTransaction = false;
final LocalDate submittedOnDate = DateUtils.getBusinessLocalDate();
final SavingsAccountTransactionType savingsAccountTransactionType = SavingsAccountTransactionType.OVERDRAFT_INTEREST;
SavingsAccountTransactionEnumData savingsAccountTransactionEnumData = new SavingsAccountTransactionEnumData(
savingsAccountTransactionType.getValue().longValue(), savingsAccountTransactionType.getCode(),
savingsAccountTransactionType.getValue().toString());
return new SavingsAccountTransactionData(amount.getAmount(), date, savingsAccount.getId(), savingsAccountTransactionEnumData,
isReversed, null, isManualTransaction, lienTransaction);
isReversed, null, isManualTransaction, lienTransaction, submittedOnDate);
}
public boolean isInterestPostingAndNotReversed() {
@@ -305,14 +307,14 @@ public final class SavingsAccountTransactionData implements Serializable {
private SavingsAccountTransactionData(final Long savingsId, final Long officeId, final PaymentDetailData paymentDetailData,
final SavingsAccountTransactionEnumData savingsAccountTransactionType, final LocalDate transactionDate,
final LocalDate createdDate, final BigDecimal amount, final boolean isReversed, final Long userId,
final LocalDate submittedOnDate, final BigDecimal amount, final boolean isReversed, final Long userId,
final boolean isManualTransaction, final Boolean lienTransaction) {
this.savingsAccountId = savingsId;
this.paymentDetailData = paymentDetailData;
this.transactionType = savingsAccountTransactionType;
this.entryType = transactionType == null ? null : transactionType.getTransactionTypeEnum().getEntryType();
this.transactionDate = transactionDate;
this.submittedOnDate = createdDate;
this.submittedOnDate = submittedOnDate;
this.amount = amount;
this.isManualTransaction = isManualTransaction;
this.lienTransaction = lienTransaction;
@@ -435,12 +437,13 @@ public final class SavingsAccountTransactionData implements Serializable {
final boolean isReversed = false;
final boolean isManualTransaction = false;
final Boolean lienTransaction = false;
final LocalDate submittedOnDate = DateUtils.getBusinessLocalDate();
SavingsAccountTransactionType savingsAccountTransactionType = SavingsAccountTransactionType.WITHHOLD_TAX;
SavingsAccountTransactionEnumData transactionType = new SavingsAccountTransactionEnumData(
savingsAccountTransactionType.getValue().longValue(), savingsAccountTransactionType.getCode(),
savingsAccountTransactionType.getValue().toString());
SavingsAccountTransactionData accountTransaction = new SavingsAccountTransactionData(amount.getAmount(), date,
savingsAccount.getId(), transactionType, isReversed, null, isManualTransaction, lienTransaction);
savingsAccount.getId(), transactionType, isReversed, null, isManualTransaction, lienTransaction, submittedOnDate);
updateTaxDetails(taxDetails, accountTransaction);
return accountTransaction;
}
@@ -509,7 +512,7 @@ public final class SavingsAccountTransactionData implements Serializable {
private SavingsAccountTransactionData(BigDecimal transactionAmount, LocalDate transactionDate, Long savingsAccountId,
SavingsAccountTransactionEnumData transactionType, boolean isReversed, String locale, boolean isManualTransaction,
final Boolean lienTransaction) {
final Boolean lienTransaction, final LocalDate submittedOnDate) {
this.id = null;
this.transactionType = transactionType;
this.entryType = transactionType == null ? null : transactionType.getTransactionTypeEnum().getEntryType();
@@ -523,7 +526,7 @@ public final class SavingsAccountTransactionData implements Serializable {
this.runningBalance = null;
this.reversed = isReversed;
this.transfer = null;
this.submittedOnDate = transactionDate;
this.submittedOnDate = submittedOnDate;
this.interestedPostedAsOn = false;
this.rowIndex = null;
this.savingsAccountId = savingsAccountId;
@@ -673,11 +676,11 @@ public final class SavingsAccountTransactionData implements Serializable {
final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date,
final CurrencyData currency, final BigDecimal amount, final BigDecimal outstandingChargeAmount, final BigDecimal runningBalance,
final boolean reversed, final AccountTransferData transfer, final boolean interestedPostedAsOn,
final String submittedByUsername, final String note) {
final String submittedByUsername, final String note, final LocalDate submittedOnDate) {
final Collection<PaymentTypeData> paymentTypeOptions = null;
return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency,
amount, outstandingChargeAmount, runningBalance, reversed, transfer, paymentTypeOptions, interestedPostedAsOn,
submittedByUsername, note, false);
submittedByUsername, note, false, submittedOnDate);
}
public static SavingsAccountTransactionData create(final Long id, final SavingsAccountTransactionEnumData transactionType,
@@ -715,30 +718,32 @@ public final class SavingsAccountTransactionData implements Serializable {
final Boolean lienTransaction = false;
return new SavingsAccountTransactionData(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, defaultLocalDate,
currency, amount, outstandingChargeAmount, runningBalance, reversed, null, null, interestedPostedAsOn, submittedByUsername,
note, lienTransaction);
note, lienTransaction, defaultLocalDate);
}
public static SavingsAccountTransactionData templateOnTop(final SavingsAccountTransactionData savingsAccountTransactionData,
final Collection<PaymentTypeData> paymentTypeOptions) {
return new SavingsAccountTransactionData(savingsAccountTransactionData.id, savingsAccountTransactionData.transactionType,
savingsAccountTransactionData.paymentDetailData, savingsAccountTransactionData.accountId,
savingsAccountTransactionData.accountNo, savingsAccountTransactionData.date, savingsAccountTransactionData.currency,
savingsAccountTransactionData.amount, savingsAccountTransactionData.outstandingChargeAmount,
savingsAccountTransactionData.runningBalance, savingsAccountTransactionData.reversed,
savingsAccountTransactionData.transfer, paymentTypeOptions, savingsAccountTransactionData.interestedPostedAsOn,
savingsAccountTransactionData.submittedByUsername, savingsAccountTransactionData.note,
savingsAccountTransactionData.lienTransaction);
return new SavingsAccountTransactionData(savingsAccountTransactionData.getId(), savingsAccountTransactionData.getTransactionType(),
savingsAccountTransactionData.getPaymentDetailData(), savingsAccountTransactionData.getAccountId(),
savingsAccountTransactionData.getAccountNo(), savingsAccountTransactionData.getDate(),
savingsAccountTransactionData.getCurrency(), savingsAccountTransactionData.getAmount(),
savingsAccountTransactionData.getOutstandingChargeAmount(), savingsAccountTransactionData.getRunningBalance(),
savingsAccountTransactionData.isReversed(), savingsAccountTransactionData.getTransfer(), paymentTypeOptions,
savingsAccountTransactionData.isInterestedPostedAsOn(), savingsAccountTransactionData.getSubmittedByUsername(),
savingsAccountTransactionData.getNote(), savingsAccountTransactionData.getLienTransaction(),
savingsAccountTransactionData.getSubmittedOnDate());
}
private SavingsAccountTransactionData(final Long id, final SavingsAccountTransactionEnumData transactionType,
final PaymentDetailData paymentDetailData, final Long savingsId, final String savingsAccountNo, final LocalDate date,
final CurrencyData currency, final BigDecimal amount, final BigDecimal outstandingChargeAmount, final BigDecimal runningBalance,
final boolean reversed, final AccountTransferData transfer, final Collection<PaymentTypeData> paymentTypeOptions,
final boolean interestedPostedAsOn, final String submittedByUsername, final String note, final Boolean lienTransaction) {
final boolean interestedPostedAsOn, final String submittedByUsername, final String note, final Boolean lienTransaction,
final LocalDate submittedOnDate) {
this(id, transactionType, paymentDetailData, savingsId, savingsAccountNo, date, currency, amount, outstandingChargeAmount,
runningBalance, reversed, transfer, paymentTypeOptions, date, interestedPostedAsOn, submittedByUsername, note, null, null,
lienTransaction, null, null);
runningBalance, reversed, transfer, paymentTypeOptions, submittedOnDate, interestedPostedAsOn, submittedByUsername, note,
null, null, lienTransaction, null, null);
}
private SavingsAccountTransactionData(final Long id, final SavingsAccountTransactionEnumData transactionType,
@@ -787,14 +792,15 @@ public final class SavingsAccountTransactionData implements Serializable {
final SavingsAccountTransactionEnumData transactionType = SavingsEnumerations
.transactionType(SavingsAccountTransactionType.WITHDRAWAL.getValue());
return new SavingsAccountTransactionData(savingsAccountTransactionData.id, transactionType,
savingsAccountTransactionData.paymentDetailData, savingsAccountTransactionData.accountId,
savingsAccountTransactionData.accountNo, currentDate, savingsAccountTransactionData.currency,
savingsAccountTransactionData.amount, savingsAccountTransactionData.outstandingChargeAmount,
savingsAccountTransactionData.runningBalance, savingsAccountTransactionData.reversed,
savingsAccountTransactionData.transfer, savingsAccountTransactionData.paymentTypeOptions,
savingsAccountTransactionData.interestedPostedAsOn, savingsAccountTransactionData.submittedByUsername,
savingsAccountTransactionData.note, savingsAccountTransactionData.lienTransaction);
return new SavingsAccountTransactionData(savingsAccountTransactionData.getId(), transactionType,
savingsAccountTransactionData.getPaymentDetailData(), savingsAccountTransactionData.getAccountId(),
savingsAccountTransactionData.getAccountNo(), currentDate, savingsAccountTransactionData.getCurrency(),
savingsAccountTransactionData.getAmount(), savingsAccountTransactionData.getOutstandingChargeAmount(),
savingsAccountTransactionData.getRunningBalance(), savingsAccountTransactionData.isReversed(),
savingsAccountTransactionData.getTransfer(), savingsAccountTransactionData.getPaymentTypeOptions(),
savingsAccountTransactionData.isInterestedPostedAsOn(), savingsAccountTransactionData.getSubmittedByUsername(),
savingsAccountTransactionData.getNote(), savingsAccountTransactionData.getLienTransaction(),
savingsAccountTransactionData.getSubmittedOnDate());
}
public void setId(final Long id) {
@@ -149,6 +149,25 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
this.createdDate = null;
}
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Office office, final PaymentDetail paymentDetail,
final Integer typeOf, final LocalDate transactionLocalDate, final LocalDateTime createdDate, final BigDecimal amount,
final boolean isReversed, final AppUser appUser, final boolean isManualTransaction, final Boolean lienTransaction,
final String refNo) {
this.savingsAccount = savingsAccount;
this.office = office;
this.typeOf = typeOf;
this.dateOf = transactionLocalDate;
this.amount = amount;
this.reversed = isReversed;
this.paymentDetail = paymentDetail;
this.createdDate = createdDate;
this.submittedOnDate = DateUtils.getBusinessLocalDate();
this.appUser = appUser;
this.isManualTransaction = isManualTransaction;
this.lienTransaction = lienTransaction;
this.refNo = refNo;
}
public static SavingsAccountTransaction deposit(final SavingsAccount savingsAccount, final Office office,
final PaymentDetail paymentDetail, final LocalDate date, final Money amount, LocalDateTime createdDate, final AppUser appUser,
final String refNo) {
@@ -226,14 +245,6 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
isReversed, appUser, isManualTransaction, lienTransaction, refNo);
}
public static SavingsAccountTransaction from(final Integer transactionTypeEnum, final LocalDate transactionDate,
final BigDecimal amount, final boolean isReversed, final BigDecimal runningBalance, final BigDecimal cumulativeBalance,
final LocalDate balanceEndDate, final Integer balanceNumberOfDays, final BigDecimal overdraftAmount,
final LocalDateTime createdDate, final boolean isManualTransaction, final Long releaseIdOfHoldAmountTransaction) {
return new SavingsAccountTransaction(transactionTypeEnum, transactionDate, amount, isReversed, runningBalance, cumulativeBalance,
balanceEndDate, balanceNumberOfDays, overdraftAmount, createdDate, isManualTransaction, releaseIdOfHoldAmountTransaction);
}
public static SavingsAccountTransaction waiver(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
final Money amount, final AppUser appUser) {
final boolean isReversed = false;
@@ -336,44 +347,6 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
isManualTransaction, lienTransaction, refNo);
}
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Office office, final PaymentDetail paymentDetail,
final Integer typeOf, final LocalDate transactionLocalDate, final LocalDateTime createdDate, final BigDecimal amount,
final boolean isReversed, final AppUser appUser, final boolean isManualTransaction, final Boolean lienTransaction,
final String refNo) {
this.savingsAccount = savingsAccount;
this.office = office;
this.typeOf = typeOf;
this.dateOf = transactionLocalDate;
this.amount = amount;
this.reversed = isReversed;
this.paymentDetail = paymentDetail;
this.createdDate = createdDate;
this.submittedOnDate = DateUtils.getBusinessLocalDate();
this.appUser = appUser;
this.isManualTransaction = isManualTransaction;
this.lienTransaction = lienTransaction;
this.refNo = refNo;
}
private SavingsAccountTransaction(final Integer transactionTypeEnum, final LocalDate transactionDate, final BigDecimal amount,
final boolean isReversed, final BigDecimal runningBalance, final BigDecimal cumulativeBalance, final LocalDate balanceEndDate,
final Integer balanceNumberOfDays, final BigDecimal overdraftAmount, final LocalDateTime createdDate,
final boolean isManualTransaction, final Long releaseIdOfHoldAmountTransaction) {
this.typeOf = transactionTypeEnum;
this.dateOf = transactionDate;
this.amount = amount;
this.reversed = isReversed;
this.runningBalance = runningBalance;
this.cumulativeBalance = cumulativeBalance;
this.balanceEndDate = balanceEndDate;
this.balanceNumberOfDays = balanceNumberOfDays;
this.overdraftAmount = overdraftAmount;
this.createdDate = createdDate;
this.submittedOnDate = DateUtils.getBusinessLocalDate();
this.isManualTransaction = isManualTransaction;
this.releaseIdOfHoldAmountTransaction = releaseIdOfHoldAmountTransaction;
}
public static SavingsAccountTransaction holdAmount(final SavingsAccount savingsAccount, final Office office,
final PaymentDetail paymentDetail, final LocalDate date, final Money amount, LocalDateTime createdDate, final AppUser appUser,
final Boolean lienTransaction) {
@@ -921,6 +894,10 @@ public final class SavingsAccountTransaction extends AbstractPersistableCustom {
return this.createdDate;
}
public LocalDate getSubmittedOnDate() {
return submittedOnDate;
}
public boolean getIsManualTransaction() {
return this.isManualTransaction;
}
@@ -1131,6 +1131,7 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
public static final String TO_TRANSFER_REVERSED = "toTransferReversed";
public static final String TO_TRANSFER_DESCRIPTION = "toTransferDescription";
public static final String SUBMITTED_BY_USERNAME = "submittedByUsername";
public static final String SUBMITTED_ON_DATE = "submittedOnDate";
private final String schemaSql;
SavingsAccountTransactionsMapper() {
@@ -1139,6 +1140,7 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
sqlBuilder.append("tr.id as transactionId, tr.transaction_type_enum as transactionType, ");
sqlBuilder.append("tr.transaction_date as transactionDate, tr.amount as transactionAmount,");
sqlBuilder.append("tr.running_balance_derived as runningBalance, tr.is_reversed as reversed,");
sqlBuilder.append("tr.submitted_on_date as submittedOnDate,");
sqlBuilder.append("fromtran.id as fromTransferId, fromtran.is_reversed as fromTransferReversed,");
sqlBuilder.append("fromtran.transaction_date as fromTransferDate, fromtran.amount as fromTransferAmount,");
sqlBuilder.append("fromtran.description as fromTransferDescription,");
@@ -1176,6 +1178,7 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
final SavingsAccountTransactionEnumData transactionType = SavingsEnumerations.transactionType(transactionTypeInt);
final LocalDate date = JdbcSupport.getLocalDate(rs, TRANSACTION_DATE);
final LocalDate submittedOnDate = JdbcSupport.getLocalDate(rs, SUBMITTED_ON_DATE);
final BigDecimal amount = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, TRANSACTION_AMOUNT);
final BigDecimal outstandingChargeAmount = null;
final BigDecimal runningBalance = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, RUNNING_BALANCE);
@@ -1233,7 +1236,8 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
final String submittedByUsername = rs.getString(SUBMITTED_BY_USERNAME);
final String note = null;
return SavingsAccountTransactionData.create(id, transactionType, paymentDetailData, savingsId, accountNo, date, currency,
amount, outstandingChargeAmount, runningBalance, reversed, transfer, postInterestAsOn, submittedByUsername, note);
amount, outstandingChargeAmount, runningBalance, reversed, transfer, postInterestAsOn, submittedByUsername, note,
submittedOnDate);
}
}
@@ -1662,9 +1666,10 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
final boolean postInterestAsOn = false;
final String submittedByUsername = null;
final String note = null;
final LocalDate submittedOnDate = DateUtils.getBusinessLocalDate();
return SavingsAccountTransactionData.create(savingsId, transactionType, paymentDetailData, savingsId, accountNo, duedate,
currency, dueamount, outstandingChargeAmount, runningBalance, false, transfer, postInterestAsOn, submittedByUsername,
note);
note, submittedOnDate);
}
}
@@ -351,7 +351,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
sqlBuilder.append("sp.accounting_type as accountingType, ");
sqlBuilder.append("tr.id as transactionId, tr.transaction_type_enum as transactionType, ");
sqlBuilder.append("tr.transaction_date as transactionDate, tr.amount as transactionAmount,");
sqlBuilder.append("tr.created_date as createdDate,tr.cumulative_balance_derived as cumulativeBalance,");
sqlBuilder.append("tr.submitted_on_date as transSubmittedOnDate,tr.cumulative_balance_derived as cumulativeBalance,");
sqlBuilder.append("tr.running_balance_derived as runningBalance, tr.is_reversed as reversed,");
sqlBuilder.append("tr.balance_end_date_derived as balanceEndDate, tr.overdraft_amount_derived as overdraftAmount,");
sqlBuilder.append("tr.is_manual as manualTransaction,tr.office_id as officeId, ");
@@ -600,7 +600,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
final LocalDate date = JdbcSupport.getLocalDate(rs, "transactionDate");
final LocalDate balanceEndDate = JdbcSupport.getLocalDate(rs, "balanceEndDate");
final LocalDate transSubmittedOnDate = JdbcSupport.getLocalDate(rs, "createdDate");
final LocalDate transSubmittedOnDate = JdbcSupport.getLocalDate(rs, "transSubmittedOnDate");
final BigDecimal amount = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "transactionAmount");
final BigDecimal overdraftAmount = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "overdraftAmount");
final BigDecimal outstandingChargeAmount = null;
@@ -1324,7 +1324,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
sqlBuilder.append("tr.transaction_date as transactionDate, tr.amount as transactionAmount,");
sqlBuilder.append(" tr.release_id_of_hold_amount as releaseTransactionId,");
sqlBuilder.append(" tr.reason_for_block as reasonForBlock,");
sqlBuilder.append("tr.created_date as submittedOnDate,");
sqlBuilder.append(" tr.submitted_on_date as submittedOnDate,");
sqlBuilder.append(" au.username as submittedByUsername, ");
sqlBuilder.append(" nt.note as transactionNote, ");
sqlBuilder.append("tr.running_balance_derived as runningBalance, tr.is_reversed as reversed,");
@@ -0,0 +1,156 @@
/**
* 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.assertTrue;
import com.fasterxml.jackson.core.JsonProcessingException;
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.time.LocalDate;
import java.time.ZoneId;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.integrationtests.common.BusinessDateHelper;
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.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.Test;
@SuppressWarnings({ "rawtypes" })
public class SavingsAccountTransactionTest {
public static final String ACCOUNT_TYPE_INDIVIDUAL = "INDIVIDUAL";
public static final String DEFAULT_DATE_FORMAT = "dd MMM yyyy";
final String startDateString = "03 June 2023";
final String depositDateString = "05 June 2023";
final String withdrawDateString = "10 June 2023";
private ResponseSpecification responseSpec;
private RequestSpecification requestSpec;
private SavingsProductHelper savingsProductHelper;
private SavingsAccountHelper savingsAccountHelper;
@BeforeEach
public void setup() {
Utils.initializeRESTAssured();
this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec);
this.savingsProductHelper = new SavingsProductHelper();
}
@Test
public void verifySavingsTransactionSubmittedOnDateAndTransactionDate() throws JsonProcessingException {
LocalDate today = LocalDate.now(ZoneId.systemDefault());
try {
enableBusinessDate(requestSpec, responseSpec, true);
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, today);
LocalDate depositDate = Utils.getDateAsLocalDate(depositDateString);
LocalDate withdrawDate = Utils.getDateAsLocalDate(withdrawDateString);
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, startDateString);
Assertions.assertNotNull(clientID);
final Integer savingsId = createSavingsAccountDailyPosting(clientID, startDateString);
Assertions.assertNotNull(savingsId);
performSavingsTransaction(savingsId, "100", depositDate, true);
performSavingsTransaction(savingsId, "50", withdrawDate, false);
} finally {
enableBusinessDate(requestSpec, responseSpec, false);
}
}
private void enableBusinessDate(RequestSpecification requestSpec, ResponseSpecification responseSpec, boolean enable) {
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, enable);
}
private void performSavingsTransaction(Integer savingsId, String amount, LocalDate transactionDate, boolean isDeposit) {
String transactionType = isDeposit ? "Deposit" : "Withdrawal";
Integer transactionId = isDeposit
? (Integer) this.savingsAccountHelper.depositToSavingsAccount(savingsId, amount, depositDateString,
CommonConstants.RESPONSE_RESOURCE_ID)
: (Integer) this.savingsAccountHelper.withdrawalFromSavingsAccount(savingsId, amount, withdrawDateString,
CommonConstants.RESPONSE_RESOURCE_ID);
Assertions.assertNotNull(transactionId);
HashMap transaction = savingsAccountHelper.getSavingsTransaction(savingsId, transactionId);
Assertions.assertNotNull(transaction);
assertEquals(transactionId, (Integer) transaction.get("id"), "Check Savings " + transactionType + " Transaction");
LocalDate transactionDateFromResponse = extractLocalDate(transaction, "date");
assertTrue(transactionDate.compareTo(transactionDateFromResponse) == 0,
"Transaction Date check for Savings " + transactionType + " Transaction");
LocalDate submittedOnDate = extractLocalDate(transaction, "submittedOnDate");
assertTrue(LocalDate.now(ZoneId.systemDefault()).compareTo(submittedOnDate) == 0,
"Submitted On Date check for Savings " + transactionType + " Transaction");
}
private LocalDate extractLocalDate(HashMap transactionMap, String fieldName) {
List<Integer> dateStringList = (List<Integer>) transactionMap.get(fieldName);
LocalDate extractedDate = dateStringList.stream()
.collect(Collectors.collectingAndThen(Collectors.toList(), list -> LocalDate.of(list.get(0), list.get(1), list.get(2))));
return extractedDate;
}
private Integer createSavingsAccountDailyPosting(final Integer clientID, final String startDate) {
final Integer savingsProductID = createSavingsProductDailyPosting();
Assertions.assertNotNull(savingsProductID);
final Integer savingsId = this.savingsAccountHelper.applyForSavingsApplicationOnDate(clientID, savingsProductID,
ACCOUNT_TYPE_INDIVIDUAL, startDate);
Assertions.assertNotNull(savingsId);
HashMap savingsStatusHashMap = this.savingsAccountHelper.approveSavingsOnDate(savingsId, startDate);
SavingsStatusChecker.verifySavingsIsApproved(savingsStatusHashMap);
savingsStatusHashMap = this.savingsAccountHelper.activateSavingsAccount(savingsId, startDate);
SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
return savingsId;
}
private Integer createSavingsProductDailyPosting() {
final String savingsProductJSON = this.savingsProductHelper.withInterestCompoundingPeriodTypeAsDaily()
.withInterestPostingPeriodTypeAsDaily().withInterestCalculationPeriodTypeAsDailyBalance().build();
return SavingsProductHelper.createSavingsProduct(savingsProductJSON, requestSpec, responseSpec);
}
// Reset configuration fields
@AfterEach
public void tearDown() {
GlobalConfigurationHelper.resetAllDefaultGlobalConfigurations(this.requestSpec, this.responseSpec);
GlobalConfigurationHelper.verifyAllDefaultGlobalConfigurations(this.requestSpec, this.responseSpec);
}
}
@@ -19,15 +19,22 @@
package org.apache.fineract.integrationtests;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
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.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.integrationtests.common.BusinessDateHelper;
import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.CommonConstants;
import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper;
@@ -65,27 +72,38 @@ public class SavingsInterestPostingIntegrationTest {
@Test
public void testSavingsDailyInterestPosting() {
// client activation, savings activation and 1st transaction date
final String startDate = "01 November 2021";
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, startDate);
Assertions.assertNotNull(clientID);
LocalDate today = LocalDate.now(ZoneId.systemDefault());
try {
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, true);
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, today);
// client activation, savings activation and 1st transaction date
final String startDate = "01 November 2021";
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, startDate);
Assertions.assertNotNull(clientID);
final Integer savingsId = createSavingsAccountDailyPosting(clientID, startDate);
final Integer savingsId = createSavingsAccountDailyPosting(clientID, startDate);
this.savingsAccountHelper.depositToSavingsAccount(savingsId, "1000", startDate, CommonConstants.RESPONSE_RESOURCE_ID);
this.savingsAccountHelper.depositToSavingsAccount(savingsId, "1000", startDate, CommonConstants.RESPONSE_RESOURCE_ID);
/***
* Perform Post interest transaction and verify the posted transaction date
*/
this.savingsAccountHelper.postInterestForSavings(savingsId);
HashMap accountDetails = this.savingsAccountHelper.getSavingsDetails(savingsId);
ArrayList<HashMap<String, Object>> transactions = (ArrayList<HashMap<String, Object>>) accountDetails.get("transactions");
HashMap<String, Object> interestPostingTransaction = transactions.get(transactions.size() - 2);
for (Map.Entry<String, Object> entry : interestPostingTransaction.entrySet()) {
LOG.info("{} - {}", entry.getKey(), entry.getValue().toString());
/***
* Perform Post interest transaction and verify the posted transaction date
*/
this.savingsAccountHelper.postInterestForSavings(savingsId);
HashMap accountDetails = this.savingsAccountHelper.getSavingsDetails(savingsId);
ArrayList<HashMap<String, Object>> transactions = (ArrayList<HashMap<String, Object>>) accountDetails.get("transactions");
HashMap<String, Object> interestPostingTransaction = transactions.get(transactions.size() - 2);
for (Map.Entry<String, Object> entry : interestPostingTransaction.entrySet()) {
LOG.info("{} - {}", entry.getKey(), entry.getValue().toString());
}
assertEquals("0.274", interestPostingTransaction.get("amount").toString(), "Equality check for interest posted amount");
assertEquals("[2021, 11, 2]", interestPostingTransaction.get("date").toString(), "Date check for Interest Posting transaction");
List<Integer> submittedOnDateStringList = (List<Integer>) interestPostingTransaction.get("submittedOnDate");
LocalDate submittedOnDate = submittedOnDateStringList.stream().collect(
Collectors.collectingAndThen(Collectors.toList(), list -> LocalDate.of(list.get(0), list.get(1), list.get(2))));
assertTrue(submittedOnDate.compareTo(today) == 0, "Submitted On Date check for Interest Posting transaction");
} finally {
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, false);
}
assertEquals("0.274", interestPostingTransaction.get("amount").toString(), "Equality check for interest posted amount");
assertEquals("[2021, 11, 2]", interestPostingTransaction.get("date").toString(), "Date check for Interest Posting transaction");
}
@@ -19,15 +19,22 @@
package org.apache.fineract.integrationtests;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
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.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.integrationtests.common.BusinessDateHelper;
import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.CommonConstants;
import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper;
@@ -142,29 +149,41 @@ public class SavingsInterestPostingJobIntegrationTest {
@Test
public void testSavingsDailyInterestPostingJob() {
// client activation, savings activation and 1st transaction date
final String startDate = "10 April 2022";
final String jobName = "Post Interest For Savings";
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, startDate);
Assertions.assertNotNull(clientID);
LocalDate today = LocalDate.now(ZoneId.systemDefault());
try {
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, true);
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, today);
// client activation, savings activation and 1st transaction date
final String startDate = "10 April 2022";
final String jobName = "Post Interest For Savings";
final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, startDate);
Assertions.assertNotNull(clientID);
final Integer savingsId = createSavingsAccountDailyPosting(clientID, startDate);
final Integer savingsId = createSavingsAccountDailyPosting(clientID, startDate);
this.savingsAccountHelper.depositToSavingsAccount(savingsId, "10000", startDate, CommonConstants.RESPONSE_RESOURCE_ID);
this.savingsAccountHelper.depositToSavingsAccount(savingsId, "10000", startDate, CommonConstants.RESPONSE_RESOURCE_ID);
/***
* Runs Post interest posting job and verify the new account created with accounting configuration set as none
* is picked up by job
*/
this.scheduleJobHelper.executeAndAwaitJob(jobName);
Object transactionObj = this.savingsAccountHelper.getSavingsDetails(savingsId, "transactions");
ArrayList<HashMap<String, Object>> transactions = (ArrayList<HashMap<String, Object>>) transactionObj;
HashMap<String, Object> interestPostingTransaction = transactions.get(transactions.size() - 3);
for (Map.Entry<String, Object> entry : interestPostingTransaction.entrySet()) {
LOG.info("{} - {}", entry.getKey(), entry.getValue().toString());
/***
* Runs Post interest posting job and verify the new account created with accounting configuration set as
* none is picked up by job
*/
this.scheduleJobHelper.executeAndAwaitJob(jobName);
Object transactionObj = this.savingsAccountHelper.getSavingsDetails(savingsId, "transactions");
ArrayList<HashMap<String, Object>> transactions = (ArrayList<HashMap<String, Object>>) transactionObj;
HashMap<String, Object> interestPostingTransaction = transactions.get(transactions.size() - 3);
for (Map.Entry<String, Object> entry : interestPostingTransaction.entrySet()) {
LOG.info("{} - {}", entry.getKey(), entry.getValue().toString());
}
assertEquals("2.7405", interestPostingTransaction.get("amount").toString(), "Equality check for interest posted amount");
assertEquals("[2022, 4, 12]", interestPostingTransaction.get("date").toString(), "Date check for Interest Posting transaction");
List<Integer> submittedOnDateStringList = (List<Integer>) interestPostingTransaction.get("submittedOnDate");
LocalDate submittedOnDate = submittedOnDateStringList.stream().collect(
Collectors.collectingAndThen(Collectors.toList(), list -> LocalDate.of(list.get(0), list.get(1), list.get(2))));
assertTrue(submittedOnDate.compareTo(today) == 0, "Submitted On Date check for Interest Posting transaction");
} finally {
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, false);
}
assertEquals("2.7405", interestPostingTransaction.get("amount").toString(), "Equality check for interest posted amount");
assertEquals("[2022, 4, 12]", interestPostingTransaction.get("date").toString(), "Date check for Interest Posting transaction");
}
@Test