[FINERACT-1968] horizontal processing for refund for active loans transaction

This commit is contained in:
taskain7
2023-11-14 15:28:35 +01:00
committed by Adam Saghy
parent 35243ee709
commit 71f9f57ba0
2 changed files with 328 additions and 31 deletions
@@ -90,9 +90,8 @@ public class RefundForActiveLoansWithAdvancedPaymentAllocationTest {
}
@Test
public void refundForActiveLoanWithDefaultPaymentAllocation() {
public void refundForActiveLoanWithDefaultPaymentAllocationProcessingVertically() {
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"));
@@ -102,7 +101,8 @@ public class RefundForActiveLoansWithAdvancedPaymentAllocationTest {
final Account expenseAccount = accountHelper.createExpenseAccount();
final Account overpaymentAccount = accountHelper.createLiabilityAccount();
Integer loanProductId = createLoanProduct("1000", "30", "4", assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
Integer loanProductId = createLoanProduct("1000", "30", "4", LoanScheduleProcessingType.VERTICAL, assetAccount, incomeAccount,
expenseAccount, overpaymentAccount);
final PostLoansResponse loanResponse = applyForLoanApplication(client.getClientId(), loanProductId, 1000L, 90, 30, 3, 0,
"01 January 2023", "01 January 2023");
@@ -288,15 +288,215 @@ public class RefundForActiveLoansWithAdvancedPaymentAllocationTest {
}
}
@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"));
loanTransactionHelper.makeRepayment("28 January 2023", 810.0f, loanId);
loanDetails = loanTransactionHelper.getLoanDetails((long) loanId);
firstRepaymentInstallment = loanDetails.getRepaymentSchedule().getPeriods().get(2);
secondRepaymentInstallment = loanDetails.getRepaymentSchedule().getPeriods().get(3);
thirdRepaymentInstallment = loanDetails.getRepaymentSchedule().getPeriods().get(4);
assertEquals(5, loanDetails.getRepaymentSchedule().getPeriods().size());
assertEquals(feePortion, firstRepaymentInstallment.getFeeChargesDue());
assertEquals(0.0f, firstRepaymentInstallment.getFeeChargesOutstanding());
assertEquals(penaltyPortion, firstRepaymentInstallment.getPenaltyChargesDue());
assertEquals(0.0f, firstRepaymentInstallment.getPenaltyChargesOutstanding());
assertEquals(250.0f, firstRepaymentInstallment.getPrincipalDue());
assertEquals(0.0f, firstRepaymentInstallment.getPrincipalOutstanding());
assertEquals(400.0f, firstRepaymentInstallment.getTotalDueForPeriod());
assertEquals(0.0f, firstRepaymentInstallment.getTotalOutstandingForPeriod());
assertEquals(LocalDate.of(2023, 1, 31), firstRepaymentInstallment.getDueDate());
assertEquals(feePortion, secondRepaymentInstallment.getFeeChargesDue());
assertEquals(0.0f, secondRepaymentInstallment.getFeeChargesOutstanding());
assertEquals(penaltyPortion, secondRepaymentInstallment.getPenaltyChargesDue());
assertEquals(0.0f, secondRepaymentInstallment.getPenaltyChargesOutstanding());
assertEquals(400.0f, secondRepaymentInstallment.getTotalDueForPeriod());
assertEquals(0.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(240.0f, thirdRepaymentInstallment.getTotalOutstandingForPeriod());
assertEquals(LocalDate.of(2023, 4, 1), thirdRepaymentInstallment.getDueDate());
loanTransactionHelper.makeRefundByCash("28 January 2023", 15.0f, loanId);
loanDetails = loanTransactionHelper.getLoanDetails((long) loanId);
firstRepaymentInstallment = loanDetails.getRepaymentSchedule().getPeriods().get(2);
secondRepaymentInstallment = loanDetails.getRepaymentSchedule().getPeriods().get(3);
thirdRepaymentInstallment = loanDetails.getRepaymentSchedule().getPeriods().get(4);
assertEquals(5, loanDetails.getRepaymentSchedule().getPeriods().size());
assertEquals(feePortion, firstRepaymentInstallment.getFeeChargesDue());
assertEquals(0.0f, firstRepaymentInstallment.getFeeChargesOutstanding());
assertEquals(penaltyPortion, firstRepaymentInstallment.getPenaltyChargesDue());
assertEquals(0.0f, firstRepaymentInstallment.getPenaltyChargesOutstanding());
assertEquals(250.0f, firstRepaymentInstallment.getPrincipalDue());
assertEquals(0.0f, firstRepaymentInstallment.getPrincipalOutstanding());
assertEquals(400.0f, firstRepaymentInstallment.getTotalDueForPeriod());
assertEquals(0.0f, firstRepaymentInstallment.getTotalOutstandingForPeriod());
assertEquals(LocalDate.of(2023, 1, 31), firstRepaymentInstallment.getDueDate());
assertEquals(feePortion, secondRepaymentInstallment.getFeeChargesDue());
assertEquals(0.0f, secondRepaymentInstallment.getFeeChargesOutstanding());
assertEquals(penaltyPortion, secondRepaymentInstallment.getPenaltyChargesDue());
assertEquals(0.0f, secondRepaymentInstallment.getPenaltyChargesOutstanding());
assertEquals(250.0f, secondRepaymentInstallment.getPrincipalDue());
assertEquals(5.0f, secondRepaymentInstallment.getPrincipalOutstanding());
assertEquals(400.0f, secondRepaymentInstallment.getTotalDueForPeriod());
assertEquals(5.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());
// fully unpaying the second installment
loanTransactionHelper.makeRefundByCash("28 January 2023", 395.0f, loanId);
loanDetails = loanTransactionHelper.getLoanDetails((long) loanId);
firstRepaymentInstallment = loanDetails.getRepaymentSchedule().getPeriods().get(2);
secondRepaymentInstallment = loanDetails.getRepaymentSchedule().getPeriods().get(3);
thirdRepaymentInstallment = loanDetails.getRepaymentSchedule().getPeriods().get(4);
assertEquals(5, loanDetails.getRepaymentSchedule().getPeriods().size());
assertEquals(feePortion, firstRepaymentInstallment.getFeeChargesDue());
assertEquals(0.0f, firstRepaymentInstallment.getFeeChargesOutstanding());
assertEquals(penaltyPortion, firstRepaymentInstallment.getPenaltyChargesDue());
assertEquals(0.0f, firstRepaymentInstallment.getPenaltyChargesOutstanding());
assertEquals(250.0f, firstRepaymentInstallment.getPrincipalDue());
assertEquals(0.0f, firstRepaymentInstallment.getPrincipalOutstanding());
assertEquals(400.0f, firstRepaymentInstallment.getTotalDueForPeriod());
assertEquals(0.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(250.0f, secondRepaymentInstallment.getPrincipalDue());
assertEquals(250.0f, secondRepaymentInstallment.getPrincipalOutstanding());
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());
} finally {
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
}
}
private Integer createLoanProduct(final String principal, final String repaymentAfterEvery, final String numberOfRepayments,
final Account... accounts) {
LoanScheduleProcessingType loanScheduleProcessingType, final Account... accounts) {
AdvancedPaymentData defaultAllocation = createDefaultPaymentAllocation();
log.info("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------");
final String loanProductJSON = new LoanProductTestBuilder().withMinPrincipal(principal).withPrincipal(principal)
.withRepaymentTypeAsDays().withRepaymentAfterEvery(repaymentAfterEvery).withNumberOfRepayments(numberOfRepayments)
.withEnableDownPayment(true, "25", true).withinterestRatePerPeriod("0").withInterestRateFrequencyTypeAsMonths()
.withRepaymentStrategy(AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY)
.withLoanScheduleType(LoanScheduleType.PROGRESSIVE).withLoanScheduleProcessingType(LoanScheduleProcessingType.VERTICAL)
.withLoanScheduleType(LoanScheduleType.PROGRESSIVE).withLoanScheduleProcessingType(loanScheduleProcessingType)
.withAmortizationTypeAsEqualPrincipalPayment().withInterestTypeAsFlat().withAccountingRulePeriodicAccrual(accounts)
.addAdvancedPaymentAllocation(defaultAllocation).withDaysInMonth("30").withDaysInYear("365").withMoratorium("0", "0")
.build(null);