diff --git a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/data/loanproduct/DefaultLoanProduct.java b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/data/loanproduct/DefaultLoanProduct.java index 0216023d6..d63f973fa 100644 --- a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/data/loanproduct/DefaultLoanProduct.java +++ b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/data/loanproduct/DefaultLoanProduct.java @@ -41,6 +41,7 @@ public enum DefaultLoanProduct implements LoanProduct { LP2_DOWNPAYMENT_AUTO_ADVANCED_PAYMENT_ALLOCATION, // LP2_DOWNPAYMENT_ADVANCED_PAYMENT_ALLOCATION, // LP2_DOWNPAYMENT_INTEREST, LP2_DOWNPAYMENT_INTEREST_AUTO, // + LP2_ADV_CUST_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL, // LP2_DOWNPAYMENT_ADV_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL, // LP2_DOWNPAYMENT_ADV_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_VERTICAL, // LP2_DOWNPAYMENT_ADV_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL_INSTALLMENT_LEVEL_DELINQUENCY, // diff --git a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/factory/LoanProductsRequestFactory.java b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/factory/LoanProductsRequestFactory.java index 6ff44f21e..376813d58 100644 --- a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/factory/LoanProductsRequestFactory.java +++ b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/factory/LoanProductsRequestFactory.java @@ -66,6 +66,7 @@ public class LoanProductsRequestFactory { public static final String NAME_PREFIX_INTEREST_FLAT_LP2 = "LP2InterestFlat-"; public static final String NAME_PREFIX_INTEREST_DECLINING = "LP1InterestDeclining-"; public static final String NAME_PREFIX_INTEREST_DECLINING_RECALCULATION = "LP1InterestDecliningRecalculation-"; + public static final String NAME_PREFIX_INTEREST_RECALCULATION_WITH_DOWN_PAYMENT_LP3 = "LP3InterestRecalculationWithDownPayment-"; public static final String NAME_PREFIX_LP2_EMI = "LP2Emi-"; public static final String SHORT_NAME_PREFIX = "p"; public static final String SHORT_NAME_PREFIX_INTEREST = "i"; @@ -94,8 +95,11 @@ public class LoanProductsRequestFactory { public static final String TRANSACTION_PROCESSING_STRATEGY_CODE = TransactionProcessingStrategyCode.PENALTIES_FEES_INTEREST_PRINCIPAL_ORDER.value; public static final String TRANSACTION_PROCESSING_STRATEGY_CODE_ADVANCED = TransactionProcessingStrategyCode.ADVANCED_PAYMENT_ALLOCATION.value; public static final Integer DAYS_IN_YEAR_TYPE = DaysInYearType.ACTUAL.value; + public static final Integer DAYS_IN_YEAR_TYPE_360 = DaysInYearType.DAYS360.value; public static final Integer DAYS_IN_MONTH_TYPE = DaysInMonthType.ACTUAL.value; + public static final Integer DAYS_IN_MONTH_TYPE_30 = DaysInMonthType.DAYS30.value; public static final Integer LOAN_ACCOUNTING_RULE = AccountingRule.ACCRUAL_PERIODIC.value; + public static final Integer LOAN_ACCOUNTING_RULE_NONE = AccountingRule.NONE.value; public static final String OVER_APPLIED_CALCULATION_TYPE = "percentage"; public static final Integer OVER_APPLIED_NUMBER = 50; public static final Integer DELINQUENCY_BUCKET_ID = DelinquencyBucket.BASIC_DELINQUENCY_BUCKET.value; @@ -657,6 +661,38 @@ public class LoanProductsRequestFactory { .recalculationRestFrequencyInterval(1);// } + public PostLoanProductsRequest defaultLoanProductsRequestLP2InterestDailyRecalculationWithDownPayment() { + final String name = Utils.randomNameGenerator(NAME_PREFIX_INTEREST_RECALCULATION_WITH_DOWN_PAYMENT_LP3, 4); + final String shortName = Utils.randomNameGenerator(SHORT_NAME_PREFIX_INTEREST, 3); + + return new PostLoanProductsRequest().name(name).shortName(shortName) + .description(DESCRIPTION_INTEREST_DECLINING_BALANCE_DAILY_RECALCULATION_COMPOUNDING_NONE).startDate(null).closeDate(null) + .accountMovesOutOfNPAOnlyOnArrearsCompletion(false).accountingRule(LOAN_ACCOUNTING_RULE_NONE) + .allowApprovedDisbursedAmountsOverApplied(true) + .allowAttributeOverrides(new AllowAttributeOverrides().amortizationType(true).interestType(true) + .transactionProcessingStrategyCode(true).interestCalculationPeriodType(true).inArrearsTolerance(true) + .repaymentEvery(true).graceOnPrincipalAndInterestPayment(true).graceOnArrearsAgeing(true)) + .allowPartialPeriodInterestCalcualtion(false).allowVariableInstallments(false).amortizationType(AMORTIZATION_TYPE) + .canDefineInstallmentAmount(true).canUseForTopup(false).charges(new ArrayList<>()).creditAllocation(new ArrayList<>()) + .currencyCode(CURRENCY_CODE).dateFormat(DATE_FORMAT).daysInMonthType(DAYS_IN_MONTH_TYPE_30) + .daysInYearType(DAYS_IN_YEAR_TYPE_360).delinquencyBucketId(DELINQUENCY_BUCKET_ID.longValue()).digitsAfterDecimal(2) + .disallowExpectedDisbursements(true).dueDaysForRepaymentEvent(1).enableDownPayment(false) + .enableInstallmentLevelDelinquency(true).fixedLength(null).holdGuaranteeFunds(false).inMultiplesOf(0) + .includeInBorrowerCycle(false).interestCalculationPeriodType(0).interestRateFrequencyType(3).interestRatePerPeriod(9.99) + .interestRateVariationsForBorrowerCycle(new ArrayList<>()).interestRecalculationCompoundingMethod(0).interestType(0) + .isArrearsBasedOnOriginalSchedule(false).isEqualAmortization(false).isInterestRecalculationEnabled(true) + .isLinkedToFloatingInterestRates(false).loanScheduleProcessingType("HORIZONTAL").loanScheduleType("PROGRESSIVE") + .locale(LOCALE_EN).maxInterestRatePerPeriod((double) 50).maxNumberOfRepayments(48).maxPrincipal((double) 10000) + .maxTrancheCount(10).minInterestRatePerPeriod((double) 0).minNumberOfRepayments(1).minPrincipal((double) 1) + .multiDisburseLoan(true).numberOfRepaymentVariationsForBorrowerCycle(new ArrayList<>()).numberOfRepayments(3) + .outstandingLoanBalance((double) 10000).overAppliedCalculationType("flat").overAppliedNumber(10000) + .overDueDaysForRepaymentEvent(2).preClosureInterestCalculationStrategy(1).principal((double) 40) + .principalThresholdForLastInstallment(50).principalVariationsForBorrowerCycle(new ArrayList<>()) + .recalculationRestFrequencyInterval(1).recalculationRestFrequencyType(2).repaymentEvery(1).repaymentFrequencyType(2L) + .repaymentStartDateType(2).rescheduleStrategyMethod(4).supportedInterestRefundTypes(new ArrayList<>()) + .transactionProcessingStrategyCode(TRANSACTION_PROCESSING_STRATEGY_CODE_ADVANCED).useBorrowerCycle(false); + } + public PostLoanProductsRequest defaultLoanProductsRequestLP2() { String name = Utils.randomNameGenerator(NAME_PREFIX_LP2, 4); String shortName = Utils.randomNameGenerator(SHORT_NAME_PREFIX, 3); diff --git a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/initializer/global/LoanProductGlobalInitializerStep.java b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/initializer/global/LoanProductGlobalInitializerStep.java index 24e51f80d..74090fd80 100644 --- a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/initializer/global/LoanProductGlobalInitializerStep.java +++ b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/initializer/global/LoanProductGlobalInitializerStep.java @@ -548,6 +548,36 @@ public class LoanProductGlobalInitializerStep implements FineractGlobalInitializ .createLoanProduct(loanProductsRequestLP2AdvPmtAllocProgressiveLoanScheduleHorizontal).execute(); TestContext.INSTANCE.set(TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL, responseLP2AdvPmtAllocProgressiveLoanScheduleHorizontal); + + // LP2 with Down-payment + advanced custom payment allocation + progressive loan schedule + horizontal + // (LP2_DOWNPAYMENT_ADV_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL) + String name44 = DefaultLoanProduct.LP2_ADV_CUST_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL.getName(); + + PostLoanProductsRequest loanProductsRequestAdvCustomPaymentAllocationProgressiveLoanSchedule = loanProductsRequestFactory + .defaultLoanProductsRequestLP2InterestDailyRecalculationWithDownPayment()// + .name(name44)// + .paymentAllocation(List.of(// + createPaymentAllocation("DEFAULT", "NEXT_INSTALLMENT", + LoanProductPaymentAllocationRule.AllocationTypesEnum.PAST_DUE_INTEREST, // + LoanProductPaymentAllocationRule.AllocationTypesEnum.PAST_DUE_PRINCIPAL, // + LoanProductPaymentAllocationRule.AllocationTypesEnum.PAST_DUE_PENALTY, // + LoanProductPaymentAllocationRule.AllocationTypesEnum.PAST_DUE_FEE, // + LoanProductPaymentAllocationRule.AllocationTypesEnum.DUE_INTEREST, // + LoanProductPaymentAllocationRule.AllocationTypesEnum.DUE_PRINCIPAL, // + LoanProductPaymentAllocationRule.AllocationTypesEnum.DUE_PENALTY, // + LoanProductPaymentAllocationRule.AllocationTypesEnum.DUE_FEE, // + LoanProductPaymentAllocationRule.AllocationTypesEnum.IN_ADVANCE_INTEREST, // + LoanProductPaymentAllocationRule.AllocationTypesEnum.IN_ADVANCE_PRINCIPAL, // + LoanProductPaymentAllocationRule.AllocationTypesEnum.IN_ADVANCE_PENALTY, // + LoanProductPaymentAllocationRule.AllocationTypesEnum.IN_ADVANCE_FEE), // + createPaymentAllocation("GOODWILL_CREDIT", "LAST_INSTALLMENT"), // + createPaymentAllocation("MERCHANT_ISSUED_REFUND", "REAMORTIZATION"), // + createPaymentAllocation("PAYOUT_REFUND", "NEXT_INSTALLMENT")));// + Response responseLoanProductsRequestAdvCustomPaymentAllocationProgressiveLoanSchedule = loanProductsApi + .createLoanProduct(loanProductsRequestAdvCustomPaymentAllocationProgressiveLoanSchedule).execute(); + TestContext.INSTANCE.set( + TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADVANCED_CUSTOM_PAYMENT_ALLOCATION_PROGRESSIVE_LOAN_SCHEDULE, + responseLoanProductsRequestAdvCustomPaymentAllocationProgressiveLoanSchedule); } public static AdvancedPaymentData createPaymentAllocation(String transactionType, String futureInstallmentAllocationRule, diff --git a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanStepDef.java b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanStepDef.java index 4fdf238d2..b460e117e 100644 --- a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanStepDef.java +++ b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanStepDef.java @@ -1141,13 +1141,10 @@ public class LoanStepDef extends AbstractStepDef { List> data = table.asLists(); for (int i = 1; i < data.size(); i++) { List expectedValues = data.get(i); - String transactionDateExpected = expectedValues.get(0); List> actualValuesList = transactions.stream()// - .filter(t -> transactionDateExpected.equals(FORMATTER.format(t.getDate())))// .map(t -> fetchValuesOfTransaction(table.row(0), t))// .collect(Collectors.toList());// - boolean containsExpectedValues = actualValuesList.stream()// - .anyMatch(actualValues -> actualValues.equals(expectedValues));// + boolean containsExpectedValues = actualValuesList.get(i - 1).equals(expectedValues);// assertThat(containsExpectedValues).as(ErrorMessageHelper.wrongValueInLineInTransactionsTab(i, actualValuesList, expectedValues)) .isTrue(); } diff --git a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/support/TestContextKey.java b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/support/TestContextKey.java index e902c4f90..eff442220 100644 --- a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/support/TestContextKey.java +++ b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/support/TestContextKey.java @@ -61,6 +61,7 @@ public abstract class TestContextKey { public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP1_INTEREST_DECLINING_PERIOD_SAME_AS_PAYMENT = "loanProductCreateResponseLP1InterestDecliningPeriodSameAsPayment"; public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP1_1MONTH_INTEREST_DECLINING_BALANCE_DAILY_RECALCULATION_COMPOUNDING_MONTHLY = "loanProductCreateResponseLP1InterestDecliningPeriodSameAsPaymentRecalculation"; public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP1_INTEREST_DECLINING_BALANCE_DAILY_RECALCULATION_COMPOUNDING_NONE = "loanProductCreateResponseLP1InterestDecliningBalanceDailyRecalculationCompoundingNone"; + public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADVANCED_CUSTOM_PAYMENT_ALLOCATION_PROGRESSIVE_LOAN_SCHEDULE = "loanProductCreateResponseLP2ProgressiveLoanScheduleCustomPaymentAllocation"; public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP1_INTEREST_DECLINING_BALANCE_DAILY_RECALCULATION_SAME_AS_REPAYMENT_COMPOUNDING_NONE = "loanProductCreateResponseLP1InterestDecliningBalanceDailyRecalculationSameAsRepaymentCompoundingNone"; public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP1_INTEREST_DECLINING_BALANCE_SAR_RECALCULATION_SAME_AS_REPAYMENT_COMPOUNDING_NONE_MULTI_DISBURSEMENT = "loanProductCreateResponseLP1InterestDecliningBalanceDailyRecalculationSameAsRepaymentCompoundingNoneMultiDisbursement"; public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP1_INTEREST_DECLINING_BALANCE_DAILY_RECALCULATION_COMPOUNDING_NONE_RESCHEDULE_REDUCE_NR_INSTALLMENTS = "loanProductCreateResponseLP1InterestDecliningBalanceDailyRecalculationCompoundingNoneRescheduleReduceNrInstallments"; diff --git a/fineract-e2e-tests-runner/src/test/resources/features/LoanAccrualTransaction.feature b/fineract-e2e-tests-runner/src/test/resources/features/LoanAccrualTransaction.feature index 23c360c0b..2805d403f 100644 --- a/fineract-e2e-tests-runner/src/test/resources/features/LoanAccrualTransaction.feature +++ b/fineract-e2e-tests-runner/src/test/resources/features/LoanAccrualTransaction.feature @@ -171,8 +171,8 @@ Feature: LoanAccrualTransaction Then Loan Transactions tab has the following data: | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | | 01 July 2023 | Disbursement | 5000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 5000.0 | - | 06 July 2023 | Accrual | 10.0 | 0.0 | 0.0 | 10.0 | 0.0 | 0.0 | | 06 July 2023 | Repayment | 5011.0 | 5000.0 | 0.0 | 10.0 | 0.0 | 0.0 | + | 06 July 2023 | Accrual | 10.0 | 0.0 | 0.0 | 10.0 | 0.0 | 0.0 | Scenario: Verify that the accrual transaction correctly created in case a CBR is applied on the loan @@ -195,8 +195,8 @@ Feature: LoanAccrualTransaction Then Loan Transactions tab has the following data: | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | | 01 July 2023 | Disbursement | 5000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 5000.0 | - | 06 July 2023 | Accrual | 10.0 | 0.0 | 0.0 | 10.0 | 0.0 | 0.0 | | 06 July 2023 | Repayment | 5011.0 | 5000.0 | 0.0 | 10.0 | 0.0 | 0.0 | + | 06 July 2023 | Accrual | 10.0 | 0.0 | 0.0 | 10.0 | 0.0 | 0.0 | When Admin makes Credit Balance Refund transaction on "06 July 2023" with 1 EUR transaction amount Then Loan status will be "CLOSED_OBLIGATIONS_MET" Then Loan Repayment schedule has 1 periods, with the following data for periods: @@ -209,8 +209,8 @@ Feature: LoanAccrualTransaction Then Loan Transactions tab has the following data: | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | | 01 July 2023 | Disbursement | 5000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 5000.0 | - | 06 July 2023 | Accrual | 10.0 | 0.0 | 0.0 | 10.0 | 0.0 | 0.0 | | 06 July 2023 | Repayment | 5011.0 | 5000.0 | 0.0 | 10.0 | 0.0 | 0.0 | + | 06 July 2023 | Accrual | 10.0 | 0.0 | 0.0 | 10.0 | 0.0 | 0.0 | | 06 July 2023 | Credit Balance Refund | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 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 d56c6b700..b3b86e030 100644 --- a/fineract-e2e-tests-runner/src/test/resources/features/LoanCharge.feature +++ b/fineract-e2e-tests-runner/src/test/resources/features/LoanCharge.feature @@ -109,7 +109,6 @@ Feature: LoanCharge Then Loan has 260 outstanding amount # TODO clear, make it work properly - @Skip Scenario: Charge adjustment works properly When Admin sets the business date to "22 October 2022" When Admin creates a client with random data @@ -147,7 +146,7 @@ Feature: LoanCharge Then Loan Repayment schedule has the following data in Total row: | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | 1000 | 0 | 0 | 10 | 1010 | 3 | 3 | 0 | 1007 | - Then Loan Transactions tab has a transaction with date: "23 October 2022", and with the following data: + Then Loan Transactions tab has a transaction with date: "04 November 2022", and with the following data: | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | | Charge Adjustment | 3.0 | 0.0 | 0.0 | 0.0 | 3.0 | 1000.0 | @@ -163,7 +162,7 @@ Feature: LoanCharge Then Loan Repayment schedule has the following data in Total row: | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | 1000 | 0 | 0 | 10 | 1010 | 11 | 11 | 0 | 999 | - Then Loan Transactions tab has a transaction with date: "25 October 2022", and with the following data: + Then Loan Transactions tab has a transaction with date: "04 November 2022", and with the following data: | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | | Charge Adjustment | 3.0 | 1.0 | 0.0 | 0.0 | 2.0 | 999.0 | @@ -574,8 +573,8 @@ Feature: LoanCharge When Admin successfully disburse the loan on "01 January 2023" with "1000" EUR transaction amount Then Loan Transactions tab has the following data: | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | - | 01 January 2023 | Repayment (at time of disbursement) | 15.0 | 0.0 | 0.0 | 15.0 | 0.0 | 1000.0 | | 01 January 2023 | Disbursement | 1000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | + | 01 January 2023 | Repayment (at time of disbursement) | 15.0 | 0.0 | 0.0 | 15.0 | 0.0 | 1000.0 | Then Loan Charges tab has the following data: | Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding | | Disbursement percentage fee | false | Disbursement | | % Amount | 15.0 | 15.0 | 0.0 | 0.0 | @@ -1673,3 +1672,39 @@ Feature: LoanCharge Then Loan Charges tab has the following data: | Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding | | NSF fee | true | Specified due date | 22 February 2023 | Flat | 100.0 | 0.0 | 100.0 | 0.0 | + + Scenario: Verify that there are no payable interest after charge adjustment made on the same date for progressive loan with custom payment allocation order + When Admin sets the business date to "27 September 2024" + When Admin creates a client with random data + When Admin creates a fully customized loan with the following data: + | LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy | + | LP2_ADV_CUST_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL | 27 Sep 2024 | 100 | 9.99 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 1 | MONTHS | 1 | MONTHS | 1 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION | + And Admin successfully approves the loan on "27 September 2024" with "40" amount and expected disbursement date on "27 September 2024" + When Admin successfully disburse the loan on "27 September 2024" with "40" EUR transaction amount + Then Loan Repayment schedule has 1 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 | + | | | 27 September 2024 | | 40.0 | | | 0.0 | | 0.0 | 0.0 | | | | + | 1 | 30 | 27 October 2024 | | 0.0 | 40.0 | 0.33 | 0.0 | 0.0 | 40.33 | 0.0 | 0.0 | 0.0 | 40.33 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 40.0 | 0.33 | 0.0 | 0.0 | 40.33 | 0.0 | 0.0 | 0.0 | 40.33 | + Then Loan Transactions tab has the following data: + | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | + | 27 September 2024 | Disbursement | 40.0 | 0.0 | 0.0 | 0.0 | 0.0 | 40.0 | + | 27 September 2024 | Accrual | 0.33 | 0.0 | 0.33 | 0.0 | 0.0 | 0.0 | + When Admin adds "LOAN_NSF_FEE" due date charge with "27 September 2024" due date and 1 EUR transaction amount + When Admin makes a charge adjustment for the last "LOAN_NSF_FEE" type charge which is due on "27 September 2024" with 1 EUR transaction amount and externalId "" + Then Loan has 40.32 outstanding amount + Then Loan Repayment schedule has 1 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 | + | | | 27 September 2024 | | 40.0 | | | 0.0 | | 0.0 | 0.0 | | | | + | 1 | 30 | 27 October 2024 | | 0.0 | 40.0 | 0.32 | 0.0 | 1.0 | 41.32 | 1.0 | 1.0 | 0.0 | 40.32 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 40.0 | 0.32 | 0.0 | 1.0 | 41.32 | 1.0 | 1.0 | 0.0 | 40.32 | + Then Loan Transactions tab has the following data: + | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | + | 27 September 2024 | Disbursement | 40.0 | 0.0 | 0.0 | 0.0 | 0.0 | 40.0 | + | 27 September 2024 | Accrual | 0.33 | 0.0 | 0.33 | 0.0 | 0.0 | 0.0 | + | 27 September 2024 | Accrual | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | + | 27 September 2024 | Charge Adjustment | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 39.0 | \ No newline at end of file diff --git a/fineract-e2e-tests-runner/src/test/resources/features/LoanChargeOff.feature b/fineract-e2e-tests-runner/src/test/resources/features/LoanChargeOff.feature index 6338c2726..0fa866774 100644 --- a/fineract-e2e-tests-runner/src/test/resources/features/LoanChargeOff.feature +++ b/fineract-e2e-tests-runner/src/test/resources/features/LoanChargeOff.feature @@ -929,8 +929,8 @@ Feature: Charge-off Then Loan Transactions tab has the following data: | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | | 01 January 2023 | Disbursement | 1000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | - | 10 February 2023 | Accrual | 20.0 | 0.0 | 0.0 | 20.0 | 0.0 | 0.0 | | 10 February 2023 | Repayment | 1020.0 | 1000.0 | 0.0 | 20.0 | 0.0 | 0.0 | + | 10 February 2023 | Accrual | 20.0 | 0.0 | 0.0 | 20.0 | 0.0 | 0.0 | | 01 June 2023 | Charge-off | 15.0 | 0.0 | 0.0 | 0.0 | 15.0 | 0.0 | When Admin sets the business date to "10 June 2023" When Customer undo "1"th "Repayment" transaction made on "10 February 2023" @@ -945,8 +945,8 @@ Feature: Charge-off Then Loan Transactions tab has the following data: | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | | 01 January 2023 | Disbursement | 1000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | - | 10 February 2023 | Accrual | 20.0 | 0.0 | 0.0 | 20.0 | 0.0 | 0.0 | | 10 February 2023 | Repayment | 1020.0 | 1000.0 | 0.0 | 20.0 | 0.0 | 0.0 | + | 10 February 2023 | Accrual | 20.0 | 0.0 | 0.0 | 20.0 | 0.0 | 0.0 | | 01 June 2023 | Charge-off | 1035.0 | 1000.0 | 0.0 | 20.0 | 15.0 | 0.0 | Then On Loan Transactions tab the "Repayment" Transaction with date "10 February 2023" is reverted @@ -976,8 +976,8 @@ Feature: Charge-off Then Loan Transactions tab has the following data: | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | | 01 January 2023 | Disbursement | 1000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | - | 10 February 2023 | Accrual | 20.0 | 0.0 | 0.0 | 20.0 | 0.0 | 0.0 | | 10 February 2023 | Repayment | 1020.0 | 1000.0 | 0.0 | 20.0 | 0.0 | 0.0 | + | 10 February 2023 | Accrual | 20.0 | 0.0 | 0.0 | 20.0 | 0.0 | 0.0 | | 01 June 2023 | Charge-off | 15.0 | 0.0 | 0.0 | 0.0 | 15.0 | 0.0 | When Admin sets the business date to "10 June 2023" When Customer undo "1"th "Repayment" transaction made on "10 February 2023" @@ -992,8 +992,8 @@ Feature: Charge-off Then Loan Transactions tab has the following data: | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | | 01 January 2023 | Disbursement | 1000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | - | 10 February 2023 | Accrual | 20.0 | 0.0 | 0.0 | 20.0 | 0.0 | 0.0 | | 10 February 2023 | Repayment | 1020.0 | 1000.0 | 0.0 | 20.0 | 0.0 | 0.0 | + | 10 February 2023 | Accrual | 20.0 | 0.0 | 0.0 | 20.0 | 0.0 | 0.0 | | 01 June 2023 | Charge-off | 1035.0 | 1000.0 | 0.0 | 20.0 | 15.0 | 0.0 | Then On Loan Transactions tab the "Repayment" Transaction with date "10 February 2023" is reverted diff --git a/fineract-e2e-tests-runner/src/test/resources/features/LoanChargeback.feature b/fineract-e2e-tests-runner/src/test/resources/features/LoanChargeback.feature index f56fb68f5..45a14d91b 100644 --- a/fineract-e2e-tests-runner/src/test/resources/features/LoanChargeback.feature +++ b/fineract-e2e-tests-runner/src/test/resources/features/LoanChargeback.feature @@ -2904,8 +2904,8 @@ Feature: LoanChargeback | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Overpayment | | 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | 0.0 | | 19 January 2024 | Merchant Issued Refund | 10.0 | 10.0 | 0.0 | 0.0 | 0.0 | 90.0 | 0.0 | - | 01 February 2024 | Repayment | 105.0 | 90.0 | 0.0 | 0.0 | 5.0 | 0.0 | 10.0 | | 01 February 2024 | Accrual | 5.0 | 0.0 | 0.0 | 0.0 | 5.0 | 0.0 | 0.0 | + | 01 February 2024 | Repayment | 105.0 | 90.0 | 0.0 | 0.0 | 5.0 | 0.0 | 10.0 | Then Loan has 0 outstanding amount Then Loan has 10 overpaid amount Then Loan status will be "OVERPAID" @@ -2937,8 +2937,8 @@ Feature: LoanChargeback | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Overpayment | | 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | 0.0 | | 19 January 2024 | Merchant Issued Refund | 10.0 | 10.0 | 0.0 | 0.0 | 0.0 | 90.0 | 0.0 | - | 01 February 2024 | Repayment | 105.0 | 90.0 | 0.0 | 0.0 | 5.0 | 0.0 | 10.0 | | 01 February 2024 | Accrual | 5.0 | 0.0 | 0.0 | 0.0 | 5.0 | 0.0 | 0.0 | + | 01 February 2024 | Repayment | 105.0 | 90.0 | 0.0 | 0.0 | 5.0 | 0.0 | 10.0 | | 15 April 2024 | Chargeback | 7.0 | 2.0 | 0.0 | 0.0 | 5.0 | 0.0 | 7.0 | Then Loan Transactions tab has a "CHARGEBACK" transaction with date "15 April 2024" which has the following Journal entries: | Type | Account code | Account name | Debit | Credit | @@ -2961,8 +2961,8 @@ Feature: LoanChargeback | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Overpayment | | 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | 0.0 | | 19 January 2024 | Merchant Issued Refund | 10.0 | 10.0 | 0.0 | 0.0 | 0.0 | 90.0 | 0.0 | - | 01 February 2024 | Repayment | 105.0 | 90.0 | 0.0 | 0.0 | 5.0 | 0.0 | 10.0 | | 01 February 2024 | Accrual | 5.0 | 0.0 | 0.0 | 0.0 | 5.0 | 0.0 | 0.0 | + | 01 February 2024 | Repayment | 105.0 | 90.0 | 0.0 | 0.0 | 5.0 | 0.0 | 10.0 | | 15 April 2024 | Chargeback | 7.0 | 2.0 | 0.0 | 0.0 | 5.0 | 0.0 | 7.0 | | 16 April 2024 | Chargeback | 7.0 | 7.0 | 0.0 | 0.0 | 0.0 | 4.0 | 3.0 | Then Loan Transactions tab has a "CHARGEBACK" transaction with date "16 April 2024" which has the following Journal entries: 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 ce9872936..3b7649d6a 100644 --- a/fineract-e2e-tests-runner/src/test/resources/features/LoanRepayment.feature +++ b/fineract-e2e-tests-runner/src/test/resources/features/LoanRepayment.feature @@ -2337,8 +2337,8 @@ Feature: LoanRepayment Then Loan Transactions tab has the following data: | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | | 01 January 2023 | Disbursement | 1000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | - | 10 January 2023 | Accrual | 20.0 | 0.0 | 0.0 | 20.0 | 0.0 | 0.0 | | 10 January 2023 | Repayment | 1020.0 | 1000.0 | 0.0 | 20.0 | 0.0 | 0.0 | + | 10 January 2023 | Accrual | 20.0 | 0.0 | 0.0 | 20.0 | 0.0 | 0.0 | Then Loan Charges tab has the following data: | Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding | | Snooze fee | false | Specified due date | 01 February 2023 | Flat | 20.0 | 20.0 | 0.0 | 0.0 | @@ -2358,8 +2358,8 @@ Feature: LoanRepayment Then Loan Transactions tab has the following data: | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | | 01 January 2023 | Disbursement | 1000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | - | 10 January 2023 | Accrual | 20.0 | 0.0 | 0.0 | 20.0 | 0.0 | 0.0 | | 10 January 2023 | Repayment | 1020.0 | 1000.0 | 0.0 | 20.0 | 0.0 | 0.0 | + | 10 January 2023 | Accrual | 20.0 | 0.0 | 0.0 | 20.0 | 0.0 | 0.0 | Then Loan Charges tab has the following data: | Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding | | NSF fee | true | Specified due date | 01 February 2023 | Flat | 20.0 | 0.0 | 0.0 | 20.0 | @@ -2451,8 +2451,8 @@ Feature: LoanRepayment Then Loan Transactions tab has the following data: | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | | 01 January 2023 | Disbursement | 1000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | - | 10 January 2023 | Accrual | 20.0 | 0.0 | 0.0 | 20.0 | 0.0 | 0.0 | | 10 January 2023 | Repayment | 1020.0 | 1000.0 | 0.0 | 20.0 | 0.0 | 0.0 | + | 10 January 2023 | Accrual | 20.0 | 0.0 | 0.0 | 20.0 | 0.0 | 0.0 | Then Loan Charges tab has the following data: | Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding | | Snooze fee | false | Specified due date | 01 February 2023 | Flat | 20.0 | 20.0 | 0.0 | 0.0 | @@ -2472,8 +2472,8 @@ Feature: LoanRepayment Then Loan Transactions tab has the following data: | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | | 01 January 2023 | Disbursement | 1000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | - | 10 January 2023 | Accrual | 20.0 | 0.0 | 0.0 | 20.0 | 0.0 | 0.0 | | 10 January 2023 | Repayment | 1020.0 | 1000.0 | 0.0 | 20.0 | 0.0 | 0.0 | + | 10 January 2023 | Accrual | 20.0 | 0.0 | 0.0 | 20.0 | 0.0 | 0.0 | Then Loan Charges tab has the following data: | Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding | | NSF fee | true | Specified due date | 28 January 2023 | Flat | 20.0 | 0.0 | 0.0 | 20.0 | @@ -2542,8 +2542,8 @@ Feature: LoanRepayment Then Loan Transactions tab has the following data: | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | | 01 January 2023 | Disbursement | 1000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | - | 10 January 2023 | Accrual | 20.0 | 0.0 | 0.0 | 20.0 | 0.0 | 0.0 | | 10 January 2023 | Repayment | 1020.0 | 1000.0 | 0.0 | 20.0 | 0.0 | 0.0 | + | 10 January 2023 | Accrual | 20.0 | 0.0 | 0.0 | 20.0 | 0.0 | 0.0 | Then Loan Charges tab has the following data: | Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding | | Snooze fee | false | Specified due date | 01 February 2023 | Flat | 20.0 | 20.0 | 0.0 | 0.0 | @@ -2563,8 +2563,8 @@ Feature: LoanRepayment Then Loan Transactions tab has the following data: | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | | 01 January 2023 | Disbursement | 1000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | - | 10 January 2023 | Accrual | 20.0 | 0.0 | 0.0 | 20.0 | 0.0 | 0.0 | | 10 January 2023 | Repayment | 1020.0 | 1000.0 | 0.0 | 20.0 | 0.0 | 0.0 | + | 10 January 2023 | Accrual | 20.0 | 0.0 | 0.0 | 20.0 | 0.0 | 0.0 | Then Loan Charges tab has the following data: | Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding | | NSF fee | true | Specified due date | 28 January 2023 | Flat | 20.0 | 0.0 | 0.0 | 20.0 | @@ -2750,8 +2750,8 @@ Feature: LoanRepayment | 01 January 2023 | Disbursement | 1000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | | 10 January 2023 | Repayment | 20.0 | 0.0 | 0.0 | 0.0 | 20.0 | 1000.0 | | 15 January 2023 | Repayment | 500.0 | 470.0 | 10.0 | 0.0 | 20.0 | 530.0 | - | 25 January 2023 | Repayment | 530.0 | 500.0 | 10.0 | 0.0 | 20.0 | 500.0 | | 25 January 2023 | Accrual | 50.0 | 0.0 | 10.0 | 20.0 | 20.0 | 0.0 | + | 25 January 2023 | Repayment | 530.0 | 500.0 | 10.0 | 0.0 | 20.0 | 500.0 | | 01 February 2023 | Repayment | 20.0 | 0.0 | 0.0 | 0.0 | 20.0 | 1000.0 | Then Loan Charges tab has the following data: | Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding | @@ -2770,8 +2770,8 @@ Feature: LoanRepayment | 01 January 2023 | Disbursement | 1000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | | 10 January 2023 | Repayment | 20.0 | 0.0 | 0.0 | 0.0 | 20.0 | 1000.0 | | 15 January 2023 | Repayment | 500.0 | 470.0 | 10.0 | 0.0 | 20.0 | 530.0 | - | 25 January 2023 | Repayment | 530.0 | 500.0 | 10.0 | 0.0 | 20.0 | 500.0 | | 25 January 2023 | Accrual | 50.0 | 0.0 | 10.0 | 20.0 | 20.0 | 0.0 | + | 25 January 2023 | Repayment | 530.0 | 500.0 | 10.0 | 0.0 | 20.0 | 500.0 | | 01 February 2023 | Repayment | 20.0 | 0.0 | 0.0 | 0.0 | 20.0 | 1000.0 | | 01 February 2023 | Repayment | 10.0 | 0.0 | 10.0 | 0.0 | 0.0 | 1000.0 | And Customer makes "AUTOPAY" repayment on "01 February 2023" with 1000 EUR transaction amount @@ -2780,8 +2780,8 @@ Feature: LoanRepayment | 01 January 2023 | Disbursement | 1000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | | 10 January 2023 | Repayment | 20.0 | 0.0 | 0.0 | 0.0 | 20.0 | 1000.0 | | 15 January 2023 | Repayment | 500.0 | 470.0 | 10.0 | 0.0 | 20.0 | 530.0 | - | 25 January 2023 | Repayment | 530.0 | 500.0 | 10.0 | 0.0 | 20.0 | 500.0 | | 25 January 2023 | Accrual | 50.0 | 0.0 | 10.0 | 20.0 | 20.0 | 0.0 | + | 25 January 2023 | Repayment | 530.0 | 500.0 | 10.0 | 0.0 | 20.0 | 500.0 | | 01 February 2023 | Repayment | 20.0 | 0.0 | 0.0 | 0.0 | 20.0 | 1000.0 | | 01 February 2023 | Repayment | 10.0 | 0.0 | 10.0 | 0.0 | 0.0 | 1000.0 | | 01 February 2023 | Repayment | 1000.0 | 1000.0 | 0.0 | 0.0 | 0.0 | 0.0 | @@ -2791,8 +2791,8 @@ Feature: LoanRepayment | 01 January 2023 | Disbursement | 1000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | | 10 January 2023 | Repayment | 20.0 | 0.0 | 0.0 | 0.0 | 20.0 | 1000.0 | | 15 January 2023 | Repayment | 500.0 | 470.0 | 10.0 | 0.0 | 20.0 | 530.0 | - | 25 January 2023 | Repayment | 530.0 | 500.0 | 10.0 | 0.0 | 20.0 | 500.0 | | 25 January 2023 | Accrual | 50.0 | 0.0 | 10.0 | 20.0 | 20.0 | 0.0 | + | 25 January 2023 | Repayment | 530.0 | 500.0 | 10.0 | 0.0 | 20.0 | 500.0 | | 01 February 2023 | Repayment | 20.0 | 0.0 | 0.0 | 0.0 | 20.0 | 1000.0 | | 01 February 2023 | Repayment | 10.0 | 0.0 | 10.0 | 0.0 | 0.0 | 1000.0 | | 01 February 2023 | Repayment | 1000.0 | 1000.0 | 0.0 | 0.0 | 0.0 | 0.0 | diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImpl.java index 1a42976b1..488c7fc55 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImpl.java @@ -837,16 +837,20 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo LoanTransactionRelationTypeEnum.CHARGE_ADJUSTMENT); loanChargeAdjustmentTransaction.getLoanTransactionRelations().add(loanTransactionRelation); - loanAccountDomainService.saveLoanTransactionWithDataIntegrityViolationChecks(loanChargeAdjustmentTransaction); - defaultLoanLifecycleStateMachine.transition(LoanEvent.LOAN_REPAYMENT_OR_WAIVER, loan); final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = loanRepaymentScheduleTransactionProcessorFactory .determineProcessor(loan.transactionProcessingStrategy()); - loanRepaymentScheduleTransactionProcessor.processLatestTransaction(loanChargeAdjustmentTransaction, - new TransactionCtx(loan.getCurrency(), loan.getRepaymentScheduleInstallments(), loan.getActiveCharges(), - new MoneyHolder(loan.getTotalOverpaidAsMoney()), null)); - loan.addLoanTransaction(loanChargeAdjustmentTransaction); + if (loan.isInterestBearing() && loan.getLoanProductRelatedDetail().isInterestRecalculationEnabled()) { + loanRepaymentScheduleTransactionProcessor.reprocessLoanTransactions(loan.getDisbursementDate(), + loan.retrieveListOfTransactionsForReprocessing(), loan.getCurrency(), loan.getRepaymentScheduleInstallments(), + loan.getActiveCharges()); + } else { + loanRepaymentScheduleTransactionProcessor.processLatestTransaction(loanChargeAdjustmentTransaction, + new TransactionCtx(loan.getCurrency(), loan.getRepaymentScheduleInstallments(), loan.getActiveCharges(), + new MoneyHolder(loan.getTotalOverpaidAsMoney()), null)); + } + loanAccountDomainService.saveLoanTransactionWithDataIntegrityViolationChecks(loanChargeAdjustmentTransaction); loan.updateLoanSummaryAndStatus(); loanAccountDomainService.saveAndFlushLoanWithDataIntegrityViolationChecks(loan);