From e42eeee15614e5666c98cc0df30a3f01fce85f98 Mon Sep 17 00:00:00 2001 From: Adam Saghy Date: Mon, 9 Dec 2024 18:57:35 +0100 Subject: [PATCH] FINERACT-2081: Refactor - Simplify `LoanSchedulePeriodData.java` class --- .../infrastructure/core/service/MathUtil.java | 168 +++--- .../LoanArrearsAgeingUpdateHandler.java | 10 +- .../LoanScheduleModelDownPaymentPeriod.java | 2 +- .../data/LoanSchedulePeriodData.java | 540 +++++++----------- .../LoanScheduleModelRepaymentPeriod.java | 2 +- .../LoanRescheduleModelRepaymentPeriod.java | 2 +- .../service/LoanArrearsAgingServiceImpl.java | 13 +- ...cheduleCalculationPlatformServiceImpl.java | 15 +- ...cheduleHistoryReadPlatformServiceImpl.java | 5 +- .../CommonLoanSummaryDataProvider.java | 7 +- .../CumulativeLoanSummaryDataProvider.java | 6 +- .../service/LoanReadPlatformServiceImpl.java | 11 +- 12 files changed, 287 insertions(+), 494 deletions(-) diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/MathUtil.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/MathUtil.java index 99365b6c235..c17d4cf5f91 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/MathUtil.java +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/MathUtil.java @@ -113,8 +113,12 @@ public static Long min(Long first, Long second, boolean notNull) { * @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 static Long add(Long first, Long second) { } /** @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 static Long subtract(Long first, Long second) { 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 static BigDecimal min(BigDecimal first, BigDecimal second, boolean notNul * @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 static BigDecimal add(BigDecimal first, BigDecimal second, MathContext mc } /** @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 static BigDecimal subtract(BigDecimal first, BigDecimal second, MathConte } /** @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 static Money plus(Money first, Money second, MathContext mc) { 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 first, Money second, Money third, MathContext mc) { - return plus(plus(first, second), third, mc); + 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, 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 static Money min(Money first, Money second, boolean notNull) { * @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 */ diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/jobs/updateloanarrearsageing/LoanArrearsAgeingUpdateHandler.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/jobs/updateloanarrearsageing/LoanArrearsAgeingUpdateHandler.java index aac6e0df972..99f1ec63287 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/jobs/updateloanarrearsageing/LoanArrearsAgeingUpdateHandler.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/jobs/updateloanarrearsageing/LoanArrearsAgeingUpdateHandler.java @@ -256,16 +256,10 @@ private LoanSchedulePeriodData fetchLoanSchedulePeriodData(ResultSet rs) throws 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(null, null, dueDate, principalDue, null, interestDueOnPrincipalOutstanding, + feeChargesDueForPeriod, penaltyChargesDueForPeriod); } } diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/data/LoanScheduleModelDownPaymentPeriod.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/data/LoanScheduleModelDownPaymentPeriod.java index ad31e819b2c..774b1a776b5 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/data/LoanScheduleModelDownPaymentPeriod.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/data/LoanScheduleModelDownPaymentPeriod.java @@ -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, diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/data/LoanSchedulePeriodData.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/data/LoanSchedulePeriodData.java index 5be2758e9ff..db26fceedc6 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/data/LoanSchedulePeriodData.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/data/LoanSchedulePeriodData.java @@ -20,21 +20,24 @@ 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; private final LocalDate fromDate; private final LocalDate dueDate; private final LocalDate obligationsMetOnDate; - private final Boolean complete; + private final boolean complete; private final Integer daysInPeriod; private final BigDecimal principalDisbursed; private final BigDecimal principalOriginalDue; @@ -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) { - - return new LoanSchedulePeriodData(periodNumber, fromDate, dueDate, principalDue, principalOutstanding, - interestDueOnPrincipalOutstanding, feeChargesDueForPeriod, penaltyChargesDueForPeriod, totalDueForPeriod, - totalInstallmentAmountForPeriod); + final BigDecimal principalDue, final BigDecimal outstandingLoanBalance, final BigDecimal interestDue, final BigDecimal feeDue, + final BigDecimal penaltyDue) { + + 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); - } - - 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, - 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) { - - 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); - } - - public static LoanSchedulePeriodData withPaidDetail(final LoanSchedulePeriodData loanSchedulePeriodData, final boolean complete, - final BigDecimal principalPaid, final BigDecimal interestPaid, final BigDecimal feeChargesPaid, - final BigDecimal 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 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(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 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 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; + 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 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; + 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 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); } } diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelRepaymentPeriod.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelRepaymentPeriod.java index 4460cfe8ddc..a358d4b9114 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelRepaymentPeriod.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanScheduleModelRepaymentPeriod.java @@ -78,7 +78,7 @@ public LoanScheduleModelRepaymentPeriod(final int periodNumber, final LocalDate 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 diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/domain/LoanRescheduleModelRepaymentPeriod.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/domain/LoanRescheduleModelRepaymentPeriod.java index 7f732728822..06a5428ac46 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/domain/LoanRescheduleModelRepaymentPeriod.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/domain/LoanRescheduleModelRepaymentPeriod.java @@ -65,7 +65,7 @@ public static LoanRescheduleModelRepaymentPeriod instance(final int periodNumber 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 diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanArrearsAgingServiceImpl.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanArrearsAgingServiceImpl.java index d4169fb8086..4d3c04391ad 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanArrearsAgingServiceImpl.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanArrearsAgingServiceImpl.java @@ -202,7 +202,7 @@ public void createInsertStatements(List insertStatement, Map 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(); } - } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/CumulativeLoanSummaryDataProvider.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/CumulativeLoanSummaryDataProvider.java index 2d4e06d9d23..b798baa3937 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/CumulativeLoanSummaryDataProvider.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/CumulativeLoanSummaryDataProvider.java @@ -46,8 +46,10 @@ public boolean accept(String loanProcessingStrategyCode) { public BigDecimal computeTotalUnpaidPayableNotDueInterestAmountOnActualPeriod(final Loan loan, final Collection periods, final LocalDate businessDate, final CurrencyData currency) { // Find the current Period (If exists one) based on the Business date - final Optional optCurrentPeriod = periods.stream() - .filter(period -> !period.getDownPaymentPeriod() && period.isActualPeriodForNotDuePayableCalculation(businessDate)) + final Optional optCurrentPeriod = periods.stream().filter(period -> !period.isDownPaymentPeriod() // + && period.getPeriod() != null // + && !businessDate.isBefore(period.getFromDate()) // + && businessDate.isBefore(period.getDueDate())) // .findFirst(); if (optCurrentPeriod.isPresent()) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java index 43fa5368826..d9fbc49b03d 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java @@ -1263,8 +1263,6 @@ public LoanScheduleData extractData(@NotNull final ResultSet rs) throws SQLExcep 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 LoanScheduleData extractData(@NotNull final ResultSet rs) throws SQLExcep 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); }