This is an automated email from the ASF dual-hosted git repository.

adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git


The following commit(s) were added to refs/heads/develop by this push:
     new 1148f5f97 FINERACT-1971: saving account annual fee test fix
1148f5f97 is described below

commit 1148f5f97473b677f23445d88134ab3488920502
Author: taskain7 <[email protected]>
AuthorDate: Mon Jan 15 17:54:20 2024 +0100

    FINERACT-1971: saving account annual fee test fix
---
 .../ClientSavingsIntegrationTest.java              | 284 +++++++++++----------
 .../integrationtests/SchedulerJobsTestResults.java |  74 +++---
 .../common/savings/SavingsAccountHelper.java       |  43 ++++
 3 files changed, 240 insertions(+), 161 deletions(-)

diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientSavingsIntegrationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientSavingsIntegrationTest.java
index 5f9be5a8a..df0cfd925 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientSavingsIntegrationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientSavingsIntegrationTest.java
@@ -41,6 +41,8 @@ import java.util.List;
 import java.util.Locale;
 import org.apache.fineract.client.models.PostPaymentTypesRequest;
 import org.apache.fineract.client.models.PostPaymentTypesResponse;
+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;
@@ -631,161 +633,181 @@ public class ClientSavingsIntegrationTest {
     @SuppressWarnings("unchecked")
     @Test
     public void testSavingsAccountCharges() {
+        Integer savingsId = null;
+        try {
+            GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, 
responseSpec, Boolean.TRUE);
+
+            LocalDate submittedDate = LocalDate.of(2022, 9, 28);
+            String submittedDateString = "28 September 2022";
+            BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, 
BusinessDateType.BUSINESS_DATE, submittedDate);
+
+            final ResponseSpecification erroResponseSpec = new 
ResponseSpecBuilder().build();
+            this.savingsAccountHelper = new 
SavingsAccountHelper(this.requestSpec, this.responseSpec);
+            final SavingsAccountHelper validationErrorHelper = new 
SavingsAccountHelper(this.requestSpec, erroResponseSpec);
+
+            final Integer clientID = 
ClientHelper.createClient(this.requestSpec, this.responseSpec);
+            ClientHelper.verifyClientCreatedOnServer(this.requestSpec, 
this.responseSpec, clientID);
+            // Assertions.assertNotNull(clientID);
+            final String minBalanceForInterestCalculation = null;
+            final String minRequiredBalance = null;
+            final String enforceMinRequiredBalance = "false";
+            final boolean allowOverdraft = false;
+            final Integer savingsProductID = 
createSavingsProduct(this.requestSpec, this.responseSpec, 
MINIMUM_OPENING_BALANCE,
+                    minBalanceForInterestCalculation, minRequiredBalance, 
enforceMinRequiredBalance, allowOverdraft);
+            Assertions.assertNotNull(savingsProductID);
 
-        final ResponseSpecification erroResponseSpec = new 
ResponseSpecBuilder().build();
-        this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, 
this.responseSpec);
-        final SavingsAccountHelper validationErrorHelper = new 
SavingsAccountHelper(this.requestSpec, erroResponseSpec);
-
-        final Integer clientID = ClientHelper.createClient(this.requestSpec, 
this.responseSpec);
-        ClientHelper.verifyClientCreatedOnServer(this.requestSpec, 
this.responseSpec, clientID);
-        // Assertions.assertNotNull(clientID);
-        final String minBalanceForInterestCalculation = null;
-        final String minRequiredBalance = null;
-        final String enforceMinRequiredBalance = "false";
-        final boolean allowOverdraft = false;
-        final Integer savingsProductID = 
createSavingsProduct(this.requestSpec, this.responseSpec, 
MINIMUM_OPENING_BALANCE,
-                minBalanceForInterestCalculation, minRequiredBalance, 
enforceMinRequiredBalance, allowOverdraft);
-        Assertions.assertNotNull(savingsProductID);
-
-        Assertions.assertNotNull(savingsProductID);
-        final Integer savingsId = 
this.savingsAccountHelper.applyForSavingsApplication(clientID, 
savingsProductID, ACCOUNT_TYPE_INDIVIDUAL);
-
-        HashMap savingsStatusHashMap = 
SavingsStatusChecker.getStatusOfSavings(this.requestSpec, this.responseSpec, 
savingsId);
-        SavingsStatusChecker.verifySavingsIsPending(savingsStatusHashMap);
-
-        final Integer withdrawalChargeId = 
ChargesHelper.createCharges(this.requestSpec, this.responseSpec,
-                ChargesHelper.getSavingsWithdrawalFeeJSON());
-        Assertions.assertNotNull(withdrawalChargeId);
-
-        this.savingsAccountHelper.addChargesForSavings(savingsId, 
withdrawalChargeId, false);
-        ArrayList<HashMap> chargesPendingState = 
this.savingsAccountHelper.getSavingsCharges(savingsId);
-        Assertions.assertEquals(1, chargesPendingState.size());
+            Assertions.assertNotNull(savingsProductID);
+            savingsId = 
this.savingsAccountHelper.applyForSavingsApplicationOnDate(clientID, 
savingsProductID, ACCOUNT_TYPE_INDIVIDUAL,
+                    submittedDateString);
 
-        Integer savingsChargeId = (Integer) 
chargesPendingState.get(0).get("id");
-        HashMap chargeChanges = 
this.savingsAccountHelper.updateCharges(savingsChargeId, savingsId);
-        Assertions.assertTrue(chargeChanges.containsKey("amount"));
+            HashMap savingsStatusHashMap = 
SavingsStatusChecker.getStatusOfSavings(this.requestSpec, this.responseSpec, 
savingsId);
+            SavingsStatusChecker.verifySavingsIsPending(savingsStatusHashMap);
 
-        Integer deletedChargeId = 
this.savingsAccountHelper.deleteCharge(savingsChargeId, savingsId);
-        assertEquals(savingsChargeId, deletedChargeId);
+            final Integer withdrawalChargeId = 
ChargesHelper.createCharges(this.requestSpec, this.responseSpec,
+                    ChargesHelper.getSavingsWithdrawalFeeJSON());
+            Assertions.assertNotNull(withdrawalChargeId);
 
-        chargesPendingState = 
this.savingsAccountHelper.getSavingsCharges(savingsId);
-        Assertions.assertTrue(chargesPendingState == null || 
chargesPendingState.size() == 0);
+            this.savingsAccountHelper.addChargesForSavings(savingsId, 
withdrawalChargeId, false);
+            ArrayList<HashMap> chargesPendingState = 
this.savingsAccountHelper.getSavingsCharges(savingsId);
+            Assertions.assertEquals(1, chargesPendingState.size());
 
-        savingsStatusHashMap = 
this.savingsAccountHelper.approveSavings(savingsId);
-        SavingsStatusChecker.verifySavingsIsApproved(savingsStatusHashMap);
+            Integer savingsChargeId = (Integer) 
chargesPendingState.get(0).get("id");
+            HashMap chargeChanges = 
this.savingsAccountHelper.updateCharges(savingsChargeId, savingsId);
+            Assertions.assertTrue(chargeChanges.containsKey("amount"));
 
-        savingsStatusHashMap = 
this.savingsAccountHelper.activateSavings(savingsId);
-        SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
+            Integer deletedChargeId = 
this.savingsAccountHelper.deleteCharge(savingsChargeId, savingsId);
+            assertEquals(savingsChargeId, deletedChargeId);
 
-        final Integer chargeId = ChargesHelper.createCharges(this.requestSpec, 
this.responseSpec, ChargesHelper.getSavingsAnnualFeeJSON());
-        Assertions.assertNotNull(chargeId);
+            chargesPendingState = 
this.savingsAccountHelper.getSavingsCharges(savingsId);
+            Assertions.assertTrue(chargesPendingState == null || 
chargesPendingState.size() == 0);
 
-        ArrayList<HashMap> charges = 
this.savingsAccountHelper.getSavingsCharges(savingsId);
-        Assertions.assertTrue(charges == null || charges.size() == 0);
-
-        this.savingsAccountHelper.addChargesForSavings(savingsId, chargeId, 
true);
-        charges = this.savingsAccountHelper.getSavingsCharges(savingsId);
-        Assertions.assertEquals(1, charges.size());
-
-        HashMap savingsChargeForPay = charges.get(0);
-        Integer annualSavingsChargeId = (Integer) 
savingsChargeForPay.get("id");
-
-        ArrayList<HashMap> savingsAccountErrorData = (ArrayList<HashMap>) 
validationErrorHelper.inactivateCharge(annualSavingsChargeId,
-                savingsId, CommonConstants.RESPONSE_ERROR);
-        
assertEquals("validation.msg.savingsaccountcharge.inactivation.of.charge.not.allowed.when.charge.is.due",
-                
savingsAccountErrorData.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
+            savingsStatusHashMap = 
this.savingsAccountHelper.approveSavingsOnDate(savingsId, submittedDateString);
+            SavingsStatusChecker.verifySavingsIsApproved(savingsStatusHashMap);
 
-        SimpleDateFormat sdf = new 
SimpleDateFormat(CommonConstants.DATE_FORMAT, Locale.US);
-        Calendar cal = Calendar.getInstance();
-        List dates = (List) savingsChargeForPay.get("dueDate");
-        cal.set(Calendar.YEAR, (Integer) dates.get(0));
-        cal.set(Calendar.MONTH, (Integer) dates.get(1) - 1);
-        cal.set(Calendar.DAY_OF_MONTH, (Integer) dates.get(2));
-        int n = 0;
-        Calendar current = Calendar.getInstance();
-        while (cal.compareTo(current) < 0) {
-            n++;
-            cal.set(Calendar.YEAR, (Integer) dates.get(0) + n);
-        }
-        cal.set(Calendar.YEAR, (Integer) dates.get(0));
-        cal.set(Calendar.MONTH, (Integer) dates.get(1) - 1);
-        cal.set(Calendar.DAY_OF_MONTH, (Integer) dates.get(2));
+            savingsStatusHashMap = 
this.savingsAccountHelper.activateSavings(savingsId, submittedDateString);
+            SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
 
-        for (int i = 1; i <= n; i++) {
-            this.savingsAccountHelper.payCharge((Integer) 
savingsChargeForPay.get("id"), savingsId,
-                    ((Float) savingsChargeForPay.get("amount")).toString(), 
sdf.format(cal.getTime()));
-            HashMap paidCharge = 
this.savingsAccountHelper.getSavingsCharge(savingsId, (Integer) 
savingsChargeForPay.get("id"));
-            Float expectedValue = (Float) savingsChargeForPay.get("amount") * 
i;
-            assertEquals(expectedValue, paidCharge.get("amountPaid"));
-            cal.set(Calendar.YEAR, (Integer) dates.get(0) + i);
-        }
+            final Integer chargeId = 
ChargesHelper.createCharges(this.requestSpec, this.responseSpec,
+                    ChargesHelper.getSavingsAnnualFeeJSON());
+            Assertions.assertNotNull(chargeId);
+
+            ArrayList<HashMap> charges = 
this.savingsAccountHelper.getSavingsCharges(savingsId);
+            Assertions.assertTrue(charges == null || charges.size() == 0);
+
+            
this.savingsAccountHelper.addChargesForSavingsWithDueDateAndFeeOnMonthDay(savingsId,
 chargeId, "10 January 2023", 100,
+                    "15 January");
+            charges = this.savingsAccountHelper.getSavingsCharges(savingsId);
+            Assertions.assertEquals(1, charges.size());
+
+            HashMap savingsChargeForPay = charges.get(0);
+            Integer annualSavingsChargeId = (Integer) 
savingsChargeForPay.get("id");
+
+            BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, 
BusinessDateType.BUSINESS_DATE, LocalDate.of(2023, 1, 16));
+
+            ArrayList<HashMap> savingsAccountErrorData = (ArrayList<HashMap>) 
validationErrorHelper.inactivateCharge(annualSavingsChargeId,
+                    savingsId, CommonConstants.RESPONSE_ERROR);
+            
assertEquals("validation.msg.savingsaccountcharge.inactivation.of.charge.not.allowed.when.charge.is.due",
+                    
savingsAccountErrorData.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
+
+            SimpleDateFormat sdf = new 
SimpleDateFormat(CommonConstants.DATE_FORMAT, Locale.US);
+            Calendar cal = Calendar.getInstance();
+            List dates = (List) savingsChargeForPay.get("dueDate");
+            cal.set(Calendar.YEAR, (Integer) dates.get(0));
+            cal.set(Calendar.MONTH, (Integer) dates.get(1) - 1);
+            cal.set(Calendar.DAY_OF_MONTH, (Integer) dates.get(2));
+            int n = 0;
+            Calendar current = Calendar.getInstance();
+            while (cal.compareTo(current) < 0) {
+                n++;
+                cal.set(Calendar.YEAR, (Integer) dates.get(0) + n);
+            }
+            cal.set(Calendar.YEAR, (Integer) dates.get(0));
+            cal.set(Calendar.MONTH, (Integer) dates.get(1) - 1);
+            cal.set(Calendar.DAY_OF_MONTH, (Integer) dates.get(2));
+
+            BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, 
BusinessDateType.BUSINESS_DATE, LocalDate.of(2024, 1, 17));
+            for (int i = 1; i <= n; i++) {
+                this.savingsAccountHelper.payCharge((Integer) 
savingsChargeForPay.get("id"), savingsId,
+                        ((Float) 
savingsChargeForPay.get("amount")).toString(), sdf.format(cal.getTime()));
+                HashMap paidCharge = 
this.savingsAccountHelper.getSavingsCharge(savingsId, (Integer) 
savingsChargeForPay.get("id"));
+                Float expectedValue = (Float) 
savingsChargeForPay.get("amount") * i;
+                assertEquals(expectedValue, paidCharge.get("amountPaid"));
+                cal.set(Calendar.YEAR, (Integer) dates.get(0) + i);
+            }
 
-        Integer inactivatedChargeId = (Integer) 
this.savingsAccountHelper.inactivateCharge(annualSavingsChargeId, savingsId,
-                CommonConstants.RESPONSE_RESOURCE_ID);
-        assertEquals(annualSavingsChargeId, inactivatedChargeId, "Inactivated 
Savings Charges Id");
+            Integer inactivatedChargeId = (Integer) 
this.savingsAccountHelper.inactivateCharge(annualSavingsChargeId, savingsId,
+                    CommonConstants.RESPONSE_RESOURCE_ID);
+            assertEquals(annualSavingsChargeId, inactivatedChargeId, 
"Inactivated Savings Charges Id");
 
-        final Integer monthlyFeechargeId = 
ChargesHelper.createCharges(this.requestSpec, this.responseSpec,
-                ChargesHelper.getSavingsMonthlyFeeJSON());
-        Assertions.assertNotNull(monthlyFeechargeId);
+            final Integer monthlyFeechargeId = 
ChargesHelper.createCharges(this.requestSpec, this.responseSpec,
+                    ChargesHelper.getSavingsMonthlyFeeJSON());
+            Assertions.assertNotNull(monthlyFeechargeId);
 
-        this.savingsAccountHelper.addChargesForSavings(savingsId, 
monthlyFeechargeId, true);
-        charges = this.savingsAccountHelper.getSavingsCharges(savingsId);
-        Assertions.assertEquals(2, charges.size());
+            this.savingsAccountHelper.addChargesForSavings(savingsId, 
monthlyFeechargeId, true);
+            charges = this.savingsAccountHelper.getSavingsCharges(savingsId);
+            Assertions.assertEquals(2, charges.size());
 
-        HashMap savingsChargeForWaive = charges.get(1);
-        final Integer monthlySavingsCharge = (Integer) 
savingsChargeForWaive.get("id");
+            HashMap savingsChargeForWaive = charges.get(1);
+            final Integer monthlySavingsCharge = (Integer) 
savingsChargeForWaive.get("id");
 
-        savingsAccountErrorData = (ArrayList<HashMap>) 
validationErrorHelper.inactivateCharge(monthlySavingsCharge, savingsId,
-                CommonConstants.RESPONSE_ERROR);
-        
assertEquals("validation.msg.savingsaccountcharge.inactivation.of.charge.not.allowed.when.charge.is.due",
-                
savingsAccountErrorData.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
+            savingsAccountErrorData = (ArrayList<HashMap>) 
validationErrorHelper.inactivateCharge(monthlySavingsCharge, savingsId,
+                    CommonConstants.RESPONSE_ERROR);
+            
assertEquals("validation.msg.savingsaccountcharge.inactivation.of.charge.not.allowed.when.charge.is.due",
+                    
savingsAccountErrorData.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
 
-        this.savingsAccountHelper.waiveCharge((Integer) 
savingsChargeForWaive.get("id"), savingsId);
-        HashMap waiveCharge = 
this.savingsAccountHelper.getSavingsCharge(savingsId, (Integer) 
savingsChargeForWaive.get("id"));
-        assertEquals(savingsChargeForWaive.get("amount"), 
waiveCharge.get("amountWaived"));
+            this.savingsAccountHelper.waiveCharge((Integer) 
savingsChargeForWaive.get("id"), savingsId);
+            HashMap waiveCharge = 
this.savingsAccountHelper.getSavingsCharge(savingsId, (Integer) 
savingsChargeForWaive.get("id"));
+            assertEquals(savingsChargeForWaive.get("amount"), 
waiveCharge.get("amountWaived"));
 
-        this.savingsAccountHelper.waiveCharge((Integer) 
savingsChargeForWaive.get("id"), savingsId);
-        waiveCharge = this.savingsAccountHelper.getSavingsCharge(savingsId, 
(Integer) savingsChargeForWaive.get("id"));
-        BigDecimal totalWaiveAmount = 
BigDecimal.valueOf(Double.valueOf((Float) savingsChargeForWaive.get("amount")));
-        totalWaiveAmount = totalWaiveAmount.add(totalWaiveAmount);
-        assertEquals(totalWaiveAmount.floatValue(), 
waiveCharge.get("amountWaived"));
+            this.savingsAccountHelper.waiveCharge((Integer) 
savingsChargeForWaive.get("id"), savingsId);
+            waiveCharge = 
this.savingsAccountHelper.getSavingsCharge(savingsId, (Integer) 
savingsChargeForWaive.get("id"));
+            BigDecimal totalWaiveAmount = 
BigDecimal.valueOf(Double.valueOf((Float) savingsChargeForWaive.get("amount")));
+            totalWaiveAmount = totalWaiveAmount.add(totalWaiveAmount);
+            assertEquals(totalWaiveAmount.floatValue(), 
waiveCharge.get("amountWaived"));
 
-        final Integer weeklyFeeId = 
ChargesHelper.createCharges(this.requestSpec, this.responseSpec,
-                ChargesHelper.getSavingsWeeklyFeeJSON());
-        Assertions.assertNotNull(weeklyFeeId);
+            final Integer weeklyFeeId = 
ChargesHelper.createCharges(this.requestSpec, this.responseSpec,
+                    ChargesHelper.getSavingsWeeklyFeeJSON());
+            Assertions.assertNotNull(weeklyFeeId);
 
-        this.savingsAccountHelper.addChargesForSavings(savingsId, weeklyFeeId, 
true);
-        charges = this.savingsAccountHelper.getSavingsCharges(savingsId);
-        Assertions.assertEquals(3, charges.size());
+            this.savingsAccountHelper.addChargesForSavings(savingsId, 
weeklyFeeId, true);
+            charges = this.savingsAccountHelper.getSavingsCharges(savingsId);
+            Assertions.assertEquals(3, charges.size());
 
-        savingsChargeForPay = charges.get(2);
-        final Integer weeklySavingsFeeId = (Integer) 
savingsChargeForPay.get("id");
+            savingsChargeForPay = charges.get(2);
+            final Integer weeklySavingsFeeId = (Integer) 
savingsChargeForPay.get("id");
 
-        savingsAccountErrorData = (ArrayList<HashMap>) 
validationErrorHelper.inactivateCharge(weeklySavingsFeeId, savingsId,
-                CommonConstants.RESPONSE_ERROR);
-        
assertEquals("validation.msg.savingsaccountcharge.inactivation.of.charge.not.allowed.when.charge.is.due",
-                
savingsAccountErrorData.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
+            savingsAccountErrorData = (ArrayList<HashMap>) 
validationErrorHelper.inactivateCharge(weeklySavingsFeeId, savingsId,
+                    CommonConstants.RESPONSE_ERROR);
+            
assertEquals("validation.msg.savingsaccountcharge.inactivation.of.charge.not.allowed.when.charge.is.due",
+                    
savingsAccountErrorData.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
 
-        cal = Calendar.getInstance();
-        dates = (List) savingsChargeForPay.get("dueDate");
-        cal.set(Calendar.YEAR, (Integer) dates.get(0));
-        cal.set(Calendar.MONTH, (Integer) dates.get(1) - 1);
-        cal.set(Calendar.DAY_OF_MONTH, (Integer) dates.get(2));
+            cal = Calendar.getInstance();
+            dates = (List) savingsChargeForPay.get("dueDate");
+            cal.set(Calendar.YEAR, (Integer) dates.get(0));
+            cal.set(Calendar.MONTH, (Integer) dates.get(1) - 1);
+            cal.set(Calendar.DAY_OF_MONTH, (Integer) dates.get(2));
 
-        // Depositing huge amount as scheduler job deducts the fee amount
-        Integer depositTransactionId = (Integer) 
this.savingsAccountHelper.depositToSavingsAccount(savingsId, "100000",
-                SavingsAccountHelper.TRANSACTION_DATE, 
CommonConstants.RESPONSE_RESOURCE_ID);
-        Assertions.assertNotNull(depositTransactionId);
+            // Depositing huge amount as scheduler job deducts the fee amount
+            String transactionDate = "17 January 2024";
+            Integer depositTransactionId = (Integer) 
this.savingsAccountHelper.depositToSavingsAccount(savingsId, "100000", 
transactionDate,
+                    CommonConstants.RESPONSE_RESOURCE_ID);
+            Assertions.assertNotNull(depositTransactionId);
 
-        this.savingsAccountHelper.payCharge((Integer) 
savingsChargeForPay.get("id"), savingsId,
-                ((Float) savingsChargeForPay.get("amount")).toString(), 
sdf.format(cal.getTime()));
-        HashMap paidCharge = 
this.savingsAccountHelper.getSavingsCharge(savingsId, (Integer) 
savingsChargeForPay.get("id"));
-        assertEquals(savingsChargeForPay.get("amount"), 
paidCharge.get("amountPaid"));
-        List nextDueDates = (List) paidCharge.get("dueDate");
-        LocalDate nextDueDate = LocalDate.of((Integer) nextDueDates.get(0), 
(Integer) nextDueDates.get(1), (Integer) nextDueDates.get(2));
-        LocalDate expectedNextDueDate = LocalDate.of((Integer) dates.get(0), 
(Integer) dates.get(1), (Integer) dates.get(2))
-                .plusWeeks((Integer) paidCharge.get("feeInterval"));
-        assertEquals(expectedNextDueDate, nextDueDate);
+            this.savingsAccountHelper.payCharge((Integer) 
savingsChargeForPay.get("id"), savingsId,
+                    ((Float) savingsChargeForPay.get("amount")).toString(), 
sdf.format(cal.getTime()));
+            HashMap paidCharge = 
this.savingsAccountHelper.getSavingsCharge(savingsId, (Integer) 
savingsChargeForPay.get("id"));
+            assertEquals(savingsChargeForPay.get("amount"), 
paidCharge.get("amountPaid"));
+            List nextDueDates = (List) paidCharge.get("dueDate");
+            LocalDate nextDueDate = LocalDate.of((Integer) 
nextDueDates.get(0), (Integer) nextDueDates.get(1),
+                    (Integer) nextDueDates.get(2));
+            LocalDate expectedNextDueDate = LocalDate.of((Integer) 
dates.get(0), (Integer) dates.get(1), (Integer) dates.get(2))
+                    .plusWeeks((Integer) paidCharge.get("feeInterval"));
+            assertEquals(expectedNextDueDate, nextDueDate);
+        } finally {
+            BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, 
BusinessDateType.BUSINESS_DATE, LocalDate.of(2024, 11, 11));
+            savingsAccountHelper.closeSavingsAccountOnDate(savingsId, "true", 
"11 November 2024");
+            GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, 
responseSpec, Boolean.FALSE);
+        }
     }
 
     /***
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/SchedulerJobsTestResults.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/SchedulerJobsTestResults.java
index 166019e81..a54b5cb33 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/SchedulerJobsTestResults.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/SchedulerJobsTestResults.java
@@ -142,48 +142,62 @@ public class SchedulerJobsTestResults {
 
     @Test
     public void testApplyAnnualFeeForSavingsJobOutcome() throws 
InterruptedException {
-        this.savingsAccountHelper = new SavingsAccountHelper(requestSpec, 
responseSpec);
+        Integer savingsId = null;
+        try {
+            GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, 
responseSpec, Boolean.TRUE);
 
-        final Integer clientID = ClientHelper.createClient(requestSpec, 
responseSpec);
-        Assertions.assertNotNull(clientID);
+            LocalDate submittedDate = LocalDate.of(2022, 9, 28);
+            String submittedDateString = "28 September 2022";
+            BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, 
BusinessDateType.BUSINESS_DATE, submittedDate);
+            this.savingsAccountHelper = new SavingsAccountHelper(requestSpec, 
responseSpec);
 
-        final Integer savingsProductID = createSavingsProduct(requestSpec, 
responseSpec,
-                ClientSavingsIntegrationTest.MINIMUM_OPENING_BALANCE);
-        Assertions.assertNotNull(savingsProductID);
+            final Integer clientID = ClientHelper.createClient(requestSpec, 
responseSpec);
+            Assertions.assertNotNull(clientID);
 
-        final Integer savingsId = 
this.savingsAccountHelper.applyForSavingsApplication(clientID, savingsProductID,
-                ClientSavingsIntegrationTest.ACCOUNT_TYPE_INDIVIDUAL);
-        Assertions.assertNotNull(savingsProductID);
+            final Integer savingsProductID = createSavingsProduct(requestSpec, 
responseSpec,
+                    ClientSavingsIntegrationTest.MINIMUM_OPENING_BALANCE);
+            Assertions.assertNotNull(savingsProductID);
 
-        HashMap savingsStatusHashMap = 
SavingsStatusChecker.getStatusOfSavings(requestSpec, responseSpec, savingsId);
-        SavingsStatusChecker.verifySavingsIsPending(savingsStatusHashMap);
+            savingsId = 
this.savingsAccountHelper.applyForSavingsApplicationOnDate(clientID, 
savingsProductID,
+                    ClientSavingsIntegrationTest.ACCOUNT_TYPE_INDIVIDUAL, 
submittedDateString);
+            Assertions.assertNotNull(savingsProductID);
 
-        final Integer annualFeeChargeId = 
ChargesHelper.createCharges(requestSpec, responseSpec, 
ChargesHelper.getSavingsAnnualFeeJSON());
-        Assertions.assertNotNull(annualFeeChargeId);
+            HashMap savingsStatusHashMap = 
SavingsStatusChecker.getStatusOfSavings(requestSpec, responseSpec, savingsId);
+            SavingsStatusChecker.verifySavingsIsPending(savingsStatusHashMap);
 
-        this.savingsAccountHelper.addChargesForSavings(savingsId, 
annualFeeChargeId, true);
-        ArrayList<HashMap> chargesPendingState = 
this.savingsAccountHelper.getSavingsCharges(savingsId);
-        Assertions.assertEquals(1, chargesPendingState.size());
+            final Integer annualFeeChargeId = 
ChargesHelper.createCharges(requestSpec, responseSpec,
+                    ChargesHelper.getSavingsAnnualFeeJSON());
+            Assertions.assertNotNull(annualFeeChargeId);
 
-        savingsStatusHashMap = 
this.savingsAccountHelper.approveSavings(savingsId);
-        SavingsStatusChecker.verifySavingsIsApproved(savingsStatusHashMap);
+            
this.savingsAccountHelper.addChargesForSavingsWithDueDateAndFeeOnMonthDay(savingsId,
 annualFeeChargeId, "10 January 2023", 100,
+                    "15 January");
+            ArrayList<HashMap> chargesPendingState = 
this.savingsAccountHelper.getSavingsCharges(savingsId);
+            Assertions.assertEquals(1, chargesPendingState.size());
 
-        savingsStatusHashMap = 
this.savingsAccountHelper.activateSavings(savingsId);
-        SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
+            savingsStatusHashMap = 
this.savingsAccountHelper.approveSavingsOnDate(savingsId, submittedDateString);
+            SavingsStatusChecker.verifySavingsIsApproved(savingsStatusHashMap);
 
-        String JobName = "Apply Annual Fee For Savings";
+            savingsStatusHashMap = 
this.savingsAccountHelper.activateSavings(savingsId, submittedDateString);
+            SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap);
 
-        this.schedulerJobHelper.executeAndAwaitJob(JobName);
+            BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, 
BusinessDateType.BUSINESS_DATE, LocalDate.of(2022, 11, 11));
+            String JobName = "Apply Annual Fee For Savings";
+
+            this.schedulerJobHelper.executeAndAwaitJob(JobName);
 
-        final HashMap savingsDetails = 
this.savingsAccountHelper.getSavingsDetails(savingsId);
-        final HashMap annualFeeDetails = (HashMap) 
savingsDetails.get("annualFee");
-        ArrayList<Integer> annualFeeDueDateAsArrayList = (ArrayList<Integer>) 
annualFeeDetails.get("dueDate");
-        LocalDate nextDueDateForAnnualFee = 
LocalDate.of(annualFeeDueDateAsArrayList.get(0), 
annualFeeDueDateAsArrayList.get(1),
-                annualFeeDueDateAsArrayList.get(2));
-        LocalDate todaysDate = Utils.getLocalDateOfTenant();
+            final HashMap savingsDetails = 
this.savingsAccountHelper.getSavingsDetails(savingsId);
+            final HashMap annualFeeDetails = (HashMap) 
savingsDetails.get("annualFee");
+            ArrayList<Integer> annualFeeDueDateAsArrayList = 
(ArrayList<Integer>) annualFeeDetails.get("dueDate");
+            LocalDate nextDueDateForAnnualFee = 
LocalDate.of(annualFeeDueDateAsArrayList.get(0), 
annualFeeDueDateAsArrayList.get(1),
+                    annualFeeDueDateAsArrayList.get(2));
+            LocalDate expectedDueDate = LocalDate.of(2023, 1, 15);
 
-        Truth.assertWithMessage("Verifying that all due Annual Fees have been 
paid").that(nextDueDateForAnnualFee)
-                .isGreaterThan(todaysDate);
+            Truth.assertWithMessage("Verifying that all due Annual Fees have 
been paid").that(nextDueDateForAnnualFee)
+                    .isEquivalentAccordingToCompareTo(expectedDueDate);
+        } finally {
+            savingsAccountHelper.closeSavingsAccountOnDate(savingsId, "true", 
"11 November 2022");
+            GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, 
responseSpec, Boolean.FALSE);
+        }
     }
 
     @Test
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/SavingsAccountHelper.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/SavingsAccountHelper.java
index 98b604574..061f8f887 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/SavingsAccountHelper.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/savings/SavingsAccountHelper.java
@@ -264,12 +264,24 @@ public class SavingsAccountHelper extends IntegrationTest 
{
                 IS_BLOCK);
     }
 
+    public HashMap activateSavings(final Integer savingsID, final String 
activationDate) {
+        LOG.info("---------------------------------- ACTIVATING SAVINGS 
APPLICATION ----------------------------------");
+        return 
performSavingApplicationActions(createSavingsOperationURL(ACTIVATE_SAVINGS_COMMAND,
 savingsID),
+                getActivatedSavingsAsJSONOnDate(activationDate), IS_BLOCK);
+    }
+
     public HashMap closeSavingsAccount(final Integer savingsID, String 
withdrawBalance) {
         LOG.info("---------------------------------- CLOSE SAVINGS APPLICATION 
----------------------------------");
         return 
performSavingApplicationActions(createSavingsOperationURL(CLOSE_SAVINGS_COMMAND,
 savingsID),
                 getCloseAccountJSON(withdrawBalance, LAST_TRANSACTION_DATE), 
IS_BLOCK);
     }
 
+    public HashMap closeSavingsAccountOnDate(final Integer savingsID, String 
withdrawBalance, final String closedOnDate) {
+        LOG.info("---------------------------------- CLOSE SAVINGS APPLICATION 
----------------------------------");
+        return 
performSavingApplicationActions(createSavingsOperationURL(CLOSE_SAVINGS_COMMAND,
 savingsID),
+                getCloseAccountJSON(withdrawBalance, closedOnDate), IS_BLOCK);
+    }
+
     public Object deleteSavingsApplication(final Integer savingsId, final 
String jsonAttributeToGetBack) {
         LOG.info("---------------------------------- DELETE SAVINGS 
APPLICATION ----------------------------------");
         return Utils.performServerDelete(this.requestSpec, this.responseSpec,
@@ -368,6 +380,13 @@ public class SavingsAccountHelper extends IntegrationTest {
                 getPeriodChargeRequestJSONWithDueDate(chargeId, addDueDate, 
amount), CommonConstants.RESPONSE_RESOURCE_ID);
     }
 
+    public Integer addChargesForSavingsWithDueDateAndFeeOnMonthDay(final 
Integer savingsId, final Integer chargeId, String addDueDate,
+            Integer amount, String feeOnMonthDay) {
+        return (Integer) performSavingActions(SAVINGS_ACCOUNT_URL + "/" + 
savingsId + "/charges?" + Utils.TENANT_IDENTIFIER,
+                
getPeriodChargeRequestJSONWithDueDateAndFeeOnMonthDay(chargeId, addDueDate, 
amount, feeOnMonthDay),
+                CommonConstants.RESPONSE_RESOURCE_ID);
+    }
+
     public Integer payCharge(final Integer chargeId, final Integer savingsId, 
String amount, String dueDate) {
         return (Integer) performSavingActions(createChargesURL("paycharge", 
savingsId, chargeId), getSavingsPayChargeJSON(amount, dueDate),
                 CommonConstants.RESPONSE_RESOURCE_ID);
@@ -493,6 +512,16 @@ public class SavingsAccountHelper extends IntegrationTest {
         return savingsAccountActivateJson;
     }
 
+    private String getActivatedSavingsAsJSONOnDate(final String 
activationDate) {
+        final HashMap<String, String> map = new HashMap<>();
+        map.put("locale", CommonConstants.LOCALE);
+        map.put("dateFormat", CommonConstants.DATE_FORMAT);
+        map.put("activatedOnDate", activationDate);
+        String savingsAccountActivateJson = new Gson().toJson(map);
+        LOG.info(savingsAccountActivateJson);
+        return savingsAccountActivateJson;
+    }
+
     private String getActivatedSavingsAsForHoldJSON() {
         final HashMap<String, String> map = new HashMap<>();
         map.put("locale", CommonConstants.LOCALE);
@@ -760,6 +789,20 @@ public class SavingsAccountHelper extends IntegrationTest {
         return json;
     }
 
+    private String 
getPeriodChargeRequestJSONWithDueDateAndFeeOnMonthDay(Integer chargeId, String 
addDueDate, Integer amount,
+            String feeOnMonthDay) {
+        final HashMap<String, Object> map = new HashMap<>();
+        map.put("chargeId", chargeId);
+        map.put("amount", amount);
+        map.put("feeOnMonthDay", feeOnMonthDay);
+        map.put("locale", CommonConstants.LOCALE);
+        map.put("monthDayFormat", "dd MMMM");
+        map.put("dateFormat", "dd MMMM yyy");
+        map.put("dueDate", addDueDate);
+        String json = new Gson().toJson(map);
+        return json;
+    }
+
     private String getAccountActivationJSON(final String activationDate) {
         final HashMap<String, Object> map = new HashMap<>();
         map.put("locale", CommonConstants.LOCALE);


Reply via email to