From 849790ea4636a566f28e1a0e5400a81260eb5787 Mon Sep 17 00:00:00 2001 From: Jose Alberto Hernandez Date: Mon, 22 Apr 2024 08:11:23 -0500 Subject: [PATCH] FINERACT-1971: Down payment (auto) transaction using installment multiples of setting --- .../organisation/monetary/domain/Money.java | 4 +- .../monetary/domain/MoneyHelper.java | 8 + .../resources/features/LoanCharge.feature | 16 +- .../features/LoanDownPayment.feature | 12 +- .../features/LoanReAmortization.feature | 16 +- .../resources/features/LoanRepayment.feature | 8 +- .../portfolio/loanaccount/domain/Loan.java | 4 +- .../domain/LoanApplicationTerms.java | 5 +- .../InternalConfigurationsApiResource.java | 88 ++++ ...WritePlatformServiceJpaRepositoryImpl.java | 5 +- ...ntAllocationLoanRepaymentScheduleTest.java | 169 +++++-- .../CustomSnapshotEventIntegrationTest.java | 48 +- ...ntLevelDelinquencyAPIIntegrationTests.java | 60 +-- .../LoanAccountRepaymentCalculationTest.java | 16 +- ...WithCreditAllocationsIntegrationTests.java | 450 +++++++++--------- .../LoanInstallmentMultiplesOfTest.java | 32 +- .../LoanRescheduleTestWithDownpayment.java | 4 +- .../common/GlobalConfigurationHelper.java | 8 + 18 files changed, 582 insertions(+), 371 deletions(-) create mode 100644 fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/api/InternalConfigurationsApiResource.java diff --git a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/domain/Money.java b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/domain/Money.java index c7e290af69f..9e2d51af9f2 100644 --- a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/domain/Money.java +++ b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/domain/Money.java @@ -124,7 +124,7 @@ public static BigDecimal roundToMultiplesOf(final BigDecimal existingVal, final BigDecimal amountScaled = existingVal; BigDecimal inMultiplesOfValue = BigDecimal.valueOf(inMultiplesOf.intValue()); if (inMultiplesOfValue.compareTo(BigDecimal.ZERO) > 0) { - amountScaled = existingVal.divide(inMultiplesOfValue, 0, RoundingMode.HALF_UP).multiply(inMultiplesOfValue); + amountScaled = existingVal.divide(inMultiplesOfValue, 0, MoneyHelper.getRoundingMode()).multiply(inMultiplesOfValue); } return amountScaled; } @@ -133,7 +133,7 @@ public static Money roundToMultiplesOf(final Money existingVal, final Integer in BigDecimal amountScaled = existingVal.getAmount(); BigDecimal inMultiplesOfValue = BigDecimal.valueOf(inMultiplesOf.intValue()); if (inMultiplesOfValue.compareTo(BigDecimal.ZERO) > 0) { - amountScaled = amountScaled.divide(inMultiplesOfValue, 0, RoundingMode.HALF_UP).multiply(inMultiplesOfValue); + amountScaled = amountScaled.divide(inMultiplesOfValue, 0, MoneyHelper.getRoundingMode()).multiply(inMultiplesOfValue); } return Money.of(existingVal.getCurrency(), amountScaled); } diff --git a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/domain/MoneyHelper.java b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/domain/MoneyHelper.java index baaf576dabe..d3cefb27d2c 100644 --- a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/domain/MoneyHelper.java +++ b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/domain/MoneyHelper.java @@ -22,10 +22,12 @@ import jakarta.annotation.PostConstruct; import java.math.MathContext; import java.math.RoundingMode; +import lombok.extern.slf4j.Slf4j; import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +@Slf4j @Component public class MoneyHelper { @@ -59,4 +61,10 @@ public static MathContext getMathContext() { } return mathContext; } + + public static void fetchRoundingModeFromGlobalConfig() { + roundingMode = RoundingMode.valueOf(staticConfigurationDomainService.getRoundingMode()); + log.info("Fetch Rounding Mode from Global Config {}", roundingMode.name()); + } + } diff --git a/fineract-e2e-tests-runner/src/test/resources/features/LoanCharge.feature b/fineract-e2e-tests-runner/src/test/resources/features/LoanCharge.feature index b3f39d6d0a6..e685d349f1f 100644 --- a/fineract-e2e-tests-runner/src/test/resources/features/LoanCharge.feature +++ b/fineract-e2e-tests-runner/src/test/resources/features/LoanCharge.feature @@ -1581,23 +1581,23 @@ Feature: LoanCharge Then Loan Transactions tab has the following data: | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | | 01 January 2023 | Disbursement | 750.0 | 0.0 | 0.0 | 0.0 | 0.0 | 750.0 | - | 01 January 2023 | Down Payment | 187.5 | 187.5 | 0.0 | 0.0 | 0.0 | 562.5 | - | 01 February 2023 | Repayment | 250.0 | 250.0 | 0.0 | 0.0 | 0.0 | 312.5 | - | 01 March 2023 | Repayment | 250.0 | 250.0 | 0.0 | 0.0 | 0.0 | 62.5 | - | 01 April 2023 | Repayment | 250.0 | 62.5 | 0.0 | 0.0 | 0.0 | 0.0 | - | 05 April 2023 | Waive loan charges | 10.0 | 0.0 | 0.0 | 0.0 | 0.0 | 62.5 | + | 01 January 2023 | Down Payment | 188.0 | 188.0 | 0.0 | 0.0 | 0.0 | 562.0 | + | 01 February 2023 | Repayment | 250.0 | 250.0 | 0.0 | 0.0 | 0.0 | 312.0 | + | 01 March 2023 | Repayment | 250.0 | 250.0 | 0.0 | 0.0 | 0.0 | 62.0 | + | 01 April 2023 | Repayment | 250.0 | 62.0 | 0.0 | 0.0 | 0.0 | 0.0 | + | 05 April 2023 | Waive loan charges | 10.0 | 0.0 | 0.0 | 0.0 | 0.0 | 62.0 | Then On Loan Transactions tab the "Repayment" Transaction with date "01 April 2023" is reverted Then Loan Repayment schedule has 5 periods, with the following data for periods: | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Waived | Outstanding | | | | 01 January 2023 | | 750.0 | | | 0.0 | | 0.0 | 0.0 | | | | | - | 1 | 0 | 01 January 2023 | 01 February 2023 | 562.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | 188.0 | 0.0 | 0.5 | 0.0 | 0.0 | + | 1 | 0 | 01 January 2023 | 01 January 2023 | 562.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | 188.0 | 0.0 | 0.0 | 0.0 | 0.0 | | 2 | 15 | 16 January 2023 | 01 February 2023 | 375.0 | 187.0 | 0.0 | 0.0 | 0.0 | 187.0 | 187.0 | 0.0 | 187.0 | 0.0 | 0.0 | | 3 | 15 | 31 January 2023 | 01 March 2023 | 188.0 | 187.0 | 0.0 | 0.0 | 0.0 | 187.0 | 187.0 | 0.0 | 187.0 | 0.0 | 0.0 | - | 4 | 15 | 15 February 2023 | | 0.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | 125.5 | 0.0 | 125.5 | 0.0 | 62.5 | + | 4 | 15 | 15 February 2023 | | 0.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | 126.0 | 0.0 | 126.0 | 0.0 | 62.0 | | 5 | 49 | 05 April 2023 | 05 April 2023 | 0.0 | 0.0 | 0.0 | 0.0 | 10.0 | 10.0 | 0.0 | 0.0 | 0.0 | 10.0 | 0.0 | Then Loan Repayment schedule has the following data in Total row: | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Waived | Outstanding | - | 750 | 0 | 0 | 10 | 760 | 687.5 | 0 | 500 | 10 | 62.5 | + | 750 | 0 | 0 | 10 | 760 | 688.0 | 0 | 500 | 10 | 62.0 | @TestRailId:C2994 Scenario: Waive charge on PIN4 progressive loan diff --git a/fineract-e2e-tests-runner/src/test/resources/features/LoanDownPayment.feature b/fineract-e2e-tests-runner/src/test/resources/features/LoanDownPayment.feature index 35ec81fe8c8..e5198501f73 100644 --- a/fineract-e2e-tests-runner/src/test/resources/features/LoanDownPayment.feature +++ b/fineract-e2e-tests-runner/src/test/resources/features/LoanDownPayment.feature @@ -2032,10 +2032,10 @@ Feature: Loan DownPayment Then Loan Repayment schedule has 4 periods, with the following data for periods: | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | | | 01 January 2022 | | 1250.0 | | | 0.0 | | 0.0 | 0.0 | | | | - | 1 | 0 | 01 January 2022 | | 937.0 | 313.0 | 0.0 | 0.0 | 0.0 | 313.0 | 0.0 | 0.0 | 0.0 | 313.0 | - | 2 | 31 | 01 February 2022 | | 625.0 | 312.0 | 0.0 | 0.0 | 0.0 | 312.0 | 0.0 | 0.0 | 0.0 | 312.0 | - | 3 | 28 | 01 March 2022 | | 313.0 | 312.0 | 0.0 | 0.0 | 0.0 | 312.0 | 0.0 | 0.0 | 0.0 | 312.0 | - | 4 | 31 | 01 April 2022 | | 0.0 | 313.0 | 0.0 | 0.0 | 0.0 | 313.0 | 0.0 | 0.0 | 0.0 | 313.0 | + | 1 | 0 | 01 January 2022 | | 938.0 | 312.0 | 0.0 | 0.0 | 0.0 | 312.0 | 0.0 | 0.0 | 0.0 | 312.0 | + | 2 | 31 | 01 February 2022 | | 625.0 | 313.0 | 0.0 | 0.0 | 0.0 | 313.0 | 0.0 | 0.0 | 0.0 | 313.0 | + | 3 | 28 | 01 March 2022 | | 312.0 | 313.0 | 0.0 | 0.0 | 0.0 | 313.0 | 0.0 | 0.0 | 0.0 | 313.0 | + | 4 | 31 | 01 April 2022 | | 0.0 | 312.0 | 0.0 | 0.0 | 0.0 | 312.0 | 0.0 | 0.0 | 0.0 | 312.0 | Then Loan Repayment schedule has the following data in Total row: | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | 1250.0 | 0 | 0 | 0 | 1250.0 | 0.0 | 0 | 0 | 1250 | @@ -2446,8 +2446,8 @@ Feature: Loan DownPayment | 2 | 15 | 16 February 2024 | 16 February 2024 | 250.0 | 125.0 | 0.0 | 0.0 | 0.0 | 125.0 | 125.0 | 0.0 | 0.0 | 0.0 | | | | 20 February 2024 | | 625.0 | | | 0.0 | | 0.0 | 0.0 | | | | | 3 | 0 | 20 February 2024 | 20 February 2024 | 719.0 | 156.0 | 0.0 | 0.0 | 0.0 | 156.0 | 156.0 | 0.0 | 0.0 | 0.0 | - | 4 | 15 | 02 March 2024 | 20 February 2024 | 359.0 | 360.0 | 0.0 | 0.0 | 0.0 | 360.0 | 360.0 | 360.0 | 0.0 | 0.0 | - | 5 | 15 | 17 March 2024 | 20 February 2024 | 0.0 | 359.0 | 0.0 | 0.0 | 0.0 | 359.0 | 359.0 | 359.0 | 0.0 | 0.0 | + | 4 | 15 | 02 March 2024 | 20 February 2024 | 360.0 | 359.0 | 0.0 | 0.0 | 0.0 | 359.0 | 359.0 | 359.0 | 0.0 | 0.0 | + | 5 | 15 | 17 March 2024 | 20 February 2024 | 0.0 | 360.0 | 0.0 | 0.0 | 0.0 | 360.0 | 360.0 | 360.0 | 0.0 | 0.0 | Then Loan Repayment schedule has the following data in Total row: | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | 1125.0 | 0.0 | 0.0 | 0.0 | 1125.0 | 1125.0 | 719.0 | 0.0 | 0.0 | diff --git a/fineract-e2e-tests-runner/src/test/resources/features/LoanReAmortization.feature b/fineract-e2e-tests-runner/src/test/resources/features/LoanReAmortization.feature index c0bb30b4e71..6b717fbf2c6 100644 --- a/fineract-e2e-tests-runner/src/test/resources/features/LoanReAmortization.feature +++ b/fineract-e2e-tests-runner/src/test/resources/features/LoanReAmortization.feature @@ -32,8 +32,8 @@ Feature: LoanReAmortization | | | 01 January 2024 | | 500.0 | | | 0.0 | | 0.0 | 0.0 | | | | | 1 | 0 | 01 January 2024 | 01 January 2024 | 375.0 | 125.0 | 0.0 | 0.0 | 0.0 | 125.0 | 125.0 | 0.0 | 0.0 | 0.0 | | 2 | 15 | 16 January 2024 | 25 January 2024 | 375.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | - | 3 | 15 | 31 January 2024 | | 187.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | - | 4 | 15 | 15 February 2024 | | 0.0 | 187.0 | 0.0 | 0.0 | 0.0 | 187.0 | 0.0 | 0.0 | 0.0 | 187.0 | + | 3 | 15 | 31 January 2024 | | 188.0 | 187.0 | 0.0 | 0.0 | 0.0 | 187.0 | 0.0 | 0.0 | 0.0 | 187.0 | + | 4 | 15 | 15 February 2024 | | 0.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | Then Loan Repayment schedule has the following data in Total row: | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | 500.0 | 0.0 | 0.0 | 0.0 | 500.0 | 125.0 | 0.0 | 0.0 | 375.0 | @@ -74,8 +74,8 @@ Feature: LoanReAmortization | | | 01 January 2024 | | 500.0 | | | 0.0 | | 0.0 | 0.0 | | | | | 1 | 0 | 01 January 2024 | 01 January 2024 | 375.0 | 125.0 | 0.0 | 0.0 | 0.0 | 125.0 | 125.0 | 0.0 | 0.0 | 0.0 | | 2 | 15 | 16 January 2024 | 25 January 2024 | 375.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | - | 3 | 15 | 31 January 2024 | | 187.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | - | 4 | 15 | 15 February 2024 | | 0.0 | 187.0 | 0.0 | 0.0 | 0.0 | 187.0 | 0.0 | 0.0 | 0.0 | 187.0 | + | 3 | 15 | 31 January 2024 | | 188.0 | 187.0 | 0.0 | 0.0 | 0.0 | 187.0 | 0.0 | 0.0 | 0.0 | 187.0 | + | 4 | 15 | 15 February 2024 | | 0.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | Then Loan Repayment schedule has the following data in Total row: | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | 500.0 | 0.0 | 0.0 | 0.0 | 500.0 | 125.0 | 0.0 | 0.0 | 375.0 | @@ -102,8 +102,8 @@ Feature: LoanReAmortization | | | 01 January 2024 | | 500.0 | | | 0.0 | | 0.0 | 0.0 | | | | | 1 | 0 | 01 January 2024 | 01 January 2024 | 375.0 | 125.0 | 0.0 | 0.0 | 0.0 | 125.0 | 125.0 | 0.0 | 0.0 | 0.0 | | 2 | 15 | 16 January 2024 | 25 January 2024 | 375.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | - | 3 | 15 | 31 January 2024 | | 187.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | - | 4 | 15 | 15 February 2024 | | 0.0 | 187.0 | 0.0 | 0.0 | 0.0 | 187.0 | 0.0 | 0.0 | 0.0 | 187.0 | + | 3 | 15 | 31 January 2024 | | 188.0 | 187.0 | 0.0 | 0.0 | 0.0 | 187.0 | 0.0 | 0.0 | 0.0 | 187.0 | + | 4 | 15 | 15 February 2024 | | 0.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | Then Loan Repayment schedule has the following data in Total row: | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | 500.0 | 0.0 | 0.0 | 0.0 | 500.0 | 125.0 | 0.0 | 0.0 | 375.0 | @@ -167,8 +167,8 @@ Feature: LoanReAmortization | | | 01 January 2024 | | 500.0 | | | 0.0 | | 0.0 | 0.0 | | | | | 1 | 0 | 01 January 2024 | 01 January 2024 | 375.0 | 125.0 | 0.0 | 0.0 | 0.0 | 125.0 | 125.0 | 0.0 | 0.0 | 0.0 | | 2 | 15 | 16 January 2024 | | 375.0 | 0.0 | 0.0 | 0.0 | 10.0 | 10.0 | 0.0 | 0.0 | 0.0 | 10.0 | - | 3 | 15 | 31 January 2024 | | 187.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | - | 4 | 15 | 15 February 2024 | | 0.0 | 187.0 | 0.0 | 0.0 | 0.0 | 187.0 | 0.0 | 0.0 | 0.0 | 187.0 | + | 3 | 15 | 31 January 2024 | | 188.0 | 187.0 | 0.0 | 0.0 | 0.0 | 187.0 | 0.0 | 0.0 | 0.0 | 187.0 | + | 4 | 15 | 15 February 2024 | | 0.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | Then Loan Repayment schedule has the following data in Total row: | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | 500.0 | 0.0 | 0.0 | 10.0 | 510.0 | 125.0 | 0.0 | 0.0 | 385.0 | diff --git a/fineract-e2e-tests-runner/src/test/resources/features/LoanRepayment.feature b/fineract-e2e-tests-runner/src/test/resources/features/LoanRepayment.feature index 46c1d9b747d..0a628f1f95c 100644 --- a/fineract-e2e-tests-runner/src/test/resources/features/LoanRepayment.feature +++ b/fineract-e2e-tests-runner/src/test/resources/features/LoanRepayment.feature @@ -3139,10 +3139,10 @@ Feature: LoanRepayment Then Loan Repayment schedule has 4 periods, with the following data for periods: | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | | | 01 September 2023 | | 1250.0 | | | 0.0 | | 0.0 | 0.0 | | | | - | 1 | 30 | 01 October 2023 | | 936.62 | 313.38 | 15.62 | 0.0 | 0.0 | 329.0 | 0.0 | 0.0 | 0.0 | 329.0 | - | 2 | 31 | 01 November 2023 | | 623.24 | 313.38 | 15.62 | 0.0 | 0.0 | 329.0 | 0.0 | 0.0 | 0.0 | 329.0 | - | 3 | 30 | 01 December 2023 | | 309.86 | 313.38 | 15.62 | 0.0 | 0.0 | 329.0 | 0.0 | 0.0 | 0.0 | 329.0 | - | 4 | 31 | 01 January 2024 | | 0.0 | 309.86 | 15.64 | 0.0 | 0.0 | 325.5 | 0.0 | 0.0 | 0.0 | 325.5 | + | 1 | 30 | 01 October 2023 | | 937.62 | 312.38 | 15.62 | 0.0 | 0.0 | 328.0 | 0.0 | 0.0 | 0.0 | 328.0 | + | 2 | 31 | 01 November 2023 | | 625.24 | 312.38 | 15.62 | 0.0 | 0.0 | 328.0 | 0.0 | 0.0 | 0.0 | 328.0 | + | 3 | 30 | 01 December 2023 | | 312.86 | 312.38 | 15.62 | 0.0 | 0.0 | 328.0 | 0.0 | 0.0 | 0.0 | 328.0 | + | 4 | 31 | 01 January 2024 | | 0.0 | 312.86 | 15.64 | 0.0 | 0.0 | 328.5 | 0.0 | 0.0 | 0.0 | 328.5 | Then Loan Repayment schedule has the following data in Total row: | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | 1250.0 | 62.50 | 0.0 | 0.0 | 1312.50 | 0.0 | 0.0 | 0.0 | 1312.50 | 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 6c07e948e39..172709b9d26 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 @@ -2968,7 +2968,9 @@ public LoanTransaction handleDownPayment(final LoanTransaction disbursementTrans } Money downPaymentMoney = Money.of(getCurrency(), MathUtil.percentageOf(disbursementTransaction.getAmount(), disbursedAmountPercentageForDownPayment, 19)); - + if (getLoanProduct().getInstallmentAmountInMultiplesOf() != null) { + downPaymentMoney = Money.roundToMultiplesOf(downPaymentMoney, getLoanProduct().getInstallmentAmountInMultiplesOf()); + } Money adjustedDownPaymentMoney = switch (getLoanProductRelatedDetail().getLoanScheduleType()) { // For Cumulative loan: To check whether the loan was overpaid when the disbursement happened and to get the // proper amount after the disbursement we are using two balances: diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanApplicationTerms.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanApplicationTerms.java index 57b2528158a..d36398b1400 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanApplicationTerms.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanApplicationTerms.java @@ -1206,10 +1206,11 @@ private double paymentPerPeriod(final BigDecimal periodicInterestRate, final Mon double installmentAmount = FinanicalFunctions.pmt(periodicInterestRate.doubleValue(), periodsRemaining.doubleValue(), principalDouble, futureValue, false); + BigDecimal fixedEmiAmount = BigDecimal.valueOf(installmentAmount); if (this.installmentAmountInMultiplesOf != null) { - installmentAmount = Money.roundToMultiplesOf(installmentAmount, this.installmentAmountInMultiplesOf); + fixedEmiAmount = Money.roundToMultiplesOf(fixedEmiAmount, this.installmentAmountInMultiplesOf); } - setFixedEmiAmount(BigDecimal.valueOf(installmentAmount)); + setFixedEmiAmount(fixedEmiAmount); } return getFixedEmiAmount().doubleValue(); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/api/InternalConfigurationsApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/api/InternalConfigurationsApiResource.java new file mode 100644 index 00000000000..515ebbf775f --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/api/InternalConfigurationsApiResource.java @@ -0,0 +1,88 @@ +/** + * 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.infrastructure.configuration.api; + +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.Context; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.UriInfo; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.infrastructure.configuration.domain.GlobalConfigurationProperty; +import org.apache.fineract.infrastructure.configuration.domain.GlobalConfigurationRepositoryWrapper; +import org.apache.fineract.infrastructure.core.boot.FineractProfiles; +import org.apache.fineract.organisation.monetary.domain.MoneyHelper; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.RequestBody; + +@Profile(FineractProfiles.TEST) +@Component +@Path("/v1/internal/configurations") +@RequiredArgsConstructor +@Slf4j +public class InternalConfigurationsApiResource implements InitializingBean { + + private final GlobalConfigurationRepositoryWrapper repository; + + @Override + @SuppressFBWarnings("SLF4J_SIGN_ONLY_FORMAT") + public void afterPropertiesSet() throws Exception { + log.warn("------------------------------------------------------------"); + log.warn(" "); + log.warn("DO NOT USE THIS IN PRODUCTION!"); + log.warn("Internal Config services mode is enabled"); + log.warn("DO NOT USE THIS IN PRODUCTION!"); + log.warn(" "); + log.warn("------------------------------------------------------------"); + + } + + @POST + @Path("{configId}/value/{configValue}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + @SuppressFBWarnings("SLF4J_SIGN_ONLY_FORMAT") + public Response updateGlobalConfiguration(@Context final UriInfo uriInfo, @PathParam("configId") Long configId, + @PathParam("configValue") Long configValue, @RequestBody(required = false) String error) { + log.warn("------------------------------------------------------------"); + log.warn(" "); + log.warn("Update trap-door config: {}", configId); + log.warn(" "); + log.warn("------------------------------------------------------------"); + + final GlobalConfigurationProperty config = repository.findOneWithNotFoundDetection(configId); + log.warn("Config to be updated {} original value {}", config.getName(), config.getValue()); + config.setValue(configValue); + repository.save(config); + log.warn("Config to be updated to {}", config.getValue()); + repository.removeFromCache(config.getName()); + MoneyHelper.fetchRoundingModeFromGlobalConfig(); + + return Response.status(Response.Status.OK).build(); + } + +} 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 b38b224206f..30178a248c1 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 @@ -488,7 +488,10 @@ public CommandProcessingResult disburseLoan(final Long loanId, final JsonCommand .getDisbursedAmountPercentageForDownPayment(); Money downPaymentMoney = Money.of(loan.getCurrency(), MathUtil.percentageOf(amountToDisburse.getAmount(), disbursedAmountPercentageForDownPayment, 19)); - + if (loan.getLoanProduct().getInstallmentAmountInMultiplesOf() != null) { + downPaymentMoney = Money.roundToMultiplesOf(downPaymentMoney, + loan.getLoanProduct().getInstallmentAmountInMultiplesOf()); + } final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(actualDisbursementDate, downPaymentMoney.getAmount(), PortfolioAccountType.SAVINGS, PortfolioAccountType.LOAN, linkedSavingsAccountData.getId(), loan.getId(), diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java index ecc47ee3990..c76f54b10db 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java @@ -60,6 +60,7 @@ import org.apache.fineract.integrationtests.common.BusinessDateHelper; import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.CommonConstants; +import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper; import org.apache.fineract.integrationtests.common.LoanRescheduleRequestHelper; import org.apache.fineract.integrationtests.common.Utils; import org.apache.fineract.integrationtests.common.accounting.Account; @@ -1802,7 +1803,8 @@ public void uc102() { }); } - // UC103: Advanced payment allocation, add charge after maturity -> N+1 installment, repay the loan + // UC103: Advanced payment allocation, add charge after maturity -> N+1 + // installment, repay the loan // ADVANCED_PAYMENT_ALLOCATION_STRATEGY // 1. Disburse the loan (500) // 2. Add charge after maturity date @@ -1872,7 +1874,8 @@ public void uc103() { // 1. Disburse the loan (500) // 2. Add charge for 3rd and 4th installments // 3. Pay little more than the charge of 1st installment - // 4. Pay little more than the principal of 1st installment and charge of 2nd installment + // 4. Pay little more than the principal of 1st installment and charge of 2nd + // installment @Test public void uc104() { runAt("22 February 2023", () -> { @@ -2026,9 +2029,11 @@ public void uc105() { }); } - // UC106: Advanced payment allocation, horizontal repayment processing, mixed grouping of allocation rules + // UC106: Advanced payment allocation, horizontal repayment processing, mixed + // grouping of allocation rules // ADVANCED_PAYMENT_ALLOCATION_STRATEGY - // 1. Create a Loan product, but the allocation rules are mixed -> expect validation error + // 1. Create a Loan product, but the allocation rules are mixed -> expect + // validation error @Test public void uc106() { runAt("22 February 2023", () -> { @@ -2048,11 +2053,15 @@ public void uc106() { }); } - // UC107: Advanced payment allocation, vertical repayment processing, mixed grouping of allocation rules + // UC107: Advanced payment allocation, vertical repayment processing, mixed + // grouping of allocation rules // ADVANCED_PAYMENT_ALLOCATION_STRATEGY - // 1. Create a Loan product, but the allocation rules are mixed -> no validation error - // 2. Change transaction processor while submitting loan -> expect validation error - // 3. Change to HORIZONTAL loan schedule processing and allocation rules are mixed - > expect validation error + // 1. Create a Loan product, but the allocation rules are mixed -> no validation + // error + // 2. Change transaction processor while submitting loan -> expect validation + // error + // 3. Change to HORIZONTAL loan schedule processing and allocation rules are + // mixed - > expect validation error @Test public void uc107() { runAt("22 February 2023", () -> { @@ -2087,7 +2096,8 @@ public void uc107() { }); } - // UC108: Advanced payment allocation, progressive loan schedule handling, rounding test + // UC108: Advanced payment allocation, progressive loan schedule handling, + // rounding test // ADVANCED_PAYMENT_ALLOCATION_STRATEGY // 1. Create a Loan product, 1000 principal, across 3 installment // 2. Submit the loan, and check the generated repayment schedule @@ -2175,7 +2185,8 @@ public void uc108() { }); } - // UC109: Advanced payment allocation, progressive loan schedule handling, rounding test + // UC109: Advanced payment allocation, progressive loan schedule handling, + // rounding test // ADVANCED_PAYMENT_ALLOCATION_STRATEGY // 1. Create a Loan product, 1000 principal, across 3 installment // 2. Submit the loan, and check the generated repayment schedule @@ -2263,9 +2274,11 @@ public void uc109() { }); } - // UC110: Advanced payment allocation, progressive loan schedule handling, rounding test + // UC110: Advanced payment allocation, progressive loan schedule handling, + // rounding test // ADVANCED_PAYMENT_ALLOCATION_STRATEGY - // 1. Create a Loan product, 40.50 principal, across 4 installment (1 down payment, 3 normal installment) + // 1. Create a Loan product, 40.50 principal, across 4 installment (1 down + // payment, 3 normal installment) // 2. Submit the loan, and check the generated repayment schedule @Test public void uc110() { @@ -2314,9 +2327,11 @@ public void uc110() { }); } - // UC111: Advanced payment allocation, progressive loan schedule handling, rounding test + // UC111: Advanced payment allocation, progressive loan schedule handling, + // rounding test // ADVANCED_PAYMENT_ALLOCATION_STRATEGY - // 1. Create a Loan product, 40.50 principal, across 4 installment (1 down payment, 3 normal installment) + // 1. Create a Loan product, 40.50 principal, across 4 installment (1 down + // payment, 3 normal installment) // 2. Submit the loan, and check the generated repayment schedule @Test public void uc111() { @@ -2785,7 +2800,8 @@ public void uc115() { }); } - // UC116: Advanced payment allocation, horizontal repayment processing, disbursement on due date of an installment + // UC116: Advanced payment allocation, horizontal repayment processing, + // disbursement on due date of an installment // ADVANCED_PAYMENT_ALLOCATION_STRATEGY // 1. Disburse the loan (1000) // 2. Add charge on disbursement date(50) @@ -2869,7 +2885,8 @@ public void uc116() { }); } - // UC117: Advanced payment allocation, horizontal repayment processing, multi disbursement on due date of an + // UC117: Advanced payment allocation, horizontal repayment processing, multi + // disbursement on due date of an // installment // ADVANCED_PAYMENT_ALLOCATION_STRATEGY // 1. Disburse the loan (1000) @@ -2962,7 +2979,8 @@ public void uc117() { }); } - // UC118: Advanced payment allocation, horizontal repayment processing, multi disbursement on disbursement date + // UC118: Advanced payment allocation, horizontal repayment processing, multi + // disbursement on disbursement date // ADVANCED_PAYMENT_ALLOCATION_STRATEGY // 1. Disburse the loan (1000) // 2. Disburse on disbursement date (400) @@ -3019,7 +3037,8 @@ public void uc118() { // UC119: Advanced payment allocation with Loan Schedule as Cumulative // ADVANCED_PAYMENT_ALLOCATION_STRATEGY - // 1. Create a Loan product with Adv. Pment. Alloc., but the loan schedule as Cumulative -> expect validation error + // 1. Create a Loan product with Adv. Pment. Alloc., but the loan schedule as + // Cumulative -> expect validation error @Test public void uc119() { runAt("02 February 2023", () -> { @@ -3038,7 +3057,8 @@ public void uc119() { }); } - // UC120: Advanced payment allocation with auto down payment and multiple disbursement on the first day + // UC120: Advanced payment allocation with auto down payment and multiple + // disbursement on the first day // ADVANCED_PAYMENT_ALLOCATION_STRATEGY // 1. Create a Loan product with Adv. Pment. Alloc., and auto down payment // 2. Submit Loan and approve @@ -3095,7 +3115,8 @@ public void uc120() { }); } - // UC121: Advanced payment allocation, horizontal repayment processing product and Loan application + // UC121: Advanced payment allocation, horizontal repayment processing product + // and Loan application // ADVANCED_PAYMENT_ALLOCATION_STRATEGY @Test public void uc121() { @@ -3542,7 +3563,8 @@ public void uc125() { }); } - // UC126: Advanced payment allocation with Fixed Length for 40 days and Loan Term for 45 days (3 repayments every 15 + // UC126: Advanced payment allocation with Fixed Length for 40 days and Loan + // Term for 45 days (3 repayments every 15 // days) // ADVANCED_PAYMENT_ALLOCATION_STRATEGY // 1. Create a Loan product with Adv. Pment. Alloc. and No Interest @@ -3587,7 +3609,8 @@ public void uc126() { }); } - // UC127: Advanced payment allocation with Fixed Length for 5 weeks and Loan Term for 6 weeks (3 repayments every 2 + // UC127: Advanced payment allocation with Fixed Length for 5 weeks and Loan + // Term for 6 weeks (3 repayments every 2 // weeks) // ADVANCED_PAYMENT_ALLOCATION_STRATEGY // 1. Create a Loan product with Adv. Pment. Alloc. and No Interest @@ -3636,7 +3659,8 @@ public void uc127() { }); } - // UC128: Advanced payment allocation with Fixed Length for 11 months and Loan Term for 12 months (6 repayments each + // UC128: Advanced payment allocation with Fixed Length for 11 months and Loan + // Term for 12 months (6 repayments each // 2 months) // every 2 months) // ADVANCED_PAYMENT_ALLOCATION_STRATEGY @@ -3690,7 +3714,8 @@ public void uc128() { }); } - // UC129: Advanced payment allocation with Fixed Length for 5 months and Loan Term for 6 months (6 repayments + // UC129: Advanced payment allocation with Fixed Length for 5 months and Loan + // Term for 6 months (6 repayments // every month) // ADVANCED_PAYMENT_ALLOCATION_STRATEGY // 1. Create a Loan product with Adv. Pment. Alloc. and No Interest @@ -3714,11 +3739,13 @@ public void uc129() { }); } - // UC130: Advanced payment allocation with Fixed Length for 5 months and Loan Term for 6 months (6 repayments + // UC130: Advanced payment allocation with Fixed Length for 5 months and Loan + // Term for 6 months (6 repayments // every month) // ADVANCED_PAYMENT_ALLOCATION_STRATEGY // 1. Create a Loan product with Adv. Pment. Alloc. and No Interest - // 2. Submit Loan and approve -> expect validation error - Fixed Length without Advanced Payment Allocation + // 2. Submit Loan and approve -> expect validation error - Fixed Length without + // Advanced Payment Allocation @Test public void uc130() { final String operationDate = "22 November 2023"; @@ -3730,7 +3757,8 @@ public void uc130() { .numberOfRepayments(6).repaymentEvery(1).repaymentFrequencyType(repaymentFrequencyType.longValue()).fixedLength(6); PostLoanProductsResponse loanProductResponse = loanProductHelper.createLoanProduct(product); - // Try to use Fixed Length without Advanced Payment Allocation as transaction processing strategy code + // Try to use Fixed Length without Advanced Payment Allocation as transaction + // processing strategy code LOG.info("Try to use Fixed Length without Advanced Payment Allocation as transaction processing strategy code"); CallFailedRuntimeException exception = assertThrows(CallFailedRuntimeException.class, () -> loanTransactionHelper.applyLoan(new PostLoansRequest().clientId(client.getClientId()) @@ -3749,11 +3777,13 @@ public void uc130() { }); } - // UC131: Advanced payment allocation with Fixed Length for 5 months and Loan Term for 6 months (6 repayments + // UC131: Advanced payment allocation with Fixed Length for 5 months and Loan + // Term for 6 months (6 repayments // every month) // ADVANCED_PAYMENT_ALLOCATION_STRATEGY // 1. Create a Loan product with Adv. Pment. Alloc. and No Interest - // 2. Submit Loan and approve -> expect validation error - Interest Rate value higher than Zero + // 2. Submit Loan and approve -> expect validation error - Interest Rate value + // higher than Zero @Test public void uc131() { final String operationDate = "22 November 2023"; @@ -3784,11 +3814,13 @@ public void uc131() { }); } - // UC132: Advanced payment allocation with Fixed Length for 5 months and Loan Term for 6 months (3 repayments + // UC132: Advanced payment allocation with Fixed Length for 5 months and Loan + // Term for 6 months (3 repayments // every 2 months) // ADVANCED_PAYMENT_ALLOCATION_STRATEGY // 1. Create a Loan product with Adv. Pment. Alloc. and No Interest - // 2. Submit Loan and approve -> expect validation error - Loan acount Fixed Length with a wrong Loan Term setup + // 2. Submit Loan and approve -> expect validation error - Loan acount Fixed + // Length with a wrong Loan Term setup @Test public void uc132() { final String operationDate = "22 November 2023"; @@ -3819,7 +3851,8 @@ public void uc132() { }); } - // UC133: Advanced payment allocation with higher Fixed Length for 50 days than Loan Term for 45 days (3 repayments + // UC133: Advanced payment allocation with higher Fixed Length for 50 days than + // Loan Term for 45 days (3 repayments // every 15 days) // ADVANCED_PAYMENT_ALLOCATION_STRATEGY // 1. Create a Loan product with Adv. Pment. Alloc. and No Interest @@ -3867,7 +3900,8 @@ public void uc133() { }); } - // UC134: Advanced payment allocation with Fixed Length for 119 days and Loan Term for 120 days (4 repayments every + // UC134: Advanced payment allocation with Fixed Length for 119 days and Loan + // Term for 120 days (4 repayments every // 30 // days) and Reschedule // ADVANCED_PAYMENT_ALLOCATION_STRATEGY @@ -3939,7 +3973,8 @@ public void uc134() { }); } - // UC135: Advanced payment allocation with Fixed Length for 119 days and Loan Term for 120 days (4 repayments every + // UC135: Advanced payment allocation with Fixed Length for 119 days and Loan + // Term for 120 days (4 repayments every // 30 // days) and Reschedule // ADVANCED_PAYMENT_ALLOCATION_STRATEGY @@ -4011,6 +4046,72 @@ public void uc135() { }); } + // UC136: Advanced payment allocation, using auto downpayment with installment + // amount in multiples of 1 + // ADVANCED_PAYMENT_ALLOCATION_STRATEGY + // 1. Create a Loan product with Adv. Pment. Alloc. + // 2. Submit Loan and approve + // 3. Disburse the loan and validate downpayment + @Test + public void uc136() { + AtomicLong createdLoanId = new AtomicLong(); + runAt("23 March 2024", () -> { + // Rounding mode - HALF_DOWN + GlobalConfigurationHelper.updateValueForGlobalConfigurationInternal(requestSpec, responseSpec, "23", 5); + createLoanForRoundingMethodValidation(true); + + // Rounding mode - HALF_UP + GlobalConfigurationHelper.updateValueForGlobalConfigurationInternal(requestSpec, responseSpec, "23", 4); + createLoanForRoundingMethodValidation(false); + + // Rounding mode - HALF_EVEN - Default + GlobalConfigurationHelper.updateValueForGlobalConfigurationInternal(requestSpec, responseSpec, "23", 6); + }); + } + + private void createLoanForRoundingMethodValidation(boolean isHalfDown) { + LOG.info("------------------------------ROUNDING HALF DOWN {} ---------------------------------------", isHalfDown); + + PostLoanProductsRequest product = createOnePeriod30DaysLongNoInterestPeriodicAccrualProductWithAdvancedPaymentAllocation() + .installmentAmountInMultiplesOf(null).numberOfRepayments(3).repaymentEvery(15).enableDownPayment(true) + .enableAutoRepaymentForDownPayment(true).disbursedAmountPercentageForDownPayment(BigDecimal.valueOf(25)).minPrincipal(10.0) + .installmentAmountInMultiplesOf(1); + PostLoanProductsResponse loanProductResponse = loanProductHelper.createLoanProduct(product); + PostLoansRequest applicationRequest = applyLoanRequest(client.getClientId(), loanProductResponse.getResourceId(), "23 March 2024", + 10.0, 4); + + applicationRequest = applicationRequest.numberOfRepayments(3).loanTermFrequency(45) + .transactionProcessingStrategyCode(LoanProductTestBuilder.ADVANCED_PAYMENT_ALLOCATION_STRATEGY).repaymentEvery(15); + + PostLoansResponse loanResponse = loanTransactionHelper.applyLoan(applicationRequest); + + loanTransactionHelper.approveLoan(loanResponse.getLoanId(), new PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(10)) + .dateFormat(DATETIME_PATTERN).approvedOnDate("23 March 2024").locale("en")); + + loanTransactionHelper.disburseLoan(loanResponse.getLoanId(), new PostLoansLoanIdRequest().actualDisbursementDate("23 March 2024") + .dateFormat(DATETIME_PATTERN).transactionAmount(BigDecimal.valueOf(10.0)).locale("en")); + + // verify schedule + if (isHalfDown) { + verifyRepaymentSchedule(loanResponse.getLoanId(), // + installment(10, null, "23 March 2024"), // + installment(2, 0, 0, 0, 0.0, true, "23 March 2024", 8), // + installment(3, 0, 0, 0, 3, false, "07 April 2024", 5), // + installment(3, 0, 0, 0, 3, false, "22 April 2024", 2), // + installment(2, 0, 0, 0, 2, false, "07 May 2024", 0.0) // + ); + } else { + LOG.info("Loan Id {}", loanResponse.getLoanId()); + verifyRepaymentSchedule(loanResponse.getLoanId(), // + installment(10, null, "23 March 2024"), // + installment(3, 0, 0, 0, 0.0, true, "23 March 2024", 7), // + installment(2, 0, 0, 0, 2, false, "07 April 2024", 5), // + installment(2, 0, 0, 0, 2, false, "22 April 2024", 3), // + installment(3, 0, 0, 0, 3, false, "07 May 2024", 0.0) // + ); + } + } + private static List getPaymentAllocationOrder(PaymentAllocationType... paymentAllocationTypes) { AtomicInteger integer = new AtomicInteger(1); return Arrays.stream(paymentAllocationTypes).map(pat -> { diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/CustomSnapshotEventIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/CustomSnapshotEventIntegrationTest.java index 67876ec0643..e8b9e335928 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/CustomSnapshotEventIntegrationTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/CustomSnapshotEventIntegrationTest.java @@ -76,10 +76,10 @@ public void testSnapshotEventGenerationWhenLoanInstallmentIsNotPayed() { // Verify Repayment Schedule and Due Dates verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, false, "31 January 2023"), // - installment(313.0, false, "02 March 2023"), // - installment(313.0, false, "01 April 2023"), // - installment(311.0, false, "01 May 2023") // + installment(312.0, false, "31 January 2023"), // + installment(312.0, false, "02 March 2023"), // + installment(312.0, false, "01 April 2023"), // + installment(314.0, false, "01 May 2023") // ); // delete all external events @@ -124,10 +124,10 @@ public void testNoSnapshotEventGenerationWhenLoanInstallmentIsPayed() { // Verify Repayment Schedule and Due Dates verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, false, "31 January 2023"), // - installment(313.0, false, "02 March 2023"), // - installment(313.0, false, "01 April 2023"), // - installment(311.0, false, "01 May 2023") // + installment(312.0, false, "31 January 2023"), // + installment(312.0, false, "02 March 2023"), // + installment(312.0, false, "01 April 2023"), // + installment(314.0, false, "01 May 2023") // ); addRepaymentForLoan(loanId, 313.0, "31 January 2023"); @@ -135,10 +135,10 @@ public void testNoSnapshotEventGenerationWhenLoanInstallmentIsPayed() { // Verify Repayment Schedule and Due Dates verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, true, "31 January 2023"), // - installment(313.0, false, "02 March 2023"), // - installment(313.0, false, "01 April 2023"), // - installment(311.0, false, "01 May 2023") // + installment(312.0, true, "31 January 2023"), // + installment(312.0, false, "02 March 2023"), // + installment(312.0, false, "01 April 2023"), // + installment(314.0, false, "01 May 2023") // ); // delete all external events @@ -181,10 +181,10 @@ public void testNoSnapshotEventGenerationWhenWhenCustomSnapshotEventCOBTaskIsNot // Verify Repayment Schedule and Due Dates verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, false, "31 January 2023"), // - installment(313.0, false, "02 March 2023"), // - installment(313.0, false, "01 April 2023"), // - installment(311.0, false, "01 May 2023") // + installment(312.0, false, "31 January 2023"), // + installment(312.0, false, "02 March 2023"), // + installment(312.0, false, "01 April 2023"), // + installment(314.0, false, "01 May 2023") // ); // delete all external events @@ -227,10 +227,10 @@ public void testNoSnapshotEventGenerationWhenCOBDateIsNotMatchingWithInstallment // Verify Repayment Schedule and Due Dates verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, false, "31 January 2023"), // - installment(313.0, false, "02 March 2023"), // - installment(313.0, false, "01 April 2023"), // - installment(311.0, false, "01 May 2023") // + installment(312.0, false, "31 January 2023"), // + installment(312.0, false, "02 March 2023"), // + installment(312.0, false, "01 April 2023"), // + installment(314.0, false, "01 May 2023") // ); // delete all external events @@ -271,10 +271,10 @@ public void testNoSnapshotEventGenerationWhenCustomSnapshotEventIsDisabled() { // Verify Repayment Schedule and Due Dates verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, false, "31 January 2023"), // - installment(313.0, false, "02 March 2023"), // - installment(313.0, false, "01 April 2023"), // - installment(311.0, false, "01 May 2023") // + installment(312.0, false, "31 January 2023"), // + installment(312.0, false, "02 March 2023"), // + installment(312.0, false, "01 April 2023"), // + installment(314.0, false, "01 May 2023") // ); // delete all external events diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/InstallmentLevelDelinquencyAPIIntegrationTests.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/InstallmentLevelDelinquencyAPIIntegrationTests.java index 7a426c52ab6..fb9183169cd 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/InstallmentLevelDelinquencyAPIIntegrationTests.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/InstallmentLevelDelinquencyAPIIntegrationTests.java @@ -74,31 +74,31 @@ public void testInstallmentLevelDelinquencyFourRangesInTheBucket() { // Verify Repayment Schedule and Due Dates verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, false, "31 January 2023"), // 120 days delinquent -> range4 - installment(313.0, false, "02 March 2023"), // 90 days delinquent -> range4 - installment(313.0, false, "01 April 2023"), // 60 days delinquent -> range3 - installment(311.0, false, "01 May 2023") // 30 days delinquent -> range2 + installment(312.0, false, "31 January 2023"), // 120 days delinquent -> range4 + installment(312.0, false, "02 March 2023"), // 90 days delinquent -> range4 + installment(312.0, false, "01 April 2023"), // 60 days delinquent -> range3 + installment(314.0, false, "01 May 2023") // 30 days delinquent -> range2 ); // since the current day is 31 May 2023, therefore all the installments are delinquent verifyDelinquency(loanId, 120, "1250.0", // - delinquency(11, 30, "311.0"), // 4th installment - delinquency(31, 60, "313.0"), // 3rd installment - delinquency(61, null, "626.0") // 1st installment + 2nd installment + delinquency(11, 30, "314.0"), // 4th installment + delinquency(31, 60, "312.0"), // 3rd installment + delinquency(61, null, "624.0") // 1st installment + 2nd installment ); // Repayment of the first two installments addRepaymentForLoan(loanId, 626.0, "31 May 2023"); verifyDelinquency(loanId, 60, "624.0", // - delinquency(11, 30, "311.0"), // 4th installment - delinquency(31, 60, "313.0") // 3rd installment + delinquency(11, 30, "314.0"), // 4th installment + delinquency(31, 60, "310.0") // 3rd installment ); // Partial repayment addRepaymentForLoan(loanId, 100.0, "31 May 2023"); verifyDelinquency(loanId, 60, "524.0", // - delinquency(11, 30, "311.0"), // 4th installment - delinquency(31, 60, "213.0") // 3rd installment + delinquency(11, 30, "314.0"), // 4th installment + delinquency(31, 60, "210.0") // 3rd installment ); // Repay the loan fully @@ -135,23 +135,23 @@ public void testInstallmentLevelDelinquencyTwoRangesInTheBucket() { // Verify Repayment Schedule and Due Dates verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, false, "31 January 2023"), // 120 days delinquent -> range2 - installment(313.0, false, "02 March 2023"), // 90 days delinquent -> range2 - installment(313.0, false, "01 April 2023"), // 60 days delinquent -> range1 - installment(311.0, false, "01 May 2023") // 30 days delinquent -> range1 + installment(312.0, false, "31 January 2023"), // 120 days delinquent -> range2 + installment(312.0, false, "02 March 2023"), // 90 days delinquent -> range2 + installment(312.0, false, "01 April 2023"), // 60 days delinquent -> range1 + installment(314.0, false, "01 May 2023") // 30 days delinquent -> range1 ); verifyDelinquency(loanId, 120, "1250.0", // - delinquency(1, 60, "624.0"), // 4th installment - delinquency(61, null, "626.0") // 1st installment + 2nd installment + delinquency(1, 60, "626.0"), // 4th installment + delinquency(61, null, "624.0") // 1st installment + 2nd installment ); // repay the first installment addRepaymentForLoan(loanId, 313.0, "31 May 2023"); verifyDelinquency(loanId, 90, "937.0", // - delinquency(1, 60, "624.0"), // 4th installment - delinquency(61, null, "313.0") // 1st installment + 2nd installment + delinquency(1, 60, "626.0"), // 4th installment + delinquency(61, null, "311.0") // 1st installment + 2nd installment ); }); @@ -185,10 +185,10 @@ public void testInstallmentLevelDelinquencyIsTurnedOff() { // Verify Repayment Schedule and Due Dates verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, false, "31 January 2023"), // 120 days delinquent -> range2 - installment(313.0, false, "02 March 2023"), // 90 days delinquent -> range2 - installment(313.0, false, "01 April 2023"), // 60 days delinquent -> range1 - installment(311.0, false, "01 May 2023") // 30 days delinquent -> range1 + installment(312.0, false, "31 January 2023"), // 120 days delinquent -> range2 + installment(312.0, false, "02 March 2023"), // 90 days delinquent -> range2 + installment(312.0, false, "01 April 2023"), // 60 days delinquent -> range1 + installment(314.0, false, "01 May 2023") // 30 days delinquent -> range1 ); // this should be empty as the installment level delinquency is not enabled for this loan @@ -223,21 +223,21 @@ public void testInstallmentLevelDelinquencyUpdatedWhenCOBIsExecuted() { // Verify Repayment Schedule and Due Dates verifyRepaymentSchedule(loanId, // - installment(1250.0, null, "01 January 2023"), installment(313.0, false, "31 January 2023"), - installment(313.0, false, "02 March 2023"), installment(313.0, false, "01 April 2023"), - installment(311.0, false, "01 May 2023")); + installment(1250.0, null, "01 January 2023"), installment(312.0, false, "31 January 2023"), + installment(312.0, false, "02 March 2023"), installment(312.0, false, "01 April 2023"), + installment(314.0, false, "01 May 2023")); // The first installment falls into the first range - verifyDelinquency(loanId, 1, "313.0", // - delinquency(1, 1, "313.0") // 4th installment + verifyDelinquency(loanId, 1, "312.0", // + delinquency(1, 1, "312.0") // 4th installment ); // Let's go one day ahead in the time updateBusinessDateAndExecuteCOBJob("2 February 2023"); // The first installment is not two days delinquent and therefore falls into the second range - verifyDelinquency(loanId, 2, "313.0", // - delinquency(2, null, "313.0") // 4th installment + verifyDelinquency(loanId, 2, "312.0", // + delinquency(2, null, "312.0") // 4th installment ); }); } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountRepaymentCalculationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountRepaymentCalculationTest.java index cb0c4a53e79..63dfc7d2220 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountRepaymentCalculationTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountRepaymentCalculationTest.java @@ -205,19 +205,19 @@ public void loanAccountWithEnableDownPaymentWithInstallmentsInMultipleOfSetAsOne assertNotNull(loanDetails.getRepaymentSchedule()); // first period [2023-03-03 to 2023-03-03] down payment installment - verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(1), 313.0, 1, LocalDate.of(2023, 3, 3), + verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(1), 312.0, 1, LocalDate.of(2023, 3, 3), LocalDate.of(2023, 3, 3), false); // second period [2023-03-03 to 2023-04-03] regular installment - verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(2), 312.0, 2, LocalDate.of(2023, 3, 3), + verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(2), 313.0, 2, LocalDate.of(2023, 3, 3), LocalDate.of(2023, 4, 3), false); // third period [2023-04-03 to 2023-05-03] regular installment - verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(3), 312.0, 3, LocalDate.of(2023, 4, 3), + verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(3), 313.0, 3, LocalDate.of(2023, 4, 3), LocalDate.of(2023, 5, 3), false); // fourth period [2023-05-03 to 2023-06-03] regular installment - verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(4), 313.0, 4, LocalDate.of(2023, 5, 3), + verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(4), 312.0, 4, LocalDate.of(2023, 5, 3), LocalDate.of(2023, 6, 3), false); // disbursement @@ -228,19 +228,19 @@ public void loanAccountWithEnableDownPaymentWithInstallmentsInMultipleOfSetAsOne assertNotNull(loanDetails.getRepaymentSchedule()); // first period [2023-03-03 to 2023-03-03] down payment installment - verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(1), 313.0, 1, LocalDate.of(2023, 3, 3), + verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(1), 312.0, 1, LocalDate.of(2023, 3, 3), LocalDate.of(2023, 3, 3), false); // second period [2023-03-03 to 2023-04-03] regular installment - verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(2), 312.0, 2, LocalDate.of(2023, 3, 3), + verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(2), 313.0, 2, LocalDate.of(2023, 3, 3), LocalDate.of(2023, 4, 3), false); // third period [2023-04-03 to 2023-05-03] regular installment - verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(3), 312.0, 3, LocalDate.of(2023, 4, 3), + verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(3), 313.0, 3, LocalDate.of(2023, 4, 3), LocalDate.of(2023, 5, 3), false); // fourth period [2023-05-03 to 2023-06-03] regular installment - verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(4), 313.0, 4, LocalDate.of(2023, 5, 3), + verifyPeriodDetails(loanDetails.getRepaymentSchedule().getPeriods().get(4), 312.0, 4, LocalDate.of(2023, 5, 3), LocalDate.of(2023, 6, 3), false); } finally { diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargebackWithCreditAllocationsIntegrationTests.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargebackWithCreditAllocationsIntegrationTests.java index c6a87649db7..4a1c6d33ca8 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargebackWithCreditAllocationsIntegrationTests.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargebackWithCreditAllocationsIntegrationTests.java @@ -70,24 +70,24 @@ public void simpleChargebackWithCreditAllocationPenaltyFeeInterestAndPrincipal() verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 383.0, false, "01 February 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(312.0, 0, 50, 20, 382.0, false, "01 February 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); // Update Business Date updateBusinessDate("20 January 2023"); // Add Repayment - Long repaymentTransaction = addRepaymentForLoan(loanId, 383.0, "20 January 2023"); + Long repaymentTransaction = addRepaymentForLoan(loanId, 382.0, "20 January 2023"); verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(312.0, 0, 50, 20, 0.0, true, "01 February 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); // Add Chargeback @@ -96,17 +96,17 @@ public void simpleChargebackWithCreditAllocationPenaltyFeeInterestAndPrincipal() verifyTransactions(loanId, // transaction(1250.0, "Disbursement", "01 January 2023", 1250.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), // - transaction(383.0, "Repayment", "20 January 2023", 937.0, 313.0, 0.0, 50.0, 20.0, 0.0, 0.0), // - transaction(100.0, "Chargeback", "20 January 2023", 967.0, 30.0, 0.0, 50.0, 20.0, 0.0, 0.0) // + transaction(382.0, "Repayment", "20 January 2023", 938.0, 312.0, 0.0, 50.0, 20.0, 0.0, 0.0), // + transaction(100.0, "Chargeback", "20 January 2023", 968.0, 30.0, 0.0, 50.0, 20.0, 0.0, 0.0) // ); // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(343.0, 0, 100, 40, 100.0, false, "01 February 2023"), - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(342.0, 0, 100, 40, 100.0, false, "01 February 2023"), + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); }); } @@ -133,24 +133,24 @@ public void simpleChargebackWithCreditAllocationPenaltyFeeInterestAndPrincipalOn verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 383.0, false, "01 February 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(312.0, 0, 50, 20, 382.0, false, "01 February 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); // Update Business Date updateBusinessDate("20 January 2023"); // Add Repayment - Long repaymentTransaction = addRepaymentForLoan(loanId, 383.0, "20 January 2023"); + Long repaymentTransaction = addRepaymentForLoan(loanId, 382.0, "20 January 2023"); verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(312.0, 0, 50, 20, 0.0, true, "01 February 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); updateBusinessDate("01 February 2023"); @@ -161,17 +161,17 @@ public void simpleChargebackWithCreditAllocationPenaltyFeeInterestAndPrincipalOn verifyTransactions(loanId, // transaction(1250.0, "Disbursement", "01 January 2023", 1250.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), // - transaction(383.0, "Repayment", "20 January 2023", 937.0, 313.0, 0.0, 50.0, 20.0, 0.0, 0.0), // - transaction(100.0, "Chargeback", "01 February 2023", 967.0, 30.0, 0.0, 50.0, 20.0, 0.0, 0.0) // + transaction(382.0, "Repayment", "20 January 2023", 938.0, 312.0, 0.0, 50.0, 20.0, 0.0, 0.0), // + transaction(100.0, "Chargeback", "01 February 2023", 968.0, 30.0, 0.0, 50.0, 20.0, 0.0, 0.0) // ); // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 0, true, "01 February 2023"), // - installment(343.0, 0, 50, 20, 413.0, false, "01 March 2023"), - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(312.0, 0, 50, 20, 0, true, "01 February 2023"), // + installment(342.0, 0, 50, 20, 412.0, false, "01 March 2023"), + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); }); } @@ -198,24 +198,24 @@ public void simpleChargebackWithCreditAllocationPenaltyFeeInterestAndPrincipalOn verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 383.0, false, "01 February 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(312.0, 0, 50, 20, 382.0, false, "01 February 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); // Update Business Date updateBusinessDate("20 January 2023"); // Add Repayment - Long repaymentTransaction = addRepaymentForLoan(loanId, 383.0, "20 January 2023"); + Long repaymentTransaction = addRepaymentForLoan(loanId, 382.0, "20 January 2023"); verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(312.0, 0, 50, 20, 0.0, true, "01 February 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); updateBusinessDate("01 May 2023"); @@ -226,17 +226,17 @@ public void simpleChargebackWithCreditAllocationPenaltyFeeInterestAndPrincipalOn verifyTransactions(loanId, // transaction(1250.0, "Disbursement", "01 January 2023", 1250.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), // - transaction(383.0, "Repayment", "20 January 2023", 937.0, 313.0, 0.0, 50.0, 20.0, 0.0, 0.0), // - transaction(100.0, "Chargeback", "01 May 2023", 967.0, 30.0, 0.0, 50.0, 20.0, 0.0, 0.0) // + transaction(382.0, "Repayment", "20 January 2023", 938.0, 312.0, 0.0, 50.0, 20.0, 0.0, 0.0), // + transaction(100.0, "Chargeback", "01 May 2023", 968.0, 30.0, 0.0, 50.0, 20.0, 0.0, 0.0) // ); // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(341.0, 0, 50, 20, 411.0, false, "01 May 2023") // + installment(312.0, 0, 50, 20, 0.0, true, "01 February 2023"), + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(344.0, 0, 50, 20, 414.0, false, "01 May 2023") // ); }); } @@ -259,36 +259,36 @@ public void chargebackWithCreditAllocationPenaltyFeeInterestAndPrincipalOnNPlusO verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 February 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(312.0, 0, 0, 0, 312.0, false, "01 February 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); // Update Business Date + and make a full repayment for the first installment updateBusinessDate("20 January 2023"); - addRepaymentForLoan(loanId, 313.0, "20 January 2023"); + addRepaymentForLoan(loanId, 312.0, "20 January 2023"); // Update Business Date + and make a full repayment for the second installment updateBusinessDate("20 February 2023"); - addRepaymentForLoan(loanId, 313.0, "20 February 2023"); + addRepaymentForLoan(loanId, 312.0, "20 February 2023"); // Update Business Date + and make a full repayment for the third installment updateBusinessDate("20 March 2023"); - addRepaymentForLoan(loanId, 313.0, "20 March 2023"); + addRepaymentForLoan(loanId, 312.0, "20 March 2023"); // Add some charges Update Business Date + and make a full repayment for the fourth installment updateBusinessDate("20 April 2023"); addCharge(loanId, false, 50, "20 April 2023"); addCharge(loanId, true, 20, "20 April 2023"); - Long repaymentTransaction = addRepaymentForLoan(loanId, 381.0, "20 April 2023"); + Long repaymentTransaction = addRepaymentForLoan(loanId, 384.0, "20 April 2023"); verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 0, 0, 0.0, true, "01 February 2023"), // - installment(313.0, 0, 0, 0, 0.0, true, "01 March 2023"), // - installment(313.0, 0, 0, 0, 0.0, true, "01 April 2023"), // - installment(311.0, 0, 50, 20, 0.0, true, "01 May 2023") // + installment(312.0, 0, 0, 0, 0.0, true, "01 February 2023"), // + installment(312.0, 0, 0, 0, 0.0, true, "01 March 2023"), // + installment(312.0, 0, 0, 0, 0.0, true, "01 April 2023"), // + installment(314.0, 0, 50, 20, 0.0, true, "01 May 2023") // ); // Let's move over the maturity date and chargeback some money @@ -299,20 +299,20 @@ public void chargebackWithCreditAllocationPenaltyFeeInterestAndPrincipalOnNPlusO verifyTransactions(loanId, // transaction(1250.0, "Disbursement", "01 January 2023", 1250.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), // - transaction(313.0, "Repayment", "20 January 2023", 937.0, 313.0, 0.0, 0.0, 0.0, 0.0, 0.0), // - transaction(313.0, "Repayment", "20 February 2023", 624.0, 313.0, 0.0, 0.0, 0.0, 0.0, 0.0), // - transaction(313.0, "Repayment", "20 March 2023", 311.0, 313.0, 0.0, 0.0, 0.0, 0.0, 0.0), // - transaction(381.0, "Repayment", "20 April 2023", 0.0, 311.0, 0.0, 50.0, 20.0, 0.0, 0.0), // + transaction(312.0, "Repayment", "20 January 2023", 938.0, 312.0, 0.0, 0.0, 0.0, 0.0, 0.0), // + transaction(312.0, "Repayment", "20 February 2023", 626.0, 312.0, 0.0, 0.0, 0.0, 0.0, 0.0), // + transaction(312.0, "Repayment", "20 March 2023", 314.0, 312.0, 0.0, 0.0, 0.0, 0.0, 0.0), // + transaction(384.0, "Repayment", "20 April 2023", 0.0, 314.0, 0.0, 50.0, 20.0, 0.0, 0.0), // transaction(70.0, "Accrual", "20 April 2023", 0.0, 0.0, 0.0, 50.0, 20.0, 0.0, 0.0), // transaction(100.0, "Chargeback", "02 May 2023", 30.0, 30.0, 0.0, 50.0, 20.0, 0.0, 0.0) // ); verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 0, 0, 0.0, true, "01 February 2023"), // - installment(313.0, 0, 0, 0, 0.0, true, "01 March 2023"), // - installment(313.0, 0, 0, 0, 0.0, true, "01 April 2023"), // - installment(311.0, 0, 50, 20, 0.0, true, "01 May 2023"), // + installment(312.0, 0, 0, 0, 0.0, true, "01 February 2023"), // + installment(312.0, 0, 0, 0, 0.0, true, "01 March 2023"), // + installment(312.0, 0, 0, 0, 0.0, true, "01 April 2023"), // + installment(314.0, 0, 50, 20, 0.0, true, "01 May 2023"), // installment(30.0, 0, 50, 20, 100.0, false, "02 May 2023") // ); }); @@ -340,24 +340,24 @@ public void chargebackWithCreditAllocationAndReverseReplayWithBackdatedPayment() verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 383.0, false, "01 February 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(312.0, 0, 50, 20, 382.0, false, "01 February 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); // Update Business Date updateBusinessDate("20 January 2023"); // Add Repayment - Long repaymentTransaction = addRepaymentForLoan(loanId, 383.0, "20 January 2023"); + Long repaymentTransaction = addRepaymentForLoan(loanId, 382.0, "20 January 2023"); verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(312.0, 0, 50, 20, 0.0, true, "01 February 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); updateBusinessDate("21 January 2023"); @@ -367,17 +367,17 @@ public void chargebackWithCreditAllocationAndReverseReplayWithBackdatedPayment() verifyTransactions(loanId, // transaction(1250.0, "Disbursement", "01 January 2023", 1250.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), // - transaction(383.0, "Repayment", "20 January 2023", 937.0, 313.0, 0.0, 50.0, 20.0, 0.0, 0.0), // - transaction(100.0, "Chargeback", "21 January 2023", 967.0, 30.0, 0.0, 50.0, 20.0, 0.0, 0.0) // + transaction(382.0, "Repayment", "20 January 2023", 938.0, 312.0, 0.0, 50.0, 20.0, 0.0, 0.0), // + transaction(100.0, "Chargeback", "21 January 2023", 968.0, 30.0, 0.0, 50.0, 20.0, 0.0, 0.0) // ); // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(343.0, 0, 100, 40, 100.0, false, "01 February 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(342.0, 0, 100, 40, 100.0, false, "01 February 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); // let's add a backdated repayment on 19th of January to trigger reverse replaying the chargeback, that will @@ -387,8 +387,8 @@ public void chargebackWithCreditAllocationAndReverseReplayWithBackdatedPayment() verifyTransactions(loanId, // transaction(1250.0, "Disbursement", "01 January 2023", 1250.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), // transaction(200.0, "Repayment", "19 January 2023", 1120.0, 130.0, 0.0, 50.0, 20.0, 0.0, 0.0), // - transaction(383.0, "Repayment", "20 January 2023", 737.0, 383.0, 0.0, 0.0, 0.0, 0.0, 0.0), // - transaction(100.0, "Chargeback", "21 January 2023", 837.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0) // + transaction(382.0, "Repayment", "20 January 2023", 738.0, 382.0, 0.0, 0.0, 0.0, 0.0, 0.0), // + transaction(100.0, "Chargeback", "21 January 2023", 838.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0) // ); }); } @@ -415,24 +415,24 @@ public void chargebackWithCreditAllocationReverseReplayedWithBackdatedPayment() verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 383.0, false, "01 February 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(312.0, 0, 50, 20, 382.0, false, "01 February 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); // Update Business Date updateBusinessDate("20 January 2023"); // Add Repayment - Long repaymentTransaction = addRepaymentForLoan(loanId, 383.0, "20 January 2023"); + Long repaymentTransaction = addRepaymentForLoan(loanId, 382.0, "20 January 2023"); verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(312.0, 0, 50, 20, 0.0, true, "01 February 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); updateBusinessDate("22 January 2023"); @@ -442,17 +442,17 @@ public void chargebackWithCreditAllocationReverseReplayedWithBackdatedPayment() verifyTransactions(loanId, // transaction(1250.0, "Disbursement", "01 January 2023", 1250.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), // - transaction(383.0, "Repayment", "20 January 2023", 937.0, 313.0, 0.0, 50.0, 20.0, 0.0, 0.0), // - transaction(100.0, "Chargeback", "22 January 2023", 967.0, 30.0, 0.0, 50.0, 20.0, 0.0, 0.0) // + transaction(382.0, "Repayment", "20 January 2023", 938.0, 312.0, 0.0, 50.0, 20.0, 0.0, 0.0), // + transaction(100.0, "Chargeback", "22 January 2023", 968.0, 30.0, 0.0, 50.0, 20.0, 0.0, 0.0) // ); // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(343.0, 0, 100, 40, 100.0, false, "01 February 2023"), - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(342.0, 0, 100, 40, 100.0, false, "01 February 2023"), + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); // let's add a backdated repayment on 21th of January that will reverse replay the chargeback transaction @@ -462,12 +462,12 @@ public void chargebackWithCreditAllocationReverseReplayedWithBackdatedPayment() verifyTransactions(loanId, // transaction(1250.0, "Disbursement", "01 January 2023", 1250.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), // - transaction(383.0, "Repayment", "20 January 2023", 937.0, 313.0, 0.0, 50.0, 20.0, 0.0, 0.0), // - transaction(200.0, "Repayment", "21 January 2023", 737.0, 200.0, 0.0, 0.0, 0.0, 0.0, 0.0), // - transaction(100.0, "Chargeback", "22 January 2023", 767.0, 30.0, 0.0, 50.0, 20.0, 0.0, 0.0) // + transaction(382.0, "Repayment", "20 January 2023", 938.0, 312.0, 0.0, 50.0, 20.0, 0.0, 0.0), // + transaction(200.0, "Repayment", "21 January 2023", 738.0, 200.0, 0.0, 0.0, 0.0, 0.0, 0.0), // + transaction(100.0, "Chargeback", "22 January 2023", 768.0, 30.0, 0.0, 50.0, 20.0, 0.0, 0.0) // ); - verifyLoanSummaryAmounts(loanId, 30.0, 50.0, 20.0, 837.0); + verifyLoanSummaryAmounts(loanId, 30.0, 50.0, 20.0, 838.0); }); } @@ -495,24 +495,24 @@ public void chargebackWithCreditAllocationPrincipalInterestFeePenalty() { verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 383.0, false, "01 February 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(312.0, 0, 50, 20, 382.0, false, "01 February 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); // Update Business Date updateBusinessDate("20 January 2023"); // Add Repayment - Long repaymentTransaction = addRepaymentForLoan(loanId, 383.0, "20 January 2023"); + Long repaymentTransaction = addRepaymentForLoan(loanId, 382.0, "20 January 2023"); verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(312.0, 0, 50, 20, 0.0, true, "01 February 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); // Add Chargeback @@ -520,20 +520,20 @@ public void chargebackWithCreditAllocationPrincipalInterestFeePenalty() { verifyTransactions(loanId, // transaction(1250.0, "Disbursement", "01 January 2023", 1250.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), // - transaction(383.0, "Repayment", "20 January 2023", 937.0, 313.0, 0.0, 50.0, 20.0, 0.0, 0.0), // - transaction(100.0, "Chargeback", "20 January 2023", 1037.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0) // + transaction(382.0, "Repayment", "20 January 2023", 938.0, 312.0, 0.0, 50.0, 20.0, 0.0, 0.0), // + transaction(100.0, "Chargeback", "20 January 2023", 1038.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0) // ); // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(413.0, 0, 50, 20, 100.0, false, "01 February 2023"), - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(412.0, 0, 50, 20, 100.0, false, "01 February 2023"), + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); - verifyLoanSummaryAmounts(loanId, 100.0, 0.0, 0.0, 1037); + verifyLoanSummaryAmounts(loanId, 100.0, 0.0, 0.0, 1038); }); } @@ -559,10 +559,10 @@ public void chargebackWithCreditAllocationPrincipalInterestFeePenaltyWhenOverpai verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 383.0, false, "01 February 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(312.0, 0, 50, 20, 382.0, false, "01 February 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); // Update Business Date @@ -574,10 +574,10 @@ public void chargebackWithCreditAllocationPrincipalInterestFeePenaltyWhenOverpai verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), // - installment(313.0, 0, 0, 0, 0.0, true, "01 March 2023"), // - installment(313.0, 0, 0, 0, 0.0, true, "01 April 2023"), // - installment(311.0, 0, 0, 0, 0.0, true, "01 May 2023") // + installment(312.0, 0, 50, 20, 0.0, true, "01 February 2023"), // + installment(312.0, 0, 0, 0, 0.0, true, "01 March 2023"), // + installment(312.0, 0, 0, 0, 0.0, true, "01 April 2023"), // + installment(314.0, 0, 0, 0, 0.0, true, "01 May 2023") // ); updateBusinessDate("02 May 2023"); @@ -596,10 +596,10 @@ public void chargebackWithCreditAllocationPrincipalInterestFeePenaltyWhenOverpai // DEFAULT payment allocation is ..., DUE_PENALTY, DUE_FEE, DUE_PRINCIPAL, ... verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 0, true, "01 February 2023"), // - installment(313.0, 0, 0, 0, 0, true, "01 March 2023"), // - installment(313.0, 0, 0, 0, 0, true, "01 April 2023"), // - installment(311.0, 0, 0, 0, 0, true, "01 May 2023"), // + installment(312.0, 0, 50, 20, 0, true, "01 February 2023"), // + installment(312.0, 0, 0, 0, 0, true, "01 March 2023"), // + installment(312.0, 0, 0, 0, 0, true, "01 April 2023"), // + installment(314.0, 0, 0, 0, 0, true, "01 May 2023"), // installment(100.0, 0, 0, 0, outstanding(50.0, 0d, 0d, 50.0), false, "02 May 2023") // ); }); @@ -627,10 +627,10 @@ public void chargebackWithCreditAllocationFeePenaltyPrincipalInterestWhenOverpai verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 383.0, false, "01 February 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(312.0, 0, 50, 20, 382.0, false, "01 February 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); // Update Business Date @@ -642,10 +642,10 @@ public void chargebackWithCreditAllocationFeePenaltyPrincipalInterestWhenOverpai verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), // - installment(313.0, 0, 0, 0, 0.0, true, "01 March 2023"), // - installment(313.0, 0, 0, 0, 0.0, true, "01 April 2023"), // - installment(311.0, 0, 0, 0, 0.0, true, "01 May 2023") // + installment(312.0, 0, 50, 20, 0.0, true, "01 February 2023"), // + installment(312.0, 0, 0, 0, 0.0, true, "01 March 2023"), // + installment(312.0, 0, 0, 0, 0.0, true, "01 April 2023"), // + installment(314.0, 0, 0, 0, 0.0, true, "01 May 2023") // ); // Add Chargeback @@ -662,10 +662,10 @@ public void chargebackWithCreditAllocationFeePenaltyPrincipalInterestWhenOverpai // DEFAULT payment allocation is ..., DUE_PENALTY, DUE_FEE, DUE_PRINCIPAL, ... verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(343.0, 0, 100, 40, outstanding(30.0, 20.0, 0.0, 50.0), false, "01 February 2023"), // - installment(313.0, 0, 0, 0, 0.0, true, "01 March 2023"), // - installment(313.0, 0, 0, 0, 0.0, true, "01 April 2023"), // - installment(311.0, 0, 0, 0, 0.0, true, "01 May 2023") // + installment(342.0, 0, 100, 40, outstanding(30.0, 20.0, 0.0, 50.0), false, "01 February 2023"), // + installment(312.0, 0, 0, 0, 0.0, true, "01 March 2023"), // + installment(312.0, 0, 0, 0, 0.0, true, "01 April 2023"), // + installment(314.0, 0, 0, 0, 0.0, true, "01 May 2023") // ); verifyLoanSummaryAmounts(loanId, 30.0, 50.0, 20.0, 50.0); @@ -694,10 +694,10 @@ public void chargebackWithCreditAllocationFeePenaltyPrincipalInterestWhenOverpai verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 383.0, false, "01 February 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(312.0, 0, 50, 20, 382.0, false, "01 February 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); // Update Business Date @@ -709,10 +709,10 @@ public void chargebackWithCreditAllocationFeePenaltyPrincipalInterestWhenOverpai verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), // - installment(313.0, 0, 0, 0, 0.0, true, "01 March 2023"), // - installment(313.0, 0, 0, 0, 0.0, true, "01 April 2023"), // - installment(311.0, 0, 0, 0, 0.0, true, "01 May 2023") // + installment(312.0, 0, 50, 20, 0.0, true, "01 February 2023"), // + installment(312.0, 0, 0, 0, 0.0, true, "01 March 2023"), // + installment(312.0, 0, 0, 0, 0.0, true, "01 April 2023"), // + installment(314.0, 0, 0, 0, 0.0, true, "01 May 2023") // ); // Add Chargeback @@ -729,10 +729,10 @@ public void chargebackWithCreditAllocationFeePenaltyPrincipalInterestWhenOverpai // DEFAULT payment allocation is ..., DUE_PRINCIPAL, DUE_FEE, DUE_PENALTY ... verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(343.0, 0, 100, 40, outstanding(0.0, 30.0, 20.0, 50.0), false, "01 February 2023"), // - installment(313.0, 0, 0, 0, 0.0, true, "01 March 2023"), // - installment(313.0, 0, 0, 0, 0.0, true, "01 April 2023"), // - installment(311.0, 0, 0, 0, 0.0, true, "01 May 2023") // + installment(342.0, 0, 100, 40, outstanding(0.0, 30.0, 20.0, 50.0), false, "01 February 2023"), // + installment(312.0, 0, 0, 0, 0.0, true, "01 March 2023"), // + installment(312.0, 0, 0, 0, 0.0, true, "01 April 2023"), // + installment(314.0, 0, 0, 0, 0.0, true, "01 May 2023") // ); verifyLoanSummaryAmounts(loanId, 30.0, 50.0, 20.0, 50.0); @@ -761,24 +761,24 @@ public void doubleChargebackWithCreditAllocationPenaltyFeeInterestAndPrincipal() verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 383.0, false, "01 February 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(312.0, 0, 50, 20, 382.0, false, "01 February 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); // Update Business Date updateBusinessDate("20 January 2023"); // Add Repayment - Long repaymentTransaction = addRepaymentForLoan(loanId, 383.0, "20 January 2023"); + Long repaymentTransaction = addRepaymentForLoan(loanId, 382.0, "20 January 2023"); verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(312.0, 0, 50, 20, 0.0, true, "01 February 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); // Add Chargeback @@ -787,17 +787,17 @@ public void doubleChargebackWithCreditAllocationPenaltyFeeInterestAndPrincipal() verifyTransactions(loanId, // transaction(1250.0, "Disbursement", "01 January 2023", 1250.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), // - transaction(383.0, "Repayment", "20 January 2023", 937.0, 313.0, 0.0, 50.0, 20.0, 0.0, 0.0), // - transaction(100.0, "Chargeback", "20 January 2023", 967.0, 30.0, 0.0, 50.0, 20.0, 0.0, 0.0) // + transaction(382.0, "Repayment", "20 January 2023", 938.0, 312.0, 0.0, 50.0, 20.0, 0.0, 0.0), // + transaction(100.0, "Chargeback", "20 January 2023", 968.0, 30.0, 0.0, 50.0, 20.0, 0.0, 0.0) // ); // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(343.0, 0, 100, 40, 100.0, false, "01 February 2023"), - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(342.0, 0, 100, 40, 100.0, false, "01 February 2023"), + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); updateBusinessDate("21 January 2023"); @@ -806,18 +806,18 @@ public void doubleChargebackWithCreditAllocationPenaltyFeeInterestAndPrincipal() verifyTransactions(loanId, // transaction(1250.0, "Disbursement", "01 January 2023", 1250.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), // - transaction(383.0, "Repayment", "20 January 2023", 937.0, 313.0, 0.0, 50.0, 20.0, 0.0, 0.0), // - transaction(100.0, "Chargeback", "20 January 2023", 967, 30.0, 0.0, 50.0, 20.0, 0.0, 0.0), // - transaction(100.0, "Chargeback", "21 January 2023", 1067.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0) // + transaction(382.0, "Repayment", "20 January 2023", 938.0, 312.0, 0.0, 50.0, 20.0, 0.0, 0.0), // + transaction(100.0, "Chargeback", "20 January 2023", 968.0, 30.0, 0.0, 50.0, 20.0, 0.0, 0.0), // + transaction(100.0, "Chargeback", "21 January 2023", 1068.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0) // ); // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(443.0, 0, 100, 40, 200.0, false, "01 February 2023"), - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(442.0, 0, 100, 40, 200.0, false, "01 February 2023"), + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); }); @@ -845,24 +845,24 @@ public void doubleChargebackReverseReplayedBothFeeAndPenaltyPayedWithCreditAlloc verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 383.0, false, "01 February 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(312.0, 0, 50, 20, 382.0, false, "01 February 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); // Update Business Date updateBusinessDate("20 January 2023"); // Add Repayment - Long repaymentTransaction = addRepaymentForLoan(loanId, 383.0, "20 January 2023"); + Long repaymentTransaction = addRepaymentForLoan(loanId, 382.0, "20 January 2023"); verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(312.0, 0, 50, 20, 0.0, true, "01 February 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); // Add Chargeback @@ -871,17 +871,17 @@ public void doubleChargebackReverseReplayedBothFeeAndPenaltyPayedWithCreditAlloc verifyTransactions(loanId, // transaction(1250.0, "Disbursement", "01 January 2023", 1250.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), // - transaction(383.0, "Repayment", "20 January 2023", 937.0, 313.0, 0.0, 50.0, 20.0, 0.0, 0.0), // - transaction(100.0, "Chargeback", "20 January 2023", 967.0, 30.0, 0.0, 50.0, 20.0, 0.0, 0.0) // + transaction(382.0, "Repayment", "20 January 2023", 938.0, 312.0, 0.0, 50.0, 20.0, 0.0, 0.0), // + transaction(100.0, "Chargeback", "20 January 2023", 968.0, 30.0, 0.0, 50.0, 20.0, 0.0, 0.0) // ); // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(343.0, 0, 100, 40, 100.0, false, "01 February 2023"), - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(342.0, 0, 100, 40, 100.0, false, "01 February 2023"), + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); updateBusinessDate("21 January 2023"); @@ -890,18 +890,18 @@ public void doubleChargebackReverseReplayedBothFeeAndPenaltyPayedWithCreditAlloc verifyTransactions(loanId, // transaction(1250.0, "Disbursement", "01 January 2023", 1250.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), // - transaction(383.0, "Repayment", "20 January 2023", 937.0, 313.0, 0.0, 50.0, 20.0, 0.0, 0.0), // - transaction(100.0, "Chargeback", "20 January 2023", 967.0, 30.0, 0.0, 50.0, 20.0, 0.0, 0.0), // - transaction(100.0, "Chargeback", "21 January 2023", 1067.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0) // + transaction(382.0, "Repayment", "20 January 2023", 938.0, 312.0, 0.0, 50.0, 20.0, 0.0, 0.0), // + transaction(100.0, "Chargeback", "20 January 2023", 968.0, 30.0, 0.0, 50.0, 20.0, 0.0, 0.0), // + transaction(100.0, "Chargeback", "21 January 2023", 1068.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0) // ); // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(443.0, 0, 100, 40, 200.0, false, "01 February 2023"), - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(442.0, 0, 100, 40, 200.0, false, "01 February 2023"), + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); // Let's add repayment to trigger reverse replay for both chargebacks @@ -910,9 +910,9 @@ public void doubleChargebackReverseReplayedBothFeeAndPenaltyPayedWithCreditAlloc verifyTransactions(loanId, // transaction(1250.0, "Disbursement", "01 January 2023", 1250.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), // transaction(200.0, "Repayment", "19 January 2023", 1120.0, 130.0, 0.0, 50.0, 20.0, 0.0, 0.0), // - transaction(383.0, "Repayment", "20 January 2023", 737.0, 383.0, 0.0, 0.0, 0.0, 0.0, 0.0), // - transaction(100.0, "Chargeback", "20 January 2023", 837.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0), // - transaction(100.0, "Chargeback", "21 January 2023", 937.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0) // + transaction(382.0, "Repayment", "20 January 2023", 738.0, 382.0, 0.0, 0.0, 0.0, 0.0, 0.0), // + transaction(100.0, "Chargeback", "20 January 2023", 838.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0), // + transaction(100.0, "Chargeback", "21 January 2023", 938.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0) // ); }); } @@ -939,24 +939,24 @@ public void doubleChargebackReverseReplayedOnlyPenaltyPayedWithCreditAllocationP verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 383.0, false, "01 February 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(312.0, 0, 50, 20, 382.0, false, "01 February 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); // Update Business Date updateBusinessDate("20 January 2023"); // Add Repayment - Long repaymentTransaction = addRepaymentForLoan(loanId, 383.0, "20 January 2023"); + Long repaymentTransaction = addRepaymentForLoan(loanId, 382.0, "20 January 2023"); verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, 0, 50, 20, 0.0, true, "01 February 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(312.0, 0, 50, 20, 0.0, true, "01 February 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); // Add Chargeback @@ -965,17 +965,17 @@ public void doubleChargebackReverseReplayedOnlyPenaltyPayedWithCreditAllocationP verifyTransactions(loanId, // transaction(1250.0, "Disbursement", "01 January 2023", 1250.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), // - transaction(383.0, "Repayment", "20 January 2023", 937.0, 313.0, 0.0, 50.0, 20.0, 0.0, 0.0), // - transaction(100.0, "Chargeback", "20 January 2023", 967.0, 30.0, 0.0, 50.0, 20.0, 0.0, 0.0) // + transaction(382.0, "Repayment", "20 January 2023", 938.0, 312.0, 0.0, 50.0, 20.0, 0.0, 0.0), // + transaction(100.0, "Chargeback", "20 January 2023", 968.0, 30.0, 0.0, 50.0, 20.0, 0.0, 0.0) // ); // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(343.0, 0, 100, 40, 100.0, false, "01 February 2023"), - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(342.0, 0, 100, 40, 100.0, false, "01 February 2023"), + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); updateBusinessDate("21 January 2023"); @@ -984,18 +984,18 @@ public void doubleChargebackReverseReplayedOnlyPenaltyPayedWithCreditAllocationP verifyTransactions(loanId, // transaction(1250.0, "Disbursement", "01 January 2023", 1250.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), // - transaction(383.0, "Repayment", "20 January 2023", 937.0, 313.0, 0.0, 50.0, 20.0, 0.0, 0.0), // - transaction(100.0, "Chargeback", "20 January 2023", 967.0, 30.0, 0.0, 50.0, 20.0, 0.0, 0.0), // - transaction(100.0, "Chargeback", "21 January 2023", 1067.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0) // + transaction(382.0, "Repayment", "20 January 2023", 938.0, 312.0, 0.0, 50.0, 20.0, 0.0, 0.0), // + transaction(100.0, "Chargeback", "20 January 2023", 968.0, 30.0, 0.0, 50.0, 20.0, 0.0, 0.0), // + transaction(100.0, "Chargeback", "21 January 2023", 1068.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0) // ); // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(443.0, 0, 100, 40, 200.0, false, "01 February 2023"), - installment(313.0, 0, 0, 0, 313.0, false, "01 March 2023"), // - installment(313.0, 0, 0, 0, 313.0, false, "01 April 2023"), // - installment(311.0, 0, 0, 0, 311.0, false, "01 May 2023") // + installment(442.0, 0, 100, 40, 200.0, false, "01 February 2023"), + installment(312.0, 0, 0, 0, 312.0, false, "01 March 2023"), // + installment(312.0, 0, 0, 0, 312.0, false, "01 April 2023"), // + installment(314.0, 0, 0, 0, 314.0, false, "01 May 2023") // ); // Let's add repayment to trigger reverse replay for both chargebacks @@ -1004,9 +1004,9 @@ public void doubleChargebackReverseReplayedOnlyPenaltyPayedWithCreditAllocationP verifyTransactions(loanId, // transaction(1250.0, "Disbursement", "01 January 2023", 1250.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), // transaction(20.0, "Repayment", "19 January 2023", 1250.0, 0.0, 0.0, 0.0, 20.0, 0.0, 0.0), // - transaction(383.0, "Repayment", "20 January 2023", 917.0, 333.0, 0.0, 50.0, 0.0, 0.0, 0.0), // - transaction(100.0, "Chargeback", "20 January 2023", 967.0, 50.0, 0.0, 50.0, 0.0, 0.0, 0.0), // - transaction(100.0, "Chargeback", "21 January 2023", 1067.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0) // + transaction(382.0, "Repayment", "20 January 2023", 918.0, 332.0, 0.0, 50.0, 0.0, 0.0, 0.0), // + transaction(100.0, "Chargeback", "20 January 2023", 968.0, 50.0, 0.0, 50.0, 0.0, 0.0, 0.0), // + transaction(100.0, "Chargeback", "21 January 2023", 1068.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0) // ); }); } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanInstallmentMultiplesOfTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanInstallmentMultiplesOfTest.java index cbde7e33465..71dcd17ab2b 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanInstallmentMultiplesOfTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanInstallmentMultiplesOfTest.java @@ -78,10 +78,10 @@ public void test_LoanRepaymentScheduleIsEquallyDistributed_WhenNoInterest_ButInt // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(313.0, false, "01 February 2023"), // - installment(313.0, false, "01 March 2023"), // - installment(313.0, false, "01 April 2023"), // - installment(311.0, false, "01 May 2023") // + installment(312.0, false, "01 February 2023"), // + installment(312.0, false, "01 March 2023"), // + installment(312.0, false, "01 April 2023"), // + installment(314.0, false, "01 May 2023") // ); // disburse Loan @@ -89,11 +89,11 @@ public void test_LoanRepaymentScheduleIsEquallyDistributed_WhenNoInterest_ButInt // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // - installment(1250.0, null, "01 January 2023"), // - installment(313.0, false, "01 February 2023"), // - installment(313.0, false, "01 March 2023"), // - installment(313.0, false, "01 April 2023"), // - installment(311.0, false, "01 May 2023") // + installment(1250, null, "01 January 2023"), // + installment(312.0, false, "01 February 2023"), // + installment(312.0, false, "01 March 2023"), // + installment(312.0, false, "01 April 2023"), // + installment(314.0, false, "01 May 2023") // ); }); } @@ -142,9 +142,9 @@ public void test_LoanRepaymentScheduleIsEquallyDistributed_WhenInterestIsPresent // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // installment(1250.0, null, "01 January 2023"), // - installment(417.5, 12.5, 430.0, false, "01 February 2023"), // - installment(417.5, 12.5, 430.0, false, "01 March 2023"), // - installment(415.0, 12.5, 427.5, false, "01 April 2023") // + installment(416.5, 12.5, 429.0, false, "01 February 2023"), // + installment(416.5, 12.5, 429.0, false, "01 March 2023"), // + installment(417.0, 12.5, 429.5, false, "01 April 2023") // ); // disburse Loan @@ -152,10 +152,10 @@ public void test_LoanRepaymentScheduleIsEquallyDistributed_WhenInterestIsPresent // Verify Repayment Schedule verifyRepaymentSchedule(loanId, // - installment(1250.0, null, "01 January 2023"), // - installment(417.5, 12.5, 430.0, false, "01 February 2023"), // - installment(417.5, 12.5, 430.0, false, "01 March 2023"), // - installment(415.0, 12.5, 427.5, false, "01 April 2023") // + installment(1250, null, "01 January 2023"), // + installment(416.5, 12.5, 429.0, false, "01 February 2023"), // + installment(416.5, 12.5, 429.0, false, "01 March 2023"), // + installment(417.0, 12.5, 429.5, false, "01 April 2023") // ); }); } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleTestWithDownpayment.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleTestWithDownpayment.java index a6b41dd31d6..abf0b2f88bf 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleTestWithDownpayment.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleTestWithDownpayment.java @@ -59,8 +59,8 @@ public void testRescheduleWithDownPayment() { verifyRepaymentSchedule(loanId, // installment(1500.0, null, "01 January 2023"), // installment(375.0, false, "01 January 2023"), // - installment(563.0, false, "31 January 2023"), // - installment(562.0, false, "02 March 2023") // + installment(562.0, false, "31 January 2023"), // + installment(563.0, false, "02 March 2023") // ); // 1st Disburse Loan diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/GlobalConfigurationHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/GlobalConfigurationHelper.java index e098a75cb60..1e49b10aebe 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/GlobalConfigurationHelper.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/GlobalConfigurationHelper.java @@ -614,6 +614,14 @@ public static Integer updateEnabledFlagForGlobalConfiguration(final RequestSpeci updateGlobalConfigUpdateEnabledFlagAsJSON(enabled), "resourceId"); } + public static void updateValueForGlobalConfigurationInternal(final RequestSpecification requestSpec, + final ResponseSpecification responseSpec, final String configId, final int value) { + final String GLOBAL_CONFIG_UPDATE_URL = "/fineract-provider/api/v1/internal/configurations/" + configId + "/value/" + value + "?" + + Utils.TENANT_IDENTIFIER; + log.info("---------------------------UPDATE VALUE FOR GLOBAL CONFIG (internal) ---------------------------------------"); + Utils.performServerPost(requestSpec, responseSpec, GLOBAL_CONFIG_UPDATE_URL, Utils.emptyJson()); + } + // Deprecated because it's using configId as a String @Deprecated public static Integer updateEnabledFlagForGlobalConfiguration(final RequestSpecification requestSpec,