FINERACT-1981: do not calculate interest for charge adjustment when the activities occur on the same day

This commit is contained in:
Oleksii Novikov
2024-10-25 09:55:59 +02:00
committed by Adam Saghy
parent 4198b0bcf9
commit 8a2560fe2e
11 changed files with 138 additions and 34 deletions
@@ -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, //
@@ -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);
@@ -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<PostLoanProductsResponse> 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,
@@ -1141,13 +1141,10 @@ public class LoanStepDef extends AbstractStepDef {
List<List<String>> data = table.asLists();
for (int i = 1; i < data.size(); i++) {
List<String> expectedValues = data.get(i);
String transactionDateExpected = expectedValues.get(0);
List<List<String>> 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();
}
@@ -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";
@@ -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 |
@@ -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 |
@@ -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
@@ -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:
@@ -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 |
@@ -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);