Skip to content

Commit

Permalink
FINERACT-2081: Loan account data additional fields for summary and de…
Browse files Browse the repository at this point in the history
…linquency
  • Loading branch information
Jose Alberto Hernandez committed Jul 3, 2024
1 parent b482fbd commit d14403e
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,22 @@ public CollectionData getOverdueCollectionData(final Loan loan, List<LoanDelinqu
return CollectionData.template();
}

BigDecimal delinquentPrincipal = BigDecimal.ZERO;
BigDecimal delinquentInterest = BigDecimal.ZERO;
BigDecimal delinquentFee = BigDecimal.ZERO;
BigDecimal delinquentPenalty = BigDecimal.ZERO;

// Get the oldest overdue installment if exists one
for (LoanRepaymentScheduleInstallment installment : loan.getRepaymentScheduleInstallments()) {
if (!installment.isObligationsMet()) {
if (DateUtils.isBefore(installment.getDueDate(), businessDate)) {
log.debug("Loan Id: {} with installment {} due date {}", loan.getId(), installment.getInstallmentNumber(),
installment.getDueDate());
outstandingAmount = outstandingAmount.add(installment.getTotalOutstanding(loanCurrency).getAmount());
delinquentPrincipal = delinquentPrincipal.add(installment.getPrincipalOutstanding(loanCurrency).getAmount());
delinquentInterest = delinquentInterest.add(installment.getInterestOutstanding(loanCurrency).getAmount());
delinquentFee = delinquentFee.add(installment.getFeeChargesOutstanding(loanCurrency).getAmount());
delinquentPenalty = delinquentPenalty.add(installment.getPenaltyChargesOutstanding(loanCurrency).getAmount());
if (!oldestOverdueInstallment) {
log.debug("Oldest installment {} {}", installment.getInstallmentNumber(), installment.getDueDate());
CollectionData overDueInstallmentDelinquentData = calculateDelinquencyDataForOverdueInstallment(loan, installment);
Expand All @@ -85,6 +94,10 @@ public CollectionData getOverdueCollectionData(final Loan loan, List<LoanDelinqu
CollectionData nonOverDueInstallmentDelinquentData = calculateDelinquencyDataForNonOverdueInstallment(loan,
installment);
outstandingAmount = outstandingAmount.add(nonOverDueInstallmentDelinquentData.getDelinquentAmount());
delinquentPrincipal = delinquentPrincipal.add(nonOverDueInstallmentDelinquentData.getDelinquentPrincipal());
delinquentInterest = delinquentInterest.add(nonOverDueInstallmentDelinquentData.getDelinquentInterest());
delinquentFee = delinquentFee.add(nonOverDueInstallmentDelinquentData.getDelinquentFee());
delinquentPenalty = delinquentPenalty.add(nonOverDueInstallmentDelinquentData.getDelinquentPenalty());
if (!overdueSinceDateWasSet) {
overdueSinceDate = nonOverDueInstallmentDelinquentData.getDelinquentDate();
overdueSinceDateWasSet = true;
Expand All @@ -110,6 +123,11 @@ public CollectionData getOverdueCollectionData(final Loan loan, List<LoanDelinqu
collectionData.setDelinquentDate(overdueSinceDate);
}
collectionData.setDelinquentAmount(outstandingAmount);
collectionData.setDelinquentPrincipal(delinquentPrincipal);
collectionData.setDelinquentInterest(delinquentInterest);
collectionData.setDelinquentFee(delinquentFee);
collectionData.setDelinquentPenalty(delinquentPenalty);

collectionData.setDelinquentDays(0L);
Long delinquentDays = overdueDays - graceDays;
if (delinquentDays > 0) {
Expand Down Expand Up @@ -248,8 +266,17 @@ private CollectionData calculateDelinquencyDataForOverdueInstallment(final Loan
LocalDate overdueSinceDate = null;
CollectionData collectionData = CollectionData.template();
BigDecimal outstandingAmount = BigDecimal.ZERO;
BigDecimal delinquentPrincipal = BigDecimal.ZERO;
BigDecimal delinquentInterest = BigDecimal.ZERO;
BigDecimal delinquentFee = BigDecimal.ZERO;
BigDecimal delinquentPenalty = BigDecimal.ZERO;

outstandingAmount = outstandingAmount.add(installment.getTotalOutstanding(loanCurrency).getAmount());
delinquentPrincipal = delinquentPrincipal.add(installment.getPrincipalOutstanding(loanCurrency).getAmount());
delinquentInterest = delinquentInterest.add(installment.getInterestOutstanding(loanCurrency).getAmount());
delinquentFee = delinquentFee.add(installment.getFeeChargesOutstanding(loanCurrency).getAmount());
delinquentPenalty = delinquentPenalty.add(installment.getPenaltyChargesOutstanding(loanCurrency).getAmount());

overdueSinceDate = installment.getDueDate();
BigDecimal amountAvailable = installment.getTotalPaid(loanCurrency).getAmount();
boolean isLatestInstallment = Objects.equals(installment.getId(), latestInstallment.getId());
Expand All @@ -272,6 +299,10 @@ private CollectionData calculateDelinquencyDataForOverdueInstallment(final Loan
}
collectionData.setDelinquentDate(overdueSinceDate);
collectionData.setDelinquentAmount(outstandingAmount);
collectionData.setDelinquentPrincipal(delinquentPrincipal);
collectionData.setDelinquentInterest(delinquentInterest);
collectionData.setDelinquentFee(delinquentFee);
collectionData.setDelinquentPenalty(delinquentPenalty);
return collectionData;
}

Expand All @@ -283,6 +314,10 @@ private CollectionData calculateDelinquencyDataForNonOverdueInstallment(final Lo
LocalDate overdueSinceDate = null;
CollectionData collectionData = CollectionData.template();
BigDecimal outstandingAmount = BigDecimal.ZERO;
BigDecimal delinquentPrincipal = BigDecimal.ZERO;
BigDecimal delinquentInterest = BigDecimal.ZERO;
BigDecimal delinquentFee = BigDecimal.ZERO;
BigDecimal delinquentPenalty = BigDecimal.ZERO;

List<LoanTransaction> chargebackTransactions = loan.getLoanTransactions(LoanTransaction::isChargeback);
BigDecimal amountAvailable = installment.getTotalPaid(loanCurrency).getAmount();
Expand All @@ -306,6 +341,10 @@ private CollectionData calculateDelinquencyDataForNonOverdueInstallment(final Lo
}
collectionData.setDelinquentDate(overdueSinceDate);
collectionData.setDelinquentAmount(outstandingAmount);
collectionData.setDelinquentPrincipal(delinquentPrincipal);
collectionData.setDelinquentInterest(delinquentInterest);
collectionData.setDelinquentFee(delinquentFee);
collectionData.setDelinquentPenalty(delinquentPenalty);
return collectionData;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,14 @@ public final class CollectionData {
public Collection<DelinquencyPausePeriod> delinquencyPausePeriods;
public Collection<InstallmentLevelDelinquency> installmentLevelDelinquency;

private BigDecimal delinquentPrincipal;
private BigDecimal delinquentInterest;
private BigDecimal delinquentFee;
private BigDecimal delinquentPenalty;

public static CollectionData template() {
final BigDecimal zero = BigDecimal.ZERO;
return new CollectionData(zero, 0L, null, 0L, null, zero, null, zero, null, zero, null, null);
return new CollectionData(zero, 0L, null, 0L, null, zero, null, zero, null, zero, null, null, zero, zero, zero, zero);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,14 @@ public class LoanSummaryData {
private BigDecimal totalCreditBalanceRefundReversed;
private BigDecimal totalRepaymentTransaction;
private BigDecimal totalRepaymentTransactionReversed;
private BigDecimal totalInterestRefund;
private BigDecimal totalInterestPaymentWaiver;
private final Long chargeOffReasonId;
private final String chargeOffReason;

private BigDecimal totalUnpaidAccruedDueInterest;
private BigDecimal totalUnpaidAccruedNotDueInterest;

public static LoanSummaryData withTransactionAmountsSummary(final LoanSummaryData defaultSummaryData,
final Collection<LoanTransactionData> loanTransactions) {

Expand All @@ -110,6 +115,8 @@ public static LoanSummaryData withTransactionAmountsSummary(final LoanSummaryDat
BigDecimal totalCreditBalanceRefundReversed = BigDecimal.ZERO;
BigDecimal totalRepaymentTransaction = BigDecimal.ZERO;
BigDecimal totalRepaymentTransactionReversed = BigDecimal.ZERO;
BigDecimal totalInterestRefund = BigDecimal.ZERO;
BigDecimal totalInterestPaymentWaiver = BigDecimal.ZERO;

if (!CollectionUtils.isEmpty(loanTransactions)) {

Expand All @@ -131,6 +138,8 @@ public static LoanSummaryData withTransactionAmountsSummary(final LoanSummaryDat
loanTransactions);
totalRepaymentTransaction = computeTotalRepaymentTransactionAmount(loanTransactions);
totalRepaymentTransactionReversed = computeTotalAmountForReversedTransactions(LoanTransactionType.REPAYMENT, loanTransactions);
totalInterestPaymentWaiver = computeTotalAmountForNonReversedTransactions(LoanTransactionType.INTEREST_PAYMENT_WAIVER,
loanTransactions);
}

return LoanSummaryData.builder().currency(defaultSummaryData.currency).principalDisbursed(defaultSummaryData.principalDisbursed)
Expand Down Expand Up @@ -163,7 +172,8 @@ public static LoanSummaryData withTransactionAmountsSummary(final LoanSummaryDat
.totalChargeAdjustment(totalChargeAdjustment).totalChargeAdjustmentReversed(totalChargeAdjustmentReversed)
.totalChargeback(totalChargeback).totalCreditBalanceRefund(totalCreditBalanceRefund)
.totalCreditBalanceRefundReversed(totalCreditBalanceRefundReversed).totalRepaymentTransaction(totalRepaymentTransaction)
.totalRepaymentTransactionReversed(totalRepaymentTransactionReversed).build();
.totalRepaymentTransactionReversed(totalRepaymentTransactionReversed).totalInterestRefund(totalInterestRefund)
.totalInterestPaymentWaiver(totalInterestPaymentWaiver).build();
}

public static LoanSummaryData withOnlyCurrencyData(CurrencyData currencyData) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ public enum LoanTransactionType {
DOWN_PAYMENT(28, "loanTransactionType.downPayment"), //
REAGE(29, "loanTransactionType.reAge"), //
REAMORTIZE(30, "loanTransactionType.reAmortize"), //
INTEREST_PAYMENT_WAIVER(31, "loanTransactionType.interestPaymentWaiver"), //
;
INTEREST_PAYMENT_WAIVER(31, "loanTransactionType.interestPaymentWaiver"); //

private final Integer value;
private final String code;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ private LocalDate getEffectiveDate() {
}

private boolean isBackdatedCharge() {
return loanCharge.get().getDueDate().isBefore(loanCharge.get().getSubmittedOnDate());
return (loanCharge.get().getDueDate() != null && loanCharge.get().getDueDate().isBefore(loanCharge.get().getSubmittedOnDate()));
}

private LocalDate getSubmittedOnDate() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,10 @@ private GetLoansLoanIdFeeFrequency() {}
@Schema(example = "0.000000")
public Double totalRepaymentTransaction;
@Schema(example = "0.000000")
public Double totalInterestRefund;
@Schema(example = "0.000000")
public Double totalInterestPaymentWaiver;
@Schema(example = "0.000000")
public Double totalRepaymentTransactionReversed;
public Set<GetLoansLoanIdOverdueCharges> overdueCharges;
@Schema(example = "1")
Expand Down Expand Up @@ -984,6 +988,14 @@ private GetLoansLoanIdDelinquencySummary() {}
public LocalDate delinquentDate;
@Schema(example = "100.000000")
public Double delinquentAmount;
@Schema(example = "80.000000")
public Double delinquentPrincipal;
@Schema(example = "10.000000")
public Double delinquentInterest;
@Schema(example = "6.000000")
public Double delinquentFee;
@Schema(example = "4.000000")
public Double delinquentPenalty;
@Schema(example = "[2022, 07, 01]")
public LocalDate lastPaymentDate;
@Schema(example = "100.000000")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,9 @@ public void givenLoanAccountWithDelinquencyBucketWhenRangeChangeThenEventIsRaise
LocalDate overDueSinceDate = DateUtils.getBusinessLocalDate().minusDays(2);
LoanScheduleDelinquencyData loanScheduleDelinquencyData = new LoanScheduleDelinquencyData(1L, overDueSinceDate, 1L,
loanForProcessing);
CollectionData collectionData = new CollectionData(BigDecimal.ZERO, 2L, null, 2L, overDueSinceDate, BigDecimal.ZERO, null, null,
null, null, null, null);
final BigDecimal zero = BigDecimal.ZERO;
CollectionData collectionData = new CollectionData(zero, 2L, null, 2L, overDueSinceDate, zero, null, null, null, null, null, null,
zero, zero, zero, zero);

Map<Long, CollectionData> installmentsCollection = new HashMap<>();

Expand Down Expand Up @@ -221,11 +222,11 @@ public void test_ApplyDelinquencyTagToLoan_ExecutesDelinquencyApplication_InTheR
LocalDate overDueSinceDate = DateUtils.getBusinessLocalDate().minusDays(2);
LoanScheduleDelinquencyData loanScheduleDelinquencyData = new LoanScheduleDelinquencyData(1L, overDueSinceDate, 1L,
loanForProcessing);
CollectionData collectionData = new CollectionData(BigDecimal.ZERO, 2L, null, 2L, overDueSinceDate, BigDecimal.ZERO, null, null,
null, null, null, null);
CollectionData collectionData = new CollectionData(zeroAmount, 2L, null, 2L, overDueSinceDate, zeroAmount, null, null, null, null,
null, null, zeroAmount, zeroAmount, zeroAmount, zeroAmount);

CollectionData installmentCollectionData = new CollectionData(BigDecimal.ZERO, 2L, null, 2L, overDueSinceDate,
installmentPrincipalAmount, null, null, null, null, null, null);
CollectionData installmentCollectionData = new CollectionData(zeroAmount, 2L, null, 2L, overDueSinceDate,
installmentPrincipalAmount, null, null, null, null, null, null, zeroAmount, zeroAmount, zeroAmount, zeroAmount);

Map<Long, CollectionData> installmentsCollection = new HashMap<>();
installmentsCollection.put(1L, installmentCollectionData);
Expand Down Expand Up @@ -349,11 +350,12 @@ public void givenLoanAccountWithOverdueInstallmentAndEnableInstallmentThenDelinq
LocalDate overDueSinceDate = DateUtils.getBusinessLocalDate().minusDays(2);
LoanScheduleDelinquencyData loanScheduleDelinquencyData = new LoanScheduleDelinquencyData(1L, overDueSinceDate, 1L,
loanForProcessing);
CollectionData collectionData = new CollectionData(BigDecimal.ZERO, 2L, null, 2L, overDueSinceDate, BigDecimal.ZERO, null, null,
null, null, null, null);

CollectionData installmentCollectionData = new CollectionData(BigDecimal.ZERO, 2L, null, 2L, overDueSinceDate,
installmentPrincipalAmount, null, null, null, null, null, null);
CollectionData collectionData = new CollectionData(zeroAmount, 2L, null, 2L, overDueSinceDate, zeroAmount, null, null, null, null,
null, null, zeroAmount, zeroAmount, zeroAmount, zeroAmount);

CollectionData installmentCollectionData = new CollectionData(zeroAmount, 2L, null, 2L, overDueSinceDate,
installmentPrincipalAmount, null, null, null, null, null, null, zeroAmount, zeroAmount, zeroAmount, zeroAmount);

Map<Long, CollectionData> installmentsCollection = new HashMap<>();
installmentsCollection.put(1L, installmentCollectionData);
Expand Down Expand Up @@ -426,11 +428,11 @@ public void givenLoanAccountWithOverdueInstallmentAndEnableInstallmentThenDelinq
LocalDate overDueSinceDate = DateUtils.getBusinessLocalDate().minusDays(29);
LoanScheduleDelinquencyData loanScheduleDelinquencyData = new LoanScheduleDelinquencyData(1L, overDueSinceDate, 1L,
loanForProcessing);
CollectionData collectionData = new CollectionData(BigDecimal.ZERO, 29L, null, 29L, overDueSinceDate, BigDecimal.ZERO, null, null,
null, null, null, null);
CollectionData collectionData = new CollectionData(BigDecimal.ZERO, 29L, null, 29L, overDueSinceDate, zeroAmount, null, null, null,
null, null, null, zeroAmount, zeroAmount, zeroAmount, zeroAmount);

CollectionData installmentCollectionData = new CollectionData(BigDecimal.ZERO, 29L, null, 29L, overDueSinceDate,
installmentPrincipalAmount, null, null, null, null, null, null);
CollectionData installmentCollectionData = new CollectionData(zeroAmount, 29L, null, 29L, overDueSinceDate,
installmentPrincipalAmount, null, null, null, null, null, null, zeroAmount, zeroAmount, zeroAmount, zeroAmount);

Map<Long, CollectionData> installmentsCollection = new HashMap<>();
installmentsCollection.put(1L, installmentCollectionData);
Expand Down Expand Up @@ -514,14 +516,14 @@ public void givenLoanAccountWithOverdueInstallmentsAndEnableInstallmentThenDelin
LocalDate overDueSinceDate = DateUtils.getBusinessLocalDate().minusDays(29);
LoanScheduleDelinquencyData loanScheduleDelinquencyData = new LoanScheduleDelinquencyData(1L, overDueSinceDate, 1L,
loanForProcessing);
CollectionData collectionData = new CollectionData(BigDecimal.ZERO, 29L, null, 29L, overDueSinceDate, BigDecimal.ZERO, null, null,
null, null, null, null);
CollectionData collectionData = new CollectionData(zeroAmount, 29L, null, 29L, overDueSinceDate, zeroAmount, null, null, null, null,
null, null, zeroAmount, zeroAmount, zeroAmount, zeroAmount);

CollectionData installmentCollectionData_1 = new CollectionData(BigDecimal.ZERO, 29L, null, 29L, overDueSinceDate,
installmentPrincipalAmount, null, null, null, null, null, null);
CollectionData installmentCollectionData_1 = new CollectionData(zeroAmount, 29L, null, 29L, overDueSinceDate,
installmentPrincipalAmount, null, null, null, null, null, null, zeroAmount, zeroAmount, zeroAmount, zeroAmount);

CollectionData installmentCollectionData_2 = new CollectionData(BigDecimal.ZERO, 0L, null, 0L, null, installmentPrincipalAmount,
null, null, null, null, null, null);
CollectionData installmentCollectionData_2 = new CollectionData(zeroAmount, 0L, null, 0L, null, installmentPrincipalAmount, null,
null, null, null, null, null, zeroAmount, zeroAmount, zeroAmount, zeroAmount);

Map<Long, CollectionData> installmentsCollection = new HashMap<>();
installmentsCollection.put(1L, installmentCollectionData_1);
Expand Down

0 comments on commit d14403e

Please sign in to comment.