FINERACT-2272: Move fetching chargeback transactions out of foreach of delinquency calculation
This commit is contained in:
committed by
Adam Saghy
parent
91da34a8c6
commit
5cd604df43
+35
-32
@@ -48,12 +48,14 @@ public class LoanDelinquencyDomainServiceImpl implements LoanDelinquencyDomainSe
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public CollectionData getOverdueCollectionData(final Loan loan, List<LoanDelinquencyActionData> effectiveDelinquencyList) {
|
public CollectionData getOverdueCollectionData(final Loan loan, final List<LoanDelinquencyActionData> effectiveDelinquencyList) {
|
||||||
|
final List<LoanTransaction> chargebackTransactions = loanTransactionReadService.fetchLoanTransactionsByType(loan.getId(), null,
|
||||||
|
LoanTransactionType.CHARGEBACK);
|
||||||
final LocalDate businessDate = DateUtils.getBusinessLocalDate();
|
final LocalDate businessDate = DateUtils.getBusinessLocalDate();
|
||||||
|
|
||||||
final MonetaryCurrency loanCurrency = loan.getCurrency();
|
final MonetaryCurrency loanCurrency = loan.getCurrency();
|
||||||
|
final CollectionData collectionData = CollectionData.template();
|
||||||
|
|
||||||
LocalDate overdueSinceDate = null;
|
LocalDate overdueSinceDate = null;
|
||||||
CollectionData collectionData = CollectionData.template();
|
|
||||||
BigDecimal outstandingAmount = BigDecimal.ZERO;
|
BigDecimal outstandingAmount = BigDecimal.ZERO;
|
||||||
boolean oldestOverdueInstallment = false;
|
boolean oldestOverdueInstallment = false;
|
||||||
boolean overdueSinceDateWasSet = false;
|
boolean overdueSinceDateWasSet = false;
|
||||||
@@ -85,7 +87,8 @@ public class LoanDelinquencyDomainServiceImpl implements LoanDelinquencyDomainSe
|
|||||||
delinquentPenalty = delinquentPenalty.add(installment.getPenaltyChargesOutstanding(loanCurrency).getAmount());
|
delinquentPenalty = delinquentPenalty.add(installment.getPenaltyChargesOutstanding(loanCurrency).getAmount());
|
||||||
if (!oldestOverdueInstallment) {
|
if (!oldestOverdueInstallment) {
|
||||||
log.debug("Oldest installment {} {}", installment.getInstallmentNumber(), installment.getDueDate());
|
log.debug("Oldest installment {} {}", installment.getInstallmentNumber(), installment.getDueDate());
|
||||||
CollectionData overDueInstallmentDelinquentData = calculateDelinquencyDataForOverdueInstallment(loan, installment);
|
final CollectionData overDueInstallmentDelinquentData = calculateDelinquencyDataForOverdueInstallment(loan,
|
||||||
|
installment, chargebackTransactions);
|
||||||
overdueSinceDate = overDueInstallmentDelinquentData.getDelinquentDate();
|
overdueSinceDate = overDueInstallmentDelinquentData.getDelinquentDate();
|
||||||
oldestOverdueInstallment = true;
|
oldestOverdueInstallment = true;
|
||||||
overdueSinceDateWasSet = true;
|
overdueSinceDateWasSet = true;
|
||||||
@@ -94,7 +97,7 @@ public class LoanDelinquencyDomainServiceImpl implements LoanDelinquencyDomainSe
|
|||||||
log.debug("Loan Id: {} with installment {} due date {}", loan.getId(), installment.getInstallmentNumber(),
|
log.debug("Loan Id: {} with installment {} due date {}", loan.getId(), installment.getInstallmentNumber(),
|
||||||
installment.getDueDate());
|
installment.getDueDate());
|
||||||
firstNotYetDueInstallment = true;
|
firstNotYetDueInstallment = true;
|
||||||
CollectionData nonOverDueInstallmentDelinquentData = calculateDelinquencyDataForNonOverdueInstallment(loan,
|
final CollectionData nonOverDueInstallmentDelinquentData = calculateDelinquencyDataForNonOverdueInstallment(loan,
|
||||||
installment);
|
installment);
|
||||||
outstandingAmount = outstandingAmount.add(nonOverDueInstallmentDelinquentData.getDelinquentAmount());
|
outstandingAmount = outstandingAmount.add(nonOverDueInstallmentDelinquentData.getDelinquentAmount());
|
||||||
delinquentPrincipal = delinquentPrincipal.add(nonOverDueInstallmentDelinquentData.getDelinquentPrincipal());
|
delinquentPrincipal = delinquentPrincipal.add(nonOverDueInstallmentDelinquentData.getDelinquentPrincipal());
|
||||||
@@ -115,7 +118,7 @@ public class LoanDelinquencyDomainServiceImpl implements LoanDelinquencyDomainSe
|
|||||||
}
|
}
|
||||||
log.debug("Loan id {} with overdue since date {} and outstanding amount {}", loan.getId(), overdueSinceDate, outstandingAmount);
|
log.debug("Loan id {} with overdue since date {} and outstanding amount {}", loan.getId(), overdueSinceDate, outstandingAmount);
|
||||||
|
|
||||||
Long overdueDays = 0L;
|
long overdueDays = 0L;
|
||||||
if (overdueSinceDate != null) {
|
if (overdueSinceDate != null) {
|
||||||
overdueDays = DateUtils.getDifferenceInDays(overdueSinceDate, businessDate);
|
overdueDays = DateUtils.getDifferenceInDays(overdueSinceDate, businessDate);
|
||||||
if (overdueDays < 0) {
|
if (overdueDays < 0) {
|
||||||
@@ -132,22 +135,23 @@ public class LoanDelinquencyDomainServiceImpl implements LoanDelinquencyDomainSe
|
|||||||
collectionData.setDelinquentPenalty(delinquentPenalty);
|
collectionData.setDelinquentPenalty(delinquentPenalty);
|
||||||
|
|
||||||
collectionData.setDelinquentDays(0L);
|
collectionData.setDelinquentDays(0L);
|
||||||
Long delinquentDays = overdueDays - graceDays;
|
final long delinquentDays = overdueDays - graceDays;
|
||||||
if (delinquentDays > 0) {
|
if (delinquentDays > 0) {
|
||||||
calculateDelinquentDays(effectiveDelinquencyList, businessDate, collectionData, delinquentDays);
|
calculateDelinquentDays(effectiveDelinquencyList, businessDate, collectionData, delinquentDays);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("Result: {}", collectionData.toString());
|
log.debug("Result: {}", collectionData);
|
||||||
return collectionData;
|
return collectionData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LoanDelinquencyData getLoanDelinquencyData(final Loan loan, List<LoanDelinquencyActionData> effectiveDelinquencyList) {
|
public LoanDelinquencyData getLoanDelinquencyData(final Loan loan, List<LoanDelinquencyActionData> effectiveDelinquencyList) {
|
||||||
|
final List<LoanTransaction> chargebackTransactions = loanTransactionReadService.fetchLoanTransactionsByType(loan.getId(), null,
|
||||||
|
LoanTransactionType.CHARGEBACK);
|
||||||
final LocalDate businessDate = DateUtils.getBusinessLocalDate();
|
final LocalDate businessDate = DateUtils.getBusinessLocalDate();
|
||||||
|
final CollectionData collectionData = CollectionData.template();
|
||||||
|
final Map<Long, CollectionData> loanInstallmentsCollectionData = new HashMap<>();
|
||||||
LocalDate overdueSinceDate = null;
|
LocalDate overdueSinceDate = null;
|
||||||
CollectionData collectionData = CollectionData.template();
|
|
||||||
Map<Long, CollectionData> loanInstallmentsCollectionData = new HashMap<>();
|
|
||||||
BigDecimal outstandingAmount = BigDecimal.ZERO;
|
BigDecimal outstandingAmount = BigDecimal.ZERO;
|
||||||
boolean oldestOverdueInstallment = false;
|
boolean oldestOverdueInstallment = false;
|
||||||
boolean overdueSinceDateWasSet = false;
|
boolean overdueSinceDateWasSet = false;
|
||||||
@@ -164,7 +168,8 @@ public class LoanDelinquencyDomainServiceImpl implements LoanDelinquencyDomainSe
|
|||||||
for (LoanRepaymentScheduleInstallment installment : loan.getRepaymentScheduleInstallments()) {
|
for (LoanRepaymentScheduleInstallment installment : loan.getRepaymentScheduleInstallments()) {
|
||||||
CollectionData installmentCollectionData = CollectionData.template();
|
CollectionData installmentCollectionData = CollectionData.template();
|
||||||
if (!installment.isObligationsMet()) {
|
if (!installment.isObligationsMet()) {
|
||||||
installmentCollectionData = getInstallmentOverdueCollectionData(loan, installment, effectiveDelinquencyList);
|
installmentCollectionData = getInstallmentOverdueCollectionData(loan, installment, effectiveDelinquencyList,
|
||||||
|
chargebackTransactions);
|
||||||
outstandingAmount = outstandingAmount.add(installmentCollectionData.getDelinquentAmount());
|
outstandingAmount = outstandingAmount.add(installmentCollectionData.getDelinquentAmount());
|
||||||
// Get the oldest overdue installment if exists
|
// Get the oldest overdue installment if exists
|
||||||
if (DateUtils.isBefore(installment.getDueDate(), businessDate)) {
|
if (DateUtils.isBefore(installment.getDueDate(), businessDate)) {
|
||||||
@@ -194,7 +199,7 @@ public class LoanDelinquencyDomainServiceImpl implements LoanDelinquencyDomainSe
|
|||||||
}
|
}
|
||||||
log.debug("Loan id {} with overdue since date {} and outstanding amount {}", loan.getId(), overdueSinceDate, outstandingAmount);
|
log.debug("Loan id {} with overdue since date {} and outstanding amount {}", loan.getId(), overdueSinceDate, outstandingAmount);
|
||||||
|
|
||||||
Long overdueDays = 0L;
|
long overdueDays = 0L;
|
||||||
if (overdueSinceDate != null) {
|
if (overdueSinceDate != null) {
|
||||||
overdueDays = DateUtils.getDifferenceInDays(overdueSinceDate, businessDate);
|
overdueDays = DateUtils.getDifferenceInDays(overdueSinceDate, businessDate);
|
||||||
if (overdueDays < 0) {
|
if (overdueDays < 0) {
|
||||||
@@ -206,7 +211,7 @@ public class LoanDelinquencyDomainServiceImpl implements LoanDelinquencyDomainSe
|
|||||||
}
|
}
|
||||||
collectionData.setDelinquentAmount(outstandingAmount);
|
collectionData.setDelinquentAmount(outstandingAmount);
|
||||||
collectionData.setDelinquentDays(0L);
|
collectionData.setDelinquentDays(0L);
|
||||||
Long delinquentDays = overdueDays - graceDays;
|
final long delinquentDays = overdueDays - graceDays;
|
||||||
if (delinquentDays > 0) {
|
if (delinquentDays > 0) {
|
||||||
calculateDelinquentDays(effectiveDelinquencyList, businessDate, collectionData, delinquentDays);
|
calculateDelinquentDays(effectiveDelinquencyList, businessDate, collectionData, delinquentDays);
|
||||||
}
|
}
|
||||||
@@ -221,28 +226,28 @@ public class LoanDelinquencyDomainServiceImpl implements LoanDelinquencyDomainSe
|
|||||||
}
|
}
|
||||||
|
|
||||||
private CollectionData getInstallmentOverdueCollectionData(final Loan loan, final LoanRepaymentScheduleInstallment installment,
|
private CollectionData getInstallmentOverdueCollectionData(final Loan loan, final LoanRepaymentScheduleInstallment installment,
|
||||||
List<LoanDelinquencyActionData> effectiveDelinquencyList) {
|
final List<LoanDelinquencyActionData> effectiveDelinquencyList, final List<LoanTransaction> chargebackTransactions) {
|
||||||
final LocalDate businessDate = DateUtils.getBusinessLocalDate();
|
final LocalDate businessDate = DateUtils.getBusinessLocalDate();
|
||||||
LocalDate overdueSinceDate = null;
|
final CollectionData collectionData = CollectionData.template();
|
||||||
CollectionData collectionData = CollectionData.template();
|
LocalDate overdueSinceDate;
|
||||||
BigDecimal outstandingAmount = BigDecimal.ZERO;
|
BigDecimal outstandingAmount = BigDecimal.ZERO;
|
||||||
if (DateUtils.isBefore(installment.getDueDate(), businessDate)) {
|
if (DateUtils.isBefore(installment.getDueDate(), businessDate)) {
|
||||||
// checking overdue installment delinquency data
|
// checking overdue installment delinquency data
|
||||||
CollectionData overDueInstallmentDelinquentData = calculateDelinquencyDataForOverdueInstallment(loan, installment);
|
final CollectionData overDueInstallmentDelinquentData = calculateDelinquencyDataForOverdueInstallment(loan, installment,
|
||||||
|
chargebackTransactions);
|
||||||
outstandingAmount = outstandingAmount.add(overDueInstallmentDelinquentData.getDelinquentAmount());
|
outstandingAmount = outstandingAmount.add(overDueInstallmentDelinquentData.getDelinquentAmount());
|
||||||
overdueSinceDate = overDueInstallmentDelinquentData.getDelinquentDate();
|
overdueSinceDate = overDueInstallmentDelinquentData.getDelinquentDate();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// checking non overdue installment for chargeback transactions before installment due date and before
|
// checking non overdue installment for chargeback transactions before installment due date and before
|
||||||
// business date
|
// business date
|
||||||
CollectionData nonOverDueInstallmentDelinquentData = calculateDelinquencyDataForNonOverdueInstallment(loan, installment);
|
final CollectionData nonOverDueInstallmentDelinquentData = calculateDelinquencyDataForNonOverdueInstallment(loan, installment);
|
||||||
outstandingAmount = outstandingAmount.add(nonOverDueInstallmentDelinquentData.getDelinquentAmount());
|
outstandingAmount = outstandingAmount.add(nonOverDueInstallmentDelinquentData.getDelinquentAmount());
|
||||||
overdueSinceDate = nonOverDueInstallmentDelinquentData.getDelinquentDate();
|
overdueSinceDate = nonOverDueInstallmentDelinquentData.getDelinquentDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grace days are not considered for installment level delinquency calculation currently.
|
// Grace days are not considered for installment level delinquency calculation currently.
|
||||||
|
long overdueDays = 0L;
|
||||||
Long overdueDays = 0L;
|
|
||||||
if (overdueSinceDate != null) {
|
if (overdueSinceDate != null) {
|
||||||
overdueDays = DateUtils.getDifferenceInDays(overdueSinceDate, businessDate);
|
overdueDays = DateUtils.getDifferenceInDays(overdueSinceDate, businessDate);
|
||||||
if (overdueDays < 0) {
|
if (overdueDays < 0) {
|
||||||
@@ -253,7 +258,7 @@ public class LoanDelinquencyDomainServiceImpl implements LoanDelinquencyDomainSe
|
|||||||
}
|
}
|
||||||
collectionData.setDelinquentAmount(outstandingAmount);
|
collectionData.setDelinquentAmount(outstandingAmount);
|
||||||
collectionData.setDelinquentDays(0L);
|
collectionData.setDelinquentDays(0L);
|
||||||
Long delinquentDays = overdueDays;
|
final long delinquentDays = overdueDays;
|
||||||
if (delinquentDays > 0) {
|
if (delinquentDays > 0) {
|
||||||
calculateDelinquentDays(effectiveDelinquencyList, businessDate, collectionData, delinquentDays);
|
calculateDelinquentDays(effectiveDelinquencyList, businessDate, collectionData, delinquentDays);
|
||||||
}
|
}
|
||||||
@@ -262,13 +267,11 @@ public class LoanDelinquencyDomainServiceImpl implements LoanDelinquencyDomainSe
|
|||||||
}
|
}
|
||||||
|
|
||||||
private CollectionData calculateDelinquencyDataForOverdueInstallment(final Loan loan,
|
private CollectionData calculateDelinquencyDataForOverdueInstallment(final Loan loan,
|
||||||
final LoanRepaymentScheduleInstallment installment) {
|
final LoanRepaymentScheduleInstallment installment, final List<LoanTransaction> chargebackTransactions) {
|
||||||
final MonetaryCurrency loanCurrency = loan.getCurrency();
|
final MonetaryCurrency loanCurrency = loan.getCurrency();
|
||||||
LoanRepaymentScheduleInstallment latestInstallment = loan.getLastLoanRepaymentScheduleInstallment();
|
final LoanRepaymentScheduleInstallment latestInstallment = loan.getLastLoanRepaymentScheduleInstallment();
|
||||||
List<LoanTransaction> chargebackTransactions = loanTransactionReadService.fetchLoanTransactionsByType(loan.getId(), null,
|
final CollectionData collectionData = CollectionData.template();
|
||||||
LoanTransactionType.CHARGEBACK);
|
LocalDate overdueSinceDate;
|
||||||
LocalDate overdueSinceDate = null;
|
|
||||||
CollectionData collectionData = CollectionData.template();
|
|
||||||
BigDecimal outstandingAmount = BigDecimal.ZERO;
|
BigDecimal outstandingAmount = BigDecimal.ZERO;
|
||||||
BigDecimal delinquentPrincipal = BigDecimal.ZERO;
|
BigDecimal delinquentPrincipal = BigDecimal.ZERO;
|
||||||
BigDecimal delinquentInterest = BigDecimal.ZERO;
|
BigDecimal delinquentInterest = BigDecimal.ZERO;
|
||||||
@@ -283,13 +286,13 @@ public class LoanDelinquencyDomainServiceImpl implements LoanDelinquencyDomainSe
|
|||||||
|
|
||||||
overdueSinceDate = installment.getDueDate();
|
overdueSinceDate = installment.getDueDate();
|
||||||
BigDecimal amountAvailable = installment.getTotalPaid(loanCurrency).getAmount();
|
BigDecimal amountAvailable = installment.getTotalPaid(loanCurrency).getAmount();
|
||||||
boolean isLatestInstallment = Objects.equals(installment.getId(), latestInstallment.getId());
|
final boolean isLatestInstallment = Objects.equals(installment.getId(), latestInstallment.getId());
|
||||||
for (LoanTransaction loanTransaction : chargebackTransactions) {
|
for (LoanTransaction loanTransaction : chargebackTransactions) {
|
||||||
boolean isLoanTransactionIsOnOrAfterInstallmentFromDate = DateUtils.isEqual(loanTransaction.getTransactionDate(),
|
final boolean isLoanTransactionIsOnOrAfterInstallmentFromDate = DateUtils.isEqual(loanTransaction.getTransactionDate(),
|
||||||
installment.getFromDate()) || DateUtils.isAfter(loanTransaction.getTransactionDate(), installment.getFromDate());
|
installment.getFromDate()) || DateUtils.isAfter(loanTransaction.getTransactionDate(), installment.getFromDate());
|
||||||
boolean isLoanTransactionIsBeforeNotLastInstallmentDueDate = !isLatestInstallment
|
final boolean isLoanTransactionIsBeforeNotLastInstallmentDueDate = !isLatestInstallment
|
||||||
&& DateUtils.isBefore(loanTransaction.getTransactionDate(), installment.getDueDate());
|
&& DateUtils.isBefore(loanTransaction.getTransactionDate(), installment.getDueDate());
|
||||||
boolean isLoanTransactionIsOnOrBeforeLastInstallmentDueDate = isLatestInstallment
|
final boolean isLoanTransactionIsOnOrBeforeLastInstallmentDueDate = isLatestInstallment
|
||||||
&& (DateUtils.isEqual(loanTransaction.getTransactionDate(), installment.getDueDate())
|
&& (DateUtils.isEqual(loanTransaction.getTransactionDate(), installment.getDueDate())
|
||||||
|| DateUtils.isBefore(loanTransaction.getTransactionDate(), installment.getDueDate()));
|
|| DateUtils.isBefore(loanTransaction.getTransactionDate(), installment.getDueDate()));
|
||||||
if (isLoanTransactionIsOnOrAfterInstallmentFromDate
|
if (isLoanTransactionIsOnOrAfterInstallmentFromDate
|
||||||
|
|||||||
Reference in New Issue
Block a user