FINERACT-2190: Avoid recreation of loan repayment schedule periods
This commit is contained in:
committed by
Adam Saghy
parent
b9cfa470ff
commit
52c41b1471
-51
@@ -57,7 +57,6 @@ import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
@@ -112,7 +111,6 @@ import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.Loa
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanApplicationTerms;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleGenerator;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModel;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModelPeriod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.AmortizationMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.CreditAllocationTransactionType;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
|
||||
@@ -610,8 +608,6 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
|
||||
this.interestChargedFromDate = loanApplicationTerms.getInterestChargedFromDate();
|
||||
this.submittedOnDate = submittedOnDate != null ? submittedOnDate : DateUtils.getBusinessLocalDate();
|
||||
|
||||
updateLoanSchedule(loanScheduleModel);
|
||||
|
||||
updateSummaryWithTotalFeeChargesDueAtDisbursement(deriveSumTotalOfChargesDueAtDisbursement());
|
||||
|
||||
// Copy interest recalculation settings if interest recalculation is enabled
|
||||
@@ -1005,53 +1001,6 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
|
||||
this.rates.addAll(loanRates);
|
||||
}
|
||||
|
||||
public void updateLoanSchedule(final LoanScheduleModel modifiedLoanSchedule) {
|
||||
this.repaymentScheduleInstallments.clear();
|
||||
for (final LoanScheduleModelPeriod scheduledLoanInstallment : modifiedLoanSchedule.getPeriods()) {
|
||||
|
||||
if (scheduledLoanInstallment.isRepaymentPeriod() || scheduledLoanInstallment.isDownPaymentPeriod()) {
|
||||
final LoanRepaymentScheduleInstallment installment = new LoanRepaymentScheduleInstallment(this,
|
||||
scheduledLoanInstallment.periodNumber(), scheduledLoanInstallment.periodFromDate(),
|
||||
scheduledLoanInstallment.periodDueDate(), scheduledLoanInstallment.principalDue(),
|
||||
scheduledLoanInstallment.interestDue(), scheduledLoanInstallment.feeChargesDue(),
|
||||
scheduledLoanInstallment.penaltyChargesDue(), scheduledLoanInstallment.isRecalculatedInterestComponent(),
|
||||
scheduledLoanInstallment.getLoanCompoundingDetails(), scheduledLoanInstallment.rescheduleInterestPortion(),
|
||||
scheduledLoanInstallment.isDownPaymentPeriod());
|
||||
addLoanRepaymentScheduleInstallment(installment);
|
||||
}
|
||||
}
|
||||
updateLoanScheduleDependentDerivedFields();
|
||||
updateLoanSummaryDerivedFields();
|
||||
}
|
||||
|
||||
public void updateLoanSchedule(final Collection<LoanRepaymentScheduleInstallment> installments) {
|
||||
List<LoanRepaymentScheduleInstallment> existingInstallments = new ArrayList<>(this.repaymentScheduleInstallments);
|
||||
repaymentScheduleInstallments.clear();
|
||||
for (final LoanRepaymentScheduleInstallment installment : installments) {
|
||||
LoanRepaymentScheduleInstallment existingInstallment = findByInstallmentNumber(existingInstallments,
|
||||
installment.getInstallmentNumber());
|
||||
if (existingInstallment != null) {
|
||||
Set<LoanInstallmentCharge> existingCharges = existingInstallment.getInstallmentCharges();
|
||||
installment.getInstallmentCharges().addAll(existingCharges);
|
||||
existingCharges.forEach(c -> c.setInstallment(installment));
|
||||
existingInstallment.getInstallmentCharges().clear();
|
||||
}
|
||||
addLoanRepaymentScheduleInstallment(installment);
|
||||
}
|
||||
updateLoanScheduleDependentDerivedFields();
|
||||
updateLoanSummaryDerivedFields();
|
||||
}
|
||||
|
||||
private LoanRepaymentScheduleInstallment findByInstallmentNumber(Collection<LoanRepaymentScheduleInstallment> installments,
|
||||
Integer installmentNumber) {
|
||||
for (LoanRepaymentScheduleInstallment installment : installments) {
|
||||
if (Objects.equals(installment.getInstallmentNumber(), installmentNumber)) {
|
||||
return installment;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void updateLoanScheduleDependentDerivedFields() {
|
||||
if (this.getLoanRepaymentScheduleInstallmentsSize() > 0) {
|
||||
this.expectedMaturityDate = determineExpectedMaturityDate();
|
||||
|
||||
+81
-25
@@ -38,10 +38,12 @@ import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.core.service.MathUtil;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModelPeriod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.AllocationType;
|
||||
import org.apache.fineract.portfolio.repaymentwithpostdatedchecks.domain.PostDatedChecks;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Table(name = "m_loan_repayment_schedule")
|
||||
public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDateTimeCustom<Long>
|
||||
@@ -60,67 +62,67 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
||||
@Column(name = "duedate", nullable = false)
|
||||
private LocalDate dueDate;
|
||||
|
||||
@Column(name = "principal_amount", scale = 6, precision = 19, nullable = true)
|
||||
@Column(name = "principal_amount", scale = 6, precision = 19)
|
||||
private BigDecimal principal;
|
||||
|
||||
@Column(name = "principal_completed_derived", scale = 6, precision = 19, nullable = true)
|
||||
@Column(name = "principal_completed_derived", scale = 6, precision = 19)
|
||||
private BigDecimal principalCompleted;
|
||||
|
||||
@Column(name = "principal_writtenoff_derived", scale = 6, precision = 19, nullable = true)
|
||||
@Column(name = "principal_writtenoff_derived", scale = 6, precision = 19)
|
||||
private BigDecimal principalWrittenOff;
|
||||
|
||||
@Column(name = "interest_amount", scale = 6, precision = 19, nullable = true)
|
||||
@Column(name = "interest_amount", scale = 6, precision = 19)
|
||||
private BigDecimal interestCharged;
|
||||
|
||||
@Column(name = "interest_completed_derived", scale = 6, precision = 19, nullable = true)
|
||||
@Column(name = "interest_completed_derived", scale = 6, precision = 19)
|
||||
private BigDecimal interestPaid;
|
||||
|
||||
@Column(name = "interest_waived_derived", scale = 6, precision = 19, nullable = true)
|
||||
@Column(name = "interest_waived_derived", scale = 6, precision = 19)
|
||||
private BigDecimal interestWaived;
|
||||
|
||||
@Column(name = "interest_writtenoff_derived", scale = 6, precision = 19, nullable = true)
|
||||
@Column(name = "interest_writtenoff_derived", scale = 6, precision = 19)
|
||||
private BigDecimal interestWrittenOff;
|
||||
|
||||
@Column(name = "accrual_interest_derived", scale = 6, precision = 19, nullable = true)
|
||||
@Column(name = "accrual_interest_derived", scale = 6, precision = 19)
|
||||
private BigDecimal interestAccrued;
|
||||
|
||||
@Column(name = "reschedule_interest_portion", scale = 6, precision = 19, nullable = true)
|
||||
@Column(name = "reschedule_interest_portion", scale = 6, precision = 19)
|
||||
private BigDecimal rescheduleInterestPortion;
|
||||
|
||||
@Column(name = "fee_charges_amount", scale = 6, precision = 19, nullable = true)
|
||||
@Column(name = "fee_charges_amount", scale = 6, precision = 19)
|
||||
private BigDecimal feeChargesCharged;
|
||||
|
||||
@Column(name = "fee_charges_completed_derived", scale = 6, precision = 19, nullable = true)
|
||||
@Column(name = "fee_charges_completed_derived", scale = 6, precision = 19)
|
||||
private BigDecimal feeChargesPaid;
|
||||
|
||||
@Column(name = "fee_charges_writtenoff_derived", scale = 6, precision = 19, nullable = true)
|
||||
@Column(name = "fee_charges_writtenoff_derived", scale = 6, precision = 19)
|
||||
private BigDecimal feeChargesWrittenOff;
|
||||
|
||||
@Column(name = "fee_charges_waived_derived", scale = 6, precision = 19, nullable = true)
|
||||
@Column(name = "fee_charges_waived_derived", scale = 6, precision = 19)
|
||||
private BigDecimal feeChargesWaived;
|
||||
|
||||
@Column(name = "accrual_fee_charges_derived", scale = 6, precision = 19, nullable = true)
|
||||
@Column(name = "accrual_fee_charges_derived", scale = 6, precision = 19)
|
||||
private BigDecimal feeAccrued;
|
||||
|
||||
@Column(name = "penalty_charges_amount", scale = 6, precision = 19, nullable = true)
|
||||
@Column(name = "penalty_charges_amount", scale = 6, precision = 19)
|
||||
private BigDecimal penaltyCharges;
|
||||
|
||||
@Column(name = "penalty_charges_completed_derived", scale = 6, precision = 19, nullable = true)
|
||||
@Column(name = "penalty_charges_completed_derived", scale = 6, precision = 19)
|
||||
private BigDecimal penaltyChargesPaid;
|
||||
|
||||
@Column(name = "penalty_charges_writtenoff_derived", scale = 6, precision = 19, nullable = true)
|
||||
@Column(name = "penalty_charges_writtenoff_derived", scale = 6, precision = 19)
|
||||
private BigDecimal penaltyChargesWrittenOff;
|
||||
|
||||
@Column(name = "penalty_charges_waived_derived", scale = 6, precision = 19, nullable = true)
|
||||
@Column(name = "penalty_charges_waived_derived", scale = 6, precision = 19)
|
||||
private BigDecimal penaltyChargesWaived;
|
||||
|
||||
@Column(name = "accrual_penalty_charges_derived", scale = 6, precision = 19, nullable = true)
|
||||
@Column(name = "accrual_penalty_charges_derived", scale = 6, precision = 19)
|
||||
private BigDecimal penaltyAccrued;
|
||||
|
||||
@Column(name = "total_paid_in_advance_derived", scale = 6, precision = 19, nullable = true)
|
||||
@Column(name = "total_paid_in_advance_derived", scale = 6, precision = 19)
|
||||
private BigDecimal totalPaidInAdvance;
|
||||
|
||||
@Column(name = "total_paid_late_derived", scale = 6, precision = 19, nullable = true)
|
||||
@Column(name = "total_paid_late_derived", scale = 6, precision = 19)
|
||||
private BigDecimal totalPaidLate;
|
||||
|
||||
@Column(name = "completed_derived", nullable = false)
|
||||
@@ -139,17 +141,17 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
||||
// approach
|
||||
// https://blog.thepete.net/blog/2023/12/05/expand/contract-making-a-breaking-change-without-a-big-bang/
|
||||
@Setter
|
||||
@Column(name = "credits_amount", scale = 6, precision = 19, nullable = true)
|
||||
@Column(name = "credits_amount", scale = 6, precision = 19)
|
||||
private BigDecimal creditedPrincipal;
|
||||
|
||||
@Setter
|
||||
@Column(name = "credited_interest", scale = 6, precision = 19, nullable = true)
|
||||
@Column(name = "credited_interest", scale = 6, precision = 19)
|
||||
private BigDecimal creditedInterest;
|
||||
|
||||
@Column(name = "credited_fee", scale = 6, precision = 19, nullable = true)
|
||||
@Column(name = "credited_fee", scale = 6, precision = 19)
|
||||
private BigDecimal creditedFee;
|
||||
|
||||
@Column(name = "credited_penalty", scale = 6, precision = 19, nullable = true)
|
||||
@Column(name = "credited_penalty", scale = 6, precision = 19)
|
||||
private BigDecimal creditedPenalty;
|
||||
|
||||
@Column(name = "is_down_payment", nullable = false)
|
||||
@@ -1068,4 +1070,58 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
||||
MathUtil.nullToZero(MathUtil.add(getPrincipal(), getInterestCharged(), getFeeChargesCharged(), getPenaltyCharges())));
|
||||
}
|
||||
|
||||
public void copyFrom(final LoanScheduleModelPeriod period) {
|
||||
resetBalances();
|
||||
setFromDate(period.periodFromDate());
|
||||
setDueDate(period.periodDueDate());
|
||||
setPrincipal(period.principalDue());
|
||||
setInterestCharged(period.interestDue());
|
||||
setFeeChargesCharged(period.feeChargesDue());
|
||||
setPenaltyCharges(period.penaltyChargesDue());
|
||||
|
||||
setRecalculatedInterestComponent(period.isRecalculatedInterestComponent());
|
||||
if (getLoanCompoundingDetails() != null) {
|
||||
getLoanCompoundingDetails().clear();
|
||||
}
|
||||
if (period.getLoanCompoundingDetails() != null) {
|
||||
period.getLoanCompoundingDetails().forEach(lcd -> {
|
||||
lcd.setLoanRepaymentScheduleInstallment(this);
|
||||
getLoanCompoundingDetails().add(lcd);
|
||||
});
|
||||
}
|
||||
setRescheduleInterestPortion(period.rescheduleInterestPortion());
|
||||
setDownPayment(period.isDownPaymentPeriod());
|
||||
|
||||
setAdditional(false);
|
||||
setReAged(false);
|
||||
}
|
||||
|
||||
public void copyFrom(final LoanRepaymentScheduleInstallment installment) {
|
||||
setFromDate(installment.getFromDate());
|
||||
setDueDate(installment.getDueDate());
|
||||
|
||||
setPrincipal(installment.getPrincipal());
|
||||
setInterestCharged(installment.getInterestCharged());
|
||||
setFeeChargesCharged(installment.getFeeChargesCharged());
|
||||
setPenaltyCharges(installment.getPenaltyCharges());
|
||||
setRecalculatedInterestComponent(installment.isRecalculatedInterestComponent());
|
||||
if (getLoanCompoundingDetails() != null) {
|
||||
getLoanCompoundingDetails().clear();
|
||||
}
|
||||
if (installment.getLoanCompoundingDetails() != null) {
|
||||
installment.getLoanCompoundingDetails().forEach(lcd -> {
|
||||
lcd.setLoanRepaymentScheduleInstallment(this);
|
||||
getLoanCompoundingDetails().add(lcd);
|
||||
});
|
||||
}
|
||||
|
||||
Set<LoanInstallmentCharge> installmentCharges = installment.getInstallmentCharges();
|
||||
installmentCharges.forEach(c -> c.setInstallment(this));
|
||||
getInstallmentCharges().addAll(installmentCharges);
|
||||
|
||||
setAdditional(installment.isAdditional());
|
||||
setReAged(installment.isReAged());
|
||||
setDownPayment(installment.isDownPayment());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+10
-8
@@ -29,6 +29,7 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanCharge;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanScheduleDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModel;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.schedule.LoanScheduleComponent;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class LoanScheduleService {
|
||||
@@ -36,16 +37,17 @@ public class LoanScheduleService {
|
||||
private final LoanChargeService loanChargeService;
|
||||
private final ReprocessLoanTransactionsService reprocessLoanTransactionsService;
|
||||
private final LoanTransactionProcessingService loadTransactionProcessingService;
|
||||
private final LoanScheduleComponent loanSchedule;
|
||||
|
||||
/**
|
||||
* Ability to regenerate the repayment schedule based on the loans current details/state.
|
||||
*/
|
||||
public void regenerateRepaymentSchedule(final Loan loan, final ScheduleGeneratorDTO scheduleGeneratorDTO) {
|
||||
final LoanScheduleModel loanSchedule = loan.regenerateScheduleModel(scheduleGeneratorDTO);
|
||||
if (loanSchedule == null) {
|
||||
final LoanScheduleModel loanScheduleModel = loan.regenerateScheduleModel(scheduleGeneratorDTO);
|
||||
if (loanScheduleModel == null) {
|
||||
return;
|
||||
}
|
||||
loan.updateLoanSchedule(loanSchedule);
|
||||
loanSchedule.updateLoanSchedule(loan, loanScheduleModel);
|
||||
final Set<LoanCharge> charges = loan.getActiveCharges();
|
||||
for (final LoanCharge loanCharge : charges) {
|
||||
if (!loanCharge.isWaived()) {
|
||||
@@ -80,15 +82,15 @@ public class LoanScheduleService {
|
||||
|
||||
public void regenerateRepaymentScheduleWithInterestRecalculation(final Loan loan, final ScheduleGeneratorDTO generatorDTO) {
|
||||
final LocalDate lastTransactionDate = loan.getLastUserTransactionDate();
|
||||
final LoanScheduleDTO loanSchedule = loadTransactionProcessingService.getRecalculatedSchedule(generatorDTO, loan);
|
||||
if (loanSchedule == null) {
|
||||
final LoanScheduleDTO loanScheduleDTO = loadTransactionProcessingService.getRecalculatedSchedule(generatorDTO, loan);
|
||||
if (loanScheduleDTO == null) {
|
||||
return;
|
||||
}
|
||||
// Either the installments got recalculated or the model
|
||||
if (loanSchedule.getInstallments() != null) {
|
||||
loan.updateLoanSchedule(loanSchedule.getInstallments());
|
||||
if (loanScheduleDTO.getInstallments() != null) {
|
||||
loanSchedule.updateLoanSchedule(loan, loanScheduleDTO.getInstallments());
|
||||
} else {
|
||||
loan.updateLoanSchedule(loanSchedule.getLoanScheduleModel());
|
||||
loanSchedule.updateLoanSchedule(loan, loanScheduleDTO.getLoanScheduleModel());
|
||||
}
|
||||
loan.setInterestRecalculatedOn(DateUtils.getBusinessLocalDate());
|
||||
final LocalDate lastRepaymentDate = loan.getLastRepaymentPeriodDueDate(true);
|
||||
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.service.schedule;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModel;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModelPeriod;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class LoanScheduleComponent {
|
||||
|
||||
public void updateLoanSchedule(Loan loan, final LoanScheduleModel modifiedLoanSchedule) {
|
||||
final List<LoanScheduleModelPeriod> periods = modifiedLoanSchedule.getPeriods();
|
||||
for (final LoanScheduleModelPeriod scheduledLoanInstallment : modifiedLoanSchedule.getPeriods()) {
|
||||
if (scheduledLoanInstallment.isRepaymentPeriod() || scheduledLoanInstallment.isDownPaymentPeriod()) {
|
||||
LoanRepaymentScheduleInstallment existingInstallment = findByInstallmentNumber(loan.getRepaymentScheduleInstallments(),
|
||||
scheduledLoanInstallment.periodNumber());
|
||||
if (existingInstallment == null) {
|
||||
final LoanRepaymentScheduleInstallment installment = new LoanRepaymentScheduleInstallment(loan,
|
||||
scheduledLoanInstallment.periodNumber(), scheduledLoanInstallment.periodFromDate(),
|
||||
scheduledLoanInstallment.periodDueDate(), scheduledLoanInstallment.principalDue(),
|
||||
scheduledLoanInstallment.interestDue(), scheduledLoanInstallment.feeChargesDue(),
|
||||
scheduledLoanInstallment.penaltyChargesDue(), scheduledLoanInstallment.isRecalculatedInterestComponent(),
|
||||
scheduledLoanInstallment.getLoanCompoundingDetails(), scheduledLoanInstallment.rescheduleInterestPortion(),
|
||||
scheduledLoanInstallment.isDownPaymentPeriod());
|
||||
loan.addLoanRepaymentScheduleInstallment(installment);
|
||||
} else {
|
||||
existingInstallment.copyFrom(scheduledLoanInstallment);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Review Installments removed
|
||||
loan.getRepaymentScheduleInstallments().removeIf(i -> !existInstallment(periods, i.getInstallmentNumber()));
|
||||
|
||||
loan.updateLoanScheduleDependentDerivedFields();
|
||||
loan.updateLoanSummaryDerivedFields();
|
||||
}
|
||||
|
||||
public void updateLoanSchedule(Loan loan, final List<LoanRepaymentScheduleInstallment> installments) {
|
||||
for (final LoanRepaymentScheduleInstallment installment : installments) {
|
||||
LoanRepaymentScheduleInstallment existingInstallment = findByInstallmentNumber(loan.getRepaymentScheduleInstallments(),
|
||||
installment.getInstallmentNumber());
|
||||
if (existingInstallment != null) {
|
||||
existingInstallment.copyFrom(installment);
|
||||
} else {
|
||||
loan.addLoanRepaymentScheduleInstallment(installment);
|
||||
}
|
||||
}
|
||||
// Review Installments removed
|
||||
loan.getRepaymentScheduleInstallments().removeIf(i -> !existInstallment(installments, i.getInstallmentNumber()));
|
||||
|
||||
loan.updateLoanScheduleDependentDerivedFields();
|
||||
loan.updateLoanSummaryDerivedFields();
|
||||
}
|
||||
|
||||
private LoanRepaymentScheduleInstallment findByInstallmentNumber(final Collection<LoanRepaymentScheduleInstallment> installments,
|
||||
final Integer installmentNumber) {
|
||||
return installments.stream().filter(i -> installmentNumber.compareTo(i.getInstallmentNumber()) == 0).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
private boolean existInstallment(final Collection<LoanRepaymentScheduleInstallment> installments, final Integer installmentNumber) {
|
||||
return installments.stream().anyMatch(i -> installmentNumber.compareTo(i.getInstallmentNumber()) == 0);
|
||||
}
|
||||
|
||||
private boolean existInstallment(final List<LoanScheduleModelPeriod> periods, final Integer installmentNumber) {
|
||||
return periods.stream().anyMatch(p -> p.periodNumber() != null && installmentNumber.compareTo(p.periodNumber()) == 0);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user