reluxa commented on code in PR #3583:
URL: https://github.com/apache/fineract/pull/3583#discussion_r1392469095
##########
integration-tests/src/test/java/org/apache/fineract/integrationtests/RefundForActiveLoansWithAdvancedPaymentAllocationTest.java:
##########
@@ -288,15 +288,215 @@ public void
refundForActiveLoanWithDefaultPaymentAllocation() {
}
}
+ @Test
+ public void
refundForActiveLoanWithDefaultPaymentAllocationProcessingHorizontally() {
+ try {
+ GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec,
responseSpec, Boolean.TRUE);
+ businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
+ .date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en"));
+
+ final Account assetAccount = accountHelper.createAssetAccount();
+ final Account incomeAccount = accountHelper.createIncomeAccount();
+ final Account expenseAccount =
accountHelper.createExpenseAccount();
+ final Account overpaymentAccount =
accountHelper.createLiabilityAccount();
+
+ Integer loanProductId = createLoanProduct("1000", "30", "4",
LoanScheduleProcessingType.HORIZONTAL, assetAccount, incomeAccount,
+ expenseAccount, overpaymentAccount);
+
+ final PostLoansResponse loanResponse =
applyForLoanApplication(client.getClientId(), loanProductId, 1000L, 90, 30, 3,
0,
+ "01 January 2023", "01 January 2023");
+
+ int loanId = loanResponse.getLoanId().intValue();
+
+ loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
+ new
PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000)).dateFormat(DATETIME_PATTERN)
+ .approvedOnDate("01 January 2023").locale("en"));
+
+ loanTransactionHelper.disburseLoan(loanResponse.getLoanId(),
+ new PostLoansLoanIdRequest().actualDisbursementDate("01
January 2023").dateFormat(DATETIME_PATTERN)
+
.transactionAmount(BigDecimal.valueOf(1000.00)).locale("en"));
+
+ final float feePortion = 50.0f;
+ final float penaltyPortion = 100.0f;
+
+ Integer fee = ChargesHelper.createCharges(requestSpec,
responseSpec, ChargesHelper
+
.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
String.valueOf(feePortion), false));
+
+ Integer penalty = ChargesHelper.createCharges(requestSpec,
responseSpec, ChargesHelper
+
.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
String.valueOf(penaltyPortion), true));
+
+ final String firstInstallmentChargeAddedDate =
DATE_FORMATTER.format(LocalDate.of(2023, 1, 3));
+ loanTransactionHelper.addChargesForLoan(loanId,
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(
+ String.valueOf(fee), firstInstallmentChargeAddedDate,
String.valueOf(feePortion)));
+
+ loanTransactionHelper.addChargesForLoan(loanId,
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(
+ String.valueOf(penalty), firstInstallmentChargeAddedDate,
String.valueOf(penaltyPortion)));
+
+ final String secondInstallmentChargeAddedDate =
DATE_FORMATTER.format(LocalDate.of(2023, 2, 3));
+ loanTransactionHelper.addChargesForLoan(loanId,
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(
+ String.valueOf(fee), secondInstallmentChargeAddedDate,
String.valueOf(feePortion)));
+
+ loanTransactionHelper.addChargesForLoan(loanId,
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(
+ String.valueOf(penalty), secondInstallmentChargeAddedDate,
String.valueOf(penaltyPortion)));
+
+ GetLoansLoanIdResponse loanDetails =
loanTransactionHelper.getLoanDetails((long) loanId);
+
+ GetLoansLoanIdRepaymentPeriod firstRepaymentInstallment =
loanDetails.getRepaymentSchedule().getPeriods().get(2);
+ GetLoansLoanIdRepaymentPeriod secondRepaymentInstallment =
loanDetails.getRepaymentSchedule().getPeriods().get(3);
+ GetLoansLoanIdRepaymentPeriod thirdRepaymentInstallment =
loanDetails.getRepaymentSchedule().getPeriods().get(4);
+
+ assertEquals(5,
loanDetails.getRepaymentSchedule().getPeriods().size());
+ assertEquals(feePortion,
firstRepaymentInstallment.getFeeChargesDue());
+ assertEquals(feePortion,
firstRepaymentInstallment.getFeeChargesOutstanding());
+ assertEquals(penaltyPortion,
firstRepaymentInstallment.getPenaltyChargesDue());
+ assertEquals(penaltyPortion,
firstRepaymentInstallment.getPenaltyChargesOutstanding());
+ assertEquals(250.0f, firstRepaymentInstallment.getPrincipalDue());
+ assertEquals(250.0f,
firstRepaymentInstallment.getPrincipalOutstanding());
+ assertEquals(400.0f,
firstRepaymentInstallment.getTotalDueForPeriod());
+ assertEquals(400.0f,
firstRepaymentInstallment.getTotalOutstandingForPeriod());
+ assertEquals(LocalDate.of(2023, 1, 31),
firstRepaymentInstallment.getDueDate());
+
+ assertEquals(feePortion,
secondRepaymentInstallment.getFeeChargesDue());
+ assertEquals(feePortion,
secondRepaymentInstallment.getFeeChargesOutstanding());
+ assertEquals(penaltyPortion,
secondRepaymentInstallment.getPenaltyChargesDue());
+ assertEquals(penaltyPortion,
secondRepaymentInstallment.getPenaltyChargesOutstanding());
+ assertEquals(400.0f,
secondRepaymentInstallment.getTotalDueForPeriod());
+ assertEquals(400.0f,
secondRepaymentInstallment.getTotalOutstandingForPeriod());
+ assertEquals(LocalDate.of(2023, 3, 2),
secondRepaymentInstallment.getDueDate());
+
+ assertEquals(0.0f, thirdRepaymentInstallment.getFeeChargesDue());
+ assertEquals(0.0f,
thirdRepaymentInstallment.getFeeChargesOutstanding());
+ assertEquals(0.0f,
thirdRepaymentInstallment.getPenaltyChargesDue());
+ assertEquals(0.0f,
thirdRepaymentInstallment.getPenaltyChargesOutstanding());
+ assertEquals(250.0f,
thirdRepaymentInstallment.getTotalDueForPeriod());
+ assertEquals(250.0f,
thirdRepaymentInstallment.getTotalOutstandingForPeriod());
+ assertEquals(LocalDate.of(2023, 4, 1),
thirdRepaymentInstallment.getDueDate());
+
+ businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
+ .date("2023.03.01").dateFormat("yyyy.MM.dd").locale("en"));
Review Comment:
I suggest to move the time to after 1st of April, so all the installments
will become past due. And at that point let's make payment.
0) Create the loan with the same configuration, add the same fees and
penalties
1) Set the time to 1st of April -> this makes all the installments past due
2) make pay 100 as repayment, first installment fee outstanding should be 0,
penalty should be 50. -> this proves that we are in horizontal payment strategy
as on vertical it would have payed the fee's on the 1st and on the 2nd
installment.
3) make another payment 710 -> first and second installment should be fully
payed., 3rd installment principal outstanding is 240
4) make refund with 600 ->
3rd installment prinipal outstanding will be 250 again. (10)
2nd installment principal outstanding will be 250 (260)
2nd installment fee outstanding will be 50 (310)
2nd instalment's charge outstanding will be 100 (410)
1st instalment principal outstanding will be 60 (600)
My understanding that in case of **vertical** the step 4 (refund 600) will
look like this:
3rd installment principal outstanding will be 250 (10)
2nd installment principal outstanding will be 250 (260)
1st installment principal outstanding will be 250 (510)
2nd installment fee outstanding will be 50 (560)
1st installment fee outstanding will be 40 (600)
cc: @adamsaghy
I think it might make sense to repay and refund the same amounts on
horizontal and vertical , so we can clearly see the difference between.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]