This is an automated email from the ASF dual-hosted git repository. adamsaghy pushed a commit to branch revert-5535-FINERACT-2305/remove-accrual-for-none-and-cash-accounting in repository https://gitbox.apache.org/repos/asf/fineract.git
commit 09113aa61a5062bc9742cd437d1958642ff8e1ca Author: Adam Saghy <[email protected]> AuthorDate: Thu Mar 26 14:18:02 2026 +0100 Revert "FINERACT-2305: Remove accrual transactions for None and Cash accounti…" --- .../resources/features/LoanChargeOff-Part3.feature | 2 + .../features/LoanChargesDisbursement.feature | 4 + .../features/LoanChargesProgressiveLoan.feature | 4 + .../portfolio/loanaccount/domain/Loan.java | 5 + ...dvancedPaymentScheduleTransactionProcessor.java | 3 - ...cedPaymentScheduleTransactionProcessorTest.java | 2 + .../service/LoanAccrualsProcessingServiceImpl.java | 2 +- .../LoanChargeWritePlatformServiceImpl.java | 6 +- .../service/LoanDisbursementService.java | 6 +- .../LoanWritePlatformServiceJpaRepositoryImpl.java | 6 +- .../fineract/integrationtests/BatchApiTest.java | 12 +- ...DueDateRespectiveLoanRepaymentScheduleTest.java | 532 ++++++++++++++------- ...nsactionOnDisbursementByAccountingTypeTest.java | 184 ------- .../LoanTransactionReverseReplayTest.java | 8 + .../integrationtests/SchedulerJobsTestResults.java | 10 + 15 files changed, 404 insertions(+), 382 deletions(-) diff --git a/fineract-e2e-tests-runner/src/test/resources/features/LoanChargeOff-Part3.feature b/fineract-e2e-tests-runner/src/test/resources/features/LoanChargeOff-Part3.feature index cb548da59e..89febe7360 100644 --- a/fineract-e2e-tests-runner/src/test/resources/features/LoanChargeOff-Part3.feature +++ b/fineract-e2e-tests-runner/src/test/resources/features/LoanChargeOff-Part3.feature @@ -1868,7 +1868,9 @@ Feature: Charge-off - Part3 And Loan Transactions tab has the following data: | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed | | 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false | + | 01 January 2024 | Accrual | 2.05 | 0.0 | 2.05 | 0.0 | 0.0 | 0.0 | false | false | | 15 January 2024 | Repayment | 17.01 | 16.75 | 0.26 | 0.0 | 0.0 | 83.25 | false | false | + | 01 March 2024 | Accrual Adjustment | 1.03 | 0.0 | 1.03 | 0.0 | 0.0 | 0.0 | false | false | | 01 March 2024 | Charge-off | 84.99 | 83.25 | 1.74 | 0.0 | 0.0 | 0.0 | false | false | @TestRailId:C3513 diff --git a/fineract-e2e-tests-runner/src/test/resources/features/LoanChargesDisbursement.feature b/fineract-e2e-tests-runner/src/test/resources/features/LoanChargesDisbursement.feature index 864f39b007..072c4298c4 100644 --- a/fineract-e2e-tests-runner/src/test/resources/features/LoanChargesDisbursement.feature +++ b/fineract-e2e-tests-runner/src/test/resources/features/LoanChargesDisbursement.feature @@ -354,6 +354,7 @@ Feature: LoanChargesDisbursementCharges | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed | | 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false | | 01 January 2024 | Repayment (at time of disbursement) | 0.02 | 0.0 | 0.0 | 0.02 | 0.0 | 100.0 | false | false | + | 01 January 2024 | Accrual | 2.05 | 0.0 | 2.05 | 0.0 | 0.0 | 0.0 | false | false | Then Loan Charges tab has the following data: | Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding | | Disbursement Charge | false | Disbursement | | % Interest | 0.02 | 0.02 | 0.0 | 0.0 | @@ -362,6 +363,7 @@ Feature: LoanChargesDisbursementCharges | Type | Account code | Account name | Debit | Credit | | INCOME | 404007 | Fee Income | | 0.02 | | LIABILITY | 145023 | Suspense/Clearing account | 0.02 | | + Then Loan Transactions tab has a "ACCRUAL" transaction with date "01 January 2024" has no the Journal entries # --- 1st repayment - 1 February, 2024 --- When Admin sets the business date to "01 February 2024" And Customer makes "AUTOPAY" repayment on "01 February 2024" with 17.01 EUR transaction amount @@ -381,6 +383,7 @@ Feature: LoanChargesDisbursementCharges | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed | | 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false | | 01 January 2024 | Repayment (at time of disbursement) | 0.02 | 0.0 | 0.0 | 0.02 | 0.0 | 100.0 | false | false | + | 01 January 2024 | Accrual | 2.05 | 0.0 | 2.05 | 0.0 | 0.0 | 0.0 | false | false | | 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | false | # --- 2nd repayment - 1 March, 2024 --- When Admin sets the business date to "01 March 2024" @@ -401,6 +404,7 @@ Feature: LoanChargesDisbursementCharges | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed | | 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false | | 01 January 2024 | Repayment (at time of disbursement) | 0.02 | 0.0 | 0.0 | 0.02 | 0.0 | 100.0 | false | false | + | 01 January 2024 | Accrual | 2.05 | 0.0 | 2.05 | 0.0 | 0.0 | 0.0 | false | false | | 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | false | | 01 March 2024 | Repayment | 17.01 | 16.52 | 0.49 | 0.0 | 0.0 | 67.05 | false | false | When Loan Pay-off is made on "01 March 2024" diff --git a/fineract-e2e-tests-runner/src/test/resources/features/LoanChargesProgressiveLoan.feature b/fineract-e2e-tests-runner/src/test/resources/features/LoanChargesProgressiveLoan.feature index 1597451ed9..680375579a 100644 --- a/fineract-e2e-tests-runner/src/test/resources/features/LoanChargesProgressiveLoan.feature +++ b/fineract-e2e-tests-runner/src/test/resources/features/LoanChargesProgressiveLoan.feature @@ -1740,6 +1740,8 @@ Feature: LoanChargesProgressiveLoan And Loan Transactions tab has the following data: | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed | | 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false | + | 01 January 2024 | Accrual | 2.05 | 0.0 | 2.05 | 0.0 | 0.0 | 0.0 | false | false | + | 01 March 2024 | Accrual Adjustment | 0.89 | 0.0 | 0.89 | 0.0 | 0.0 | 0.0 | false | false | | 01 March 2024 | Charge-off | 107.14 | 100.0 | 2.14 | 5.0 | 0.0 | 0.0 | false | false | When Admin makes a charge adjustment for the last "LOAN_SNOOZE_FEE" type charge which is due on "01 March 2024" with 5 EUR transaction amount and externalId "" Then Charge adjustment response has the subResourceExternalId @@ -1747,6 +1749,8 @@ Feature: LoanChargesProgressiveLoan And Loan Transactions tab has the following data: | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed | | 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false | + | 01 January 2024 | Accrual | 2.05 | 0.0 | 2.05 | 0.0 | 0.0 | 0.0 | false | false | + | 01 March 2024 | Accrual Adjustment | 0.89 | 0.0 | 0.89 | 0.0 | 0.0 | 0.0 | false | false | | 01 March 2024 | Charge-off | 107.14 | 100.0 | 2.14 | 5.0 | 0.0 | 0.0 | false | false | | 01 March 2024 | Charge Adjustment | 5.0 | 5.0 | 0.0 | 0.0 | 0.0 | 95.0 | false | false | When Loan Pay-off is made on "01 March 2024" diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java index de2cd5d7fe..5a323abf3b 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java @@ -1154,6 +1154,11 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> { return this.loanProduct.isAccountingDisabled(); } + public Boolean isNoneOrCashOrUpfrontAccrualAccountingEnabledOnLoanProduct() { + return isCashBasedAccountingEnabledOnLoanProduct() || isUpfrontAccrualAccountingEnabledOnLoanProduct() + || isAccountingDisabledOnLoanProduct(); + } + public Boolean isPeriodicAccrualAccountingEnabledOnLoanProduct() { return this.loanProduct.isPeriodicAccrualAccountingEnabled(); } diff --git a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java index 84b49a721b..7772d390d0 100644 --- a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java +++ b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java @@ -3585,9 +3585,6 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep private void createMissingAccrualTransactionDuringChargeOffIfNeeded(final BigDecimal newInterest, final LoanTransaction chargeOffTransaction, final LocalDate chargeOffDate, final TransactionCtx ctx) { final Loan loan = chargeOffTransaction.getLoan(); - if (!loan.isUpfrontAccrualAccountingEnabledOnLoanProduct() && !loan.isPeriodicAccrualAccountingEnabledOnLoanProduct()) { - return; - } final List<LoanRepaymentScheduleInstallment> relevantInstallments = loan.getRepaymentScheduleInstallments().stream() .filter(i -> !i.getFromDate().isAfter(chargeOffDate)).toList(); diff --git a/fineract-progressive-loan/src/test/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessorTest.java b/fineract-progressive-loan/src/test/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessorTest.java index 89faac6574..ac2d59b404 100644 --- a/fineract-progressive-loan/src/test/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessorTest.java +++ b/fineract-progressive-loan/src/test/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessorTest.java @@ -534,6 +534,8 @@ class AdvancedPaymentScheduleTransactionProcessorTest { Money disbursementMoney = Money.of(currency, postMaturityDisbursementAmount); LoanProductRelatedDetail loanProductRelatedDetail = mock(LoanProductRelatedDetail.class); + org.apache.fineract.portfolio.loanproduct.domain.LoanProduct loanProduct = mock( + org.apache.fineract.portfolio.loanproduct.domain.LoanProduct.class); when(loanProductRelatedDetail.getInstallmentAmountInMultiplesOf()).thenReturn(null); when(loanProductRelatedDetail.isEnableDownPayment()).thenReturn(false); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualsProcessingServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualsProcessingServiceImpl.java index 9f3d077060..21ea7ec327 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualsProcessingServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualsProcessingServiceImpl.java @@ -209,7 +209,7 @@ public class LoanAccrualsProcessingServiceImpl implements LoanAccrualsProcessing if (!accrualTransactions.isEmpty()) { if (loan.isPeriodicAccrualAccountingEnabledOnLoanProduct()) { reprocessPeriodicAccruals(loan, accrualTransactions, addEvent); - } else if (loan.isUpfrontAccrualAccountingEnabledOnLoanProduct()) { + } else if (loan.isNoneOrCashOrUpfrontAccrualAccountingEnabledOnLoanProduct()) { reprocessNonPeriodicAccruals(loan, accrualTransactions, addEvent); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImpl.java index db691def0f..47304853eb 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImpl.java @@ -1052,9 +1052,9 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo loanCharge = this.loanChargeRepository.saveAndFlush(loanCharge); // we want to apply charge transactions only for those loans charges that are applied when a loan is active and - // the loan product uses Upfront Accrual accounting, or only when the loan are closed too, - if ((loan.getStatus().isActive() && loan.isUpfrontAccrualAccountingEnabledOnLoanProduct()) || loan.getStatus().isOverpaid() - || loan.getStatus().isClosedObligationsMet()) { + // the loan product uses Upfront Accruals, or only when the loan are closed too, + if ((loan.getStatus().isActive() && loan.isNoneOrCashOrUpfrontAccrualAccountingEnabledOnLoanProduct()) + || loan.getStatus().isOverpaid() || loan.getStatus().isClosedObligationsMet()) { final LoanTransaction applyLoanChargeTransaction = loanChargeService.handleChargeAppliedTransaction(loan, loanCharge, null); if (applyLoanChargeTransaction != null) { this.loanTransactionRepository.saveAndFlush(applyLoanChargeTransaction); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanDisbursementService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanDisbursementService.java index 1f33213194..0d6d0296aa 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanDisbursementService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanDisbursementService.java @@ -242,8 +242,7 @@ public class LoanDisbursementService { && !charge.isWaived() && !charge.isFullyPaid(); /* - * create a Charge applied transaction only when Up front Accrual accounting is enabled. No accrual - * transactions should be created for None or Cash based accounting. + * create a Charge applied transaction if Up front Accrual, None or Cash based accounting is enabled */ if (isDisbursementCharge || isTrancheDisbursementCharge) { if (totalFeeChargesDueAtDisbursement.isGreaterThanZero() && !charge.getChargePaymentMode().isPaymentModeAccountTransfer()) { @@ -254,7 +253,8 @@ public class LoanDisbursementService { chargesPayment.getLoanChargesPaid().add(loanChargePaidBy); disbursentMoney = disbursentMoney.plus(charge.amount()); } - } else if (disbursedOn.equals(loan.getActualDisbursementDate()) && loan.isUpfrontAccrualAccountingEnabledOnLoanProduct()) { + } else if (disbursedOn.equals(loan.getActualDisbursementDate()) + && loan.isNoneOrCashOrUpfrontAccrualAccountingEnabledOnLoanProduct()) { final LoanTransaction applyLoanChargeTransaction = loanChargeService.handleChargeAppliedTransaction(loan, charge, disbursedOn); if (applyLoanChargeTransaction != null) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java index 64fc756112..dd5e434438 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java @@ -575,11 +575,11 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf final Money interestApplied = Money.of(loan.getCurrency(), loan.getSummary().getTotalInterestCharged()); /* - * Add an interest applied transaction only when the interest is accrued upfront (Up front accrual). No accrual - * transactions should be created for None or Cash based accounting. + * Add an interest applied transaction of the interest is accrued upfront (Up front accrual), no accounting or + * cash based accounting is selected */ if (((loan.isMultiDisburmentLoan() && loan.getDisbursedLoanDisbursementDetails().size() == 1) || !loan.isMultiDisburmentLoan()) - && loan.isUpfrontAccrualAccountingEnabledOnLoanProduct() && interestApplied.isGreaterThanZero()) { + && loan.isNoneOrCashOrUpfrontAccrualAccountingEnabledOnLoanProduct() && interestApplied.isGreaterThanZero()) { ExternalId externalId = ExternalId.empty(); if (TemporaryConfigurationServiceContainer.isExternalIdAutoGenerationEnabled()) { externalId = ExternalId.generate(); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/BatchApiTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/BatchApiTest.java index edd3ba8b48..888e493c37 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/BatchApiTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/BatchApiTest.java @@ -1637,7 +1637,7 @@ public class BatchApiTest extends BaseLoanIntegrationTest { final FromJsonHelper jsonHelper = new FromJsonHelper(); final JsonObject repayment = jsonHelper.parse(responses.get(5).getBody()).getAsJsonObject().get("transactions").getAsJsonArray() - .get(1).getAsJsonObject(); + .get(2).getAsJsonObject(); final JsonArray dateArray = repayment.get("reversedOnDate").getAsJsonArray(); final LocalDate reversedOnDate = LocalDate.of(dateArray.get(0).getAsInt(), dateArray.get(1).getAsInt(), dateArray.get(2).getAsInt()); @@ -1739,7 +1739,7 @@ public class BatchApiTest extends BaseLoanIntegrationTest { this.responseSpec, BatchHelper.toJsonString(reversalAndGetBatchRequest)); final JsonObject repayment = jsonHelper.parse(reversalResponses.get(1).getBody()).getAsJsonObject().get("transactions") - .getAsJsonArray().get(1).getAsJsonObject(); + .getAsJsonArray().get(2).getAsJsonObject(); final JsonArray dateArray = repayment.get("reversedOnDate").getAsJsonArray(); final LocalDate reversedOnDate = LocalDate.of(dateArray.get(0).getAsInt(), dateArray.get(1).getAsInt(), @@ -1814,7 +1814,7 @@ public class BatchApiTest extends BaseLoanIntegrationTest { final FromJsonHelper jsonHelper = new FromJsonHelper(); final JsonObject repayment = jsonHelper.parse(responses.get(5).getBody()).getAsJsonObject().get("transactions").getAsJsonArray() - .get(1).getAsJsonObject(); + .get(2).getAsJsonObject(); Assertions.assertEquals(HttpStatus.SC_OK, (long) responses.get(4).getStatusCode(), "Verify Status Code 200 for repayment chargeback"); @@ -1886,7 +1886,7 @@ public class BatchApiTest extends BaseLoanIntegrationTest { final FromJsonHelper jsonHelper = new FromJsonHelper(); final JsonObject goodWillCredit = jsonHelper.parse(responses.get(5).getBody()).getAsJsonObject().get("transactions") - .getAsJsonArray().get(1).getAsJsonObject(); + .getAsJsonArray().get(2).getAsJsonObject(); final JsonArray dateArray = goodWillCredit.get("reversedOnDate").getAsJsonArray(); final LocalDate reversedOnDate = LocalDate.of(dateArray.get(0).getAsInt(), dateArray.get(1).getAsInt(), dateArray.get(2).getAsInt()); @@ -1972,9 +1972,9 @@ public class BatchApiTest extends BaseLoanIntegrationTest { final FromJsonHelper jsonHelper = new FromJsonHelper(); final JsonObject merchantIssuedRefund = jsonHelper.parse(responses.get(7).getBody()).getAsJsonObject().get("transactions") - .getAsJsonArray().get(1).getAsJsonObject(); + .getAsJsonArray().get(2).getAsJsonObject(); final JsonObject payoutRefund = jsonHelper.parse(responses.get(7).getBody()).getAsJsonObject().get("transactions").getAsJsonArray() - .get(2).getAsJsonObject(); + .get(3).getAsJsonObject(); final JsonArray merchantIssuedDateArray = merchantIssuedRefund.get("reversedOnDate").getAsJsonArray(); final LocalDate merchantIssuedDate = LocalDate.of(merchantIssuedDateArray.get(0).getAsInt(), merchantIssuedDateArray.get(1).getAsInt(), merchantIssuedDateArray.get(2).getAsInt()); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/DueDateRespectiveLoanRepaymentScheduleTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/DueDateRespectiveLoanRepaymentScheduleTest.java index 2724b7032b..ad8bf4c103 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/DueDateRespectiveLoanRepaymentScheduleTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/DueDateRespectiveLoanRepaymentScheduleTest.java @@ -161,19 +161,31 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getInterestPortion())); assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getFeeChargesPortion())); assertEquals(50.0, Utils.getDoubleValue(response.getTransactions().get(2).getOutstandingLoanBalance())); - assertEquals(thirdRepaymentId, response.getTransactions().get(3).getId().intValue()); assertNull(response.getTransactions().get(3).getReversedOnDate()); assertTrue(response.getTransactions().get(3).getTransactionRelations().isEmpty()); - assertTrue(response.getTransactions().get(3).getType().getRepayment()); + assertTrue(response.getTransactions().get(3).getType().getAccrual()); assertEquals(50.0, Utils.getDoubleValue(response.getTransactions().get(3).getAmount())); assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getPrincipalPortion())); assertEquals(50.0, Utils.getDoubleValue(response.getTransactions().get(3).getPenaltyChargesPortion())); assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getOverpaymentPortion())); assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getInterestPortion())); assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getFeeChargesPortion())); - assertEquals(50.0, Utils.getDoubleValue(response.getTransactions().get(3).getOutstandingLoanBalance())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getOutstandingLoanBalance())); assertEquals(firstChargeId, response.getTransactions().get(3).getLoanChargePaidByList().get(0).getChargeId().intValue()); assertEquals(1, response.getTransactions().get(3).getLoanChargePaidByList().size()); + assertEquals(thirdRepaymentId, response.getTransactions().get(4).getId().intValue()); + assertNull(response.getTransactions().get(4).getReversedOnDate()); + assertTrue(response.getTransactions().get(4).getTransactionRelations().isEmpty()); + assertTrue(response.getTransactions().get(4).getType().getRepayment()); + assertEquals(50.0, Utils.getDoubleValue(response.getTransactions().get(4).getAmount())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(4).getPrincipalPortion())); + assertEquals(50.0, Utils.getDoubleValue(response.getTransactions().get(4).getPenaltyChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(4).getOverpaymentPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(4).getInterestPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(4).getFeeChargesPortion())); + assertEquals(50.0, Utils.getDoubleValue(response.getTransactions().get(4).getOutstandingLoanBalance())); + assertEquals(firstChargeId, response.getTransactions().get(4).getLoanChargePaidByList().get(0).getChargeId().intValue()); + assertEquals(1, response.getTransactions().get(4).getLoanChargePaidByList().size()); } finally { globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, @@ -275,19 +287,43 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getInterestPortion())); assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getFeeChargesPortion())); assertEquals(400.0, Utils.getDoubleValue(response.getTransactions().get(2).getOutstandingLoanBalance())); - assertEquals(thirdRepaymentId, response.getTransactions().get(3).getId().intValue()); assertNull(response.getTransactions().get(3).getReversedOnDate()); assertTrue(response.getTransactions().get(3).getTransactionRelations().isEmpty()); - assertTrue(response.getTransactions().get(3).getType().getRepayment()); - assertEquals(100.0, Utils.getDoubleValue(response.getTransactions().get(3).getAmount())); - assertEquals(50.0, Utils.getDoubleValue(response.getTransactions().get(3).getPrincipalPortion())); + assertTrue(response.getTransactions().get(3).getType().getAccrual()); + assertEquals(50.0, Utils.getDoubleValue(response.getTransactions().get(3).getAmount())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getPrincipalPortion())); assertEquals(50.0, Utils.getDoubleValue(response.getTransactions().get(3).getFeeChargesPortion())); assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getOverpaymentPortion())); assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getInterestPortion())); assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getPenaltyChargesPortion())); - assertEquals(350.0, Utils.getDoubleValue(response.getTransactions().get(3).getOutstandingLoanBalance())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getOutstandingLoanBalance())); assertEquals(firstChargeId, response.getTransactions().get(3).getLoanChargePaidByList().get(0).getChargeId().intValue()); assertEquals(1, response.getTransactions().get(3).getLoanChargePaidByList().size()); + assertEquals(thirdRepaymentId, response.getTransactions().get(4).getId().intValue()); + assertNull(response.getTransactions().get(4).getReversedOnDate()); + assertTrue(response.getTransactions().get(4).getTransactionRelations().isEmpty()); + assertTrue(response.getTransactions().get(4).getType().getRepayment()); + assertEquals(100.0, Utils.getDoubleValue(response.getTransactions().get(4).getAmount())); + assertEquals(50.0, Utils.getDoubleValue(response.getTransactions().get(4).getPrincipalPortion())); + assertEquals(50.0, Utils.getDoubleValue(response.getTransactions().get(4).getFeeChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(4).getOverpaymentPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(4).getInterestPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(4).getPenaltyChargesPortion())); + assertEquals(350.0, Utils.getDoubleValue(response.getTransactions().get(4).getOutstandingLoanBalance())); + assertEquals(firstChargeId, response.getTransactions().get(4).getLoanChargePaidByList().get(0).getChargeId().intValue()); + assertEquals(1, response.getTransactions().get(4).getLoanChargePaidByList().size()); + assertNull(response.getTransactions().get(5).getReversedOnDate()); + assertTrue(response.getTransactions().get(5).getTransactionRelations().isEmpty()); + assertTrue(response.getTransactions().get(5).getType().getAccrual()); + assertEquals(10.0, Utils.getDoubleValue(response.getTransactions().get(5).getAmount())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(5).getPrincipalPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(5).getFeeChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(5).getOverpaymentPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(5).getInterestPortion())); + assertEquals(10.0, Utils.getDoubleValue(response.getTransactions().get(5).getPenaltyChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(5).getOutstandingLoanBalance())); + assertEquals(secondChargeId, response.getTransactions().get(5).getLoanChargePaidByList().get(0).getChargeId().intValue()); + assertEquals(1, response.getTransactions().get(5).getLoanChargePaidByList().size()); } finally { globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, new PutGlobalConfigurationsRequest().enabled(false)); @@ -363,19 +399,45 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(1).getFeeChargesPortion())); assertEquals(500.0, Utils.getDoubleValue(response.getTransactions().get(1).getOutstandingLoanBalance())); - assertEquals(secondRepaymentId, response.getTransactions().get(2).getId().intValue()); - assertNull(response.getTransactions().get(2).getReversedOnDate()); - assertTrue(response.getTransactions().get(2).getTransactionRelations().isEmpty()); - assertTrue(response.getTransactions().get(2).getType().getRepayment()); - assertEquals(550.0, Utils.getDoubleValue(response.getTransactions().get(2).getAmount())); - assertEquals(500.0, Utils.getDoubleValue(response.getTransactions().get(2).getPrincipalPortion())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getPenaltyChargesPortion())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getOverpaymentPortion())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getInterestPortion())); - assertEquals(50.0, Utils.getDoubleValue(response.getTransactions().get(2).getFeeChargesPortion())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getOutstandingLoanBalance())); - assertEquals(firstChargeId, response.getTransactions().get(2).getLoanChargePaidByList().get(0).getChargeId().intValue()); - assertEquals(1, response.getTransactions().get(2).getLoanChargePaidByList().size()); + int repaymentOrderNo; + int accrualOrderNo; + + if (response.getTransactions().get(2).getType().getAccrual()) { + accrualOrderNo = 2; + repaymentOrderNo = 3; + } else { + accrualOrderNo = 3; + repaymentOrderNo = 2; + } + + assertNull(response.getTransactions().get(accrualOrderNo).getReversedOnDate()); + assertTrue(response.getTransactions().get(accrualOrderNo).getTransactionRelations().isEmpty()); + assertTrue(response.getTransactions().get(accrualOrderNo).getType().getAccrual()); + assertEquals(50.0, Utils.getDoubleValue(response.getTransactions().get(accrualOrderNo).getAmount())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(accrualOrderNo).getPrincipalPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(accrualOrderNo).getPenaltyChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(accrualOrderNo).getOverpaymentPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(accrualOrderNo).getInterestPortion())); + assertEquals(50.0, Utils.getDoubleValue(response.getTransactions().get(accrualOrderNo).getFeeChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(accrualOrderNo).getOutstandingLoanBalance())); + assertEquals(firstChargeId, + response.getTransactions().get(accrualOrderNo).getLoanChargePaidByList().get(0).getChargeId().intValue()); + assertEquals(1, response.getTransactions().get(accrualOrderNo).getLoanChargePaidByList().size()); + + assertEquals(secondRepaymentId, response.getTransactions().get(repaymentOrderNo).getId().intValue()); + assertNull(response.getTransactions().get(repaymentOrderNo).getReversedOnDate()); + assertTrue(response.getTransactions().get(repaymentOrderNo).getTransactionRelations().isEmpty()); + assertTrue(response.getTransactions().get(repaymentOrderNo).getType().getRepayment()); + assertEquals(550.0, Utils.getDoubleValue(response.getTransactions().get(repaymentOrderNo).getAmount())); + assertEquals(500.0, Utils.getDoubleValue(response.getTransactions().get(repaymentOrderNo).getPrincipalPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(repaymentOrderNo).getPenaltyChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(repaymentOrderNo).getOverpaymentPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(repaymentOrderNo).getInterestPortion())); + assertEquals(50.0, Utils.getDoubleValue(response.getTransactions().get(repaymentOrderNo).getFeeChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(repaymentOrderNo).getOutstandingLoanBalance())); + assertEquals(firstChargeId, + response.getTransactions().get(repaymentOrderNo).getLoanChargePaidByList().get(0).getChargeId().intValue()); + assertEquals(1, response.getTransactions().get(repaymentOrderNo).getLoanChargePaidByList().size()); } finally { globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, new PutGlobalConfigurationsRequest().enabled(false)); @@ -662,19 +724,31 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat assertEquals(0.0, Utils.getDoubleValue(response.getRepaymentSchedule().getPeriods().get(1).getPrincipalOutstanding())); assertTrue(response.getStatus().getActive()); - assertEquals(firstRepaymentId, response.getTransactions().get(1).getId().intValue()); assertNull(response.getTransactions().get(1).getReversedOnDate()); assertTrue(response.getTransactions().get(1).getTransactionRelations().isEmpty()); - assertTrue(response.getTransactions().get(1).getType().getRepayment()); - assertEquals(1010.0, Utils.getDoubleValue(response.getTransactions().get(1).getAmount())); - assertEquals(1000.0, Utils.getDoubleValue(response.getTransactions().get(1).getPrincipalPortion())); + assertTrue(response.getTransactions().get(1).getType().getAccrual()); + assertEquals(20.0, Utils.getDoubleValue(response.getTransactions().get(1).getAmount())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(1).getPrincipalPortion())); assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(1).getPenaltyChargesPortion())); assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(1).getOverpaymentPortion())); assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(1).getInterestPortion())); - assertEquals(10.0, Utils.getDoubleValue(response.getTransactions().get(1).getFeeChargesPortion())); + assertEquals(20.0, Utils.getDoubleValue(response.getTransactions().get(1).getFeeChargesPortion())); assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(1).getOutstandingLoanBalance())); assertEquals(firstChargeId, response.getTransactions().get(1).getLoanChargePaidByList().get(0).getChargeId().intValue()); assertEquals(1, response.getTransactions().get(1).getLoanChargePaidByList().size()); + assertEquals(firstRepaymentId, response.getTransactions().get(2).getId().intValue()); + assertNull(response.getTransactions().get(2).getReversedOnDate()); + assertTrue(response.getTransactions().get(2).getTransactionRelations().isEmpty()); + assertTrue(response.getTransactions().get(2).getType().getRepayment()); + assertEquals(1010.0, Utils.getDoubleValue(response.getTransactions().get(2).getAmount())); + assertEquals(1000.0, Utils.getDoubleValue(response.getTransactions().get(2).getPrincipalPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getPenaltyChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getOverpaymentPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getInterestPortion())); + assertEquals(10.0, Utils.getDoubleValue(response.getTransactions().get(2).getFeeChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getOutstandingLoanBalance())); + assertEquals(firstChargeId, response.getTransactions().get(2).getLoanChargePaidByList().get(0).getChargeId().intValue()); + assertEquals(1, response.getTransactions().get(2).getLoanChargePaidByList().size()); } finally { globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, @@ -792,20 +866,33 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat assertEquals(5.0, Utils.getDoubleValue(response.getRepaymentSchedule().getPeriods().get(1).getPrincipalOutstanding())); assertTrue(response.getStatus().getActive()); - assertEquals(secondRepayment, response.getTransactions().get(2).getId().intValue()); assertNull(response.getTransactions().get(2).getReversedOnDate()); assertTrue(response.getTransactions().get(2).getTransactionRelations().isEmpty()); - assertTrue(response.getTransactions().get(2).getType().getRepayment()); - assertEquals(1010.0, Utils.getDoubleValue(response.getTransactions().get(2).getAmount())); - assertEquals(995.0, Utils.getDoubleValue(response.getTransactions().get(2).getPrincipalPortion())); + assertTrue(response.getTransactions().get(2).getType().getAccrual()); + assertEquals(15.0, Utils.getDoubleValue(response.getTransactions().get(2).getAmount())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getPrincipalPortion())); assertEquals(15.0, Utils.getDoubleValue(response.getTransactions().get(2).getPenaltyChargesPortion())); assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getOverpaymentPortion())); assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getInterestPortion())); assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getFeeChargesPortion())); - assertEquals(5.0, Utils.getDoubleValue(response.getTransactions().get(2).getOutstandingLoanBalance())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getOutstandingLoanBalance())); assertEquals(firstChargeId, response.getTransactions().get(2).getLoanChargePaidByList().get(0).getChargeId().intValue()); assertEquals(1, response.getTransactions().get(2).getLoanChargePaidByList().size()); + assertEquals(secondRepayment, response.getTransactions().get(3).getId().intValue()); + assertNull(response.getTransactions().get(3).getReversedOnDate()); + assertTrue(response.getTransactions().get(3).getTransactionRelations().isEmpty()); + assertTrue(response.getTransactions().get(3).getType().getRepayment()); + assertEquals(1010.0, Utils.getDoubleValue(response.getTransactions().get(3).getAmount())); + assertEquals(995.0, Utils.getDoubleValue(response.getTransactions().get(3).getPrincipalPortion())); + assertEquals(15.0, Utils.getDoubleValue(response.getTransactions().get(3).getPenaltyChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getOverpaymentPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getInterestPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getFeeChargesPortion())); + assertEquals(5.0, Utils.getDoubleValue(response.getTransactions().get(3).getOutstandingLoanBalance())); + assertEquals(firstChargeId, response.getTransactions().get(3).getLoanChargePaidByList().get(0).getChargeId().intValue()); + assertEquals(1, response.getTransactions().get(3).getLoanChargePaidByList().size()); + } finally { globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, new PutGlobalConfigurationsRequest().enabled(false)); @@ -948,20 +1035,46 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat assertEquals(1000.0, Utils.getDoubleValue(response.getRepaymentSchedule().getPeriods().get(1).getPrincipalOutstanding())); assertTrue(response.getStatus().getActive()); - assertEquals(secondRepayment, response.getTransactions().get(2).getId().intValue()); assertNull(response.getTransactions().get(2).getReversedOnDate()); assertTrue(response.getTransactions().get(2).getTransactionRelations().isEmpty()); - assertTrue(response.getTransactions().get(2).getType().getRepayment()); - assertEquals(15.0, Utils.getDoubleValue(response.getTransactions().get(2).getAmount())); + assertTrue(response.getTransactions().get(2).getType().getAccrual()); + assertEquals(20.0, Utils.getDoubleValue(response.getTransactions().get(2).getAmount())); assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getPrincipalPortion())); - assertEquals(15.0, Utils.getDoubleValue(response.getTransactions().get(2).getPenaltyChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getPenaltyChargesPortion())); assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getOverpaymentPortion())); assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getInterestPortion())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getFeeChargesPortion())); - assertEquals(1000.0, Utils.getDoubleValue(response.getTransactions().get(2).getOutstandingLoanBalance())); - assertEquals(secondChargeId, response.getTransactions().get(2).getLoanChargePaidByList().get(0).getChargeId().intValue()); + assertEquals(20.0, Utils.getDoubleValue(response.getTransactions().get(2).getFeeChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getOutstandingLoanBalance())); + assertEquals(firstChargeId, response.getTransactions().get(2).getLoanChargePaidByList().get(0).getChargeId().intValue()); assertEquals(1, response.getTransactions().get(2).getLoanChargePaidByList().size()); + assertNull(response.getTransactions().get(3).getReversedOnDate()); + assertTrue(response.getTransactions().get(3).getTransactionRelations().isEmpty()); + assertTrue(response.getTransactions().get(3).getType().getAccrual()); + assertEquals(15.0, Utils.getDoubleValue(response.getTransactions().get(3).getAmount())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getPrincipalPortion())); + assertEquals(15.0, Utils.getDoubleValue(response.getTransactions().get(3).getPenaltyChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getOverpaymentPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getInterestPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getFeeChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getOutstandingLoanBalance())); + assertEquals(secondChargeId, response.getTransactions().get(3).getLoanChargePaidByList().get(0).getChargeId().intValue()); + assertEquals(1, response.getTransactions().get(3).getLoanChargePaidByList().size()); + + assertEquals(secondRepayment, response.getTransactions().get(4).getId().intValue()); + assertNull(response.getTransactions().get(4).getReversedOnDate()); + assertTrue(response.getTransactions().get(4).getTransactionRelations().isEmpty()); + assertTrue(response.getTransactions().get(4).getType().getRepayment()); + assertEquals(15.0, Utils.getDoubleValue(response.getTransactions().get(4).getAmount())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(4).getPrincipalPortion())); + assertEquals(15.0, Utils.getDoubleValue(response.getTransactions().get(4).getPenaltyChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(4).getOverpaymentPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(4).getInterestPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(4).getFeeChargesPortion())); + assertEquals(1000.0, Utils.getDoubleValue(response.getTransactions().get(4).getOutstandingLoanBalance())); + assertEquals(secondChargeId, response.getTransactions().get(4).getLoanChargePaidByList().get(0).getChargeId().intValue()); + assertEquals(1, response.getTransactions().get(4).getLoanChargePaidByList().size()); + Integer thirdRepayment = (Integer) loanTransactionHelper.makeRepayment("01 March 2023", Float.parseFloat("1000.00"), loanID) .get("resourceId"); @@ -979,18 +1092,18 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat assertEquals(0.0, Utils.getDoubleValue(response.getRepaymentSchedule().getPeriods().get(1).getPrincipalOutstanding())); assertTrue(response.getStatus().getActive()); - assertEquals(thirdRepayment, response.getTransactions().get(3).getId().intValue()); - assertNull(response.getTransactions().get(3).getReversedOnDate()); - assertTrue(response.getTransactions().get(3).getTransactionRelations().isEmpty()); - assertTrue(response.getTransactions().get(3).getType().getRepayment()); - assertEquals(1000.0, Utils.getDoubleValue(response.getTransactions().get(3).getAmount())); - assertEquals(1000.0, Utils.getDoubleValue(response.getTransactions().get(3).getPrincipalPortion())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getPenaltyChargesPortion())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getOverpaymentPortion())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getInterestPortion())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getFeeChargesPortion())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getOutstandingLoanBalance())); - assertEquals(0, response.getTransactions().get(3).getLoanChargePaidByList().size()); + assertEquals(thirdRepayment, response.getTransactions().get(5).getId().intValue()); + assertNull(response.getTransactions().get(5).getReversedOnDate()); + assertTrue(response.getTransactions().get(5).getTransactionRelations().isEmpty()); + assertTrue(response.getTransactions().get(5).getType().getRepayment()); + assertEquals(1000.0, Utils.getDoubleValue(response.getTransactions().get(5).getAmount())); + assertEquals(1000.0, Utils.getDoubleValue(response.getTransactions().get(5).getPrincipalPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(5).getPenaltyChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(5).getOverpaymentPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(5).getInterestPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(5).getFeeChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(5).getOutstandingLoanBalance())); + assertEquals(0, response.getTransactions().get(5).getLoanChargePaidByList().size()); Integer forthRepayment = (Integer) loanTransactionHelper.makeRepayment("01 March 2023", Float.parseFloat("10.00"), loanID) .get("resourceId"); @@ -1009,19 +1122,19 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat assertEquals(0.0, Utils.getDoubleValue(response.getRepaymentSchedule().getPeriods().get(1).getPrincipalOutstanding())); assertTrue(response.getStatus().getActive()); - assertEquals(forthRepayment, response.getTransactions().get(4).getId().intValue()); - assertNull(response.getTransactions().get(4).getReversedOnDate()); - assertTrue(response.getTransactions().get(4).getTransactionRelations().isEmpty()); - assertTrue(response.getTransactions().get(4).getType().getRepayment()); - assertEquals(10.0, Utils.getDoubleValue(response.getTransactions().get(4).getAmount())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(4).getPrincipalPortion())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(4).getPenaltyChargesPortion())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(4).getOverpaymentPortion())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(4).getInterestPortion())); - assertEquals(10.0, Utils.getDoubleValue(response.getTransactions().get(4).getFeeChargesPortion())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(4).getOutstandingLoanBalance())); - assertEquals(firstChargeId, response.getTransactions().get(4).getLoanChargePaidByList().get(0).getChargeId().intValue()); - assertEquals(1, response.getTransactions().get(4).getLoanChargePaidByList().size()); + assertEquals(forthRepayment, response.getTransactions().get(6).getId().intValue()); + assertNull(response.getTransactions().get(6).getReversedOnDate()); + assertTrue(response.getTransactions().get(6).getTransactionRelations().isEmpty()); + assertTrue(response.getTransactions().get(6).getType().getRepayment()); + assertEquals(10.0, Utils.getDoubleValue(response.getTransactions().get(6).getAmount())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(6).getPrincipalPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(6).getPenaltyChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(6).getOverpaymentPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(6).getInterestPortion())); + assertEquals(10.0, Utils.getDoubleValue(response.getTransactions().get(6).getFeeChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(6).getOutstandingLoanBalance())); + assertEquals(firstChargeId, response.getTransactions().get(6).getLoanChargePaidByList().get(0).getChargeId().intValue()); + assertEquals(1, response.getTransactions().get(6).getLoanChargePaidByList().size()); } finally { globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, @@ -1168,25 +1281,51 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat assertEquals(0.0, Utils.getDoubleValue(response.getRepaymentSchedule().getPeriods().get(1).getPrincipalOutstanding())); assertTrue(response.getStatus().getActive()); - assertEquals(secondRepayment, response.getTransactions().get(2).getId().intValue()); assertNull(response.getTransactions().get(2).getReversedOnDate()); assertTrue(response.getTransactions().get(2).getTransactionRelations().isEmpty()); - assertTrue(response.getTransactions().get(2).getType().getRepayment()); - assertEquals(1030.0, Utils.getDoubleValue(response.getTransactions().get(2).getAmount())); - assertEquals(1000.0, Utils.getDoubleValue(response.getTransactions().get(2).getPrincipalPortion())); - assertEquals(15.0, Utils.getDoubleValue(response.getTransactions().get(2).getPenaltyChargesPortion())); + assertTrue(response.getTransactions().get(2).getType().getAccrual()); + assertEquals(20.0, Utils.getDoubleValue(response.getTransactions().get(2).getAmount())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getPrincipalPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getPenaltyChargesPortion())); assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getOverpaymentPortion())); assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getInterestPortion())); - assertEquals(15.0, Utils.getDoubleValue(response.getTransactions().get(2).getFeeChargesPortion())); + assertEquals(20.0, Utils.getDoubleValue(response.getTransactions().get(2).getFeeChargesPortion())); assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(2).getOutstandingLoanBalance())); - if (secondChargeId.equals(response.getTransactions().get(2).getLoanChargePaidByList().get(0).getChargeId().intValue())) { - assertEquals(secondChargeId, response.getTransactions().get(2).getLoanChargePaidByList().get(0).getChargeId().intValue()); - assertEquals(firstChargeId, response.getTransactions().get(2).getLoanChargePaidByList().get(1).getChargeId().intValue()); + assertEquals(firstChargeId, response.getTransactions().get(2).getLoanChargePaidByList().get(0).getChargeId().intValue()); + assertEquals(1, response.getTransactions().get(2).getLoanChargePaidByList().size()); + + assertNull(response.getTransactions().get(3).getReversedOnDate()); + assertTrue(response.getTransactions().get(3).getTransactionRelations().isEmpty()); + assertTrue(response.getTransactions().get(3).getType().getAccrual()); + assertEquals(15.0, Utils.getDoubleValue(response.getTransactions().get(3).getAmount())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getPrincipalPortion())); + assertEquals(15.0, Utils.getDoubleValue(response.getTransactions().get(3).getPenaltyChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getOverpaymentPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getInterestPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getFeeChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getOutstandingLoanBalance())); + assertEquals(secondChargeId, response.getTransactions().get(3).getLoanChargePaidByList().get(0).getChargeId().intValue()); + assertEquals(1, response.getTransactions().get(3).getLoanChargePaidByList().size()); + + assertEquals(secondRepayment, response.getTransactions().get(4).getId().intValue()); + assertNull(response.getTransactions().get(4).getReversedOnDate()); + assertTrue(response.getTransactions().get(4).getTransactionRelations().isEmpty()); + assertTrue(response.getTransactions().get(4).getType().getRepayment()); + assertEquals(1030.0, Utils.getDoubleValue(response.getTransactions().get(4).getAmount())); + assertEquals(1000.0, Utils.getDoubleValue(response.getTransactions().get(4).getPrincipalPortion())); + assertEquals(15.0, Utils.getDoubleValue(response.getTransactions().get(4).getPenaltyChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(4).getOverpaymentPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(4).getInterestPortion())); + assertEquals(15.0, Utils.getDoubleValue(response.getTransactions().get(4).getFeeChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(4).getOutstandingLoanBalance())); + if (secondChargeId.equals(response.getTransactions().get(4).getLoanChargePaidByList().get(0).getChargeId().intValue())) { + assertEquals(secondChargeId, response.getTransactions().get(4).getLoanChargePaidByList().get(0).getChargeId().intValue()); + assertEquals(firstChargeId, response.getTransactions().get(4).getLoanChargePaidByList().get(1).getChargeId().intValue()); } else { - assertEquals(secondChargeId, response.getTransactions().get(2).getLoanChargePaidByList().get(1).getChargeId().intValue()); - assertEquals(firstChargeId, response.getTransactions().get(2).getLoanChargePaidByList().get(0).getChargeId().intValue()); + assertEquals(secondChargeId, response.getTransactions().get(4).getLoanChargePaidByList().get(1).getChargeId().intValue()); + assertEquals(firstChargeId, response.getTransactions().get(4).getLoanChargePaidByList().get(0).getChargeId().intValue()); } - assertEquals(2, response.getTransactions().get(2).getLoanChargePaidByList().size()); + assertEquals(2, response.getTransactions().get(4).getLoanChargePaidByList().size()); businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE) .date("2023.03.07").dateFormat("yyyy.MM.dd").locale("en")); @@ -1228,19 +1367,32 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat assertEquals(0.0, Utils.getDoubleValue(response.getRepaymentSchedule().getPeriods().get(2).getPrincipalPaid())); assertEquals(0.0, Utils.getDoubleValue(response.getRepaymentSchedule().getPeriods().get(2).getPrincipalOutstanding())); - assertEquals(thirdRepayment, response.getTransactions().get(3).getId().intValue()); - assertNull(response.getTransactions().get(3).getReversedOnDate()); - assertTrue(response.getTransactions().get(3).getTransactionRelations().isEmpty()); - assertTrue(response.getTransactions().get(3).getType().getRepayment()); - assertEquals(15.0, Utils.getDoubleValue(response.getTransactions().get(3).getAmount())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getPrincipalPortion())); - assertEquals(15.0, Utils.getDoubleValue(response.getTransactions().get(3).getPenaltyChargesPortion())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getOverpaymentPortion())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getInterestPortion())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(3).getFeeChargesPortion())); - assertEquals(1000.0, Utils.getDoubleValue(response.getTransactions().get(3).getOutstandingLoanBalance())); - assertEquals(secondChargeId, response.getTransactions().get(3).getLoanChargePaidByList().get(0).getChargeId().intValue()); - assertEquals(1, response.getTransactions().get(3).getLoanChargePaidByList().size()); + assertNull(response.getTransactions().get(5).getReversedOnDate()); + assertTrue(response.getTransactions().get(5).getTransactionRelations().isEmpty()); + assertTrue(response.getTransactions().get(5).getType().getAccrual()); + assertEquals(15.0, Utils.getDoubleValue(response.getTransactions().get(5).getAmount())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(5).getPrincipalPortion())); + assertEquals(15.0, Utils.getDoubleValue(response.getTransactions().get(5).getPenaltyChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(5).getOverpaymentPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(5).getInterestPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(5).getFeeChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(5).getOutstandingLoanBalance())); + assertEquals(thirdChargeId, response.getTransactions().get(5).getLoanChargePaidByList().get(0).getChargeId().intValue()); + assertEquals(1, response.getTransactions().get(5).getLoanChargePaidByList().size()); + + assertEquals(thirdRepayment, response.getTransactions().get(6).getId().intValue()); + assertNull(response.getTransactions().get(6).getReversedOnDate()); + assertTrue(response.getTransactions().get(6).getTransactionRelations().isEmpty()); + assertTrue(response.getTransactions().get(6).getType().getRepayment()); + assertEquals(15.0, Utils.getDoubleValue(response.getTransactions().get(6).getAmount())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(6).getPrincipalPortion())); + assertEquals(15.0, Utils.getDoubleValue(response.getTransactions().get(6).getPenaltyChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(6).getOverpaymentPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(6).getInterestPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(6).getFeeChargesPortion())); + assertEquals(1000.0, Utils.getDoubleValue(response.getTransactions().get(6).getOutstandingLoanBalance())); + assertEquals(secondChargeId, response.getTransactions().get(6).getLoanChargePaidByList().get(0).getChargeId().intValue()); + assertEquals(1, response.getTransactions().get(6).getLoanChargePaidByList().size()); Integer forthRepayment = (Integer) loanTransactionHelper.makeRepayment("08 March 2023", Float.parseFloat("1015.00"), loanID) .get("resourceId"); @@ -1269,19 +1421,19 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat assertEquals(0.0, Utils.getDoubleValue(response.getRepaymentSchedule().getPeriods().get(2).getPrincipalPaid())); assertEquals(0.0, Utils.getDoubleValue(response.getRepaymentSchedule().getPeriods().get(2).getPrincipalOutstanding())); - assertEquals(forthRepayment, response.getTransactions().get(4).getId().intValue()); - assertNull(response.getTransactions().get(4).getReversedOnDate()); - assertTrue(response.getTransactions().get(4).getTransactionRelations().isEmpty()); - assertTrue(response.getTransactions().get(4).getType().getRepayment()); - assertEquals(1015.0, Utils.getDoubleValue(response.getTransactions().get(4).getAmount())); - assertEquals(1000.0, Utils.getDoubleValue(response.getTransactions().get(4).getPrincipalPortion())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(4).getPenaltyChargesPortion())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(4).getOverpaymentPortion())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(4).getInterestPortion())); - assertEquals(15.0, Utils.getDoubleValue(response.getTransactions().get(4).getFeeChargesPortion())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(4).getOutstandingLoanBalance())); - assertEquals(firstChargeId, response.getTransactions().get(4).getLoanChargePaidByList().get(0).getChargeId().intValue()); - assertEquals(1, response.getTransactions().get(4).getLoanChargePaidByList().size()); + assertEquals(forthRepayment, response.getTransactions().get(7).getId().intValue()); + assertNull(response.getTransactions().get(7).getReversedOnDate()); + assertTrue(response.getTransactions().get(7).getTransactionRelations().isEmpty()); + assertTrue(response.getTransactions().get(7).getType().getRepayment()); + assertEquals(1015.0, Utils.getDoubleValue(response.getTransactions().get(7).getAmount())); + assertEquals(1000.0, Utils.getDoubleValue(response.getTransactions().get(7).getPrincipalPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(7).getPenaltyChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(7).getOverpaymentPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(7).getInterestPortion())); + assertEquals(15.0, Utils.getDoubleValue(response.getTransactions().get(7).getFeeChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(7).getOutstandingLoanBalance())); + assertEquals(firstChargeId, response.getTransactions().get(7).getLoanChargePaidByList().get(0).getChargeId().intValue()); + assertEquals(1, response.getTransactions().get(7).getLoanChargePaidByList().size()); Integer fifthRepayment = (Integer) loanTransactionHelper.makeRepayment("08 March 2023", Float.parseFloat("10.00"), loanID) .get("resourceId"); @@ -1310,24 +1462,24 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat assertEquals(0.0, Utils.getDoubleValue(response.getRepaymentSchedule().getPeriods().get(2).getPrincipalPaid())); assertEquals(0.0, Utils.getDoubleValue(response.getRepaymentSchedule().getPeriods().get(2).getPrincipalOutstanding())); - assertEquals(fifthRepayment, response.getTransactions().get(5).getId().intValue()); - assertNull(response.getTransactions().get(5).getReversedOnDate()); - assertTrue(response.getTransactions().get(5).getTransactionRelations().isEmpty()); - assertTrue(response.getTransactions().get(5).getType().getRepayment()); - assertEquals(10.0, Utils.getDoubleValue(response.getTransactions().get(5).getAmount())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(5).getPrincipalPortion())); - assertEquals(5.0, Utils.getDoubleValue(response.getTransactions().get(5).getPenaltyChargesPortion())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(5).getOverpaymentPortion())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(5).getInterestPortion())); - assertEquals(5.0, Utils.getDoubleValue(response.getTransactions().get(5).getFeeChargesPortion())); - assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(5).getOutstandingLoanBalance())); - if (firstChargeId.equals(response.getTransactions().get(5).getLoanChargePaidByList().get(0).getChargeId().intValue())) { - assertEquals(thirdChargeId, response.getTransactions().get(5).getLoanChargePaidByList().get(1).getChargeId().intValue()); + assertEquals(fifthRepayment, response.getTransactions().get(8).getId().intValue()); + assertNull(response.getTransactions().get(8).getReversedOnDate()); + assertTrue(response.getTransactions().get(8).getTransactionRelations().isEmpty()); + assertTrue(response.getTransactions().get(8).getType().getRepayment()); + assertEquals(10.0, Utils.getDoubleValue(response.getTransactions().get(8).getAmount())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(8).getPrincipalPortion())); + assertEquals(5.0, Utils.getDoubleValue(response.getTransactions().get(8).getPenaltyChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(8).getOverpaymentPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(8).getInterestPortion())); + assertEquals(5.0, Utils.getDoubleValue(response.getTransactions().get(8).getFeeChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(response.getTransactions().get(8).getOutstandingLoanBalance())); + if (firstChargeId.equals(response.getTransactions().get(8).getLoanChargePaidByList().get(0).getChargeId().intValue())) { + assertEquals(thirdChargeId, response.getTransactions().get(8).getLoanChargePaidByList().get(1).getChargeId().intValue()); } else { - assertEquals(firstChargeId, response.getTransactions().get(5).getLoanChargePaidByList().get(1).getChargeId().intValue()); - assertEquals(thirdChargeId, response.getTransactions().get(5).getLoanChargePaidByList().get(0).getChargeId().intValue()); + assertEquals(firstChargeId, response.getTransactions().get(8).getLoanChargePaidByList().get(1).getChargeId().intValue()); + assertEquals(thirdChargeId, response.getTransactions().get(8).getLoanChargePaidByList().get(0).getChargeId().intValue()); } - assertEquals(2, response.getTransactions().get(5).getLoanChargePaidByList().size()); + assertEquals(2, response.getTransactions().get(8).getLoanChargePaidByList().size()); } finally { globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, @@ -1418,6 +1570,17 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(0).getFeeChargesPortion())); assertEquals(127.95, Utils.getDoubleValue(loanDetails.getTransactions().get(0).getOutstandingLoanBalance())); + assertNull(loanDetails.getTransactions().get(1).getReversedOnDate()); + assertTrue(loanDetails.getTransactions().get(1).getTransactionRelations().isEmpty()); + assertTrue(loanDetails.getTransactions().get(1).getType().getAccrual()); + assertEquals(3.65, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getAmount())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getPrincipalPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getPenaltyChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getOverpaymentPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getInterestPortion())); + assertEquals(3.65, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getFeeChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getOutstandingLoanBalance())); + businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE) .date("2023.06.17").dateFormat("yyyy.MM.dd").locale("en")); PostLoansLoanIdTransactionsResponse merchantIssuedRefund1 = loanTransactionHelper.makeMerchantIssuedRefund(Long.valueOf(loanID), @@ -1438,16 +1601,16 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat assertEquals(2.95, Utils.getDoubleValue(loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalOutstanding())); assertTrue(loanDetails.getStatus().getActive()); - assertNull(loanDetails.getTransactions().get(1).getReversedOnDate()); - assertTrue(loanDetails.getTransactions().get(1).getTransactionRelations().isEmpty()); - assertTrue(loanDetails.getTransactions().get(1).getType().getMerchantIssuedRefund()); - assertEquals(125.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getAmount())); - assertEquals(125.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getPrincipalPortion())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getPenaltyChargesPortion())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getOverpaymentPortion())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getInterestPortion())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getFeeChargesPortion())); - assertEquals(2.95, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getOutstandingLoanBalance())); + assertNull(loanDetails.getTransactions().get(2).getReversedOnDate()); + assertTrue(loanDetails.getTransactions().get(2).getTransactionRelations().isEmpty()); + assertTrue(loanDetails.getTransactions().get(2).getType().getMerchantIssuedRefund()); + assertEquals(125.0, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getAmount())); + assertEquals(125.0, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getPrincipalPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getPenaltyChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getOverpaymentPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getInterestPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getFeeChargesPortion())); + assertEquals(2.95, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getOutstandingLoanBalance())); PostLoansLoanIdChargesChargeIdResponse chargeAdjustmentResponse = this.loanTransactionHelper.chargeAdjustment((long) loanID, (long) penalty1LoanChargeId, new PostLoansLoanIdChargesChargeIdRequest().amount(3.65)); @@ -1466,18 +1629,18 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat assertEquals(0.0, Utils.getDoubleValue(loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalOutstanding())); assertTrue(loanDetails.getStatus().getActive()); - assertNull(loanDetails.getTransactions().get(2).getReversedOnDate()); - assertFalse(loanDetails.getTransactions().get(2).getTransactionRelations().isEmpty()); + assertNull(loanDetails.getTransactions().get(3).getReversedOnDate()); + assertFalse(loanDetails.getTransactions().get(3).getTransactionRelations().isEmpty()); assertEquals((long) penalty1LoanChargeId, - loanDetails.getTransactions().get(2).getTransactionRelations().iterator().next().getToLoanCharge()); - assertTrue(loanDetails.getTransactions().get(2).getType().getChargeAdjustment()); - assertEquals(3.65, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getAmount())); - assertEquals(2.95, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getPrincipalPortion())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getPenaltyChargesPortion())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getOverpaymentPortion())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getInterestPortion())); - assertEquals(0.7, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getFeeChargesPortion())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getOutstandingLoanBalance())); + loanDetails.getTransactions().get(3).getTransactionRelations().iterator().next().getToLoanCharge()); + assertTrue(loanDetails.getTransactions().get(3).getType().getChargeAdjustment()); + assertEquals(3.65, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getAmount())); + assertEquals(2.95, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getPrincipalPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getPenaltyChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getOverpaymentPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getInterestPortion())); + assertEquals(0.7, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getFeeChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getOutstandingLoanBalance())); PostLoansLoanIdTransactionsResponse merchantIssuedRefund2 = loanTransactionHelper.makeMerchantIssuedRefund(Long.valueOf(loanID), new PostLoansLoanIdTransactionsRequest().locale("en").dateFormat("dd MMMM yyyy").transactionDate("17 June 2023") @@ -1497,16 +1660,16 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat assertEquals(0.0, Utils.getDoubleValue(loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalOutstanding())); assertTrue(loanDetails.getStatus().getClosedObligationsMet()); - assertNull(loanDetails.getTransactions().get(3).getReversedOnDate()); - assertTrue(loanDetails.getTransactions().get(3).getTransactionRelations().isEmpty()); - assertTrue(loanDetails.getTransactions().get(3).getType().getMerchantIssuedRefund()); - assertEquals(2.95, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getAmount())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getPrincipalPortion())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getPenaltyChargesPortion())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getOverpaymentPortion())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getInterestPortion())); - assertEquals(2.95, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getFeeChargesPortion())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getOutstandingLoanBalance())); + assertNull(loanDetails.getTransactions().get(4).getReversedOnDate()); + assertTrue(loanDetails.getTransactions().get(4).getTransactionRelations().isEmpty()); + assertTrue(loanDetails.getTransactions().get(4).getType().getMerchantIssuedRefund()); + assertEquals(2.95, Utils.getDoubleValue(loanDetails.getTransactions().get(4).getAmount())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(4).getPrincipalPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(4).getPenaltyChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(4).getOverpaymentPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(4).getInterestPortion())); + assertEquals(2.95, Utils.getDoubleValue(loanDetails.getTransactions().get(4).getFeeChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(4).getOutstandingLoanBalance())); } finally { globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, @@ -1599,6 +1762,17 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(0).getFeeChargesPortion())); assertEquals(127.95, Utils.getDoubleValue(loanDetails.getTransactions().get(0).getOutstandingLoanBalance())); + assertNull(loanDetails.getTransactions().get(1).getReversedOnDate()); + assertTrue(loanDetails.getTransactions().get(1).getTransactionRelations().isEmpty()); + assertTrue(loanDetails.getTransactions().get(1).getType().getAccrual()); + assertEquals(3.65, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getAmount())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getPrincipalPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getPenaltyChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getOverpaymentPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getInterestPortion())); + assertEquals(3.65, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getFeeChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getOutstandingLoanBalance())); + businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE) .date("2023.06.17").dateFormat("yyyy.MM.dd").locale("en")); @@ -1620,16 +1794,16 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat assertEquals(2.95, Utils.getDoubleValue(loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalOutstanding())); assertTrue(loanDetails.getStatus().getActive()); - assertNull(loanDetails.getTransactions().get(1).getReversedOnDate()); - assertTrue(loanDetails.getTransactions().get(1).getTransactionRelations().isEmpty()); - assertTrue(loanDetails.getTransactions().get(1).getType().getMerchantIssuedRefund()); - assertEquals(125.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getAmount())); - assertEquals(125.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getPrincipalPortion())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getPenaltyChargesPortion())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getOverpaymentPortion())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getInterestPortion())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getFeeChargesPortion())); - assertEquals(2.95, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getOutstandingLoanBalance())); + assertNull(loanDetails.getTransactions().get(2).getReversedOnDate()); + assertTrue(loanDetails.getTransactions().get(2).getTransactionRelations().isEmpty()); + assertTrue(loanDetails.getTransactions().get(2).getType().getMerchantIssuedRefund()); + assertEquals(125.0, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getAmount())); + assertEquals(125.0, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getPrincipalPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getPenaltyChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getOverpaymentPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getInterestPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getFeeChargesPortion())); + assertEquals(2.95, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getOutstandingLoanBalance())); PostLoansLoanIdChargesChargeIdResponse chargeAdjustmentResponse = this.loanTransactionHelper.chargeAdjustment((long) loanID, (long) penalty1LoanChargeId, new PostLoansLoanIdChargesChargeIdRequest().amount(3.65)); @@ -1648,18 +1822,18 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat assertEquals(0.0, Utils.getDoubleValue(loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalOutstanding())); assertTrue(loanDetails.getStatus().getActive()); - assertNull(loanDetails.getTransactions().get(2).getReversedOnDate()); - assertFalse(loanDetails.getTransactions().get(2).getTransactionRelations().isEmpty()); + assertNull(loanDetails.getTransactions().get(3).getReversedOnDate()); + assertFalse(loanDetails.getTransactions().get(3).getTransactionRelations().isEmpty()); assertEquals((long) penalty1LoanChargeId, - loanDetails.getTransactions().get(2).getTransactionRelations().iterator().next().getToLoanCharge()); - assertTrue(loanDetails.getTransactions().get(2).getType().getChargeAdjustment()); - assertEquals(3.65, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getAmount())); - assertEquals(2.95, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getPrincipalPortion())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getPenaltyChargesPortion())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getOverpaymentPortion())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getInterestPortion())); - assertEquals(0.7, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getFeeChargesPortion())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(2).getOutstandingLoanBalance())); + loanDetails.getTransactions().get(3).getTransactionRelations().iterator().next().getToLoanCharge()); + assertTrue(loanDetails.getTransactions().get(3).getType().getChargeAdjustment()); + assertEquals(3.65, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getAmount())); + assertEquals(2.95, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getPrincipalPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getPenaltyChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getOverpaymentPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getInterestPortion())); + assertEquals(0.7, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getFeeChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getOutstandingLoanBalance())); PostLoansLoanIdTransactionsResponse merchantIssuedRefund2 = loanTransactionHelper.makeMerchantIssuedRefund(Long.valueOf(loanID), new PostLoansLoanIdTransactionsRequest().locale("en").dateFormat("dd MMMM yyyy").transactionDate("17 June 2023") @@ -1679,16 +1853,16 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat assertEquals(0.0, Utils.getDoubleValue(loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalOutstanding())); assertTrue(loanDetails.getStatus().getClosedObligationsMet()); - assertNull(loanDetails.getTransactions().get(3).getReversedOnDate()); - assertTrue(loanDetails.getTransactions().get(3).getTransactionRelations().isEmpty()); - assertTrue(loanDetails.getTransactions().get(3).getType().getMerchantIssuedRefund()); - assertEquals(2.95, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getAmount())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getPrincipalPortion())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getPenaltyChargesPortion())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getOverpaymentPortion())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getInterestPortion())); - assertEquals(2.95, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getFeeChargesPortion())); - assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(3).getOutstandingLoanBalance())); + assertNull(loanDetails.getTransactions().get(4).getReversedOnDate()); + assertTrue(loanDetails.getTransactions().get(4).getTransactionRelations().isEmpty()); + assertTrue(loanDetails.getTransactions().get(4).getType().getMerchantIssuedRefund()); + assertEquals(2.95, Utils.getDoubleValue(loanDetails.getTransactions().get(4).getAmount())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(4).getPrincipalPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(4).getPenaltyChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(4).getOverpaymentPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(4).getInterestPortion())); + assertEquals(2.95, Utils.getDoubleValue(loanDetails.getTransactions().get(4).getFeeChargesPortion())); + assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(4).getOutstandingLoanBalance())); } finally { globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, new PutGlobalConfigurationsRequest().enabled(false)); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccrualTransactionOnDisbursementByAccountingTypeTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccrualTransactionOnDisbursementByAccountingTypeTest.java deleted file mode 100644 index 7727c8e860..0000000000 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccrualTransactionOnDisbursementByAccountingTypeTest.java +++ /dev/null @@ -1,184 +0,0 @@ -/** - * 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 java.math.BigDecimal; -import java.util.List; -import java.util.function.Consumer; -import lombok.extern.slf4j.Slf4j; -import org.apache.fineract.client.models.GetLoansLoanIdResponse; -import org.apache.fineract.client.models.GetLoansLoanIdTransactions; -import org.apache.fineract.client.models.PostClientsResponse; -import org.apache.fineract.client.models.PostLoanProductsRequest; -import org.apache.fineract.client.models.PostLoanProductsResponse; -import org.apache.fineract.client.models.PostLoansRequest; -import org.apache.fineract.integrationtests.common.ClientHelper; -import org.junit.jupiter.api.Test; - -@Slf4j -public class LoanAccrualTransactionOnDisbursementByAccountingTypeTest extends BaseLoanIntegrationTest { - - private static final String DISBURSEMENT_DATE = "01 January 2024"; - private static final Double LOAN_AMOUNT = 1000.0; - private static final double INTEREST_RATE_PER_PERIOD = 12.0; // 12% annual - - // Customizer to set non-zero interest rate on the loan application - // (applyLoanRequest defaults to interestRatePerPeriod=0 which would result in no interest and no accrual) - private static final Consumer<PostLoansRequest> WITH_INTEREST = request -> request - .interestRatePerPeriod(BigDecimal.valueOf(INTEREST_RATE_PER_PERIOD)); - - @Test - public void testNoAccrualTransactionCreatedForNoneAccountingType() { - runAt(DISBURSEMENT_DATE, () -> { - PostClientsResponse client = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()); - - // Create a loan product with None accounting (accountingRule = 1) - PostLoanProductsRequest productRequest = createOnePeriod30DaysPeriodicAccrualProduct(INTEREST_RATE_PER_PERIOD).accountingRule(1) // NONE - .fundSourceAccountId(null) // - .loanPortfolioAccountId(null) // - .transfersInSuspenseAccountId(null) // - .interestOnLoanAccountId(null) // - .incomeFromFeeAccountId(null) // - .incomeFromPenaltyAccountId(null) // - .incomeFromRecoveryAccountId(null) // - .writeOffAccountId(null) // - .overpaymentLiabilityAccountId(null) // - .receivableInterestAccountId(null) // - .receivableFeeAccountId(null) // - .receivablePenaltyAccountId(null) // - .goodwillCreditAccountId(null) // - .incomeFromGoodwillCreditInterestAccountId(null) // - .incomeFromGoodwillCreditFeesAccountId(null) // - .incomeFromGoodwillCreditPenaltyAccountId(null) // - .incomeFromChargeOffInterestAccountId(null) // - .incomeFromChargeOffFeesAccountId(null) // - .incomeFromChargeOffPenaltyAccountId(null) // - .chargeOffExpenseAccountId(null) // - .chargeOffFraudExpenseAccountId(null); - - PostLoanProductsResponse loanProduct = loanProductHelper.createLoanProduct(productRequest); - - Long loanId = applyAndApproveLoan(client.getClientId(), loanProduct.getResourceId(), DISBURSEMENT_DATE, LOAN_AMOUNT, 1, - WITH_INTEREST); - disburseLoan(loanId, BigDecimal.valueOf(LOAN_AMOUNT), DISBURSEMENT_DATE); - - GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId); - List<GetLoansLoanIdTransactions> transactions = loanDetails.getTransactions(); - - // Verify no Accrual transaction exists - List<GetLoansLoanIdTransactions> accrualTransactions = transactions.stream() - .filter(t -> "Accrual".equals(t.getType().getValue())).toList(); - - assertTrue(accrualTransactions.isEmpty(), - "No accrual transactions should be created for None accounting type, but found: " + accrualTransactions.size()); - }); - } - - @Test - public void testNoAccrualTransactionCreatedForCashAccountingType() { - runAt(DISBURSEMENT_DATE, () -> { - PostClientsResponse client = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()); - - // Create a loan product with Cash-based accounting (accountingRule = 2) - PostLoanProductsRequest productRequest = createOnePeriod30DaysPeriodicAccrualProduct(INTEREST_RATE_PER_PERIOD).accountingRule(2) // CASH_BASED - // Cash accounting doesn't need receivable accounts, clear them - .receivableInterestAccountId(null) // - .receivableFeeAccountId(null) // - .receivablePenaltyAccountId(null); - - PostLoanProductsResponse loanProduct = loanProductHelper.createLoanProduct(productRequest); - - Long loanId = applyAndApproveLoan(client.getClientId(), loanProduct.getResourceId(), DISBURSEMENT_DATE, LOAN_AMOUNT, 1, - WITH_INTEREST); - disburseLoan(loanId, BigDecimal.valueOf(LOAN_AMOUNT), DISBURSEMENT_DATE); - - GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId); - List<GetLoansLoanIdTransactions> transactions = loanDetails.getTransactions(); - - // Verify no Accrual transaction exists - List<GetLoansLoanIdTransactions> accrualTransactions = transactions.stream() - .filter(t -> "Accrual".equals(t.getType().getValue())).toList(); - - assertTrue(accrualTransactions.isEmpty(), - "No accrual transactions should be created for Cash accounting type, but found: " + accrualTransactions.size()); - }); - } - - @Test - public void testAccrualTransactionCreatedForUpfrontAccrualAccountingType() { - runAt(DISBURSEMENT_DATE, () -> { - PostClientsResponse client = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()); - - // Create a loan product with Accrual Upfront accounting (accountingRule = 4) - PostLoanProductsRequest productRequest = createOnePeriod30DaysPeriodicAccrualProduct(INTEREST_RATE_PER_PERIOD) - .accountingRule(4); // ACCRUAL_UPFRONT - - PostLoanProductsResponse loanProduct = loanProductHelper.createLoanProduct(productRequest); - - Long loanId = applyAndApproveLoan(client.getClientId(), loanProduct.getResourceId(), DISBURSEMENT_DATE, LOAN_AMOUNT, 1, - WITH_INTEREST); - disburseLoan(loanId, BigDecimal.valueOf(LOAN_AMOUNT), DISBURSEMENT_DATE); - - GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId); - List<GetLoansLoanIdTransactions> transactions = loanDetails.getTransactions(); - - // Verify Accrual transaction exists for upfront accounting - List<GetLoansLoanIdTransactions> accrualTransactions = transactions.stream() - .filter(t -> "Accrual".equals(t.getType().getValue())).toList(); - - assertEquals(1, accrualTransactions.size(), - "Exactly one accrual transaction should be created for Accrual Upfront accounting type"); - - // Verify the accrual transaction has a positive interest portion - BigDecimal interestPortion = accrualTransactions.getFirst().getInterestPortion(); - assertTrue(interestPortion != null && interestPortion.compareTo(BigDecimal.ZERO) > 0, - "Accrual transaction should have a positive interest portion"); - }); - } - - @Test - public void testNoAccrualTransactionAtDisbursementForPeriodicAccrualAccountingType() { - runAt(DISBURSEMENT_DATE, () -> { - PostClientsResponse client = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()); - - // Create a loan product with Accrual Periodic accounting (accountingRule = 3) - PostLoanProductsRequest productRequest = createOnePeriod30DaysPeriodicAccrualProduct(INTEREST_RATE_PER_PERIOD); - // accountingRule is already 3 (ACCRUAL_PERIODIC) by default in this method - - PostLoanProductsResponse loanProduct = loanProductHelper.createLoanProduct(productRequest); - - Long loanId = applyAndApproveLoan(client.getClientId(), loanProduct.getResourceId(), DISBURSEMENT_DATE, LOAN_AMOUNT, 1, - WITH_INTEREST); - disburseLoan(loanId, BigDecimal.valueOf(LOAN_AMOUNT), DISBURSEMENT_DATE); - - GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId); - List<GetLoansLoanIdTransactions> transactions = loanDetails.getTransactions(); - - // Verify no Accrual transaction exists at disbursement time (accruals happen via COB) - List<GetLoansLoanIdTransactions> accrualTransactions = transactions.stream() - .filter(t -> "Accrual".equals(t.getType().getValue())).toList(); - - assertTrue(accrualTransactions.isEmpty(), - "No accrual transactions should be created at disbursement for Periodic Accrual accounting type"); - }); - } -} diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionReverseReplayTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionReverseReplayTest.java index f4b26a2b74..3cd581c411 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionReverseReplayTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionReverseReplayTest.java @@ -20,6 +20,7 @@ package org.apache.fineract.integrationtests; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import io.restassured.builder.RequestSpecBuilder; import io.restassured.builder.ResponseSpecBuilder; @@ -139,6 +140,10 @@ public class LoanTransactionReverseReplayTest extends BaseLoanIntegrationTest { loanTransactionHelper.addChargesForLoan(loanId, LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty), penaltyCharge1AddedDate, "10")); inlineLoanCOBHelper.executeInlineCOB(List.of(loanId.longValue())); + GetLoansLoanIdResponse loansLoanIdResponse = loanTransactionHelper.getLoanDetails(loanExternalIdStr); + int lastTransactionIndex = loansLoanIdResponse.getTransactions().size() - 1; + assertTrue(loansLoanIdResponse.getTransactions().get(lastTransactionIndex).getType().getAccrual()); + assertEquals(10.0, Utils.getDoubleValue(loansLoanIdResponse.getTransactions().get(lastTransactionIndex).getAmount())); } finally { globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, new PutGlobalConfigurationsRequest().enabled(false)); @@ -185,6 +190,9 @@ public class LoanTransactionReverseReplayTest extends BaseLoanIntegrationTest { inlineLoanCOBHelper.executeInlineCOB(List.of(loanId.longValue())); GetLoansLoanIdResponse loansLoanIdResponse = loanTransactionHelper.getLoanDetails(loanExternalIdStr); + int lastTransactionIndex = loansLoanIdResponse.getTransactions().size() - 1; + assertTrue(loansLoanIdResponse.getTransactions().get(lastTransactionIndex).getType().getAccrual()); + assertEquals(10.0, Utils.getDoubleValue(loansLoanIdResponse.getTransactions().get(lastTransactionIndex).getAmount())); int lastPeriodIndex = loansLoanIdResponse.getRepaymentSchedule().getPeriods().size() - 1; assertEquals(LocalDate.of(2022, 10, 10), loansLoanIdResponse.getRepaymentSchedule().getPeriods().get(lastPeriodIndex).getDueDate()); 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 ebbc0b03fa..1428ee892f 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 @@ -1095,6 +1095,11 @@ public class SchedulerJobsTestResults extends IntegrationTest { Assertions.assertEquals(39.39f, (Float) repaymentScheduleDataAfter.get(1).get("penaltyChargesDue"), "Verifying From Penalty Charges due fot first Repayment after Successful completion of Scheduler Job"); + List<Map> transactions = this.loanTransactionHelper.getLoanTransactions(this.requestSpec, this.responseSpec, loanID); + Assertions.assertEquals(39.39f, (Float) transactions.get(2).get("amount")); + Assertions.assertEquals(2019, ((List) transactions.get(2).get("date")).get(0)); + Assertions.assertEquals(4, ((List) transactions.get(2).get("date")).get(1)); + Assertions.assertEquals(2, ((List) transactions.get(2).get("date")).get(2)); } finally { globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, new PutGlobalConfigurationsRequest().enabled(false)); @@ -1157,6 +1162,11 @@ public class SchedulerJobsTestResults extends IntegrationTest { Assertions.assertEquals(39.39f, (Float) repaymentScheduleDataAfter.get(1).get("penaltyChargesDue"), "Verifying From Penalty Charges due fot first Repayment after Successful completion of Scheduler Job"); + List<Map> transactions = this.loanTransactionHelper.getLoanTransactions(this.requestSpec, this.responseSpec, loanID2); + Assertions.assertEquals(39.39f, (Float) transactions.get(2).get("amount")); + Assertions.assertEquals(2020, ((List) transactions.get(2).get("date")).get(0)); + Assertions.assertEquals(5, ((List) transactions.get(2).get("date")).get(1)); + Assertions.assertEquals(2, ((List) transactions.get(2).get("date")).get(2)); } finally { globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, new PutGlobalConfigurationsRequest().enabled(false));
