FINERACT-2232: add income capitalization principal handling and repayment schedule calculations on loans
This commit is contained in:
+23
-23
@@ -5938,7 +5938,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
|
||||
executeInlineCOB(createdLoanId.get());
|
||||
GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(createdLoanId.get());
|
||||
// totalUnpaidPayableDueInterest → Total outstanding interest amount on all the periods that are before
|
||||
assertEquals(BigDecimal.valueOf(loanDetails.getSummary().getInterestCharged()).stripTrailingZeros(),
|
||||
assertEquals(loanDetails.getSummary().getInterestCharged().stripTrailingZeros(),
|
||||
loanDetails.getSummary().getTotalUnpaidPayableDueInterest().stripTrailingZeros());
|
||||
// Total outstanding interest amount on the current period, if the current period due date is after than the
|
||||
// current date
|
||||
@@ -6131,21 +6131,21 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
|
||||
GetLoansLoanIdRepaymentPeriod period = loanDetails.getRepaymentSchedule().getPeriods().get(index);
|
||||
assertEquals(dueDate, period.getDueDate());
|
||||
assertEquals(paidDate, period.getObligationsMetOnDate());
|
||||
assertEquals(balanceOfLoan, period.getPrincipalLoanBalanceOutstanding());
|
||||
assertEquals(principalDue, period.getPrincipalDue());
|
||||
assertEquals(principalPaid, period.getPrincipalPaid());
|
||||
assertEquals(principalOutstanding, period.getPrincipalOutstanding());
|
||||
assertEquals(feeDue, period.getFeeChargesDue());
|
||||
assertEquals(feePaid, period.getFeeChargesPaid());
|
||||
assertEquals(feeOutstanding, period.getFeeChargesOutstanding());
|
||||
assertEquals(penaltyDue, period.getPenaltyChargesDue());
|
||||
assertEquals(penaltyPaid, period.getPenaltyChargesPaid());
|
||||
assertEquals(penaltyOutstanding, period.getPenaltyChargesOutstanding());
|
||||
assertEquals(interestDue, period.getInterestDue());
|
||||
assertEquals(interestPaid, period.getInterestPaid());
|
||||
assertEquals(interestOutstanding, period.getInterestOutstanding());
|
||||
assertEquals(paidInAdvance, period.getTotalPaidInAdvanceForPeriod());
|
||||
assertEquals(paidLate, period.getTotalPaidLateForPeriod());
|
||||
assertEquals(balanceOfLoan, Utils.getDoubleValue(period.getPrincipalLoanBalanceOutstanding()));
|
||||
assertEquals(principalDue, Utils.getDoubleValue(period.getPrincipalDue()));
|
||||
assertEquals(principalPaid, Utils.getDoubleValue(period.getPrincipalPaid()));
|
||||
assertEquals(principalOutstanding, Utils.getDoubleValue(period.getPrincipalOutstanding()));
|
||||
assertEquals(feeDue, Utils.getDoubleValue(period.getFeeChargesDue()));
|
||||
assertEquals(feePaid, Utils.getDoubleValue(period.getFeeChargesPaid()));
|
||||
assertEquals(feeOutstanding, Utils.getDoubleValue(period.getFeeChargesOutstanding()));
|
||||
assertEquals(penaltyDue, Utils.getDoubleValue(period.getPenaltyChargesDue()));
|
||||
assertEquals(penaltyPaid, Utils.getDoubleValue(period.getPenaltyChargesPaid()));
|
||||
assertEquals(penaltyOutstanding, Utils.getDoubleValue(period.getPenaltyChargesOutstanding()));
|
||||
assertEquals(interestDue, Utils.getDoubleValue(period.getInterestDue()));
|
||||
assertEquals(interestPaid, Utils.getDoubleValue(period.getInterestPaid()));
|
||||
assertEquals(interestOutstanding, Utils.getDoubleValue(period.getInterestOutstanding()));
|
||||
assertEquals(paidInAdvance, Utils.getDoubleValue(period.getTotalPaidInAdvanceForPeriod()));
|
||||
assertEquals(paidLate, Utils.getDoubleValue(period.getTotalPaidLateForPeriod()));
|
||||
}
|
||||
|
||||
private static PostLoansResponse applyForLoanApplication(final Long clientId, final Integer loanProductId, final BigDecimal principal,
|
||||
@@ -6181,18 +6181,18 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
|
||||
|
||||
private static void validateLoanTransaction(GetLoansLoanIdResponse loanDetails, int index, double transactionAmount,
|
||||
double principalPortion, double overPaidPortion, double loanBalance) {
|
||||
assertEquals(transactionAmount, loanDetails.getTransactions().get(index).getAmount());
|
||||
assertEquals(principalPortion, loanDetails.getTransactions().get(index).getPrincipalPortion());
|
||||
assertEquals(overPaidPortion, loanDetails.getTransactions().get(index).getOverpaymentPortion());
|
||||
assertEquals(loanBalance, loanDetails.getTransactions().get(index).getOutstandingLoanBalance());
|
||||
assertEquals(transactionAmount, Utils.getDoubleValue(loanDetails.getTransactions().get(index).getAmount()));
|
||||
assertEquals(principalPortion, Utils.getDoubleValue(loanDetails.getTransactions().get(index).getPrincipalPortion()));
|
||||
assertEquals(overPaidPortion, Utils.getDoubleValue(loanDetails.getTransactions().get(index).getOverpaymentPortion()));
|
||||
assertEquals(loanBalance, Utils.getDoubleValue(loanDetails.getTransactions().get(index).getOutstandingLoanBalance()));
|
||||
}
|
||||
|
||||
private void validateLoanCharge(GetLoansLoanIdResponse loanDetails, int index, LocalDate dueDate, double charged, double paid,
|
||||
double outstanding) {
|
||||
GetLoansLoanIdLoanChargeData chargeData = loanDetails.getCharges().get(index);
|
||||
assertEquals(dueDate, chargeData.getDueDate());
|
||||
assertEquals(charged, chargeData.getAmount());
|
||||
assertEquals(paid, chargeData.getAmountPaid());
|
||||
assertEquals(outstanding, chargeData.getAmountOutstanding());
|
||||
assertEquals(charged, Utils.getDoubleValue(chargeData.getAmount()));
|
||||
assertEquals(paid, Utils.getDoubleValue(chargeData.getAmountPaid()));
|
||||
assertEquals(outstanding, Utils.getDoubleValue(chargeData.getAmountOutstanding()));
|
||||
}
|
||||
}
|
||||
|
||||
+64
-54
@@ -177,22 +177,22 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
|
||||
GetLoansLoanIdRepaymentPeriod period = loanDetails.getRepaymentSchedule().getPeriods().stream()
|
||||
.filter(p -> Objects.equals(p.getPeriod(), index)).findFirst().orElseThrow();
|
||||
assertEquals(dueDate, period.getDueDate());
|
||||
assertEquals(principalDue, period.getPrincipalDue());
|
||||
assertEquals(principalPaid, period.getPrincipalPaid());
|
||||
assertEquals(principalOutstanding, period.getPrincipalOutstanding());
|
||||
assertEquals(paidInAdvance, period.getTotalPaidInAdvanceForPeriod());
|
||||
assertEquals(paidLate, period.getTotalPaidLateForPeriod());
|
||||
assertEquals(principalDue, Utils.getDoubleValue(period.getPrincipalDue()));
|
||||
assertEquals(principalPaid, Utils.getDoubleValue(period.getPrincipalPaid()));
|
||||
assertEquals(principalOutstanding, Utils.getDoubleValue(period.getPrincipalOutstanding()));
|
||||
assertEquals(paidInAdvance, Utils.getDoubleValue(period.getTotalPaidInAdvanceForPeriod()));
|
||||
assertEquals(paidLate, Utils.getDoubleValue(period.getTotalPaidLateForPeriod()));
|
||||
}
|
||||
|
||||
protected static void validateRepaymentPeriod(GetLoansLoanIdResponse loanDetails, Integer index, double principalDue,
|
||||
double principalPaid, double principalOutstanding, double paidInAdvance, double paidLate) {
|
||||
GetLoansLoanIdRepaymentPeriod period = loanDetails.getRepaymentSchedule().getPeriods().stream()
|
||||
.filter(p -> Objects.equals(p.getPeriod(), index)).findFirst().orElseThrow();
|
||||
assertEquals(principalDue, period.getPrincipalDue());
|
||||
assertEquals(principalPaid, period.getPrincipalPaid());
|
||||
assertEquals(principalOutstanding, period.getPrincipalOutstanding());
|
||||
assertEquals(paidInAdvance, period.getTotalPaidInAdvanceForPeriod());
|
||||
assertEquals(paidLate, period.getTotalPaidLateForPeriod());
|
||||
assertEquals(principalDue, Utils.getDoubleValue(period.getPrincipalDue()));
|
||||
assertEquals(principalPaid, Utils.getDoubleValue(period.getPrincipalPaid()));
|
||||
assertEquals(principalOutstanding, Utils.getDoubleValue(period.getPrincipalOutstanding()));
|
||||
assertEquals(paidInAdvance, Utils.getDoubleValue(period.getTotalPaidInAdvanceForPeriod()));
|
||||
assertEquals(paidLate, Utils.getDoubleValue(period.getTotalPaidLateForPeriod()));
|
||||
}
|
||||
|
||||
protected static void validateFullyUnpaidRepaymentPeriod(GetLoansLoanIdResponse loanDetails, Integer index, String dueDate,
|
||||
@@ -233,20 +233,20 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
|
||||
GetLoansLoanIdRepaymentPeriod period = loanDetails.getRepaymentSchedule().getPeriods().stream()
|
||||
.filter(p -> Objects.equals(p.getPeriod(), index)).findFirst().orElseThrow();
|
||||
assertEquals(dueDate, period.getDueDate());
|
||||
assertEquals(principalDue, period.getPrincipalDue());
|
||||
assertEquals(principalPaid, period.getPrincipalPaid());
|
||||
assertEquals(principalOutstanding, period.getPrincipalOutstanding());
|
||||
assertEquals(feeDue, period.getFeeChargesDue());
|
||||
assertEquals(feePaid, period.getFeeChargesPaid());
|
||||
assertEquals(feeOutstanding, period.getFeeChargesOutstanding());
|
||||
assertEquals(penaltyDue, period.getPenaltyChargesDue());
|
||||
assertEquals(penaltyPaid, period.getPenaltyChargesPaid());
|
||||
assertEquals(penaltyOutstanding, period.getPenaltyChargesOutstanding());
|
||||
assertEquals(interestDue, period.getInterestDue());
|
||||
assertEquals(interestPaid, period.getInterestPaid());
|
||||
assertEquals(interestOutstanding, period.getInterestOutstanding());
|
||||
assertEquals(paidInAdvance, period.getTotalPaidInAdvanceForPeriod());
|
||||
assertEquals(paidLate, period.getTotalPaidLateForPeriod());
|
||||
assertEquals(principalDue, Utils.getDoubleValue(period.getPrincipalDue()));
|
||||
assertEquals(principalPaid, Utils.getDoubleValue(period.getPrincipalPaid()));
|
||||
assertEquals(principalOutstanding, Utils.getDoubleValue(period.getPrincipalOutstanding()));
|
||||
assertEquals(feeDue, Utils.getDoubleValue(period.getFeeChargesDue()));
|
||||
assertEquals(feePaid, Utils.getDoubleValue(period.getFeeChargesPaid()));
|
||||
assertEquals(feeOutstanding, Utils.getDoubleValue(period.getFeeChargesOutstanding()));
|
||||
assertEquals(penaltyDue, Utils.getDoubleValue(period.getPenaltyChargesDue()));
|
||||
assertEquals(penaltyPaid, Utils.getDoubleValue(period.getPenaltyChargesPaid()));
|
||||
assertEquals(penaltyOutstanding, Utils.getDoubleValue(period.getPenaltyChargesOutstanding()));
|
||||
assertEquals(interestDue, Utils.getDoubleValue(period.getInterestDue()));
|
||||
assertEquals(interestPaid, Utils.getDoubleValue(period.getInterestPaid()));
|
||||
assertEquals(interestOutstanding, Utils.getDoubleValue(period.getInterestOutstanding()));
|
||||
assertEquals(paidInAdvance, Utils.getDoubleValue(period.getTotalPaidInAdvanceForPeriod()));
|
||||
assertEquals(paidLate, Utils.getDoubleValue(period.getTotalPaidLateForPeriod()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -410,6 +410,15 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
|
||||
.loanScheduleProcessingType("HORIZONTAL");//
|
||||
}
|
||||
|
||||
protected PostLoanProductsRequest create4IProgressiveWithCapitalizedIncome() {
|
||||
return create4IProgressive().enableIncomeCapitalization(true)//
|
||||
.capitalizedIncomeCalculationType(PostLoanProductsRequest.CapitalizedIncomeCalculationTypeEnum.FLAT)//
|
||||
.capitalizedIncomeStrategy(PostLoanProductsRequest.CapitalizedIncomeStrategyEnum.EQUAL_AMORTIZATION)//
|
||||
.deferredIncomeLiabilityAccountId(deferredIncomeLiabilityAccount.getAccountID().longValue())//
|
||||
.incomeFromCapitalizationAccountId(feeIncomeAccount.getAccountID().longValue())//
|
||||
.capitalizedIncomeType(PostLoanProductsRequest.CapitalizedIncomeTypeEnum.FEE);
|
||||
}
|
||||
|
||||
// Loan product with proper accounting setup
|
||||
protected PostLoanProductsRequest createOnePeriod30DaysPeriodicAccrualProduct(double interestRatePerPeriod) {
|
||||
return new PostLoanProductsRequest().name(Utils.uniqueRandomStringGenerator("LOAN_PRODUCT_", 6))//
|
||||
@@ -615,7 +624,7 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
|
||||
Assertions.assertEquals(transactions.length, loanDetails.getTransactions().size());
|
||||
Arrays.stream(transactions).forEach(tr -> {
|
||||
Optional<GetLoansLoanIdTransactions> optTx = loanDetails.getTransactions().stream()
|
||||
.filter(item -> Objects.equals(item.getAmount(), tr.amount) //
|
||||
.filter(item -> Objects.equals(Utils.getDoubleValue(item.getAmount()), tr.amount) //
|
||||
&& Objects.equals(item.getType().getValue(), tr.type) //
|
||||
&& Objects.equals(item.getDate(), LocalDate.parse(tr.date, dateTimeFormatter)))
|
||||
.findFirst();
|
||||
@@ -638,16 +647,17 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
|
||||
} else {
|
||||
Assertions.assertEquals(transactions.length, loanDetails.getTransactions().size(), "Number of transactions on loan " + loanId);
|
||||
Arrays.stream(transactions).forEach(tr -> {
|
||||
boolean found = loanDetails.getTransactions().stream().anyMatch(item -> Objects.equals(item.getAmount(), tr.amount) //
|
||||
&& Objects.equals(item.getType().getValue(), tr.type) //
|
||||
&& Objects.equals(item.getDate(), LocalDate.parse(tr.date, dateTimeFormatter)) //
|
||||
&& Objects.equals(item.getOutstandingLoanBalance(), tr.outstandingPrincipal) //
|
||||
&& Objects.equals(item.getPrincipalPortion(), tr.principalPortion) //
|
||||
&& Objects.equals(item.getInterestPortion(), tr.interestPortion) //
|
||||
&& Objects.equals(item.getFeeChargesPortion(), tr.feePortion) //
|
||||
&& Objects.equals(item.getPenaltyChargesPortion(), tr.penaltyPortion) //
|
||||
&& Objects.equals(item.getOverpaymentPortion(), tr.overpaymentPortion) //
|
||||
&& Objects.equals(item.getUnrecognizedIncomePortion(), tr.unrecognizedPortion) //
|
||||
boolean found = loanDetails.getTransactions().stream()
|
||||
.anyMatch(item -> Objects.equals(Utils.getDoubleValue(item.getAmount()), tr.amount) //
|
||||
&& Objects.equals(item.getType().getValue(), tr.type) //
|
||||
&& Objects.equals(item.getDate(), LocalDate.parse(tr.date, dateTimeFormatter)) //
|
||||
&& Objects.equals(Utils.getDoubleValue(item.getOutstandingLoanBalance()), tr.outstandingPrincipal) //
|
||||
&& Objects.equals(Utils.getDoubleValue(item.getPrincipalPortion()), tr.principalPortion) //
|
||||
&& Objects.equals(Utils.getDoubleValue(item.getInterestPortion()), tr.interestPortion) //
|
||||
&& Objects.equals(Utils.getDoubleValue(item.getFeeChargesPortion()), tr.feePortion) //
|
||||
&& Objects.equals(Utils.getDoubleValue(item.getPenaltyChargesPortion()), tr.penaltyPortion) //
|
||||
&& Objects.equals(Utils.getDoubleValue(item.getOverpaymentPortion()), tr.overpaymentPortion) //
|
||||
&& Objects.equals(Utils.getDoubleValue(item.getUnrecognizedIncomePortion()), tr.unrecognizedPortion) //
|
||||
);
|
||||
Assertions.assertTrue(found, "Required transaction not found: " + tr + " on loan " + loanId);
|
||||
});
|
||||
@@ -823,8 +833,8 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
|
||||
private void verifyPeriodsEquality(List<GetLoansLoanIdRepaymentPeriod> savedPeriods, List<GetLoansLoanIdRepaymentPeriod> actualPeriods,
|
||||
int startIndex, int endIndex, boolean shouldEqual) {
|
||||
for (int i = startIndex; i < endIndex; i++) {
|
||||
Double savedTotalDue = savedPeriods.get(i).getTotalDueForPeriod();
|
||||
Double actualTotalDue = actualPeriods.get(i).getTotalDueForPeriod();
|
||||
Double savedTotalDue = Utils.getDoubleValue(savedPeriods.get(i).getTotalDueForPeriod());
|
||||
Double actualTotalDue = Utils.getDoubleValue(actualPeriods.get(i).getTotalDueForPeriod());
|
||||
|
||||
if (shouldEqual) {
|
||||
assertEquals(savedTotalDue, actualTotalDue, String.format(
|
||||
@@ -848,19 +858,19 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
|
||||
int installmentNumber = 0;
|
||||
for (int i = 0; i < installments.length; i++) {
|
||||
GetLoansLoanIdRepaymentPeriod period = loanResponse.getRepaymentSchedule().getPeriods().get(i);
|
||||
Double principalDue = period.getPrincipalDue();
|
||||
Double principalDue = Utils.getDoubleValue(period.getPrincipalDue());
|
||||
Double amount = installments[i].principalAmount;
|
||||
|
||||
if (installments[i].completed == null) { // this is for the disbursement
|
||||
Assertions.assertEquals(amount, period.getPrincipalLoanBalanceOutstanding(),
|
||||
Assertions.assertEquals(amount, Utils.getDoubleValue(period.getPrincipalLoanBalanceOutstanding()),
|
||||
"%d. installment's principal due is different, expected: %.2f, actual: %.2f".formatted(i, amount,
|
||||
period.getPrincipalLoanBalanceOutstanding()));
|
||||
Utils.getDoubleValue(period.getPrincipalLoanBalanceOutstanding())));
|
||||
} else {
|
||||
Assertions.assertEquals(amount, principalDue,
|
||||
"%d. installment's principal due is different, expected: %.2f, actual: %.2f".formatted(i, amount, principalDue));
|
||||
|
||||
Double interestAmount = installments[i].interestAmount;
|
||||
Double interestDue = period.getInterestDue();
|
||||
Double interestDue = Utils.getDoubleValue(period.getInterestDue());
|
||||
if (interestAmount != null) {
|
||||
Assertions.assertEquals(interestAmount, interestDue,
|
||||
"%d. installment's interest due is different, expected: %.2f, actual: %.2f".formatted(i, interestAmount,
|
||||
@@ -868,14 +878,14 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
|
||||
}
|
||||
|
||||
Double feeAmount = installments[i].feeAmount;
|
||||
Double feeDue = period.getFeeChargesDue();
|
||||
Double feeDue = Utils.getDoubleValue(period.getFeeChargesDue());
|
||||
if (feeAmount != null) {
|
||||
Assertions.assertEquals(feeAmount, feeDue,
|
||||
"%d. installment's fee charges due is different, expected: %.2f, actual: %.2f".formatted(i, feeAmount, feeDue));
|
||||
}
|
||||
|
||||
Double penaltyAmount = installments[i].penaltyAmount;
|
||||
Double penaltyDue = period.getPenaltyChargesDue();
|
||||
Double penaltyDue = Utils.getDoubleValue(period.getPenaltyChargesDue());
|
||||
if (penaltyAmount != null) {
|
||||
Assertions.assertEquals(penaltyAmount, penaltyDue,
|
||||
"%d. installment's penalty charges due is different, expected: %.2f, actual: %.2f".formatted(i, penaltyAmount,
|
||||
@@ -883,7 +893,7 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
|
||||
}
|
||||
|
||||
Double outstandingAmount = installments[i].totalOutstandingAmount;
|
||||
Double totalOutstanding = period.getTotalOutstandingForPeriod();
|
||||
Double totalOutstanding = Utils.getDoubleValue(period.getTotalOutstandingForPeriod());
|
||||
if (outstandingAmount != null) {
|
||||
Assertions.assertEquals(outstandingAmount, totalOutstanding,
|
||||
"%d. installment's total outstanding is different, expected: %.2f, actual: %.2f".formatted(i, outstandingAmount,
|
||||
@@ -893,7 +903,7 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
|
||||
Double outstandingPrincipalExpected = installments[i].outstandingAmounts != null
|
||||
? installments[i].outstandingAmounts.principalOutstanding
|
||||
: null;
|
||||
Double outstandingPrincipal = period.getPrincipalOutstanding();
|
||||
Double outstandingPrincipal = Utils.getDoubleValue(period.getPrincipalOutstanding());
|
||||
if (outstandingPrincipalExpected != null) {
|
||||
Assertions.assertEquals(outstandingPrincipalExpected, outstandingPrincipal,
|
||||
"%d. installment's outstanding principal is different, expected: %.2f, actual: %.2f".formatted(i,
|
||||
@@ -903,7 +913,7 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
|
||||
Double outstandingFeeExpected = installments[i].outstandingAmounts != null
|
||||
? installments[i].outstandingAmounts.feeOutstanding
|
||||
: null;
|
||||
Double outstandingFee = period.getFeeChargesOutstanding();
|
||||
Double outstandingFee = Utils.getDoubleValue(period.getFeeChargesOutstanding());
|
||||
if (outstandingFeeExpected != null) {
|
||||
Assertions.assertEquals(outstandingFeeExpected, outstandingFee,
|
||||
"%d. installment's outstanding fee is different, expected: %.2f, actual: %.2f".formatted(i,
|
||||
@@ -913,7 +923,7 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
|
||||
Double outstandingPenaltyExpected = installments[i].outstandingAmounts != null
|
||||
? installments[i].outstandingAmounts.penaltyOutstanding
|
||||
: null;
|
||||
Double outstandingPenalty = period.getPenaltyChargesOutstanding();
|
||||
Double outstandingPenalty = Utils.getDoubleValue(period.getPenaltyChargesOutstanding());
|
||||
if (outstandingPenaltyExpected != null) {
|
||||
Assertions.assertEquals(outstandingPenaltyExpected, outstandingPenalty,
|
||||
"%d. installment's outstanding penalty is different, expected: %.2f, actual: %.2f".formatted(i,
|
||||
@@ -923,7 +933,7 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
|
||||
Double outstandingTotalExpected = installments[i].outstandingAmounts != null
|
||||
? installments[i].outstandingAmounts.totalOutstanding
|
||||
: null;
|
||||
Double outstandingTotal = period.getTotalOutstandingForPeriod();
|
||||
Double outstandingTotal = Utils.getDoubleValue(period.getTotalOutstandingForPeriod());
|
||||
if (outstandingTotalExpected != null) {
|
||||
Assertions.assertEquals(outstandingTotalExpected, outstandingTotal,
|
||||
"%d. installment's total outstanding is different, expected: %.2f, actual: %.2f".formatted(i,
|
||||
@@ -931,7 +941,7 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
|
||||
}
|
||||
|
||||
Double loanBalanceExpected = installments[i].loanBalance;
|
||||
Double loanBalance = period.getPrincipalLoanBalanceOutstanding();
|
||||
Double loanBalance = Utils.getDoubleValue(period.getPrincipalLoanBalanceOutstanding());
|
||||
if (loanBalanceExpected != null) {
|
||||
Assertions.assertEquals(loanBalanceExpected, loanBalance,
|
||||
"%d. installment's loan balance is different, expected: %.2f, actual: %.2f".formatted(i, loanBalanceExpected,
|
||||
@@ -1226,11 +1236,11 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
|
||||
|
||||
protected void validateLoanSummaryBalances(GetLoansLoanIdResponse loanDetails, Double totalOutstanding, Double totalRepayment,
|
||||
Double principalOutstanding, Double principalPaid, Double totalOverpaid) {
|
||||
assertEquals(totalOutstanding, loanDetails.getSummary().getTotalOutstanding());
|
||||
assertEquals(totalRepayment, loanDetails.getSummary().getTotalRepayment());
|
||||
assertEquals(principalOutstanding, loanDetails.getSummary().getPrincipalOutstanding());
|
||||
assertEquals(principalPaid, loanDetails.getSummary().getPrincipalPaid());
|
||||
assertEquals(totalOverpaid, loanDetails.getTotalOverpaid());
|
||||
assertEquals(totalOutstanding, Utils.getDoubleValue(loanDetails.getSummary().getTotalOutstanding()));
|
||||
assertEquals(totalRepayment, Utils.getDoubleValue(loanDetails.getSummary().getTotalRepayment()));
|
||||
assertEquals(principalOutstanding, Utils.getDoubleValue(loanDetails.getSummary().getPrincipalOutstanding()));
|
||||
assertEquals(principalPaid, Utils.getDoubleValue(loanDetails.getSummary().getPrincipalPaid()));
|
||||
assertEquals(totalOverpaid, Utils.getDoubleValue(loanDetails.getTotalOverpaid()));
|
||||
}
|
||||
|
||||
protected void checkMaturityDates(long loanId, LocalDate expectedMaturityDate, LocalDate actualMaturityDate) {
|
||||
|
||||
+3
-1
@@ -38,6 +38,7 @@ import org.apache.fineract.client.models.PutLoansLoanIdResponse;
|
||||
import org.apache.fineract.client.util.CallFailedRuntimeException;
|
||||
import org.apache.fineract.integrationtests.common.ClientHelper;
|
||||
import org.apache.fineract.integrationtests.common.SchedulerJobHelper;
|
||||
import org.apache.fineract.integrationtests.common.Utils;
|
||||
import org.apache.fineract.integrationtests.common.products.DelinquencyBucketsHelper;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -619,7 +620,8 @@ public class InstallmentLevelDelinquencyAPIIntegrationTests extends BaseLoanInte
|
||||
.getInstallmentLevelDelinquency();
|
||||
|
||||
assertThat(loan.getDelinquent().getDelinquentDays()).isEqualTo(loanLevelDelinquentDays);
|
||||
assertThat(loan.getDelinquent().getDelinquentAmount()).isEqualByComparingTo(Double.valueOf(loanLevelDelinquentAmount));
|
||||
assertThat(Utils.getDoubleValue(loan.getDelinquent().getDelinquentAmount()))
|
||||
.isEqualByComparingTo(Double.valueOf(loanLevelDelinquentAmount));
|
||||
|
||||
if (expectedInstallmentLevelDelinquencyData != null && expectedInstallmentLevelDelinquencyData.length > 0) {
|
||||
assertThat(installmentLevelDelinquency).isNotNull();
|
||||
|
||||
+15
-12
@@ -33,6 +33,7 @@ import org.apache.fineract.client.models.PostClientsResponse;
|
||||
import org.apache.fineract.client.models.PostLoanProductsResponse;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest;
|
||||
import org.apache.fineract.integrationtests.common.ClientHelper;
|
||||
import org.apache.fineract.integrationtests.common.Utils;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -468,8 +469,9 @@ public class LoanCOBCreateAccrualsTest extends BaseLoanIntegrationTest {
|
||||
GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
|
||||
|
||||
// No unexpected big accruals or any accrual adjustments
|
||||
Assertions.assertTrue(loanDetails.getTransactions().stream().noneMatch(t -> (t.getType().getAccrual() && t.getAmount() > 0.31)
|
||||
|| "loanTransactionType.accrualAdjustment".equals(t.getType().getCode())));
|
||||
Assertions.assertTrue(
|
||||
loanDetails.getTransactions().stream().noneMatch(t -> (t.getType().getAccrual() && t.getAmount().doubleValue() > 0.31)
|
||||
|| "loanTransactionType.accrualAdjustment".equals(t.getType().getCode())));
|
||||
|
||||
// Accruals around installment due dates are as expected
|
||||
validateTransactionsExist(loanDetails, //
|
||||
@@ -691,16 +693,17 @@ public class LoanCOBCreateAccrualsTest extends BaseLoanIntegrationTest {
|
||||
|
||||
private void validateTransactionsExist(GetLoansLoanIdResponse loanDetails, TransactionExt... transactions) {
|
||||
Arrays.stream(transactions).forEach(tr -> {
|
||||
boolean found = loanDetails.getTransactions().stream().anyMatch(item -> Objects.equals(item.getAmount(), tr.amount) //
|
||||
&& Objects.equals(item.getType().getValue(), tr.type) //
|
||||
&& Objects.equals(item.getDate(), LocalDate.parse(tr.date, dateTimeFormatter)) //
|
||||
&& Objects.equals(item.getOutstandingLoanBalance(), tr.outstandingPrincipal) //
|
||||
&& Objects.equals(item.getPrincipalPortion(), tr.principalPortion) //
|
||||
&& Objects.equals(item.getInterestPortion(), tr.interestPortion) //
|
||||
&& Objects.equals(item.getFeeChargesPortion(), tr.feePortion) //
|
||||
&& Objects.equals(item.getPenaltyChargesPortion(), tr.penaltyPortion) //
|
||||
&& Objects.equals(item.getOverpaymentPortion(), tr.overpaymentPortion) //
|
||||
&& Objects.equals(item.getUnrecognizedIncomePortion(), tr.unrecognizedPortion) //
|
||||
boolean found = loanDetails.getTransactions().stream()
|
||||
.anyMatch(item -> Objects.equals(Utils.getDoubleValue(item.getAmount()), tr.amount) //
|
||||
&& Objects.equals(item.getType().getValue(), tr.type) //
|
||||
&& Objects.equals(item.getDate(), LocalDate.parse(tr.date, dateTimeFormatter)) //
|
||||
&& Objects.equals(Utils.getDoubleValue(item.getOutstandingLoanBalance()), tr.outstandingPrincipal) //
|
||||
&& Objects.equals(Utils.getDoubleValue(item.getPrincipalPortion()), tr.principalPortion) //
|
||||
&& Objects.equals(Utils.getDoubleValue(item.getInterestPortion()), tr.interestPortion) //
|
||||
&& Objects.equals(Utils.getDoubleValue(item.getFeeChargesPortion()), tr.feePortion) //
|
||||
&& Objects.equals(Utils.getDoubleValue(item.getPenaltyChargesPortion()), tr.penaltyPortion) //
|
||||
&& Objects.equals(Utils.getDoubleValue(item.getOverpaymentPortion()), tr.overpaymentPortion) //
|
||||
&& Objects.equals(Utils.getDoubleValue(item.getUnrecognizedIncomePortion()), tr.unrecognizedPortion) //
|
||||
);
|
||||
Assertions.assertTrue(found, "Required transaction not found: " + tr + " on loan " + loanDetails.getId());
|
||||
});
|
||||
|
||||
+3
-3
@@ -78,7 +78,7 @@ public class LoanCapitalizedIncomeTest extends BaseLoanIntegrationTest {
|
||||
transaction(100.0, "Disbursement", "01 January 2024"), //
|
||||
transaction(50.0, "Capitalized Income", "01 January 2024"), //
|
||||
transaction(0.55, "Capitalized Income Amortization", "01 January 2024"), //
|
||||
transaction(0.02, "Accrual", "02 January 2024"), //
|
||||
transaction(0.03, "Accrual", "02 January 2024"), //
|
||||
transaction(0.55, "Capitalized Income Amortization", "02 January 2024") //
|
||||
);
|
||||
|
||||
@@ -89,8 +89,8 @@ public class LoanCapitalizedIncomeTest extends BaseLoanIntegrationTest {
|
||||
journalEntry(50, deferredIncomeLiabilityAccount, "CREDIT"), //
|
||||
journalEntry(0.55, deferredIncomeLiabilityAccount, "DEBIT"), //
|
||||
journalEntry(0.55, feeIncomeAccount, "CREDIT"), //
|
||||
journalEntry(0.02, interestReceivableAccount, "DEBIT"), //
|
||||
journalEntry(0.02, interestIncomeAccount, "CREDIT"), //
|
||||
journalEntry(0.03, interestReceivableAccount, "DEBIT"), //
|
||||
journalEntry(0.03, interestIncomeAccount, "CREDIT"), //
|
||||
journalEntry(0.55, deferredIncomeLiabilityAccount, "DEBIT"), //
|
||||
journalEntry(0.55, feeIncomeAccount, "CREDIT") //
|
||||
);
|
||||
|
||||
+4
-3
@@ -27,6 +27,7 @@ import org.apache.fineract.client.models.PostLoanProductsResponse;
|
||||
import org.apache.fineract.client.models.PostLoansResponse;
|
||||
import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants;
|
||||
import org.apache.fineract.integrationtests.common.ClientHelper;
|
||||
import org.apache.fineract.integrationtests.common.Utils;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -78,8 +79,8 @@ public class LoanChargeProgressiveTest extends BaseLoanIntegrationTest {
|
||||
final PostChargesResponse chargeResponse = createCharge(20.0d, "EUR");
|
||||
addLoanCharge(loanId, chargeResponse.getResourceId(), "03 October 2024", 20.0d);
|
||||
final GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
|
||||
Assertions.assertTrue(
|
||||
loanDetails.getTransactions().stream().anyMatch(t -> t.getType().getAccrual() && t.getAmount().equals(20.0d)));
|
||||
Assertions.assertTrue(loanDetails.getTransactions().stream()
|
||||
.anyMatch(t -> t.getType().getAccrual() && Utils.getDoubleValue(t.getAmount()).equals(20.0d)));
|
||||
});
|
||||
runAt("04 October 2024", () -> {
|
||||
globalConfigurationHelper.manageConfigurations(GlobalConfigurationConstants.ENABLE_IMMEDIATE_CHARGE_ACCRUAL_POST_MATURITY,
|
||||
@@ -87,7 +88,7 @@ public class LoanChargeProgressiveTest extends BaseLoanIntegrationTest {
|
||||
executeInlineCOB(loanId);
|
||||
final GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
|
||||
Assertions.assertTrue(loanDetails.getTransactions().stream()
|
||||
.anyMatch(t -> t.getType().getAccrual() && t.getFeeChargesPortion().equals(20.0d)));
|
||||
.anyMatch(t -> t.getType().getAccrual() && Utils.getDoubleValue(t.getFeeChargesPortion()).equals(20.0d)));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+5
-2
@@ -28,6 +28,7 @@ import org.apache.fineract.client.models.PostLoanProductsRequest;
|
||||
import org.apache.fineract.client.models.PostLoanProductsResponse;
|
||||
import org.apache.fineract.integrationtests.common.ClientHelper;
|
||||
import org.apache.fineract.integrationtests.common.SchedulerJobHelper;
|
||||
import org.apache.fineract.integrationtests.common.Utils;
|
||||
import org.apache.fineract.integrationtests.common.products.DelinquencyBucketsHelper;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -231,12 +232,14 @@ public class LoanDelinquencyForNonActiveAccountsTest extends BaseLoanIntegration
|
||||
.getInstallmentLevelDelinquency();
|
||||
|
||||
assertThat(loan.getDelinquent().getDelinquentDays()).isEqualTo(loanLevelDelinquentDays);
|
||||
assertThat(loan.getDelinquent().getDelinquentAmount()).isEqualByComparingTo(Double.valueOf(loanLevelDelinquentAmount));
|
||||
assertThat(Utils.getDoubleValue(loan.getDelinquent().getDelinquentAmount()))
|
||||
.isEqualByComparingTo(Double.valueOf(loanLevelDelinquentAmount));
|
||||
if (expectedLastRepaymentDate != null && expectedLastRepaymentAmount != null) {
|
||||
assertThat(loan.getDelinquent().getLastRepaymentDate()).isNotNull();
|
||||
Assertions.assertEquals(expectedLastRepaymentDate, loan.getDelinquent().getLastRepaymentDate().format(dateTimeFormatter));
|
||||
assertThat(loan.getDelinquent().getLastRepaymentAmount()).isNotNull();
|
||||
assertThat(loan.getDelinquent().getLastRepaymentAmount()).isEqualByComparingTo(Double.valueOf(expectedLastRepaymentAmount));
|
||||
assertThat(Utils.getDoubleValue(loan.getDelinquent().getLastRepaymentAmount()))
|
||||
.isEqualByComparingTo(Double.valueOf(expectedLastRepaymentAmount));
|
||||
}
|
||||
|
||||
if (expectedInstallmentLevelDelinquencyData != null && expectedInstallmentLevelDelinquencyData.length > 0) {
|
||||
|
||||
+7
-6
@@ -314,7 +314,7 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
getLoansLoanIdResponse = this.loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
|
||||
assertNotNull(getLoansLoanIdResponse);
|
||||
this.loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
|
||||
final Double limit = 2.0;
|
||||
final BigDecimal limit = BigDecimal.TWO;
|
||||
evaluateEqualInstallmentsForRepaymentSchedule(getLoansLoanIdResponse.getRepaymentSchedule(), limit);
|
||||
log.info("-----------MULTI DISBURSAL LOAN EQUAL INSTALLMENTS SUCCESSFULLY-------");
|
||||
}
|
||||
@@ -665,9 +665,9 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
return collateral;
|
||||
}
|
||||
|
||||
public void evaluateEqualInstallmentsForRepaymentSchedule(GetLoansLoanIdRepaymentSchedule getLoanRepaymentSchedule, Double limit) {
|
||||
Double totalOutstandingForPeriod = 0.0;
|
||||
Double totalInstallmentAmountForPeriod = 0.0;
|
||||
public void evaluateEqualInstallmentsForRepaymentSchedule(GetLoansLoanIdRepaymentSchedule getLoanRepaymentSchedule, BigDecimal limit) {
|
||||
BigDecimal totalOutstandingForPeriod = BigDecimal.ZERO;
|
||||
BigDecimal totalInstallmentAmountForPeriod = BigDecimal.ZERO;
|
||||
if (getLoanRepaymentSchedule != null) {
|
||||
log.info("Loan with {} periods", getLoanRepaymentSchedule.getPeriods().size());
|
||||
for (GetLoansLoanIdRepaymentPeriod period : getLoanRepaymentSchedule.getPeriods()) {
|
||||
@@ -678,8 +678,9 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
totalOutstandingForPeriod = period.getTotalOutstandingForPeriod();
|
||||
totalInstallmentAmountForPeriod = period.getTotalInstallmentAmountForPeriod();
|
||||
} else {
|
||||
assertTrue(Math.abs(period.getTotalOutstandingForPeriod() - totalOutstandingForPeriod) <= limit);
|
||||
assertTrue(Math.abs(period.getTotalInstallmentAmountForPeriod() - totalInstallmentAmountForPeriod) <= limit);
|
||||
assertTrue(period.getTotalOutstandingForPeriod().subtract(totalOutstandingForPeriod).abs().compareTo(limit) <= 0);
|
||||
assertTrue(period.getTotalInstallmentAmountForPeriod().subtract(totalInstallmentAmountForPeriod).abs()
|
||||
.compareTo(limit) <= 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -149,7 +149,7 @@ public class LoanRefundTransactionTest extends BaseLoanIntegrationTest {
|
||||
GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
|
||||
Assertions.assertTrue(loanDetails.getTransactions().stream()
|
||||
.filter(transaction -> transaction.getType().getCode().equals("loanTransactionType.interestRefund"))
|
||||
.allMatch(transaction -> transaction.getAmount().compareTo(0.0) > 0));
|
||||
.allMatch(transaction -> transaction.getAmount().doubleValue() > 0.0));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+36
-34
@@ -110,9 +110,9 @@ public class LoanRepaymentScheduleWithDownPaymentTest extends BaseLoanIntegratio
|
||||
LocalDate expectedRepaymentDueDate = LocalDate.of(2022, 10, 3);
|
||||
|
||||
assertTrue(periods.stream() //
|
||||
.anyMatch(period -> expectedDownPaymentAmount.equals(period.getTotalDueForPeriod()) //
|
||||
.anyMatch(period -> expectedDownPaymentAmount.equals(Utils.getDoubleValue(period.getTotalDueForPeriod())) //
|
||||
&& expectedDownPaymentDueDate.equals(period.getDueDate())));
|
||||
assertTrue(periods.stream().anyMatch(period -> expectedRepaymentAmount.equals(period.getTotalDueForPeriod())
|
||||
assertTrue(periods.stream().anyMatch(period -> expectedRepaymentAmount.equals(Utils.getDoubleValue(period.getTotalDueForPeriod()))
|
||||
&& expectedRepaymentDueDate.equals(period.getDueDate())));
|
||||
}
|
||||
|
||||
@@ -157,11 +157,11 @@ public class LoanRepaymentScheduleWithDownPaymentTest extends BaseLoanIntegratio
|
||||
LocalDate expectedRepaymentDueDate = LocalDate.of(2022, 10, 3);
|
||||
|
||||
assertTrue(periods.stream() //
|
||||
.anyMatch(period -> expectedDownPaymentAmount.equals(period.getTotalPaidForPeriod()) //
|
||||
.anyMatch(period -> expectedDownPaymentAmount.equals(Utils.getDoubleValue(period.getTotalPaidForPeriod())) //
|
||||
&& expectedDownPaymentDueDate.equals(period.getDueDate())));
|
||||
assertEquals(expectedRepaymentAmount, summary.getTotalOutstanding());
|
||||
assertEquals(expectedRepaymentAmount, Utils.getDoubleValue(summary.getTotalOutstanding()));
|
||||
assertEquals(expectedDownPaymentAmount, summary.getTotalRepaymentTransaction());
|
||||
assertTrue(periods.stream().anyMatch(period -> expectedRepaymentAmount.equals(period.getTotalDueForPeriod())
|
||||
assertTrue(periods.stream().anyMatch(period -> expectedRepaymentAmount.equals(Utils.getDoubleValue(period.getTotalDueForPeriod()))
|
||||
&& expectedRepaymentDueDate.equals(period.getDueDate())));
|
||||
}
|
||||
|
||||
@@ -205,9 +205,9 @@ public class LoanRepaymentScheduleWithDownPaymentTest extends BaseLoanIntegratio
|
||||
LocalDate expectedRepaymentDueDate = LocalDate.of(2022, 10, 3);
|
||||
|
||||
assertTrue(periods.stream() //
|
||||
.anyMatch(period -> expectedDownPaymentAmount.equals(period.getTotalDueForPeriod()) //
|
||||
.anyMatch(period -> expectedDownPaymentAmount.equals(Utils.getDoubleValue(period.getTotalDueForPeriod())) //
|
||||
&& expectedDownPaymentDueDate.equals(period.getDueDate())));
|
||||
assertTrue(periods.stream().anyMatch(period -> expectedRepaymentAmount.equals(period.getTotalDueForPeriod())
|
||||
assertTrue(periods.stream().anyMatch(period -> expectedRepaymentAmount.equals(Utils.getDoubleValue(period.getTotalDueForPeriod()))
|
||||
&& expectedRepaymentDueDate.equals(period.getDueDate())));
|
||||
}
|
||||
|
||||
@@ -253,12 +253,12 @@ public class LoanRepaymentScheduleWithDownPaymentTest extends BaseLoanIntegratio
|
||||
LocalDate expectedRepaymentDueDate = LocalDate.of(2022, 10, 3);
|
||||
|
||||
assertTrue(periods.stream() //
|
||||
.anyMatch(period -> expectedFirstDownPaymentAmount.equals(period.getTotalDueForPeriod()) //
|
||||
.anyMatch(period -> expectedFirstDownPaymentAmount.equals(Utils.getDoubleValue(period.getTotalDueForPeriod())) //
|
||||
&& expectedFirstDownPaymentDueDate.equals(period.getDueDate())));
|
||||
assertTrue(periods.stream() //
|
||||
.anyMatch(period -> expectedSecondDownPaymentAmount.equals(period.getTotalDueForPeriod())
|
||||
.anyMatch(period -> expectedSecondDownPaymentAmount.equals(Utils.getDoubleValue(period.getTotalDueForPeriod()))
|
||||
&& expectedSecondDownPaymentDueDate.equals(period.getDueDate())));
|
||||
assertTrue(periods.stream().anyMatch(period -> expectedRepaymentAmount.equals(period.getTotalDueForPeriod())
|
||||
assertTrue(periods.stream().anyMatch(period -> expectedRepaymentAmount.equals(Utils.getDoubleValue(period.getTotalDueForPeriod()))
|
||||
&& expectedRepaymentDueDate.equals(period.getDueDate())));
|
||||
}
|
||||
|
||||
@@ -306,15 +306,15 @@ public class LoanRepaymentScheduleWithDownPaymentTest extends BaseLoanIntegratio
|
||||
Double expectedTotalRepaymentAmount = expectedFirstDownPaymentAmount + expectedSecondDownPaymentAmount;
|
||||
|
||||
assertTrue(periods.stream() //
|
||||
.anyMatch(period -> expectedFirstDownPaymentAmount.equals(period.getTotalPaidForPeriod()) //
|
||||
.anyMatch(period -> expectedFirstDownPaymentAmount.equals(Utils.getDoubleValue(period.getTotalPaidForPeriod())) //
|
||||
&& expectedFirstDownPaymentDueDate.equals(period.getDueDate())));
|
||||
assertTrue(periods.stream() //
|
||||
.anyMatch(period -> expectedSecondDownPaymentAmount.equals(period.getTotalPaidForPeriod())
|
||||
.anyMatch(period -> expectedSecondDownPaymentAmount.equals(Utils.getDoubleValue(period.getTotalPaidForPeriod()))
|
||||
&& expectedSecondDownPaymentDueDate.equals(period.getDueDate())));
|
||||
assertTrue(periods.stream().anyMatch(period -> expectedRepaymentAmount.equals(period.getTotalDueForPeriod())
|
||||
assertTrue(periods.stream().anyMatch(period -> expectedRepaymentAmount.equals(Utils.getDoubleValue(period.getTotalDueForPeriod()))
|
||||
&& expectedRepaymentDueDate.equals(period.getDueDate())));
|
||||
assertEquals(expectedRepaymentAmount, summary.getTotalOutstanding());
|
||||
assertEquals(expectedTotalRepaymentAmount, summary.getTotalRepaymentTransaction());
|
||||
assertEquals(expectedRepaymentAmount, Utils.getDoubleValue(summary.getTotalOutstanding()));
|
||||
assertEquals(expectedTotalRepaymentAmount, Utils.getDoubleValue(summary.getTotalRepaymentTransaction()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -529,14 +529,14 @@ public class LoanRepaymentScheduleWithDownPaymentTest extends BaseLoanIntegratio
|
||||
LocalDate expectedRepaymentDueDate = LocalDate.of(2022, 10, 3);
|
||||
|
||||
assertTrue(periods.stream() //
|
||||
.anyMatch(period -> expectedDownPaymentAmount.equals(period.getTotalDueForPeriod()) //
|
||||
.anyMatch(period -> expectedDownPaymentAmount.equals(Utils.getDoubleValue(period.getTotalDueForPeriod())) //
|
||||
&& expectedDownPaymentDueDate.equals(period.getDueDate()) //
|
||||
&& Double.valueOf(0.00).equals(period.getFeeChargesDue())));
|
||||
&& Double.valueOf(0.00).equals(Utils.getDoubleValue(period.getFeeChargesDue()))));
|
||||
assertTrue(periods.stream() //
|
||||
.anyMatch(period -> expectedTotalDueForRepaymentInstallment.equals(period.getTotalDueForPeriod()) //
|
||||
&& expectedRepaymentAmount.equals(period.getPrincipalDue()) //
|
||||
.anyMatch(period -> expectedTotalDueForRepaymentInstallment.equals(Utils.getDoubleValue(period.getTotalDueForPeriod())) //
|
||||
&& expectedRepaymentAmount.equals(Utils.getDoubleValue(period.getPrincipalDue())) //
|
||||
&& expectedRepaymentDueDate.equals(period.getDueDate()) //
|
||||
&& feeAmount.equals(period.getFeeChargesDue())));
|
||||
&& feeAmount.equals(Utils.getDoubleValue(period.getFeeChargesDue()))));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -694,16 +694,16 @@ public class LoanRepaymentScheduleWithDownPaymentTest extends BaseLoanIntegratio
|
||||
LocalDate expectedRepaymentDueDate = LocalDate.of(2022, 10, 3);
|
||||
|
||||
assertTrue(periods.stream() //
|
||||
.anyMatch(period -> expectedDownPaymentAmount.equals(period.getTotalDueForPeriod()) //
|
||||
.anyMatch(period -> expectedDownPaymentAmount.equals(Utils.getDoubleValue(period.getTotalDueForPeriod())) //
|
||||
&& expectedDownPaymentDueDate.equals(period.getDueDate()) //
|
||||
&& Double.valueOf(0.00).equals(period.getFeeChargesDue()) //
|
||||
&& Double.valueOf(0.00).equals(period.getInterestDue())));
|
||||
&& Double.valueOf(0.00).equals(Utils.getDoubleValue(period.getFeeChargesDue())) //
|
||||
&& Double.valueOf(0.00).equals(Utils.getDoubleValue(period.getInterestDue()))));
|
||||
assertTrue(periods.stream() //
|
||||
.anyMatch(period -> expectedTotalDueForRepaymentInstallment.equals(period.getTotalDueForPeriod()) //
|
||||
&& expectedRepaymentAmount.equals(period.getPrincipalDue()) //
|
||||
.anyMatch(period -> expectedTotalDueForRepaymentInstallment.equals(Utils.getDoubleValue(period.getTotalDueForPeriod())) //
|
||||
&& expectedRepaymentAmount.equals(Utils.getDoubleValue(period.getPrincipalDue())) //
|
||||
&& expectedRepaymentDueDate.equals(period.getDueDate()) //
|
||||
&& feeAmount.equals(period.getFeeChargesDue()) //
|
||||
&& Double.valueOf(10.0).equals(period.getInterestDue())));
|
||||
&& feeAmount.equals(Utils.getDoubleValue(period.getFeeChargesDue())) //
|
||||
&& Double.valueOf(10.0).equals(Utils.getDoubleValue(period.getInterestDue()))));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -864,10 +864,11 @@ public class LoanRepaymentScheduleWithDownPaymentTest extends BaseLoanIntegratio
|
||||
LocalDate expectedRepaymentDueDate = LocalDate.of(2022, 10, 3);
|
||||
|
||||
assertTrue(periods.stream() //
|
||||
.anyMatch(period -> expectedDownPaymentAmount.equals(period.getTotalDueForPeriod()) //
|
||||
.anyMatch(period -> expectedDownPaymentAmount.equals(Utils.getDoubleValue(period.getTotalDueForPeriod())) //
|
||||
&& expectedDownPaymentDueDate.equals(period.getDueDate())));
|
||||
assertTrue(periods.stream().anyMatch(period -> expectedRepaymentAmount.equals(period.getTotalDueForPeriod())
|
||||
&& expectedRepaymentDueDate.equals(period.getDueDate())));
|
||||
assertTrue(
|
||||
periods.stream().anyMatch(period -> expectedRepaymentAmount.equals(Utils.getDoubleValue(period.getTotalDueForPeriod()))
|
||||
&& expectedRepaymentDueDate.equals(period.getDueDate())));
|
||||
assertNotNull(loanDetails.getDelinquencyRange());
|
||||
assertEquals(2, loanDetails.getDelinquent().getDelinquentDays());
|
||||
} finally {
|
||||
@@ -1662,12 +1663,13 @@ public class LoanRepaymentScheduleWithDownPaymentTest extends BaseLoanIntegratio
|
||||
Double expectedTotalRepaymentTransactionAmount = 0.00;
|
||||
|
||||
assertTrue(periods.stream() //
|
||||
.anyMatch(period -> expectedDownPaymentAmount.equals(period.getTotalOutstandingForPeriod()) //
|
||||
.anyMatch(period -> expectedDownPaymentAmount.equals(Utils.getDoubleValue(period.getTotalOutstandingForPeriod())) //
|
||||
&& expectedDownPaymentDueDate.equals(period.getDueDate())));
|
||||
assertEquals(expectedTotalOutstandingAmount, summary.getTotalOutstanding());
|
||||
assertEquals(expectedTotalOutstandingAmount, Utils.getDoubleValue(summary.getTotalOutstanding()));
|
||||
assertEquals(expectedTotalRepaymentTransactionAmount, summary.getTotalRepaymentTransaction());
|
||||
assertTrue(periods.stream().anyMatch(period -> expectedRepaymentAmount.equals(period.getTotalOutstandingForPeriod())
|
||||
&& expectedRepaymentDueDate.equals(period.getDueDate())));
|
||||
assertTrue(periods.stream()
|
||||
.anyMatch(period -> expectedRepaymentAmount.equals(Utils.getDoubleValue(period.getTotalOutstandingForPeriod()))
|
||||
&& expectedRepaymentDueDate.equals(period.getDueDate())));
|
||||
}
|
||||
|
||||
private void checkNoDownPaymentTransaction(final Integer loanID) {
|
||||
|
||||
+36
@@ -19,7 +19,9 @@
|
||||
package org.apache.fineract.integrationtests;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.List;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentPeriod;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
|
||||
import org.apache.fineract.client.models.PostLoanProductsResponse;
|
||||
import org.apache.fineract.client.models.PostLoansResponse;
|
||||
@@ -248,4 +250,38 @@ public class LoanSummaryTest extends BaseLoanIntegrationTest {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCapitalizedIncomeExistsInRepaymentScheduleAndModifiesPrincipal() {
|
||||
runAt("01 March 2023", () -> {
|
||||
final PostLoanProductsResponse loanProductsResponse = loanProductHelper
|
||||
.createLoanProduct(create4IProgressiveWithCapitalizedIncome());
|
||||
PostLoansResponse postLoansResponse = loanTransactionHelper.applyLoan(applyLP2ProgressiveLoanRequest(clientId,
|
||||
loanProductsResponse.getResourceId(), "01 March 2023", 10000.00, 12.00, 4, null));
|
||||
loanId = postLoansResponse.getLoanId();
|
||||
loanTransactionHelper.approveLoan(loanId, approveLoanRequest(10000.00, "01 March 2023"));
|
||||
disburseLoan(loanId, BigDecimal.valueOf(1000.00), "01 March 2023");
|
||||
});
|
||||
runAt("02 March 2023", () -> {
|
||||
loanTransactionHelper.addCapitalizedIncome(loanId, "02 March 2023", 100.00);
|
||||
});
|
||||
|
||||
BigDecimal thousand = BigDecimal.valueOf(1000.0);
|
||||
BigDecimal hundred = BigDecimal.valueOf(100.0);
|
||||
BigDecimal thousandOneHundred = BigDecimal.valueOf(1100.0);
|
||||
|
||||
GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
|
||||
|
||||
Assertions.assertEquals(thousand, loanDetails.getPrincipal().setScale(1, RoundingMode.HALF_UP));
|
||||
Assertions.assertEquals(thousand, loanDetails.getSummary().getPrincipalDisbursed().setScale(1, RoundingMode.HALF_UP));
|
||||
Assertions.assertEquals(hundred,
|
||||
loanDetails.getSummary().getTotalPrincipalFromCapitalizedIncome().setScale(1, RoundingMode.HALF_UP));
|
||||
Assertions.assertEquals(thousandOneHundred, loanDetails.getSummary().getTotalPrincipal().setScale(1, RoundingMode.HALF_UP));
|
||||
Assertions.assertEquals(thousandOneHundred, loanDetails.getSummary().getPrincipalOutstanding().setScale(1, RoundingMode.HALF_UP));
|
||||
|
||||
List<GetLoansLoanIdRepaymentPeriod> periods = loanDetails.getRepaymentSchedule().getPeriods();
|
||||
Assertions.assertEquals(6, periods.size());
|
||||
Assertions.assertEquals(thousand, periods.get(0).getPrincipalLoanBalanceOutstanding().setScale(1, RoundingMode.HALF_UP));
|
||||
Assertions.assertEquals(hundred, periods.get(1).getPrincipalLoanBalanceOutstanding().setScale(1, RoundingMode.HALF_UP));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -46,8 +46,8 @@ public class ProgressiveLoanTrancheTest extends BaseLoanIntegrationTest {
|
||||
|
||||
runAt("20 December 2024", () -> {
|
||||
Long loanId = applyAndApproveProgressiveLoan(client.getClientId(), loanProductsResponse.getResourceId(), "20 December 2024",
|
||||
500.0, 7.0, 6, (request) -> request.disbursementData(
|
||||
List.of(new PostLoansDisbursementData().expectedDisbursementDate("20 December 2024").principal(100.0))));
|
||||
500.0, 7.0, 6, (request) -> request.disbursementData(List.of(new PostLoansDisbursementData()
|
||||
.expectedDisbursementDate("20 December 2024").principal(BigDecimal.valueOf(100.0)))));
|
||||
|
||||
loanIdRef.set(loanId);
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@ import io.restassured.response.Response;
|
||||
import io.restassured.specification.RequestSpecification;
|
||||
import io.restassured.specification.ResponseSpecification;
|
||||
import java.io.File;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.security.SecureRandom;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
@@ -569,4 +571,8 @@ public final class Utils {
|
||||
public static long getDifferenceInMonths(final LocalDate localDateBefore, final LocalDate localDateAfter) {
|
||||
return MONTHS.between(localDateBefore, localDateAfter);
|
||||
}
|
||||
|
||||
public static Double getDoubleValue(BigDecimal amount) {
|
||||
return amount == null ? null : amount.setScale(2, RoundingMode.HALF_UP).doubleValue();
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -2688,7 +2688,7 @@ public class LoanTransactionHelper {
|
||||
log.info(" Id {} code {} date {} amount {}", transaction.getId(), transaction.getType().getCode(), transaction.getDate(),
|
||||
transaction.getAmount());
|
||||
if (transactionType.equals(transaction.getType().getCode())) {
|
||||
transactionsAmount += transaction.getAmount();
|
||||
transactionsAmount += Utils.getDoubleValue(transaction.getAmount());
|
||||
}
|
||||
}
|
||||
assertEquals(amountExpected, transactionsAmount);
|
||||
@@ -2707,7 +2707,7 @@ public class LoanTransactionHelper {
|
||||
}
|
||||
}
|
||||
assertEquals(transactionExpected, Utils.dateFormatter.format(lastTransaction.getDate()));
|
||||
assertEquals(amountExpected, lastTransaction.getAmount());
|
||||
assertEquals(amountExpected, Utils.getDoubleValue(lastTransaction.getAmount()));
|
||||
return lastTransaction.getId();
|
||||
}
|
||||
|
||||
@@ -2722,7 +2722,7 @@ public class LoanTransactionHelper {
|
||||
if (getLoansLoanIdSummary != null) {
|
||||
log.info("Loan with Principal Outstanding Balance {} expected {}", getLoansLoanIdSummary.getPrincipalOutstanding(),
|
||||
amountExpected);
|
||||
assertEquals(amountExpected, getLoansLoanIdSummary.getPrincipalOutstanding());
|
||||
assertEquals(amountExpected, Utils.getDoubleValue(getLoansLoanIdSummary.getPrincipalOutstanding()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2730,7 +2730,7 @@ public class LoanTransactionHelper {
|
||||
GetLoansLoanIdSummary getLoansLoanIdSummary = getLoansLoanIdResponse.getSummary();
|
||||
if (getLoansLoanIdSummary != null) {
|
||||
log.info("Loan with Fees Outstanding Balance {} expected {}", getLoansLoanIdSummary.getFeeChargesOutstanding(), amountExpected);
|
||||
assertEquals(amountExpected, getLoansLoanIdSummary.getFeeChargesOutstanding());
|
||||
assertEquals(amountExpected, Utils.getDoubleValue(getLoansLoanIdSummary.getFeeChargesOutstanding()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2738,14 +2738,14 @@ public class LoanTransactionHelper {
|
||||
GetLoansLoanIdSummary getLoansLoanIdSummary = getLoansLoanIdResponse.getSummary();
|
||||
assertNotNull(getLoansLoanIdSummary);
|
||||
log.info("Loan with Fees Outstanding Balance {} expected {}", getLoansLoanIdSummary.getFeeChargesOutstanding(), amountExpected);
|
||||
assertEquals(amountExpected, getLoansLoanIdSummary.getPenaltyChargesOutstanding());
|
||||
assertEquals(amountExpected, Utils.getDoubleValue(getLoansLoanIdSummary.getPenaltyChargesOutstanding()));
|
||||
}
|
||||
|
||||
public void validateLoanTotalOustandingBalance(GetLoansLoanIdResponse getLoansLoanIdResponse, Double amountExpected) {
|
||||
GetLoansLoanIdSummary getLoansLoanIdSummary = getLoansLoanIdResponse.getSummary();
|
||||
if (getLoansLoanIdSummary != null) {
|
||||
log.info("Loan with Total Outstanding Balance {} expected {}", getLoansLoanIdSummary.getTotalOutstanding(), amountExpected);
|
||||
assertEquals(amountExpected, getLoansLoanIdSummary.getTotalOutstanding());
|
||||
assertEquals(amountExpected, Utils.getDoubleValue(getLoansLoanIdSummary.getTotalOutstanding()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user