Skip to content

Commit b8acf19

Browse files
committed
1 parent 12cefac commit b8acf19

1 file changed

Lines changed: 27 additions & 36 deletions

File tree

fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java

Lines changed: 27 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import java.util.HashMap;
4545
import java.util.LinkedHashMap;
4646
import java.util.LinkedHashSet;
47+
import java.util.LinkedList;
4748
import java.util.List;
4849
import java.util.ListIterator;
4950
import java.util.Map;
@@ -1699,10 +1700,9 @@ private void recalculateRepaymentPeriodsWithEMICalculation(final Money amortizab
16991700
.allMatch(i -> i.getDueDate().isBefore(transactionDate));
17001701

17011702
if (amortizableAmount.isGreaterThanZero()) {
1702-
Optional<LoanRepaymentScheduleInstallment> additionalInstallmentOptional = installments.stream()
1703-
.filter(LoanRepaymentScheduleInstallment::isAdditional).findFirst();
17041703
if (isPostMaturityDisbursement) {
1705-
LoanRepaymentScheduleInstallment additionalInstallment = additionalInstallmentOptional.orElse(null);
1704+
LoanRepaymentScheduleInstallment additionalInstallment = installments.stream()
1705+
.filter(LoanRepaymentScheduleInstallment::isAdditional).findFirst().orElse(null);
17061706
if (additionalInstallment != null && additionalInstallment.getPrincipal(currency).isZero()) {
17071707
additionalInstallment.updatePrincipal(amortizableAmount.getAmount());
17081708
}
@@ -1712,28 +1712,14 @@ private void recalculateRepaymentPeriodsWithEMICalculation(final Money amortizab
17121712
final AtomicInteger installmentCounter = new AtomicInteger();
17131713
final ILoanConfigurationDetails loanProductRelatedDetail = model.loanProductRelatedDetail();
17141714

1715+
List<LoanRepaymentScheduleInstallment> newInstallments = new LinkedList<>();
1716+
17151717
model.repaymentPeriods().forEach(rm -> {
17161718
LoanRepaymentScheduleInstallment installment = null;
17171719
while (iterator.hasNext() && (installment == null || installment.isAdditional() || installment.isDownPayment())) {
17181720
installment = iterator.next();
17191721
installmentCounter.getAndIncrement();
17201722
}
1721-
if (installment == null) {
1722-
Optional<LoanRepaymentScheduleInstallment> additional = installments.stream()
1723-
.filter(LoanRepaymentScheduleInstallment::isAdditional).findAny();
1724-
if (additional.isPresent()) {
1725-
installment = additional.get();
1726-
}
1727-
}
1728-
boolean mergeToAdditional = installment != null && installment.isAdditional()
1729-
&& !installment.getDueDate().isAfter(rm.getDueDate());
1730-
boolean adjustAdditional = installment != null && installment.isAdditional()
1731-
&& installment.getDueDate().isAfter(rm.getDueDate());
1732-
if (mergeToAdditional) {
1733-
installment.setFromDate(rm.getFromDate());
1734-
installment.setDueDate(rm.getDueDate());
1735-
installment.setAdditional(false);
1736-
}
17371723

17381724
if (installment != null && installment.getDueDate().equals(rm.getDueDate())
17391725
&& !installment.getDueDate().isBefore(transactionDate)) {
@@ -1743,9 +1729,7 @@ private void recalculateRepaymentPeriodsWithEMICalculation(final Money amortizab
17431729
} else {
17441730
if (loanProductRelatedDetail != null && loanProductRelatedDetail.isAllowFullTermForTranche()
17451731
&& loanProductRelatedDetail.getNumberOfRepayments() > 0 && !rm.getDueDate().isBefore(transactionDate)) {
1746-
1747-
// fix new installment index.
1748-
if (!adjustAdditional) {
1732+
if (installment == null || !installment.isAdditional()) {
17491733
installmentCounter.getAndIncrement();
17501734
}
17511735
final LoanRepaymentScheduleInstallment newInstallment = new LoanRepaymentScheduleInstallment(
@@ -1754,21 +1738,28 @@ private void recalculateRepaymentPeriodsWithEMICalculation(final Money amortizab
17541738
false, false, false);
17551739

17561740
newInstallment.updateObligationsMet(currency, transactionDate);
1757-
// fix order of installments in the list.
1758-
iterator.previous();
17591741
iterator.add(newInstallment);
1760-
iterator.next();
1761-
if (adjustAdditional) {
1762-
// fix installment and charge relation due to updated maturity date
1763-
moveRelatedChargesToInstallment(processedLoanCharges, newInstallment, List.of(installment), currency);
1764-
}
1742+
newInstallments.add(newInstallment);
17651743
}
17661744
}
1767-
if (adjustAdditional) {
1768-
installment.setFromDate(rm.getDueDate());
1769-
installment.setInstallmentNumber(installmentCounter.incrementAndGet());
1770-
}
17711745
});
1746+
// fix additional installment
1747+
Optional<LoanRepaymentScheduleInstallment> additionalInstallmentOptional = installments.stream()
1748+
.filter(LoanRepaymentScheduleInstallment::isAdditional).findFirst();
1749+
if (additionalInstallmentOptional.isPresent() && !newInstallments.isEmpty()) {
1750+
LoanRepaymentScheduleInstallment additional = additionalInstallmentOptional.get();
1751+
// iterate trough new installments to fix charges
1752+
for (LoanRepaymentScheduleInstallment installment : newInstallments) {
1753+
moveRelatedChargesToInstallment(processedLoanCharges, installment, List.of(additional), currency);
1754+
additional.setFromDate(installment.getDueDate());
1755+
additional.setInstallmentNumber(installment.getInstallmentNumber() + 1);
1756+
}
1757+
installments.remove(additional);
1758+
if (additional.getDueDate().isAfter(model.getMaturityDate())) {
1759+
// step is needed to move the additional installment to the end of the list.
1760+
installments.add(additional);
1761+
}
1762+
}
17721763
}
17731764
}
17741765

@@ -3892,11 +3883,11 @@ private void handleReAgeWithCommonStrategy(LoanTransaction loanTransaction, Comm
38923883
}
38933884

38943885
private void moveRelatedChargesToInstallment(Set<LoanCharge> charges, LoanRepaymentScheduleInstallment target,
3895-
List<LoanRepaymentScheduleInstallment> installments, MonetaryCurrency currency) {
3896-
int firstNormalInstallmentNumber = LoanRepaymentScheduleProcessingWrapper.fetchFirstNormalInstallmentNumber(installments);
3886+
List<LoanRepaymentScheduleInstallment> sources, MonetaryCurrency currency) {
3887+
int firstNormalInstallmentNumber = LoanRepaymentScheduleProcessingWrapper.fetchFirstNormalInstallmentNumber(sources);
38973888
Set<LoanCharge> chargesOfNewInstallment = getLoanChargesOfInstallment(charges, target, firstNormalInstallmentNumber);
38983889
Integer targetInstallmentNumber = target.getInstallmentNumber();
3899-
installments.stream().filter(i -> Objects.equals(i.getInstallmentNumber(), targetInstallmentNumber)).findFirst()
3890+
sources.stream().filter(source -> Objects.equals(source.getInstallmentNumber(), targetInstallmentNumber)).findFirst()
39003891
.filter(source -> source != target).ifPresent(source -> {
39013892
// move fees
39023893
chargesOfNewInstallment.stream().filter(LoanCharge::isNotFullyPaid).filter(LoanCharge::isFeeCharge)

0 commit comments

Comments
 (0)