FINERACT-2081: Refactor - Simplify LoanSchedulePeriodData.java class
This commit is contained in:
+72
-96
@@ -113,8 +113,12 @@ public final class MathUtil {
|
||||
* @param notNull
|
||||
* if true then null parameter is omitted, otherwise returns null
|
||||
*/
|
||||
public static Long min(Long first, Long second, Long third, boolean notNull) {
|
||||
return min(min(first, second, notNull), third, notNull);
|
||||
public static Long min(boolean notNull, Long first, Long... amounts) {
|
||||
Long result = first;
|
||||
for (Long amount : amounts) {
|
||||
result = min(result, amount, notNull);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @return sum the two values considering null values */
|
||||
@@ -123,18 +127,12 @@ public final class MathUtil {
|
||||
}
|
||||
|
||||
/** @return sum the values considering null values */
|
||||
public static Long add(Long first, Long second, Long third) {
|
||||
return add(add(first, second), third);
|
||||
}
|
||||
|
||||
/** @return sum the values considering null values */
|
||||
public static Long add(Long first, Long second, Long third, Long fourth) {
|
||||
return add(add(add(first, second), third), fourth);
|
||||
}
|
||||
|
||||
/** @return sum the values considering null values */
|
||||
public static Long add(Long first, Long second, Long third, Long fourth, Long fifth) {
|
||||
return add(add(add(add(first, second), third), fourth), fifth);
|
||||
public static Long add(Long... amounts) {
|
||||
Long result = null;
|
||||
for (Long amount : amounts) {
|
||||
result = add(result, amount);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @return first minus second considering null values, maybe negative */
|
||||
@@ -142,18 +140,24 @@ public final class MathUtil {
|
||||
return first == null ? null : second == null ? first : Math.subtractExact(first, second);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return first minus the others considering null values, maybe negative
|
||||
*/
|
||||
public static Long subtractToZero(Long first, Long second, Long third) {
|
||||
return subtractToZero(subtract(first, second), third);
|
||||
/** @return first minus second considering null values, maybe negative */
|
||||
public static Long subtract(Long first, Long... amounts) {
|
||||
Long result = first;
|
||||
for (Long amount : amounts) {
|
||||
result = subtract(result, amount);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return first minus the others considering null values, maybe negative
|
||||
*/
|
||||
public static Long subtractToZero(Long first, Long second, Long third, Long fourth) {
|
||||
return subtractToZero(subtract(subtract(first, second), third), fourth);
|
||||
public static Long subtractToZero(Long first, Long... amounts) {
|
||||
Long result = first;
|
||||
for (Long amount : amounts) {
|
||||
result = subtractToZero(result, amount);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @return NONE negative first minus second considering null values */
|
||||
@@ -241,8 +245,12 @@ public final class MathUtil {
|
||||
* @param notNull
|
||||
* if true then null parameter is omitted, otherwise returns null
|
||||
*/
|
||||
public static BigDecimal min(BigDecimal first, BigDecimal second, BigDecimal third, boolean notNull) {
|
||||
return min(min(first, second, notNull), third, notNull);
|
||||
public static BigDecimal min(boolean notNull, BigDecimal first, BigDecimal... amounts) {
|
||||
BigDecimal result = first;
|
||||
for (BigDecimal amount : amounts) {
|
||||
result = min(result, amount, notNull);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @return sum the two values considering null values */
|
||||
@@ -256,44 +264,21 @@ public final class MathUtil {
|
||||
}
|
||||
|
||||
/** @return sum the values considering null values */
|
||||
public static BigDecimal add(BigDecimal first, BigDecimal second, BigDecimal third) {
|
||||
return add(first, second, third, MoneyHelper.getMathContext());
|
||||
}
|
||||
|
||||
/** @return sum the values considering null values */
|
||||
public static BigDecimal add(BigDecimal first, BigDecimal second, BigDecimal third, MathContext mc) {
|
||||
return add(add(first, second, mc), third, mc);
|
||||
}
|
||||
|
||||
/** @return sum the values considering null values */
|
||||
public static BigDecimal add(BigDecimal first, BigDecimal second, BigDecimal third, BigDecimal fourth) {
|
||||
return add(first, second, third, fourth, MoneyHelper.getMathContext());
|
||||
}
|
||||
|
||||
/** @return sum the values considering null values */
|
||||
public static BigDecimal add(BigDecimal first, BigDecimal second, BigDecimal third, BigDecimal fourth, MathContext mc) {
|
||||
return add(add(add(first, second, mc), third, mc), fourth, mc);
|
||||
}
|
||||
|
||||
/** @return sum the values considering null values */
|
||||
public static BigDecimal add(BigDecimal first, BigDecimal second, BigDecimal third, BigDecimal fourth, BigDecimal fifth) {
|
||||
return add(first, second, third, fourth, fifth, MoneyHelper.getMathContext());
|
||||
}
|
||||
|
||||
/** @return sum the values considering null values */
|
||||
public static BigDecimal add(BigDecimal first, BigDecimal second, BigDecimal third, BigDecimal fourth, BigDecimal fifth,
|
||||
MathContext mc) {
|
||||
return add(add(add(add(first, second, mc), third, mc), fourth, mc), fifth, mc);
|
||||
public static BigDecimal add(BigDecimal... amounts) {
|
||||
BigDecimal result = null;
|
||||
for (BigDecimal amount : amounts) {
|
||||
result = add(result, amount, MoneyHelper.getMathContext());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @return first minus second considering null values, maybe negative */
|
||||
public static BigDecimal subtract(BigDecimal first, BigDecimal second) {
|
||||
return subtract(first, second, MoneyHelper.getMathContext());
|
||||
}
|
||||
|
||||
/** @return first minus the others considering null values, maybe negative */
|
||||
public static BigDecimal subtract(BigDecimal first, BigDecimal second, BigDecimal third) {
|
||||
return subtract(subtract(first, second), third);
|
||||
public static BigDecimal subtract(BigDecimal first, BigDecimal... amounts) {
|
||||
BigDecimal result = first;
|
||||
for (BigDecimal amount : amounts) {
|
||||
result = subtract(result, amount, MoneyHelper.getMathContext());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @return first minus second considering null values, maybe negative */
|
||||
@@ -302,22 +287,9 @@ public final class MathUtil {
|
||||
}
|
||||
|
||||
/** @return NONE negative first minus second considering null values */
|
||||
public static BigDecimal subtractToZero(BigDecimal first, BigDecimal second) {
|
||||
return negativeToZero(subtract(first, second));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return first minus the others considering null values, maybe negative
|
||||
*/
|
||||
public static BigDecimal subtractToZero(BigDecimal first, BigDecimal second, BigDecimal third) {
|
||||
return subtractToZero(subtract(first, second), third);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return first minus the others considering null values, maybe negative
|
||||
*/
|
||||
public static BigDecimal subtractToZero(BigDecimal first, BigDecimal second, BigDecimal third, BigDecimal fourth) {
|
||||
return subtractToZero(subtract(subtract(first, second), third), fourth);
|
||||
public static BigDecimal subtractToZero(BigDecimal first, BigDecimal... amounts) {
|
||||
BigDecimal result = subtract(first, amounts);
|
||||
return negativeToZero(result);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -409,39 +381,39 @@ public final class MathUtil {
|
||||
return first == null ? second : second == null ? first : first.plus(second, mc);
|
||||
}
|
||||
|
||||
public static Money plus(Money first, Money second, Money third) {
|
||||
return plus(plus(first, second), third);
|
||||
public static Money plus(Money... multipleAmounts) {
|
||||
Money result = null;
|
||||
for (Money amount : multipleAmounts) {
|
||||
result = plus(result, amount);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Money plus(Money first, Money second, Money third, MathContext mc) {
|
||||
return plus(plus(first, second), third, mc);
|
||||
}
|
||||
|
||||
public static Money plus(Money first, Money second, Money third, Money fourth) {
|
||||
return plus(plus(plus(first, second), third), fourth);
|
||||
public static Money plus(MathContext mc, Money... multipleAmounts) {
|
||||
Money result = null;
|
||||
for (Money amount : multipleAmounts) {
|
||||
result = plus(result, amount, mc);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Money minus(Money first, Money second) {
|
||||
return first == null ? null : second == null ? first : first.minus(second);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return first minus the others considering null values, maybe negative
|
||||
*/
|
||||
public static Money minusToZero(Money first, Money second, Money third) {
|
||||
return minusToZero(minus(first, second), third);
|
||||
public static Money minus(Money first, Money... multipleAmounts) {
|
||||
Money result = first;
|
||||
for (Money amount : multipleAmounts) {
|
||||
result = minus(result, amount);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return first minus the others considering null values, maybe negative
|
||||
*/
|
||||
public static Money minusToZero(Money first, Money second, Money third, Money fourth) {
|
||||
return minusToZero(minus(minus(first, second), third), fourth);
|
||||
}
|
||||
|
||||
/** @return NONE negative first minus second considering null values */
|
||||
public static Money minusToZero(Money first, Money second) {
|
||||
return negativeToZero(minus(first, second));
|
||||
public static Money minusToZero(Money first, Money... multipleAmounts) {
|
||||
return negativeToZero(minus(first, multipleAmounts));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -459,8 +431,12 @@ public final class MathUtil {
|
||||
* @param notNull
|
||||
* if true then null parameter is omitted, otherwise returns null
|
||||
*/
|
||||
public static Money min(Money first, Money second, Money third, boolean notNull) {
|
||||
return min(min(first, second, notNull), third, notNull);
|
||||
public static Money min(boolean notNull, Money first, Money... amounts) {
|
||||
Money result = first;
|
||||
for (Money amount : amounts) {
|
||||
result = min(result, amount, notNull);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @return Money null safe negate */
|
||||
|
||||
+6
-9
@@ -227,7 +227,8 @@ public class LoanArrearsAgeingUpdateHandler {
|
||||
|
||||
LoanOriginalScheduleExtractor(DatabaseSpecificSQLGenerator sqlGenerator) {
|
||||
final StringBuilder scheduleDetail = new StringBuilder();
|
||||
scheduleDetail.append("select ml.id as loanId, mr.duedate as dueDate, mr.principal_amount as principalAmount, ");
|
||||
scheduleDetail.append(
|
||||
"select ml.id as loanId, mr.installment as installmentNumber, mr.fromdate as fromDate, mr.duedate as dueDate, mr.principal_amount as principalAmount, ");
|
||||
scheduleDetail.append(
|
||||
"mr.interest_amount as interestAmount, mr.fee_charges_amount as feeAmount, mr.penalty_charges_amount as penaltyAmount ");
|
||||
scheduleDetail.append("from m_loan ml INNER JOIN m_loan_repayment_schedule_history mr on mr.loan_id = ml.id ");
|
||||
@@ -253,19 +254,15 @@ public class LoanArrearsAgeingUpdateHandler {
|
||||
}
|
||||
|
||||
private LoanSchedulePeriodData fetchLoanSchedulePeriodData(ResultSet rs) throws SQLException {
|
||||
final Integer installmentNumber = JdbcSupport.getInteger(rs, "installmentNumber");
|
||||
final LocalDate fromDate = JdbcSupport.getLocalDate(rs, "fromDate");
|
||||
final LocalDate dueDate = JdbcSupport.getLocalDate(rs, "dueDate");
|
||||
final BigDecimal principalDue = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "principalAmount");
|
||||
final BigDecimal interestDueOnPrincipalOutstanding = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "interestAmount");
|
||||
final BigDecimal totalInstallmentAmount = principalDue.add(interestDueOnPrincipalOutstanding);
|
||||
final BigDecimal feeChargesDueForPeriod = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "feeAmount");
|
||||
final BigDecimal penaltyChargesDueForPeriod = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "penaltyAmount");
|
||||
final Integer periodNumber = null;
|
||||
final LocalDate fromDate = null;
|
||||
final BigDecimal principalOutstanding = null;
|
||||
final BigDecimal totalDueForPeriod = null;
|
||||
return LoanSchedulePeriodData.repaymentOnlyPeriod(periodNumber, fromDate, dueDate, principalDue, principalOutstanding,
|
||||
interestDueOnPrincipalOutstanding, feeChargesDueForPeriod, penaltyChargesDueForPeriod, totalDueForPeriod,
|
||||
totalInstallmentAmount);
|
||||
return LoanSchedulePeriodData.repaymentOnlyPeriod(installmentNumber, fromDate, dueDate, principalDue, null,
|
||||
interestDueOnPrincipalOutstanding, feeChargesDueForPeriod, penaltyChargesDueForPeriod);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ public final class LoanScheduleModelDownPaymentPeriod implements LoanScheduleMod
|
||||
|
||||
private final int periodNumber;
|
||||
private final LocalDate periodDate;
|
||||
private Money principalDue;
|
||||
private final Money principalDue;
|
||||
private final Money outstandingLoanBalance;
|
||||
|
||||
public static LoanScheduleModelDownPaymentPeriod downPayment(final int periodNumber, final LocalDate periodDate,
|
||||
|
||||
+186
-342
@@ -20,14 +20,17 @@ package org.apache.fineract.portfolio.loanaccount.loanschedule.data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.core.service.MathUtil;
|
||||
|
||||
/**
|
||||
* Immutable data object that represents a period of a loan schedule.
|
||||
*
|
||||
*/
|
||||
@Getter
|
||||
@Builder
|
||||
public final class LoanSchedulePeriodData {
|
||||
|
||||
private final Integer period;
|
||||
@@ -72,434 +75,275 @@ public final class LoanSchedulePeriodData {
|
||||
private final BigDecimal totalInstallmentAmountForPeriod;
|
||||
private final BigDecimal totalCredits;
|
||||
private final BigDecimal totalAccruedInterest;
|
||||
private final Boolean downPaymentPeriod;
|
||||
private final boolean downPaymentPeriod;
|
||||
|
||||
public static LoanSchedulePeriodData disbursementOnlyPeriod(final LocalDate disbursementDate, final BigDecimal principalDisbursed,
|
||||
final BigDecimal feeChargesDueAtTimeOfDisbursement, final boolean isDisbursed) {
|
||||
final Integer periodNumber = null;
|
||||
final LocalDate from = null;
|
||||
return new LoanSchedulePeriodData(periodNumber, from, disbursementDate, principalDisbursed, feeChargesDueAtTimeOfDisbursement,
|
||||
isDisbursed);
|
||||
return builder().dueDate(disbursementDate) //
|
||||
.principalDisbursed(principalDisbursed) //
|
||||
.principalLoanBalanceOutstanding(principalDisbursed) //
|
||||
.feeChargesDue(feeChargesDueAtTimeOfDisbursement) //
|
||||
.feeChargesPaid(isDisbursed ? feeChargesDueAtTimeOfDisbursement : null) //
|
||||
.feeChargesOutstanding(isDisbursed ? null : feeChargesDueAtTimeOfDisbursement) //
|
||||
.totalOriginalDueForPeriod(feeChargesDueAtTimeOfDisbursement) //
|
||||
.totalDueForPeriod(feeChargesDueAtTimeOfDisbursement) //
|
||||
.totalPaidForPeriod(isDisbursed ? feeChargesDueAtTimeOfDisbursement : null) //
|
||||
.totalOutstandingForPeriod(isDisbursed ? null : feeChargesDueAtTimeOfDisbursement) //
|
||||
.totalActualCostOfLoanForPeriod(feeChargesDueAtTimeOfDisbursement) //
|
||||
.totalOverdue(DateUtils.isBeforeBusinessDate(disbursementDate) && !isDisbursed ? feeChargesDueAtTimeOfDisbursement : null) //
|
||||
.build();
|
||||
}
|
||||
|
||||
public static LoanSchedulePeriodData repaymentOnlyPeriod(final Integer periodNumber, final LocalDate fromDate, final LocalDate dueDate,
|
||||
final BigDecimal principalDue, final BigDecimal principalOutstanding, final BigDecimal interestDueOnPrincipalOutstanding,
|
||||
final BigDecimal feeChargesDueForPeriod, final BigDecimal penaltyChargesDueForPeriod, final BigDecimal totalDueForPeriod,
|
||||
final BigDecimal totalInstallmentAmountForPeriod) {
|
||||
final BigDecimal principalDue, final BigDecimal outstandingLoanBalance, final BigDecimal interestDue, final BigDecimal feeDue,
|
||||
final BigDecimal penaltyDue) {
|
||||
|
||||
return new LoanSchedulePeriodData(periodNumber, fromDate, dueDate, principalDue, principalOutstanding,
|
||||
interestDueOnPrincipalOutstanding, feeChargesDueForPeriod, penaltyChargesDueForPeriod, totalDueForPeriod,
|
||||
totalInstallmentAmountForPeriod);
|
||||
BigDecimal totalDue = MathUtil.add(principalDue, interestDue, feeDue, penaltyDue);
|
||||
BigDecimal totalActualCostOfLoanForPeriod = MathUtil.add(interestDue, feeDue, penaltyDue);
|
||||
BigDecimal totalInstallmentAmount = MathUtil.add(principalDue, interestDue);
|
||||
|
||||
return builder().period(periodNumber) //
|
||||
.fromDate(fromDate) //
|
||||
.dueDate(dueDate) //
|
||||
.daysInPeriod(DateUtils.getExactDifferenceInDays(fromDate, dueDate)) //
|
||||
.principalDue(principalDue) //
|
||||
.principalOriginalDue(principalDue) //
|
||||
.principalOutstanding(principalDue) //
|
||||
.principalLoanBalanceOutstanding(outstandingLoanBalance) //
|
||||
.interestDue(interestDue) //
|
||||
.interestOriginalDue(interestDue) //
|
||||
.interestOutstanding(interestDue) //
|
||||
.feeChargesDue(feeDue) //
|
||||
.feeChargesOutstanding(feeDue) //
|
||||
.penaltyChargesDue(penaltyDue) //
|
||||
.penaltyChargesOutstanding(penaltyDue) //
|
||||
.totalOriginalDueForPeriod(totalDue) //
|
||||
.totalDueForPeriod(totalDue) //
|
||||
.totalOutstandingForPeriod(totalDue) //
|
||||
.totalActualCostOfLoanForPeriod(totalActualCostOfLoanForPeriod) //
|
||||
.totalInstallmentAmountForPeriod(totalInstallmentAmount) //
|
||||
.totalOverdue(DateUtils.isBeforeBusinessDate(dueDate) ? totalDue : null) //
|
||||
.build();
|
||||
}
|
||||
|
||||
public static LoanSchedulePeriodData downPaymentOnlyPeriod(final Integer periodNumber, final LocalDate periodDate,
|
||||
final BigDecimal principalDue, final BigDecimal principalOutstanding) {
|
||||
return new LoanSchedulePeriodData(periodNumber, periodDate, periodDate, principalDue, principalOutstanding);
|
||||
final BigDecimal principalDue, final BigDecimal outstandingLoanBalance) {
|
||||
return builder().period(periodNumber) //
|
||||
.fromDate(periodDate) //
|
||||
.dueDate(periodDate) //
|
||||
.principalOriginalDue(principalDue) //
|
||||
.principalDue(principalDue) //
|
||||
.principalOutstanding(principalDue) //
|
||||
.principalLoanBalanceOutstanding(outstandingLoanBalance) //
|
||||
.totalOriginalDueForPeriod(principalDue) //
|
||||
.totalDueForPeriod(principalDue) //
|
||||
.totalOutstandingForPeriod(principalDue) //
|
||||
.totalInstallmentAmountForPeriod(principalDue) //
|
||||
.downPaymentPeriod(true) //
|
||||
.totalOverdue(DateUtils.isBeforeBusinessDate(periodDate) ? principalDue : null) //
|
||||
.build();
|
||||
}
|
||||
|
||||
public static LoanSchedulePeriodData periodWithPayments(@SuppressWarnings("unused") final Long loanId, final Integer periodNumber,
|
||||
final LocalDate fromDate, final LocalDate dueDate, final LocalDate obligationsMetOnDate, final boolean complete,
|
||||
final BigDecimal principalOriginalDue, final BigDecimal principalPaid, final BigDecimal principalWrittenOff,
|
||||
final BigDecimal principalOutstanding, final BigDecimal outstandingPrincipalBalanceOfLoan,
|
||||
final BigDecimal interestDueOnPrincipalOutstanding, final BigDecimal interestPaid, final BigDecimal interestWaived,
|
||||
final BigDecimal interestWrittenOff, final BigDecimal interestOutstanding, final BigDecimal feeChargesDue,
|
||||
final BigDecimal feeChargesPaid, final BigDecimal feeChargesWaived, final BigDecimal feeChargesWrittenOff,
|
||||
final BigDecimal feeChargesOutstanding, final BigDecimal penaltyChargesDue, final BigDecimal penaltyChargesPaid,
|
||||
final BigDecimal penaltyChargesWaived, final BigDecimal penaltyChargesWrittenOff, final BigDecimal penaltyChargesOutstanding,
|
||||
final BigDecimal totalDueForPeriod, final BigDecimal totalPaid, final BigDecimal totalPaidInAdvanceForPeriod,
|
||||
public static LoanSchedulePeriodData periodWithPayments(final Integer periodNumber, final LocalDate fromDate, final LocalDate dueDate,
|
||||
final LocalDate obligationsMetOnDate, final boolean complete, final BigDecimal principalOriginalDue,
|
||||
final BigDecimal principalPaid, final BigDecimal principalWrittenOff, final BigDecimal principalOutstanding,
|
||||
final BigDecimal outstandingPrincipalBalanceOfLoan, final BigDecimal interestDue, final BigDecimal interestPaid,
|
||||
final BigDecimal interestWaived, final BigDecimal interestWrittenOff, final BigDecimal interestOutstanding,
|
||||
final BigDecimal feeChargesDue, final BigDecimal feeChargesPaid, final BigDecimal feeChargesWaived,
|
||||
final BigDecimal feeChargesWrittenOff, final BigDecimal feeChargesOutstanding, final BigDecimal penaltyChargesDue,
|
||||
final BigDecimal penaltyChargesPaid, final BigDecimal penaltyChargesWaived, final BigDecimal penaltyChargesWrittenOff,
|
||||
final BigDecimal penaltyChargesOutstanding, final BigDecimal totalPaid, final BigDecimal totalPaidInAdvanceForPeriod,
|
||||
final BigDecimal totalPaidLateForPeriod, final BigDecimal totalWaived, final BigDecimal totalWrittenOff,
|
||||
final BigDecimal totalOutstanding, final BigDecimal totalActualCostOfLoanForPeriod,
|
||||
final BigDecimal totalInstallmentAmountForPeriod, final BigDecimal totalCredits, final boolean isDownPayment,
|
||||
final BigDecimal totalAccruedInterest) {
|
||||
final BigDecimal totalCredits, final boolean isDownPayment, final BigDecimal totalAccruedInterest) {
|
||||
|
||||
return new LoanSchedulePeriodData(periodNumber, fromDate, dueDate, obligationsMetOnDate, complete, principalOriginalDue,
|
||||
principalPaid, principalWrittenOff, principalOutstanding, outstandingPrincipalBalanceOfLoan,
|
||||
interestDueOnPrincipalOutstanding, interestPaid, interestWaived, interestWrittenOff, interestOutstanding, feeChargesDue,
|
||||
feeChargesPaid, feeChargesWaived, feeChargesWrittenOff, feeChargesOutstanding, penaltyChargesDue, penaltyChargesPaid,
|
||||
penaltyChargesWaived, penaltyChargesWrittenOff, penaltyChargesOutstanding, totalDueForPeriod, totalPaid,
|
||||
totalPaidInAdvanceForPeriod, totalPaidLateForPeriod, totalWaived, totalWrittenOff, totalOutstanding,
|
||||
totalActualCostOfLoanForPeriod, totalInstallmentAmountForPeriod, totalCredits, isDownPayment, totalAccruedInterest);
|
||||
BigDecimal totalDue = MathUtil.add(principalOriginalDue, interestDue, feeChargesDue, penaltyChargesDue);
|
||||
BigDecimal totalOutstanding = MathUtil.add(principalOutstanding, interestOutstanding, feeChargesOutstanding,
|
||||
penaltyChargesOutstanding);
|
||||
BigDecimal totalActualCostOfLoanForPeriod = MathUtil.add(interestDue, feeChargesDue, penaltyChargesDue);
|
||||
BigDecimal totalInstallmentAmount = MathUtil.add(principalOriginalDue, interestDue);
|
||||
|
||||
return builder().period(periodNumber) //
|
||||
.fromDate(fromDate) //
|
||||
.dueDate(dueDate) //
|
||||
.obligationsMetOnDate(obligationsMetOnDate) //
|
||||
.complete(complete) //
|
||||
.daysInPeriod(DateUtils.getExactDifferenceInDays(fromDate, dueDate)) //
|
||||
.principalDue(principalOriginalDue) //
|
||||
.principalOriginalDue(principalOriginalDue) //
|
||||
.principalPaid(principalPaid) //
|
||||
.principalWrittenOff(principalWrittenOff) //
|
||||
.principalOutstanding(principalOutstanding) //
|
||||
.principalLoanBalanceOutstanding(outstandingPrincipalBalanceOfLoan) //
|
||||
.interestDue(interestDue) //
|
||||
.interestOriginalDue(interestDue) //
|
||||
.interestPaid(interestPaid) //
|
||||
.interestWaived(interestWaived) //
|
||||
.interestWrittenOff(interestWrittenOff) //
|
||||
.interestOutstanding(interestOutstanding) //
|
||||
.feeChargesDue(feeChargesDue) //
|
||||
.feeChargesPaid(feeChargesPaid) //
|
||||
.feeChargesWaived(feeChargesWaived) //
|
||||
.feeChargesWrittenOff(feeChargesWrittenOff) //
|
||||
.feeChargesOutstanding(feeChargesOutstanding) //
|
||||
.penaltyChargesDue(penaltyChargesDue) //
|
||||
.penaltyChargesPaid(penaltyChargesPaid) //
|
||||
.penaltyChargesWaived(penaltyChargesWaived) //
|
||||
.penaltyChargesWrittenOff(penaltyChargesWrittenOff) //
|
||||
.penaltyChargesOutstanding(penaltyChargesOutstanding) //
|
||||
.totalOriginalDueForPeriod(totalDue) //
|
||||
.totalDueForPeriod(totalDue) //
|
||||
.totalPaidForPeriod(totalPaid) //
|
||||
.totalPaidInAdvanceForPeriod(totalPaidInAdvanceForPeriod) //
|
||||
.totalPaidLateForPeriod(totalPaidLateForPeriod) //
|
||||
.totalWaivedForPeriod(totalWaived) //
|
||||
.totalWrittenOffForPeriod(totalWrittenOff) //
|
||||
.totalOutstandingForPeriod(totalOutstanding) //
|
||||
.totalActualCostOfLoanForPeriod(totalActualCostOfLoanForPeriod) //
|
||||
.totalInstallmentAmountForPeriod(totalInstallmentAmount) //
|
||||
.totalOverdue(DateUtils.isBeforeBusinessDate(dueDate) ? totalOutstanding : null) //
|
||||
.totalCredits(totalCredits) //
|
||||
.downPaymentPeriod(isDownPayment) //
|
||||
.totalAccruedInterest(totalAccruedInterest) //
|
||||
.build();
|
||||
}
|
||||
|
||||
public static LoanSchedulePeriodData withPaidDetail(final LoanSchedulePeriodData loanSchedulePeriodData, final boolean complete,
|
||||
final BigDecimal principalPaid, final BigDecimal interestPaid, final BigDecimal feeChargesPaid,
|
||||
final BigDecimal penaltyChargesPaid) {
|
||||
BigDecimal totalOutstanding = MathUtil.subtract(loanSchedulePeriodData.totalDueForPeriod, principalPaid, interestPaid,
|
||||
feeChargesPaid, penaltyChargesPaid);
|
||||
|
||||
return new LoanSchedulePeriodData(loanSchedulePeriodData.period, loanSchedulePeriodData.fromDate, loanSchedulePeriodData.dueDate,
|
||||
loanSchedulePeriodData.obligationsMetOnDate, complete, loanSchedulePeriodData.principalOriginalDue, principalPaid,
|
||||
loanSchedulePeriodData.principalWrittenOff, loanSchedulePeriodData.principalOutstanding,
|
||||
loanSchedulePeriodData.principalLoanBalanceOutstanding, loanSchedulePeriodData.interestDue, interestPaid,
|
||||
loanSchedulePeriodData.interestWaived, loanSchedulePeriodData.interestWrittenOff,
|
||||
loanSchedulePeriodData.interestOutstanding, loanSchedulePeriodData.feeChargesDue, feeChargesPaid,
|
||||
loanSchedulePeriodData.feeChargesWaived, loanSchedulePeriodData.feeChargesWrittenOff,
|
||||
loanSchedulePeriodData.feeChargesOutstanding, loanSchedulePeriodData.penaltyChargesDue, penaltyChargesPaid,
|
||||
loanSchedulePeriodData.penaltyChargesWaived, loanSchedulePeriodData.penaltyChargesWrittenOff,
|
||||
loanSchedulePeriodData.penaltyChargesOutstanding, loanSchedulePeriodData.totalDueForPeriod,
|
||||
loanSchedulePeriodData.totalPaidForPeriod, loanSchedulePeriodData.totalPaidInAdvanceForPeriod,
|
||||
loanSchedulePeriodData.totalPaidLateForPeriod, loanSchedulePeriodData.totalWaivedForPeriod,
|
||||
loanSchedulePeriodData.totalWrittenOffForPeriod, loanSchedulePeriodData.totalOutstandingForPeriod,
|
||||
loanSchedulePeriodData.totalActualCostOfLoanForPeriod, loanSchedulePeriodData.totalInstallmentAmountForPeriod,
|
||||
loanSchedulePeriodData.totalCredits, loanSchedulePeriodData.getDownPaymentPeriod(),
|
||||
loanSchedulePeriodData.totalAccruedInterest);
|
||||
}
|
||||
|
||||
/*
|
||||
* constructor used for creating period on loan schedule that is only a disbursement (typically first period)
|
||||
*/
|
||||
private LoanSchedulePeriodData(final Integer periodNumber, final LocalDate fromDate, final LocalDate dueDate,
|
||||
final BigDecimal principalDisbursed, final BigDecimal chargesDueAtTimeOfDisbursement, final boolean isDisbursed) {
|
||||
this.period = periodNumber;
|
||||
this.fromDate = fromDate;
|
||||
this.dueDate = dueDate;
|
||||
this.obligationsMetOnDate = null;
|
||||
this.complete = null;
|
||||
if (fromDate != null) {
|
||||
this.daysInPeriod = DateUtils.getExactDifferenceInDays(this.fromDate, this.dueDate);
|
||||
} else {
|
||||
this.daysInPeriod = null;
|
||||
}
|
||||
this.principalDisbursed = principalDisbursed;
|
||||
this.principalOriginalDue = null;
|
||||
this.principalDue = null;
|
||||
this.principalPaid = null;
|
||||
this.principalWrittenOff = null;
|
||||
this.principalOutstanding = null;
|
||||
this.principalLoanBalanceOutstanding = principalDisbursed;
|
||||
|
||||
this.interestOriginalDue = null;
|
||||
this.interestDue = null;
|
||||
this.interestPaid = null;
|
||||
this.interestWaived = null;
|
||||
this.interestWrittenOff = null;
|
||||
this.interestOutstanding = null;
|
||||
|
||||
this.feeChargesDue = chargesDueAtTimeOfDisbursement;
|
||||
if (isDisbursed) {
|
||||
this.feeChargesPaid = chargesDueAtTimeOfDisbursement;
|
||||
this.feeChargesWaived = null;
|
||||
this.feeChargesWrittenOff = null;
|
||||
this.feeChargesOutstanding = null;
|
||||
} else {
|
||||
this.feeChargesPaid = null;
|
||||
this.feeChargesWaived = null;
|
||||
this.feeChargesWrittenOff = null;
|
||||
this.feeChargesOutstanding = chargesDueAtTimeOfDisbursement;
|
||||
}
|
||||
|
||||
this.penaltyChargesDue = null;
|
||||
this.penaltyChargesPaid = null;
|
||||
this.penaltyChargesWaived = null;
|
||||
this.penaltyChargesWrittenOff = null;
|
||||
this.penaltyChargesOutstanding = null;
|
||||
|
||||
this.totalOriginalDueForPeriod = chargesDueAtTimeOfDisbursement;
|
||||
this.totalDueForPeriod = chargesDueAtTimeOfDisbursement;
|
||||
this.totalPaidForPeriod = this.feeChargesPaid;
|
||||
this.totalPaidInAdvanceForPeriod = null;
|
||||
this.totalPaidLateForPeriod = null;
|
||||
this.totalWaivedForPeriod = null;
|
||||
this.totalWrittenOffForPeriod = null;
|
||||
this.totalOutstandingForPeriod = this.feeChargesOutstanding;
|
||||
this.totalActualCostOfLoanForPeriod = this.feeChargesDue;
|
||||
this.totalInstallmentAmountForPeriod = null;
|
||||
this.totalOverdue = DateUtils.isBeforeBusinessDate(dueDate) ? this.totalOutstandingForPeriod : null;
|
||||
this.totalCredits = BigDecimal.ZERO;
|
||||
this.totalAccruedInterest = BigDecimal.ZERO;
|
||||
this.downPaymentPeriod = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* used for repayment only period when creating an empty loan schedule for preview etc
|
||||
*/
|
||||
private LoanSchedulePeriodData(final Integer periodNumber, final LocalDate fromDate, final LocalDate dueDate,
|
||||
final BigDecimal principalOriginalDue, final BigDecimal principalOutstanding,
|
||||
final BigDecimal interestDueOnPrincipalOutstanding, final BigDecimal feeChargesDueForPeriod,
|
||||
final BigDecimal penaltyChargesDueForPeriod, final BigDecimal totalDueForPeriod, BigDecimal totalInstallmentAmountForPeriod) {
|
||||
this.period = periodNumber;
|
||||
this.fromDate = fromDate;
|
||||
this.dueDate = dueDate;
|
||||
this.obligationsMetOnDate = null;
|
||||
this.complete = null;
|
||||
if (fromDate != null) {
|
||||
this.daysInPeriod = DateUtils.getExactDifferenceInDays(this.fromDate, this.dueDate);
|
||||
} else {
|
||||
this.daysInPeriod = null;
|
||||
}
|
||||
this.principalDisbursed = null;
|
||||
this.principalOriginalDue = principalOriginalDue;
|
||||
this.principalDue = principalOriginalDue;
|
||||
this.principalPaid = null;
|
||||
this.principalWrittenOff = null;
|
||||
this.principalOutstanding = principalOriginalDue;
|
||||
this.principalLoanBalanceOutstanding = principalOutstanding;
|
||||
|
||||
this.interestOriginalDue = interestDueOnPrincipalOutstanding;
|
||||
this.interestDue = interestDueOnPrincipalOutstanding;
|
||||
this.interestPaid = null;
|
||||
this.interestWaived = null;
|
||||
this.interestWrittenOff = null;
|
||||
this.interestOutstanding = interestDueOnPrincipalOutstanding;
|
||||
|
||||
this.feeChargesDue = feeChargesDueForPeriod;
|
||||
this.feeChargesPaid = null;
|
||||
this.feeChargesWaived = null;
|
||||
this.feeChargesWrittenOff = null;
|
||||
this.feeChargesOutstanding = null;
|
||||
|
||||
this.penaltyChargesDue = penaltyChargesDueForPeriod;
|
||||
this.penaltyChargesPaid = null;
|
||||
this.penaltyChargesWaived = null;
|
||||
this.penaltyChargesWrittenOff = null;
|
||||
this.penaltyChargesOutstanding = null;
|
||||
|
||||
this.totalOriginalDueForPeriod = totalDueForPeriod;
|
||||
this.totalDueForPeriod = totalDueForPeriod;
|
||||
this.totalPaidForPeriod = BigDecimal.ZERO;
|
||||
this.totalPaidInAdvanceForPeriod = null;
|
||||
this.totalPaidLateForPeriod = null;
|
||||
this.totalWaivedForPeriod = null;
|
||||
this.totalWrittenOffForPeriod = null;
|
||||
this.totalOutstandingForPeriod = totalDueForPeriod;
|
||||
this.totalActualCostOfLoanForPeriod = interestDueOnPrincipalOutstanding.add(feeChargesDueForPeriod);
|
||||
this.totalInstallmentAmountForPeriod = totalInstallmentAmountForPeriod;
|
||||
this.totalOverdue = DateUtils.isBeforeBusinessDate(dueDate) ? this.totalOutstandingForPeriod : null;
|
||||
this.totalCredits = BigDecimal.ZERO;
|
||||
this.totalAccruedInterest = BigDecimal.ZERO;
|
||||
this.downPaymentPeriod = false;
|
||||
}
|
||||
|
||||
// TODO refactor the class to builder pattern
|
||||
/*
|
||||
* used for down payment only period when creating an empty loan schedule for preview etc
|
||||
*/
|
||||
private LoanSchedulePeriodData(Integer periodNumber, LocalDate fromDate, LocalDate dueDate, BigDecimal principalDue,
|
||||
BigDecimal principalOutstanding) {
|
||||
this.period = periodNumber;
|
||||
this.fromDate = fromDate;
|
||||
this.dueDate = dueDate;
|
||||
this.obligationsMetOnDate = null;
|
||||
this.complete = null;
|
||||
this.daysInPeriod = 1; // TODO: check this may should be 0 or somewhere else should be 1?
|
||||
this.principalDisbursed = null;
|
||||
this.principalOriginalDue = principalDue;
|
||||
this.principalDue = principalOriginalDue;
|
||||
this.principalPaid = null;
|
||||
this.principalWrittenOff = null;
|
||||
this.principalOutstanding = principalOriginalDue;
|
||||
this.principalLoanBalanceOutstanding = principalOutstanding;
|
||||
|
||||
this.interestOriginalDue = null;
|
||||
this.interestDue = null;
|
||||
this.interestPaid = null;
|
||||
this.interestWaived = null;
|
||||
this.interestWrittenOff = null;
|
||||
this.interestOutstanding = null;
|
||||
|
||||
this.feeChargesDue = null;
|
||||
this.feeChargesPaid = null;
|
||||
this.feeChargesWaived = null;
|
||||
this.feeChargesWrittenOff = null;
|
||||
this.feeChargesOutstanding = null;
|
||||
|
||||
this.penaltyChargesDue = null;
|
||||
this.penaltyChargesPaid = null;
|
||||
this.penaltyChargesWaived = null;
|
||||
this.penaltyChargesWrittenOff = null;
|
||||
this.penaltyChargesOutstanding = null;
|
||||
|
||||
this.totalOriginalDueForPeriod = principalDue;
|
||||
this.totalDueForPeriod = principalDue;
|
||||
this.totalPaidForPeriod = BigDecimal.ZERO;
|
||||
this.totalPaidInAdvanceForPeriod = null;
|
||||
this.totalPaidLateForPeriod = null;
|
||||
this.totalWaivedForPeriod = null;
|
||||
this.totalWrittenOffForPeriod = null;
|
||||
this.totalOutstandingForPeriod = totalDueForPeriod;
|
||||
this.totalActualCostOfLoanForPeriod = null;
|
||||
this.totalInstallmentAmountForPeriod = totalDueForPeriod;
|
||||
this.totalOverdue = DateUtils.isBeforeBusinessDate(dueDate) ? this.totalOutstandingForPeriod : null;
|
||||
this.totalCredits = BigDecimal.ZERO;
|
||||
this.downPaymentPeriod = true;
|
||||
this.totalAccruedInterest = BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Used for creating loan schedule periods with full information on expected principal, interest & charges along
|
||||
* with what portion of each is paid.
|
||||
*/
|
||||
private LoanSchedulePeriodData(final Integer periodNumber, final LocalDate fromDate, final LocalDate dueDate,
|
||||
final LocalDate obligationsMetOnDate, final boolean complete, final BigDecimal principalOriginalDue,
|
||||
final BigDecimal principalPaid, final BigDecimal principalWrittenOff, final BigDecimal principalOutstanding,
|
||||
final BigDecimal principalLoanBalanceOutstanding, final BigDecimal interestDueOnPrincipalOutstanding,
|
||||
final BigDecimal interestPaid, final BigDecimal interestWaived, final BigDecimal interestWrittenOff,
|
||||
final BigDecimal interestOutstanding, final BigDecimal feeChargesDue, final BigDecimal feeChargesPaid,
|
||||
final BigDecimal feeChargesWaived, final BigDecimal feeChargesWrittenOff, final BigDecimal feeChargesOutstanding,
|
||||
final BigDecimal penaltyChargesDue, final BigDecimal penaltyChargesPaid, final BigDecimal penaltyChargesWaived,
|
||||
final BigDecimal penaltyChargesWrittenOff, final BigDecimal penaltyChargesOutstanding, final BigDecimal totalDueForPeriod,
|
||||
final BigDecimal totalPaid, final BigDecimal totalPaidInAdvanceForPeriod, final BigDecimal totalPaidLateForPeriod,
|
||||
final BigDecimal totalWaived, final BigDecimal totalWrittenOff, final BigDecimal totalOutstanding,
|
||||
final BigDecimal totalActualCostOfLoanForPeriod, final BigDecimal totalInstallmentAmountForPeriod,
|
||||
final BigDecimal totalCredits, final boolean isDownPayment, final BigDecimal totalAccruedInterest) {
|
||||
this.period = periodNumber;
|
||||
this.fromDate = fromDate;
|
||||
this.dueDate = dueDate;
|
||||
this.obligationsMetOnDate = obligationsMetOnDate;
|
||||
this.complete = complete;
|
||||
if (fromDate != null) {
|
||||
this.daysInPeriod = DateUtils.getExactDifferenceInDays(this.fromDate, this.dueDate);
|
||||
} else {
|
||||
this.daysInPeriod = null;
|
||||
}
|
||||
this.principalDisbursed = null;
|
||||
this.principalOriginalDue = principalOriginalDue;
|
||||
this.principalDue = principalOriginalDue;
|
||||
this.principalPaid = principalPaid;
|
||||
this.principalWrittenOff = principalWrittenOff;
|
||||
this.principalOutstanding = principalOutstanding;
|
||||
this.principalLoanBalanceOutstanding = principalLoanBalanceOutstanding;
|
||||
|
||||
this.interestOriginalDue = interestDueOnPrincipalOutstanding;
|
||||
this.interestDue = interestDueOnPrincipalOutstanding;
|
||||
this.interestPaid = interestPaid;
|
||||
this.interestWaived = interestWaived;
|
||||
this.interestWrittenOff = interestWrittenOff;
|
||||
this.interestOutstanding = interestOutstanding;
|
||||
|
||||
this.feeChargesDue = feeChargesDue;
|
||||
this.feeChargesPaid = feeChargesPaid;
|
||||
this.feeChargesWaived = feeChargesWaived;
|
||||
this.feeChargesWrittenOff = feeChargesWrittenOff;
|
||||
this.feeChargesOutstanding = feeChargesOutstanding;
|
||||
|
||||
this.penaltyChargesDue = penaltyChargesDue;
|
||||
this.penaltyChargesPaid = penaltyChargesPaid;
|
||||
this.penaltyChargesWaived = penaltyChargesWaived;
|
||||
this.penaltyChargesWrittenOff = penaltyChargesWrittenOff;
|
||||
this.penaltyChargesOutstanding = penaltyChargesOutstanding;
|
||||
|
||||
this.totalOriginalDueForPeriod = totalDueForPeriod;
|
||||
this.totalDueForPeriod = totalDueForPeriod;
|
||||
this.totalPaidForPeriod = totalPaid;
|
||||
this.totalPaidInAdvanceForPeriod = totalPaidInAdvanceForPeriod;
|
||||
this.totalPaidLateForPeriod = totalPaidLateForPeriod;
|
||||
this.totalWaivedForPeriod = totalWaived;
|
||||
this.totalWrittenOffForPeriod = totalWrittenOff;
|
||||
this.totalOutstandingForPeriod = totalOutstanding;
|
||||
this.totalActualCostOfLoanForPeriod = totalActualCostOfLoanForPeriod;
|
||||
this.totalInstallmentAmountForPeriod = totalInstallmentAmountForPeriod;
|
||||
this.totalOverdue = DateUtils.isBeforeBusinessDate(dueDate) ? this.totalOutstandingForPeriod : null;
|
||||
this.totalCredits = totalCredits;
|
||||
this.downPaymentPeriod = isDownPayment;
|
||||
this.totalAccruedInterest = totalAccruedInterest;
|
||||
}
|
||||
|
||||
private BigDecimal defaultToZeroIfNull(final BigDecimal possibleNullValue) {
|
||||
BigDecimal value = BigDecimal.ZERO;
|
||||
if (possibleNullValue != null) {
|
||||
value = possibleNullValue;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public boolean isActualPeriodForNotDuePayableCalculation(final LocalDate businessDate) {
|
||||
boolean actualPeriod = false;
|
||||
if (getPeriod() != null) {
|
||||
if (getPeriod() == 1) {
|
||||
actualPeriod = ((businessDate.compareTo(getFromDate()) >= 0) && businessDate.compareTo(getDueDate()) < 0);
|
||||
} else {
|
||||
actualPeriod = ((businessDate.compareTo(getFromDate()) >= 0) && businessDate.compareTo(getDueDate()) < 0);
|
||||
}
|
||||
}
|
||||
|
||||
return actualPeriod;
|
||||
return builder().period(loanSchedulePeriodData.period) //
|
||||
.fromDate(loanSchedulePeriodData.fromDate) //
|
||||
.dueDate(loanSchedulePeriodData.dueDate) //
|
||||
.obligationsMetOnDate(loanSchedulePeriodData.obligationsMetOnDate) //
|
||||
.complete(complete) //
|
||||
.daysInPeriod(DateUtils.getExactDifferenceInDays(loanSchedulePeriodData.fromDate, loanSchedulePeriodData.dueDate)) //
|
||||
.principalDue(loanSchedulePeriodData.principalOriginalDue) //
|
||||
.principalOriginalDue(loanSchedulePeriodData.principalOriginalDue) //
|
||||
.principalPaid(principalPaid) //
|
||||
.principalWrittenOff(loanSchedulePeriodData.principalWrittenOff) //
|
||||
.principalOutstanding(MathUtil.subtract(loanSchedulePeriodData.principalOriginalDue, principalPaid)) //
|
||||
.principalLoanBalanceOutstanding(loanSchedulePeriodData.principalLoanBalanceOutstanding) //
|
||||
.interestDue(loanSchedulePeriodData.interestDue) //
|
||||
.interestOriginalDue(loanSchedulePeriodData.interestDue) //
|
||||
.interestPaid(interestPaid) //
|
||||
.interestWaived(loanSchedulePeriodData.interestWaived) //
|
||||
.interestWrittenOff(loanSchedulePeriodData.interestWrittenOff) //
|
||||
.interestOutstanding(MathUtil.subtract(loanSchedulePeriodData.interestDue, interestPaid)) //
|
||||
.feeChargesDue(loanSchedulePeriodData.feeChargesDue) //
|
||||
.feeChargesPaid(feeChargesPaid) //
|
||||
.feeChargesWaived(loanSchedulePeriodData.feeChargesWaived) //
|
||||
.feeChargesWrittenOff(loanSchedulePeriodData.feeChargesWrittenOff) //
|
||||
.feeChargesOutstanding(MathUtil.subtract(loanSchedulePeriodData.feeChargesDue, feeChargesPaid)) //
|
||||
.penaltyChargesDue(loanSchedulePeriodData.penaltyChargesDue) //
|
||||
.penaltyChargesPaid(penaltyChargesPaid) //
|
||||
.penaltyChargesWaived(loanSchedulePeriodData.penaltyChargesWaived) //
|
||||
.penaltyChargesWrittenOff(loanSchedulePeriodData.penaltyChargesWrittenOff) //
|
||||
.penaltyChargesOutstanding(MathUtil.subtract(loanSchedulePeriodData.penaltyChargesDue, penaltyChargesPaid)) //
|
||||
.totalOriginalDueForPeriod(loanSchedulePeriodData.totalDueForPeriod) //
|
||||
.totalDueForPeriod(loanSchedulePeriodData.totalDueForPeriod) //
|
||||
.totalPaidForPeriod(MathUtil.add(principalPaid, interestPaid, feeChargesPaid, penaltyChargesPaid)) //
|
||||
.totalPaidInAdvanceForPeriod(loanSchedulePeriodData.totalPaidInAdvanceForPeriod) //
|
||||
.totalPaidLateForPeriod(loanSchedulePeriodData.totalPaidLateForPeriod) //
|
||||
.totalWaivedForPeriod(loanSchedulePeriodData.totalWaivedForPeriod) //
|
||||
.totalWrittenOffForPeriod(loanSchedulePeriodData.totalWrittenOffForPeriod) //
|
||||
.totalOutstandingForPeriod(totalOutstanding) //
|
||||
.totalActualCostOfLoanForPeriod(loanSchedulePeriodData.totalActualCostOfLoanForPeriod) //
|
||||
.totalInstallmentAmountForPeriod(loanSchedulePeriodData.totalInstallmentAmountForPeriod) //
|
||||
.totalOverdue(DateUtils.isBeforeBusinessDate(loanSchedulePeriodData.dueDate) ? totalOutstanding : null) //
|
||||
.totalCredits(loanSchedulePeriodData.totalCredits) //
|
||||
.downPaymentPeriod(loanSchedulePeriodData.isDownPaymentPeriod()) //
|
||||
.totalAccruedInterest(loanSchedulePeriodData.totalAccruedInterest) //
|
||||
.build();
|
||||
}
|
||||
|
||||
public BigDecimal getPrincipalDisbursed() {
|
||||
return defaultToZeroIfNull(this.principalDisbursed);
|
||||
return MathUtil.nullToDefault(this.principalDisbursed, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
public BigDecimal getPrincipalDue() {
|
||||
return defaultToZeroIfNull(this.principalDue);
|
||||
return MathUtil.nullToDefault(this.principalDue, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
public BigDecimal getPrincipalPaid() {
|
||||
return defaultToZeroIfNull(this.principalPaid);
|
||||
return MathUtil.nullToDefault(this.principalPaid, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
public BigDecimal getPrincipalWrittenOff() {
|
||||
return defaultToZeroIfNull(this.principalWrittenOff);
|
||||
return MathUtil.nullToDefault(this.principalWrittenOff, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
public BigDecimal getPrincipalOutstanding() {
|
||||
return defaultToZeroIfNull(this.principalOutstanding);
|
||||
return MathUtil.nullToDefault(this.principalOutstanding, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
public BigDecimal getInterestDue() {
|
||||
return defaultToZeroIfNull(this.interestDue);
|
||||
return MathUtil.nullToDefault(this.interestDue, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
public BigDecimal getInterestPaid() {
|
||||
return defaultToZeroIfNull(this.interestPaid);
|
||||
return MathUtil.nullToDefault(this.interestPaid, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
public BigDecimal getInterestWaived() {
|
||||
return defaultToZeroIfNull(this.interestWaived);
|
||||
return MathUtil.nullToDefault(this.interestWaived, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
public BigDecimal getInterestWrittenOff() {
|
||||
return defaultToZeroIfNull(this.interestWrittenOff);
|
||||
return MathUtil.nullToDefault(this.interestWrittenOff, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
public BigDecimal getInterestOutstanding() {
|
||||
return defaultToZeroIfNull(this.interestOutstanding);
|
||||
return MathUtil.nullToDefault(this.interestOutstanding, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
public BigDecimal getFeeChargesDue() {
|
||||
return defaultToZeroIfNull(this.feeChargesDue);
|
||||
return MathUtil.nullToDefault(this.feeChargesDue, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
public BigDecimal getFeeChargesWaived() {
|
||||
return defaultToZeroIfNull(this.feeChargesWaived);
|
||||
return MathUtil.nullToDefault(this.feeChargesWaived, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
public BigDecimal getFeeChargesWrittenOff() {
|
||||
return defaultToZeroIfNull(this.feeChargesWrittenOff);
|
||||
return MathUtil.nullToDefault(this.feeChargesWrittenOff, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
public BigDecimal getFeeChargesPaid() {
|
||||
return defaultToZeroIfNull(this.feeChargesPaid);
|
||||
return MathUtil.nullToDefault(this.feeChargesPaid, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
public BigDecimal getFeeChargesOutstanding() {
|
||||
return defaultToZeroIfNull(this.feeChargesOutstanding);
|
||||
return MathUtil.nullToDefault(this.feeChargesOutstanding, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
public BigDecimal getPenaltyChargesDue() {
|
||||
return defaultToZeroIfNull(this.penaltyChargesDue);
|
||||
return MathUtil.nullToDefault(this.penaltyChargesDue, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
public BigDecimal getPenaltyChargesWaived() {
|
||||
return defaultToZeroIfNull(this.penaltyChargesWaived);
|
||||
return MathUtil.nullToDefault(this.penaltyChargesWaived, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
public BigDecimal getPenaltyChargesWrittenOff() {
|
||||
return defaultToZeroIfNull(this.penaltyChargesWrittenOff);
|
||||
return MathUtil.nullToDefault(this.penaltyChargesWrittenOff, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
public BigDecimal getPenaltyChargesPaid() {
|
||||
return defaultToZeroIfNull(this.penaltyChargesPaid);
|
||||
return MathUtil.nullToDefault(this.penaltyChargesPaid, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
public BigDecimal getPenaltyChargesOutstanding() {
|
||||
return defaultToZeroIfNull(this.penaltyChargesOutstanding);
|
||||
return MathUtil.nullToDefault(this.penaltyChargesOutstanding, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
public BigDecimal getTotalOverdue() {
|
||||
return defaultToZeroIfNull(this.totalOverdue);
|
||||
return MathUtil.nullToDefault(this.totalOverdue, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
public BigDecimal totalOutstandingForPeriod() {
|
||||
return defaultToZeroIfNull(this.totalOutstandingForPeriod);
|
||||
return MathUtil.nullToDefault(this.totalOutstandingForPeriod, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ public final class LoanScheduleModelRepaymentPeriod implements LoanScheduleModel
|
||||
public LoanSchedulePeriodData toData() {
|
||||
return LoanSchedulePeriodData.repaymentOnlyPeriod(this.periodNumber, this.fromDate, this.dueDate, this.principalDue.getAmount(),
|
||||
this.outstandingLoanBalance.getAmount(), this.interestDue.getAmount(), this.feeChargesDue.getAmount(),
|
||||
this.penaltyChargesDue.getAmount(), this.totalDue.getAmount(), this.principalDue.plus(this.interestDue).getAmount());
|
||||
this.penaltyChargesDue.getAmount());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ public final class LoanRescheduleModelRepaymentPeriod implements LoanRescheduleM
|
||||
public LoanSchedulePeriodData toData() {
|
||||
return LoanSchedulePeriodData.repaymentOnlyPeriod(this.periodNumber, this.fromDate, this.dueDate, this.principalDue.getAmount(),
|
||||
this.outstandingLoanBalance.getAmount(), this.interestDue.getAmount(), this.feeChargesDue.getAmount(),
|
||||
this.penaltyChargesDue.getAmount(), this.totalDue.getAmount(), this.principalDue.plus(this.interestDue).getAmount());
|
||||
this.penaltyChargesDue.getAmount());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+7
-9
@@ -341,7 +341,8 @@ public class LoanArrearsAgingServiceImpl implements LoanArrearsAgingService {
|
||||
|
||||
OriginalScheduleExtractor(final String loanIdsAsString, DatabaseSpecificSQLGenerator sqlGenerator) {
|
||||
final StringBuilder scheduleDetail = new StringBuilder();
|
||||
scheduleDetail.append("select ml.id as loanId, mr.duedate as dueDate, mr.principal_amount as principalAmount, ");
|
||||
scheduleDetail.append(
|
||||
"select ml.id as loanId, mr.installment as installmentNumber, mr.fromdate as fromDate, mr.duedate as dueDate, mr.principal_amount as principalAmount, ");
|
||||
scheduleDetail.append(
|
||||
"mr.interest_amount as interestAmount, mr.fee_charges_amount as feeAmount, mr.penalty_charges_amount as penaltyAmount ");
|
||||
scheduleDetail.append("from m_loan ml INNER JOIN m_loan_repayment_schedule_history mr on mr.loan_id = ml.id ");
|
||||
@@ -369,19 +370,16 @@ public class LoanArrearsAgingServiceImpl implements LoanArrearsAgingService {
|
||||
}
|
||||
|
||||
private LoanSchedulePeriodData fetchLoanSchedulePeriodData(ResultSet rs) throws SQLException {
|
||||
final Integer installmentNumber = JdbcSupport.getInteger(rs, "installmentNumber");
|
||||
final LocalDate fromDate = JdbcSupport.getLocalDate(rs, "fromDate");
|
||||
final LocalDate dueDate = JdbcSupport.getLocalDate(rs, "dueDate");
|
||||
final BigDecimal principalDue = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "principalAmount");
|
||||
final BigDecimal interestDueOnPrincipalOutstanding = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "interestAmount");
|
||||
final BigDecimal totalInstallmentAmount = principalDue.add(interestDueOnPrincipalOutstanding);
|
||||
final BigDecimal feeChargesDueForPeriod = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "feeAmount");
|
||||
final BigDecimal penaltyChargesDueForPeriod = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "penaltyAmount");
|
||||
final Integer periodNumber = null;
|
||||
final LocalDate fromDate = null;
|
||||
final BigDecimal principalOutstanding = null;
|
||||
final BigDecimal totalDueForPeriod = null;
|
||||
return LoanSchedulePeriodData.repaymentOnlyPeriod(periodNumber, fromDate, dueDate, principalDue, principalOutstanding,
|
||||
interestDueOnPrincipalOutstanding, feeChargesDueForPeriod, penaltyChargesDueForPeriod, totalDueForPeriod,
|
||||
totalInstallmentAmount);
|
||||
|
||||
return LoanSchedulePeriodData.repaymentOnlyPeriod(installmentNumber, fromDate, dueDate, principalDue, null,
|
||||
interestDueOnPrincipalOutstanding, feeChargesDueForPeriod, penaltyChargesDueForPeriod);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+3
-12
@@ -122,13 +122,7 @@ public class LoanScheduleCalculationPlatformServiceImpl implements LoanScheduleC
|
||||
outstandingAmountsDTO.principal().getAmount(), outstandingAmountsDTO.interest().getAmount(),
|
||||
outstandingAmountsDTO.feeCharges().getAmount(), outstandingAmountsDTO.penaltyCharges().getAmount(), false, null);
|
||||
|
||||
Money totalAmount = totalPrincipal.plus(loanRepaymentScheduleInstallment.getFeeChargesOutstanding(currency))
|
||||
.plus(loanRepaymentScheduleInstallment.getPenaltyChargesOutstanding(currency));
|
||||
Money interestDue = Money.zero(currency);
|
||||
if (loanRepaymentScheduleInstallment.isInterestDue(currency)) {
|
||||
interestDue = loanRepaymentScheduleInstallment.getInterestOutstanding(currency);
|
||||
totalAmount = totalAmount.plus(interestDue);
|
||||
}
|
||||
Money interestDue = loanRepaymentScheduleInstallment.getInterestOutstanding(currency);
|
||||
boolean isNewPaymentRequired = loanRepaymentScheduleInstallment.isInterestDue(currency) || totalPrincipal.isGreaterThanZero();
|
||||
|
||||
LoanScheduleModel model = this.loanScheduleAssembler.assembleForInterestRecalculation(loanApplicationTerms, loan.getOfficeId(),
|
||||
@@ -141,14 +135,12 @@ public class LoanScheduleCalculationPlatformServiceImpl implements LoanScheduleC
|
||||
periodData.getFromDate(), periodData.getDueDate(), totalPrincipal.getAmount(),
|
||||
periodData.getPrincipalLoanBalanceOutstanding(), interestDue.getAmount(),
|
||||
loanRepaymentScheduleInstallment.getFeeChargesCharged(currency).getAmount(),
|
||||
loanRepaymentScheduleInstallment.getPenaltyChargesCharged(currency).getAmount(), totalAmount.getAmount(),
|
||||
totalPrincipal.plus(interestDue).getAmount());
|
||||
loanRepaymentScheduleInstallment.getPenaltyChargesCharged(currency).getAmount());
|
||||
futureInstallments.add(loanSchedulePeriodData);
|
||||
isNewPaymentRequired = false;
|
||||
} else if (DateUtils.isAfter(periodData.getDueDate(), today)) {
|
||||
futureInstallments.add(periodData);
|
||||
}
|
||||
|
||||
}
|
||||
loanScheduleData.updateFuturePeriods(futureInstallments);
|
||||
}
|
||||
@@ -198,8 +190,7 @@ public class LoanScheduleCalculationPlatformServiceImpl implements LoanScheduleC
|
||||
LoanSchedulePeriodData loanSchedulePeriodData = LoanSchedulePeriodData.repaymentOnlyPeriod(installment.getInstallmentNumber(),
|
||||
installment.getFromDate(), installment.getDueDate(), installment.getPrincipal(currency).getAmount(),
|
||||
outstanding.getAmount(), installment.getInterestCharged(currency).getAmount(),
|
||||
installment.getFeeChargesCharged(currency).getAmount(), installment.getPenaltyChargesCharged(currency).getAmount(),
|
||||
installment.getDue(currency).getAmount(), installment.getTotalPrincipalAndInterest(currency).getAmount());
|
||||
installment.getFeeChargesCharged(currency).getAmount(), installment.getPenaltyChargesCharged(currency).getAmount());
|
||||
installmentData.add(loanSchedulePeriodData);
|
||||
totalInterest = totalInterest.plus(installment.getInterestCharged(currency));
|
||||
totalCharge = totalCharge.plus(installment.getFeeChargesCharged(currency));
|
||||
|
||||
+1
-4
@@ -191,9 +191,6 @@ public class LoanScheduleHistoryReadPlatformServiceImpl implements LoanScheduleH
|
||||
final BigDecimal interestExpectedDue = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "interestDue");
|
||||
totalInterestCharged = totalInterestCharged.plus(interestExpectedDue);
|
||||
|
||||
final BigDecimal totalInstallmentAmount = totalPrincipalExpected.zero().plus(principalDue).plus(interestExpectedDue)
|
||||
.getAmount();
|
||||
|
||||
final BigDecimal feeChargesExpectedDue = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "feeChargesDue");
|
||||
totalFeeChargesCharged = totalFeeChargesCharged.plus(feeChargesExpectedDue);
|
||||
|
||||
@@ -218,7 +215,7 @@ public class LoanScheduleHistoryReadPlatformServiceImpl implements LoanScheduleH
|
||||
|
||||
final LoanSchedulePeriodData periodData = LoanSchedulePeriodData.repaymentOnlyPeriod(period, fromDate, dueDate,
|
||||
principalDue, outstandingPrincipalBalanceOfLoan, interestExpectedDue, feeChargesExpectedDue,
|
||||
penaltyChargesExpectedDue, totalDueForPeriod, totalInstallmentAmount);
|
||||
penaltyChargesExpectedDue);
|
||||
|
||||
periods.add(periodData);
|
||||
}
|
||||
|
||||
+2
-5
@@ -159,15 +159,12 @@ public abstract class CommonLoanSummaryDataProvider implements LoanSummaryDataPr
|
||||
|
||||
@Override
|
||||
public BigDecimal computeTotalUnpaidPayableDueInterestAmount(Collection<LoanSchedulePeriodData> periods, final LocalDate businessDate) {
|
||||
return periods.stream().filter(period -> !period.getDownPaymentPeriod() && businessDate.compareTo(period.getDueDate()) >= 0)
|
||||
return periods.stream().filter(period -> !period.isDownPaymentPeriod() && !businessDate.isBefore(period.getDueDate()))
|
||||
.map(LoanSchedulePeriodData::getInterestOutstanding).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoanSummaryData withOnlyCurrencyData(CurrencyData currencyData) {
|
||||
{
|
||||
return LoanSummaryData.builder().currency(currencyData).build();
|
||||
}
|
||||
return LoanSummaryData.builder().currency(currencyData).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
-2
@@ -46,8 +46,10 @@ public class CumulativeLoanSummaryDataProvider extends CommonLoanSummaryDataProv
|
||||
public BigDecimal computeTotalUnpaidPayableNotDueInterestAmountOnActualPeriod(final Loan loan,
|
||||
final Collection<LoanSchedulePeriodData> periods, final LocalDate businessDate, final CurrencyData currency) {
|
||||
// Find the current Period (If exists one) based on the Business date
|
||||
final Optional<LoanSchedulePeriodData> optCurrentPeriod = periods.stream()
|
||||
.filter(period -> !period.getDownPaymentPeriod() && period.isActualPeriodForNotDuePayableCalculation(businessDate))
|
||||
final Optional<LoanSchedulePeriodData> optCurrentPeriod = periods.stream().filter(period -> !period.isDownPaymentPeriod() //
|
||||
&& period.getPeriod() != null //
|
||||
&& !businessDate.isBefore(period.getFromDate()) //
|
||||
&& businessDate.isBefore(period.getDueDate())) //
|
||||
.findFirst();
|
||||
|
||||
if (optCurrentPeriod.isPresent()) {
|
||||
|
||||
+4
-7
@@ -1263,8 +1263,6 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
|
||||
final BigDecimal interestPaid = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "interestPaid");
|
||||
final BigDecimal interestWaived = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "interestWaived");
|
||||
final BigDecimal interestWrittenOff = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "interestWrittenOff");
|
||||
final BigDecimal totalInstallmentAmount = totalPrincipalPaid.zero().plus(principalDue).plus(interestExpectedDue)
|
||||
.getAmount();
|
||||
final BigDecimal accrualInterest = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "accrualInterest");
|
||||
|
||||
final BigDecimal interestActualDue = interestExpectedDue.subtract(interestWaived).subtract(interestWrittenOff);
|
||||
@@ -1330,14 +1328,13 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
|
||||
|
||||
LoanSchedulePeriodData periodData;
|
||||
|
||||
periodData = LoanSchedulePeriodData.periodWithPayments(loanId, period, fromDate, dueDate, obligationsMetOnDate, complete,
|
||||
periodData = LoanSchedulePeriodData.periodWithPayments(period, fromDate, dueDate, obligationsMetOnDate, complete,
|
||||
principalDue, principalPaid, principalWrittenOff, principalOutstanding, outstandingPrincipalBalanceOfLoan,
|
||||
interestExpectedDue, interestPaid, interestWaived, interestWrittenOff, interestOutstanding, feeChargesExpectedDue,
|
||||
feeChargesPaid, feeChargesWaived, feeChargesWrittenOff, feeChargesOutstanding, penaltyChargesExpectedDue,
|
||||
penaltyChargesPaid, penaltyChargesWaived, penaltyChargesWrittenOff, penaltyChargesOutstanding, totalDueForPeriod,
|
||||
totalPaidForPeriod, totalPaidInAdvanceForPeriod, totalPaidLateForPeriod, totalWaivedForPeriod,
|
||||
totalWrittenOffForPeriod, totalOutstandingForPeriod, totalActualCostOfLoanForPeriod, totalInstallmentAmount,
|
||||
credits, isDownPayment, accrualInterest);
|
||||
penaltyChargesPaid, penaltyChargesWaived, penaltyChargesWrittenOff, penaltyChargesOutstanding, totalPaidForPeriod,
|
||||
totalPaidInAdvanceForPeriod, totalPaidLateForPeriod, totalWaivedForPeriod, totalWrittenOffForPeriod, credits,
|
||||
isDownPayment, accrualInterest);
|
||||
|
||||
periods.add(periodData);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user