FINERACT-2326: Use exact business date during savings account accrual tests

This commit is contained in:
Adam Saghy
2025-08-25 09:28:12 +02:00
committed by Arnold Gálovics
parent 9ef79f86a0
commit 5d71ffd4ea
2 changed files with 189 additions and 174 deletions
@@ -18,6 +18,8 @@
*/ */
package org.apache.fineract.integrationtests; package org.apache.fineract.integrationtests;
import static org.apache.fineract.integrationtests.common.BusinessDateHelper.runAt;
import io.restassured.builder.RequestSpecBuilder; import io.restassured.builder.RequestSpecBuilder;
import io.restassured.builder.ResponseSpecBuilder; import io.restassured.builder.ResponseSpecBuilder;
import io.restassured.http.ContentType; import io.restassured.http.ContentType;
@@ -72,6 +74,7 @@ public class SavingsAccrualAccountingIntegrationTest {
@Test @Test
public void testPositiveAccrualPostsCorrectJournalEntries() { public void testPositiveAccrualPostsCorrectJournalEntries() {
runAt("12 August 2021", () -> {
// --- ARRANGE --- // --- ARRANGE ---
LOG.info("------------------------- INITIATING POSITIVE ACCRUAL ACCOUNTING TEST -------------------------"); LOG.info("------------------------- INITIATING POSITIVE ACCRUAL ACCOUNTING TEST -------------------------");
final int daysToSubtract = 10; final int daysToSubtract = 10;
@@ -82,8 +85,8 @@ public class SavingsAccrualAccountingIntegrationTest {
final Account savingsControlAccount = this.accountHelper.createLiabilityAccount("Savings Control"); final Account savingsControlAccount = this.accountHelper.createLiabilityAccount("Savings Control");
final Account interestPayableAccount = this.accountHelper.createLiabilityAccount("Interest Payable (Liability)"); final Account interestPayableAccount = this.accountHelper.createLiabilityAccount("Interest Payable (Liability)");
final Account incomeFromFeesAccount = this.accountHelper.createIncomeAccount("Income from Fees"); final Account incomeFromFeesAccount = this.accountHelper.createIncomeAccount("Income from Fees");
final Account[] accountList = { savingsReferenceAccount, savingsControlAccount, interestOnSavingsAccount, interestPayableAccount, final Account[] accountList = { savingsReferenceAccount, savingsControlAccount, interestOnSavingsAccount,
incomeFromFeesAccount }; interestPayableAccount, incomeFromFeesAccount };
final SavingsProductHelper productHelper = new SavingsProductHelper().withNominalAnnualInterestRate(new BigDecimal("10.0")) final SavingsProductHelper productHelper = new SavingsProductHelper().withNominalAnnualInterestRate(new BigDecimal("10.0"))
.withAccountingRuleAsAccrualBased(accountList) .withAccountingRuleAsAccrualBased(accountList)
@@ -98,13 +101,14 @@ public class SavingsAccrualAccountingIntegrationTest {
Assertions.assertNotNull(savingsProductId, "Failed to create savings product."); Assertions.assertNotNull(savingsProductId, "Failed to create savings product.");
final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2020"); final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2020");
final LocalDate startDate = LocalDate.now(Utils.getZoneIdOfTenant()).minusDays(daysToSubtract); final LocalDate startDate = LocalDate.of(2021, 8, 12).minusDays(daysToSubtract);
final String startDateString = DateTimeFormatter.ofPattern("dd MMMM yyyy", Locale.US).format(startDate); final String startDateString = DateTimeFormatter.ofPattern("dd MMMM yyyy", Locale.US).format(startDate);
final Integer savingsAccountId = this.savingsAccountHelper.applyForSavingsApplicationOnDate(clientId, savingsProductId, final Integer savingsAccountId = this.savingsAccountHelper.applyForSavingsApplicationOnDate(clientId, savingsProductId,
SavingsAccountHelper.ACCOUNT_TYPE_INDIVIDUAL, startDateString); SavingsAccountHelper.ACCOUNT_TYPE_INDIVIDUAL, startDateString);
this.savingsAccountHelper.approveSavingsOnDate(savingsAccountId, startDateString); this.savingsAccountHelper.approveSavingsOnDate(savingsAccountId, startDateString);
this.savingsAccountHelper.activateSavings(savingsAccountId, startDateString); this.savingsAccountHelper.activateSavings(savingsAccountId, startDateString);
this.savingsAccountHelper.depositToSavingsAccount(savingsAccountId, amount, startDateString, CommonConstants.RESPONSE_RESOURCE_ID); this.savingsAccountHelper.depositToSavingsAccount(savingsAccountId, amount, startDateString,
CommonConstants.RESPONSE_RESOURCE_ID);
// --- ACT --- // --- ACT ---
schedulerJobHelper.executeAndAwaitJob("Add Accrual Transactions For Savings"); schedulerJobHelper.executeAndAwaitJob("Add Accrual Transactions For Savings");
@@ -114,7 +118,8 @@ public class SavingsAccrualAccountingIntegrationTest {
Assertions.assertFalse(accrualTransactions.isEmpty(), "No accrual transactions were found."); Assertions.assertFalse(accrualTransactions.isEmpty(), "No accrual transactions were found.");
Number firstTransactionIdNumber = (Number) accrualTransactions.get(0).get("id"); Number firstTransactionIdNumber = (Number) accrualTransactions.get(0).get("id");
ArrayList<HashMap> journalEntries = journalEntryHelper.getJournalEntriesByTransactionId("S" + firstTransactionIdNumber.intValue()); ArrayList<HashMap> journalEntries = journalEntryHelper
.getJournalEntriesByTransactionId("S" + firstTransactionIdNumber.intValue());
Assertions.assertFalse(journalEntries.isEmpty(), "No journal entries found for positive accrual."); Assertions.assertFalse(journalEntries.isEmpty(), "No journal entries found for positive accrual.");
boolean debitFound = false; boolean debitFound = false;
@@ -140,11 +145,12 @@ public class SavingsAccrualAccountingIntegrationTest {
Assertions.assertEquals(interest, amountAccrualTransaccion); Assertions.assertEquals(interest, amountAccrualTransaccion);
} }
LOG.info("VALIDATE AMOUNT AND ACCOUNT"); LOG.info("VALIDATE AMOUNT AND ACCOUNT");
});
} }
@Test @Test
public void testNegativeAccrualPostsCorrectJournalEntries() { public void testNegativeAccrualPostsCorrectJournalEntries() {
runAt("12 August 2021", () -> {
// --- ARRANGE --- // --- ARRANGE ---
LOG.info("------------------------- INITIATING NEGATIVE ACCRUAL (OVERDRAFT) ACCOUNTING TEST -------------------------"); LOG.info("------------------------- INITIATING NEGATIVE ACCRUAL (OVERDRAFT) ACCOUNTING TEST -------------------------");
final int daysToSubtract = 10; final int daysToSubtract = 10;
@@ -158,7 +164,8 @@ public class SavingsAccrualAccountingIntegrationTest {
final Account overdraftInterestIncomeAccount = this.accountHelper.createIncomeAccount("Overdraft Interest Income"); final Account overdraftInterestIncomeAccount = this.accountHelper.createIncomeAccount("Overdraft Interest Income");
final Account expenseAccount = this.accountHelper.createExpenseAccount("Interest on Savings (Expense)"); final Account expenseAccount = this.accountHelper.createExpenseAccount("Interest on Savings (Expense)");
final Account[] accountList = { savingsReferenceAccount, savingsControlAccount, expenseAccount, overdraftInterestIncomeAccount }; final Account[] accountList = { savingsReferenceAccount, savingsControlAccount, expenseAccount,
overdraftInterestIncomeAccount };
final String overdraftLimit = "10000"; final String overdraftLimit = "10000";
final String overdraftInterestRate = "21.0"; final String overdraftInterestRate = "21.0";
@@ -178,7 +185,7 @@ public class SavingsAccrualAccountingIntegrationTest {
Assertions.assertNotNull(savingsProductId, "Savings product with overdraft creation failed."); Assertions.assertNotNull(savingsProductId, "Savings product with overdraft creation failed.");
final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2020"); final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2020");
final LocalDate startDate = LocalDate.now(Utils.getZoneIdOfTenant()).minusDays(daysToSubtract); final LocalDate startDate = LocalDate.of(2021, 8, 12).minusDays(daysToSubtract);
final String startDateString = DateTimeFormatter.ofPattern("dd MMMM yyyy", Locale.US).format(startDate); final String startDateString = DateTimeFormatter.ofPattern("dd MMMM yyyy", Locale.US).format(startDate);
final Integer savingsAccountId = this.savingsAccountHelper.applyForSavingsApplicationOnDate(clientId, savingsProductId, final Integer savingsAccountId = this.savingsAccountHelper.applyForSavingsApplicationOnDate(clientId, savingsProductId,
SavingsAccountHelper.ACCOUNT_TYPE_INDIVIDUAL, startDateString); SavingsAccountHelper.ACCOUNT_TYPE_INDIVIDUAL, startDateString);
@@ -195,7 +202,8 @@ public class SavingsAccrualAccountingIntegrationTest {
Assertions.assertFalse(accrualTransactions.isEmpty(), "No accrual transactions were found for overdraft."); Assertions.assertFalse(accrualTransactions.isEmpty(), "No accrual transactions were found for overdraft.");
Number firstTransactionIdNumber = (Number) accrualTransactions.get(0).get("id"); Number firstTransactionIdNumber = (Number) accrualTransactions.get(0).get("id");
ArrayList<HashMap> journalEntries = journalEntryHelper.getJournalEntriesByTransactionId("S" + firstTransactionIdNumber.intValue()); ArrayList<HashMap> journalEntries = journalEntryHelper
.getJournalEntriesByTransactionId("S" + firstTransactionIdNumber.intValue());
Assertions.assertFalse(journalEntries.isEmpty(), "No journal entries found for negative accrual."); Assertions.assertFalse(journalEntries.isEmpty(), "No journal entries found for negative accrual.");
boolean debitFound = false; boolean debitFound = false;
@@ -221,6 +229,7 @@ public class SavingsAccrualAccountingIntegrationTest {
Assertions.assertEquals(interest, amountAccrualTransaccion); Assertions.assertEquals(interest, amountAccrualTransaccion);
} }
LOG.info("VALIDATE AMOUNT AND ACCOUNT"); LOG.info("VALIDATE AMOUNT AND ACCOUNT");
});
} }
private List<HashMap> getAccrualTransactions(Integer savingsAccountId) { private List<HashMap> getAccrualTransactions(Integer savingsAccountId) {
@@ -18,6 +18,8 @@
*/ */
package org.apache.fineract.integrationtests; package org.apache.fineract.integrationtests;
import static org.apache.fineract.integrationtests.common.BusinessDateHelper.runAt;
import io.restassured.builder.RequestSpecBuilder; import io.restassured.builder.RequestSpecBuilder;
import io.restassured.builder.ResponseSpecBuilder; import io.restassured.builder.ResponseSpecBuilder;
import io.restassured.http.ContentType; import io.restassured.http.ContentType;
@@ -73,6 +75,7 @@ public class SavingsAccrualIntegrationTest {
@Test @Test
public void testAccrualsAreGeneratedForTenDayPeriod() { public void testAccrualsAreGeneratedForTenDayPeriod() {
runAt("12 August 2021", () -> {
// --- ARRANGE --- // --- ARRANGE ---
final Account assetAccount = this.accountHelper.createAssetAccount(); final Account assetAccount = this.accountHelper.createAssetAccount();
@@ -94,7 +97,7 @@ public class SavingsAccrualIntegrationTest {
final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2020"); final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2020");
Assertions.assertNotNull(clientId, "Error creating client."); Assertions.assertNotNull(clientId, "Error creating client.");
final LocalDate startDate = LocalDate.now(Utils.getZoneIdOfTenant()).minusDays(daysToTest); final LocalDate startDate = LocalDate.of(2021, 8, 12).minusDays(daysToTest);
final String startDateString = DateTimeFormatter.ofPattern("dd MMMM yyyy", Locale.US).format(startDate); final String startDateString = DateTimeFormatter.ofPattern("dd MMMM yyyy", Locale.US).format(startDate);
final Integer savingsAccountId = this.savingsAccountHelper.applyForSavingsApplicationOnDate(clientId, savingsProductId, final Integer savingsAccountId = this.savingsAccountHelper.applyForSavingsApplicationOnDate(clientId, savingsProductId,
@@ -108,7 +111,8 @@ public class SavingsAccrualIntegrationTest {
savingsAccountId); savingsAccountId);
SavingsStatusChecker.verifySavingsIsActive(savingsStatus); SavingsStatusChecker.verifySavingsIsActive(savingsStatus);
this.savingsAccountHelper.depositToSavingsAccount(savingsAccountId, "10000", startDateString, CommonConstants.RESPONSE_RESOURCE_ID); this.savingsAccountHelper.depositToSavingsAccount(savingsAccountId, "10000", startDateString,
CommonConstants.RESPONSE_RESOURCE_ID);
// --- ACT --- // --- ACT ---
schedulerJobHelper.executeAndAwaitJob("Add Accrual Transactions For Savings"); schedulerJobHelper.executeAndAwaitJob("Add Accrual Transactions For Savings");
@@ -124,11 +128,12 @@ public class SavingsAccrualIntegrationTest {
} }
Assertions.assertFalse(accrualTransactions.isEmpty(), "No accrual transactions were found."); Assertions.assertFalse(accrualTransactions.isEmpty(), "No accrual transactions were found.");
long daysBetween = ChronoUnit.DAYS.between(startDate, LocalDate.now(Utils.getZoneIdOfTenant())); long daysBetween = ChronoUnit.DAYS.between(startDate, LocalDate.of(2021, 8, 12));
long actualNumberOfTransactions = accrualTransactions.size(); long actualNumberOfTransactions = accrualTransactions.size();
Assertions.assertTrue(actualNumberOfTransactions >= daysBetween && actualNumberOfTransactions <= daysBetween + 1, "For a period of " Assertions.assertTrue(actualNumberOfTransactions >= daysBetween && actualNumberOfTransactions <= daysBetween + 1,
+ daysBetween + " days, a close number of transactions was expected, but found " + actualNumberOfTransactions); "For a period of " + daysBetween + " days, a close number of transactions was expected, but found "
+ actualNumberOfTransactions);
BigDecimal principal = new BigDecimal("10000"); BigDecimal principal = new BigDecimal("10000");
BigDecimal rate = new BigDecimal(interestRate).divide(new BigDecimal(100)); BigDecimal rate = new BigDecimal(interestRate).divide(new BigDecimal(100));
@@ -141,5 +146,6 @@ public class SavingsAccrualIntegrationTest {
Assertions.assertEquals(0, expectedTotalAccrual.compareTo(actualTotalAccrual), Assertions.assertEquals(0, expectedTotalAccrual.compareTo(actualTotalAccrual),
"The total accrual (" + actualTotalAccrual + ") does not match the expected (" + expectedTotalAccrual + ")"); "The total accrual (" + actualTotalAccrual + ") does not match the expected (" + expectedTotalAccrual + ")");
});
} }
} }