From 1148f5f97473b677f23445d88134ab3488920502 Mon Sep 17 00:00:00 2001 From: taskain7 Date: Mon, 15 Jan 2024 17:54:20 +0100 Subject: [PATCH] FINERACT-1971: saving account annual fee test fix --- .../ClientSavingsIntegrationTest.java | 288 ++++++++++-------- .../SchedulerJobsTestResults.java | 74 +++-- .../common/savings/SavingsAccountHelper.java | 43 +++ 3 files changed, 242 insertions(+), 163 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); - final ResponseSpecification erroResponseSpec = new ResponseSpecBuilder().build(); - this.savingsAccountHelper = new SavingsAccountHelper(this.requestSpec, this.responseSpec); - final SavingsAccountHelper validationErrorHelper = new SavingsAccountHelper(this.requestSpec, erroResponseSpec); + LocalDate submittedDate = LocalDate.of(2022, 9, 28); + String submittedDateString = "28 September 2022"; + BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, submittedDate); - 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); - Assertions.assertNotNull(savingsProductID); - final Integer savingsId = this.savingsAccountHelper.applyForSavingsApplication(clientID, savingsProductID, ACCOUNT_TYPE_INDIVIDUAL); + 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); - HashMap savingsStatusHashMap = SavingsStatusChecker.getStatusOfSavings(this.requestSpec, this.responseSpec, savingsId); - SavingsStatusChecker.verifySavingsIsPending(savingsStatusHashMap); + Assertions.assertNotNull(savingsProductID); + savingsId = this.savingsAccountHelper.applyForSavingsApplicationOnDate(clientID, savingsProductID, ACCOUNT_TYPE_INDIVIDUAL, + submittedDateString); - final Integer withdrawalChargeId = ChargesHelper.createCharges(this.requestSpec, this.responseSpec, - ChargesHelper.getSavingsWithdrawalFeeJSON()); - Assertions.assertNotNull(withdrawalChargeId); + HashMap savingsStatusHashMap = SavingsStatusChecker.getStatusOfSavings(this.requestSpec, this.responseSpec, savingsId); + SavingsStatusChecker.verifySavingsIsPending(savingsStatusHashMap); - this.savingsAccountHelper.addChargesForSavings(savingsId, withdrawalChargeId, false); - ArrayList chargesPendingState = this.savingsAccountHelper.getSavingsCharges(savingsId); - Assertions.assertEquals(1, chargesPendingState.size()); + final Integer withdrawalChargeId = ChargesHelper.createCharges(this.requestSpec, this.responseSpec, + ChargesHelper.getSavingsWithdrawalFeeJSON()); + Assertions.assertNotNull(withdrawalChargeId); - Integer savingsChargeId = (Integer) chargesPendingState.get(0).get("id"); - HashMap chargeChanges = this.savingsAccountHelper.updateCharges(savingsChargeId, savingsId); - Assertions.assertTrue(chargeChanges.containsKey("amount")); + this.savingsAccountHelper.addChargesForSavings(savingsId, withdrawalChargeId, false); + ArrayList chargesPendingState = this.savingsAccountHelper.getSavingsCharges(savingsId); + Assertions.assertEquals(1, chargesPendingState.size()); - Integer deletedChargeId = this.savingsAccountHelper.deleteCharge(savingsChargeId, savingsId); - assertEquals(savingsChargeId, deletedChargeId); + Integer savingsChargeId = (Integer) chargesPendingState.get(0).get("id"); + HashMap chargeChanges = this.savingsAccountHelper.updateCharges(savingsChargeId, savingsId); + Assertions.assertTrue(chargeChanges.containsKey("amount")); - chargesPendingState = this.savingsAccountHelper.getSavingsCharges(savingsId); - Assertions.assertTrue(chargesPendingState == null || chargesPendingState.size() == 0); + Integer deletedChargeId = this.savingsAccountHelper.deleteCharge(savingsChargeId, savingsId); + assertEquals(savingsChargeId, deletedChargeId); - savingsStatusHashMap = this.savingsAccountHelper.approveSavings(savingsId); - SavingsStatusChecker.verifySavingsIsApproved(savingsStatusHashMap); + chargesPendingState = this.savingsAccountHelper.getSavingsCharges(savingsId); + Assertions.assertTrue(chargesPendingState == null || chargesPendingState.size() == 0); - savingsStatusHashMap = this.savingsAccountHelper.activateSavings(savingsId); - SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap); + savingsStatusHashMap = this.savingsAccountHelper.approveSavingsOnDate(savingsId, submittedDateString); + SavingsStatusChecker.verifySavingsIsApproved(savingsStatusHashMap); - final Integer chargeId = ChargesHelper.createCharges(this.requestSpec, this.responseSpec, ChargesHelper.getSavingsAnnualFeeJSON()); - Assertions.assertNotNull(chargeId); + savingsStatusHashMap = this.savingsAccountHelper.activateSavings(savingsId, submittedDateString); + SavingsStatusChecker.verifySavingsIsActive(savingsStatusHashMap); - ArrayList charges = this.savingsAccountHelper.getSavingsCharges(savingsId); - Assertions.assertTrue(charges == null || charges.size() == 0); + final Integer chargeId = ChargesHelper.createCharges(this.requestSpec, this.responseSpec, + ChargesHelper.getSavingsAnnualFeeJSON()); + Assertions.assertNotNull(chargeId); - this.savingsAccountHelper.addChargesForSavings(savingsId, chargeId, true); - charges = this.savingsAccountHelper.getSavingsCharges(savingsId); - Assertions.assertEquals(1, charges.size()); + ArrayList charges = this.savingsAccountHelper.getSavingsCharges(savingsId); + Assertions.assertTrue(charges == null || charges.size() == 0); - HashMap savingsChargeForPay = charges.get(0); - Integer annualSavingsChargeId = (Integer) savingsChargeForPay.get("id"); + this.savingsAccountHelper.addChargesForSavingsWithDueDateAndFeeOnMonthDay(savingsId, chargeId, "10 January 2023", 100, + "15 January"); + charges = this.savingsAccountHelper.getSavingsCharges(savingsId); + Assertions.assertEquals(1, charges.size()); - ArrayList savingsAccountErrorData = (ArrayList) 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)); + HashMap savingsChargeForPay = charges.get(0); + Integer annualSavingsChargeId = (Integer) savingsChargeForPay.get("id"); - 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(2023, 1, 16)); + + ArrayList savingsAccountErrorData = (ArrayList) 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"); + + 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()); + + HashMap savingsChargeForWaive = charges.get(1); + final Integer monthlySavingsCharge = (Integer) savingsChargeForWaive.get("id"); + + savingsAccountErrorData = (ArrayList) 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); + 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); + + 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"); + + savingsAccountErrorData = (ArrayList) 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)); + + // 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); - 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); + 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); } - - 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); - - 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"); - - savingsAccountErrorData = (ArrayList) 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); - 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); - - 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"); - - savingsAccountErrorData = (ArrayList) 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)); - - // 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); - - 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); } /*** 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 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 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"; - final HashMap savingsDetails = this.savingsAccountHelper.getSavingsDetails(savingsId); - final HashMap annualFeeDetails = (HashMap) savingsDetails.get("annualFee"); - ArrayList annualFeeDueDateAsArrayList = (ArrayList) annualFeeDetails.get("dueDate"); - LocalDate nextDueDateForAnnualFee = LocalDate.of(annualFeeDueDateAsArrayList.get(0), annualFeeDueDateAsArrayList.get(1), - annualFeeDueDateAsArrayList.get(2)); - LocalDate todaysDate = Utils.getLocalDateOfTenant(); + this.schedulerJobHelper.executeAndAwaitJob(JobName); - Truth.assertWithMessage("Verifying that all due Annual Fees have been paid").that(nextDueDateForAnnualFee) - .isGreaterThan(todaysDate); + final HashMap savingsDetails = this.savingsAccountHelper.getSavingsDetails(savingsId); + final HashMap annualFeeDetails = (HashMap) savingsDetails.get("annualFee"); + ArrayList annualFeeDueDateAsArrayList = (ArrayList) 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) + .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 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 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 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 map = new HashMap<>(); map.put("locale", CommonConstants.LOCALE);