This is an automated email from the ASF dual-hosted git repository.

adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git

commit eb7ec383f85077bc64e01e2553ac95ef7b30ee89
Author: Adam Saghy <[email protected]>
AuthorDate: Thu Apr 3 10:48:27 2025 +0200

    FINERACT-2190: Improve copyFrom of LoanRepaymentScheduleInstallment
---
 .../infrastructure/core/service/MathUtil.java      |   8 +-
 .../loanaccount/domain/LoanInstallmentCharge.java  |  33 +---
 ...LoanInterestRecalcualtionAdditionalDetails.java |  19 +-
 .../domain/LoanRepaymentScheduleInstallment.java   | 215 ++++++++++++---------
 .../LoanTransactionToRepaymentScheduleMapping.java |  38 +---
 .../domain/PostDatedChecks.java                    |  47 +----
 ...nRescheduleRequestWritePlatformServiceImpl.java |   4 +-
 7 files changed, 150 insertions(+), 214 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 abfc246fb5..808886a88b 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
@@ -39,8 +39,8 @@ public final class MathUtil {
         return nullToDefault(value, 0L);
     }
 
-    public static Long nullToDefault(Long value, Long def) {
-        return value == null ? def : value;
+    public static Integer nullToZero(Integer value) {
+        return nullToDefault(value, 0);
     }
 
     public static Long zeroToNull(Long value) {
@@ -505,4 +505,8 @@ public final class MathUtil {
         return notNull ? first == null ? second : second == null ? first : 
max(first, second, false)
                 : isGreaterThan(first, second) ? first : second;
     }
+
+    public static boolean isEqualTo(Integer first, Integer second) {
+        return nullToZero(first).equals(nullToZero(second));
+    }
 }
diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanInstallmentCharge.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanInstallmentCharge.java
index 6582464e4c..396c069791 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanInstallmentCharge.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanInstallmentCharge.java
@@ -24,6 +24,8 @@ import jakarta.persistence.JoinColumn;
 import jakarta.persistence.ManyToOne;
 import jakarta.persistence.Table;
 import java.math.BigDecimal;
+import lombok.Getter;
+import lombok.Setter;
 import 
org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
 import org.apache.fineract.infrastructure.core.service.MathUtil;
 import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
@@ -31,6 +33,7 @@ import org.apache.fineract.organisation.monetary.domain.Money;
 import 
org.apache.fineract.portfolio.loanaccount.data.LoanInstallmentChargeData;
 
 @Entity
+@Getter
 @Table(name = "m_loan_installment_charge")
 public class LoanInstallmentCharge extends AbstractPersistableCustom<Long> 
implements Comparable<LoanInstallmentCharge> {
 
@@ -38,6 +41,7 @@ public class LoanInstallmentCharge extends 
AbstractPersistableCustom<Long> imple
     @JoinColumn(name = "loan_charge_id", referencedColumnName = "id", nullable 
= false)
     private LoanCharge loancharge;
 
+    @Setter
     @ManyToOne
     @JoinColumn(name = "loan_schedule_id", nullable = false)
     private LoanRepaymentScheduleInstallment installment;
@@ -48,6 +52,7 @@ public class LoanInstallmentCharge extends 
AbstractPersistableCustom<Long> imple
     @Column(name = "amount_paid_derived", scale = 6, precision = 19, nullable 
= true)
     private BigDecimal amountPaid;
 
+    @Setter
     @Column(name = "amount_waived_derived", scale = 6, precision = 19, 
nullable = true)
     private BigDecimal amountWaived;
 
@@ -140,10 +145,6 @@ public class LoanInstallmentCharge extends 
AbstractPersistableCustom<Long> imple
         return this.amount.subtract(totalAccountedFor);
     }
 
-    public BigDecimal getAmount() {
-        return this.amount;
-    }
-
     public Money getAmount(final MonetaryCurrency currency) {
         return Money.of(currency, this.amount);
     }
@@ -152,22 +153,10 @@ public class LoanInstallmentCharge extends 
AbstractPersistableCustom<Long> imple
         return Money.of(currency, this.amountPaid);
     }
 
-    public BigDecimal getAmountOutstanding() {
-        return this.amountOutstanding;
-    }
-
     private BigDecimal calculateAmountOutstanding(final MonetaryCurrency 
currency) {
         return 
getAmount(currency).minus(getAmountWaived(currency)).minus(getAmountPaid(currency)).getAmount();
     }
 
-    public boolean isPaid() {
-        return this.paid;
-    }
-
-    public boolean isWaived() {
-        return this.waived;
-    }
-
     public boolean isPending() {
         return !MathUtil.isZero(this.amountOutstanding);
     }
@@ -228,10 +217,6 @@ public class LoanInstallmentCharge extends 
AbstractPersistableCustom<Long> imple
         this.paid = false;
     }
 
-    public void setAmountWaived(final BigDecimal amountWaived) {
-        this.amountWaived = amountWaived;
-    }
-
     public void undoWaiveFlag() {
         this.waived = false;
     }
@@ -317,14 +302,6 @@ public class LoanInstallmentCharge extends 
AbstractPersistableCustom<Long> imple
         return this.loancharge;
     }
 
-    public LoanRepaymentScheduleInstallment getInstallment() {
-        return this.installment;
-    }
-
-    public void setInstallment(LoanRepaymentScheduleInstallment installment) {
-        this.installment = installment;
-    }
-
     public LoanInstallmentChargeData toData() {
         return 
LoanInstallmentChargeData.builder().installmentNumber(installment.getInstallmentNumber()).dueDate(installment.getDueDate())
                 
.amount(amount).amountOutstanding(amountOutstanding).amountWaived(amountWaived).paid(paid).waived(waived).build();
diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanInterestRecalcualtionAdditionalDetails.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanInterestRecalcualtionAdditionalDetails.java
index 17886d9e47..7768858915 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanInterestRecalcualtionAdditionalDetails.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanInterestRecalcualtionAdditionalDetails.java
@@ -25,12 +25,16 @@ import jakarta.persistence.ManyToOne;
 import jakarta.persistence.Table;
 import java.math.BigDecimal;
 import java.time.LocalDate;
+import lombok.Getter;
+import lombok.Setter;
 import 
org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
 
 @Entity
 @Table(name = "m_loan_interest_recalculation_additional_details")
+@Getter
 public class LoanInterestRecalcualtionAdditionalDetails extends 
AbstractPersistableCustom<Long> {
 
+    @Setter
     @ManyToOne(optional = false)
     @JoinColumn(name = "loan_repayment_schedule_id", nullable = false)
     private LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment;
@@ -52,19 +56,4 @@ public class LoanInterestRecalcualtionAdditionalDetails 
extends AbstractPersista
         this.amount = amount;
     }
 
-    public LocalDate getEffectiveDate() {
-        return this.effectiveDate;
-    }
-
-    public BigDecimal getAmount() {
-        return this.amount;
-    }
-
-    public LoanRepaymentScheduleInstallment 
getLoanRepaymentScheduleInstallment() {
-        return loanRepaymentScheduleInstallment;
-    }
-
-    public void 
setLoanRepaymentScheduleInstallment(LoanRepaymentScheduleInstallment 
loanRepaymentScheduleInstallment) {
-        this.loanRepaymentScheduleInstallment = 
loanRepaymentScheduleInstallment;
-    }
 }
diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java
index 80c299aacc..191bc71b16 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java
@@ -33,6 +33,7 @@ import java.util.List;
 import java.util.Set;
 import lombok.Getter;
 import lombok.Setter;
+import org.apache.commons.lang3.StringUtils;
 import 
org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
 import org.apache.fineract.infrastructure.core.service.DateUtils;
 import org.apache.fineract.infrastructure.core.service.MathUtil;
@@ -56,7 +57,7 @@ public class LoanRepaymentScheduleInstallment extends 
AbstractAuditableWithUTCDa
     @Column(name = "installment", nullable = false)
     private Integer installmentNumber;
 
-    @Column(name = "fromdate", nullable = true)
+    @Column(name = "fromdate")
     private LocalDate fromDate;
 
     @Column(name = "duedate", nullable = false)
@@ -140,11 +141,9 @@ public class LoanRepaymentScheduleInstallment extends 
AbstractAuditableWithUTCDa
     // TODO: At some point in time this database column needs to be renamed to 
credited_principal using the following
     // 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)
     private BigDecimal creditedPrincipal;
 
-    @Setter
     @Column(name = "credited_interest", scale = 6, precision = 19)
     private BigDecimal creditedInterest;
 
@@ -392,10 +391,6 @@ public class LoanRepaymentScheduleInstallment extends 
AbstractAuditableWithUTCDa
         return getInterestOutstanding(currency).isGreaterThanZero();
     }
 
-    public Money getTotalPrincipalAndInterest(final MonetaryCurrency currency) 
{
-        return getPrincipal(currency).plus(getInterestCharged(currency));
-    }
-
     public Money getTotalOutstanding(final MonetaryCurrency currency) {
         return 
getPrincipalOutstanding(currency).plus(getInterestOutstanding(currency)).plus(getFeeChargesOutstanding(currency))
                 .plus(getPenaltyChargesOutstanding(currency));
@@ -405,10 +400,6 @@ public class LoanRepaymentScheduleInstallment extends 
AbstractAuditableWithUTCDa
         this.loan = loan;
     }
 
-    public boolean isPartlyPaid() {
-        return !this.obligationsMet && (this.interestPaid != null || 
this.feeChargesPaid != null || this.principalCompleted != null);
-    }
-
     public boolean isNotFullyPaidOff() {
         return !this.obligationsMet;
     }
@@ -734,18 +725,6 @@ public class LoanRepaymentScheduleInstallment extends 
AbstractAuditableWithUTCDa
         this.penaltyAccrued = 
MathUtil.zeroToNull(MathUtil.toBigDecimal(penalityCharges));
     }
 
-    public void setInterestAccrued(BigDecimal interestAccrued) {
-        this.interestAccrued = interestAccrued;
-    }
-
-    public void setFeeAccrued(BigDecimal feeAccrued) {
-        this.feeAccrued = feeAccrued;
-    }
-
-    public void setPenaltyAccrued(BigDecimal penaltyAccrued) {
-        this.penaltyAccrued = penaltyAccrued;
-    }
-
     public void updateObligationsMet(final MonetaryCurrency currency, final 
LocalDate transactionDate) {
         if (!this.obligationsMet && getTotalOutstanding(currency).isZero()) {
             this.obligationsMet = true;
@@ -802,18 +781,6 @@ public class LoanRepaymentScheduleInstallment extends 
AbstractAuditableWithUTCDa
         return Money.of(currency, this.totalPaidInAdvance);
     }
 
-    public Money getTotalPaidLate(final MonetaryCurrency currency) {
-        return Money.of(currency, this.totalPaidLate);
-    }
-
-    public boolean isRecalculatedInterestComponent() {
-        return this.recalculatedInterestComponent;
-    }
-
-    public void setRecalculatedInterestComponent(boolean 
recalculatedInterestComponent) {
-        this.recalculatedInterestComponent = recalculatedInterestComponent;
-    }
-
     public void updateInstallmentNumber(final Integer installmentNumber) {
         if (installmentNumber != null) {
             this.installmentNumber = installmentNumber;
@@ -832,10 +799,6 @@ public class LoanRepaymentScheduleInstallment extends 
AbstractAuditableWithUTCDa
         this.obligationsMetOnDate = obligationsMetOnDate;
     }
 
-    public void updateInterestWrittenOff(final BigDecimal interestWrittenOff) {
-        this.interestWrittenOff = interestWrittenOff;
-    }
-
     public void updatePrincipal(final BigDecimal principal) {
         this.principal = principal;
     }
@@ -1007,41 +970,15 @@ public class LoanRepaymentScheduleInstallment extends 
AbstractAuditableWithUTCDa
                 .plus(getPenaltyChargesCharged(currency));
     }
 
-    public Set<LoanInterestRecalcualtionAdditionalDetails> 
getLoanCompoundingDetails() {
-        return this.loanCompoundingDetails;
-    }
-
-    public Money getAccruedInterestOutstanding(final MonetaryCurrency 
currency) {
-        final Money interestAccountedFor = 
getInterestPaid(currency).plus(getInterestWaived(currency))
-                .plus(getInterestWrittenOff(currency));
-        return getInterestAccrued(currency).minus(interestAccountedFor);
-    }
-
     public Money getTotalPaid(final MonetaryCurrency currency) {
         return 
getPenaltyChargesPaid(currency).plus(getFeeChargesPaid(currency)).plus(getInterestPaid(currency))
                 .plus(getPrincipalCompleted(currency));
     }
 
-    public void setRescheduleInterestPortion(BigDecimal 
rescheduleInterestPortion) {
-        this.rescheduleInterestPortion = rescheduleInterestPortion;
-    }
-
-    public void setFeeChargesWaived(final BigDecimal newFeeChargesCharged) {
-        this.feeChargesWaived = newFeeChargesCharged;
-    }
-
-    public void setPenaltyChargesWaived(final BigDecimal 
newPenaltyChargesCharged) {
-        this.penaltyChargesWaived = newPenaltyChargesCharged;
-    }
-
     public void markAsAdditional() {
         this.additional = true;
     }
 
-    public Set<LoanTransactionToRepaymentScheduleMapping> 
getLoanTransactionToRepaymentScheduleMappings() {
-        return this.loanTransactionToRepaymentScheduleMappings;
-    }
-
     public void resetBalances() {
         resetDerivedComponents();
         resetPrincipalDue();
@@ -1071,57 +1008,149 @@ public class LoanRepaymentScheduleInstallment extends 
AbstractAuditableWithUTCDa
     }
 
     public void copyFrom(final LoanScheduleModelPeriod period) {
+        // Reset fields and relations
         resetBalances();
+        updateLoanCompoundingDetails(period.getLoanCompoundingDetails());
+        getInstallmentCharges().clear();
+        getPostDatedChecks().clear();
+        getLoanTransactionToRepaymentScheduleMappings().clear();
+        // Update fields
         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) {
+        if (getId().equals(installment.getId())) {
+            return;
+        }
+        // Reset balances
+        resetBalances();
+        // Dates
         setFromDate(installment.getFromDate());
         setDueDate(installment.getDueDate());
-
+        setObligationsMetOnDate(installment.getObligationsMetOnDate());
+        // Flags
+        setObligationsMet(installment.isObligationsMet());
+        setAdditional(installment.isAdditional());
+        setReAged(installment.isReAged());
+        setDownPayment(installment.isDownPayment());
+        // Principal
         setPrincipal(installment.getPrincipal());
+        setPrincipalCompleted(installment.getPrincipalCompleted());
+        setPrincipalWrittenOff(installment.getPrincipalWrittenOff());
+        // Interest
         setInterestCharged(installment.getInterestCharged());
+        setInterestAccrued(installment.getInterestAccrued());
+        setInterestPaid(installment.getInterestPaid());
+        setInterestWaived(installment.getInterestWaived());
+        setInterestWrittenOff(installment.getInterestWrittenOff());
+        
setRescheduleInterestPortion(installment.getRescheduleInterestPortion());
+        
setRecalculatedInterestComponent(installment.isRecalculatedInterestComponent());
+        // Fee
         setFeeChargesCharged(installment.getFeeChargesCharged());
+        setFeeChargesPaid(installment.getFeeChargesPaid());
+        setFeeAccrued(installment.getFeeAccrued());
+        setFeeChargesWaived(installment.getFeeChargesWaived());
+        setFeeChargesWrittenOff(installment.getFeeChargesWrittenOff());
+        // Penalty
         setPenaltyCharges(installment.getPenaltyCharges());
-        
setRecalculatedInterestComponent(installment.isRecalculatedInterestComponent());
-        if (getLoanCompoundingDetails() != null) {
-            getLoanCompoundingDetails().clear();
+        setPenaltyAccrued(installment.getPenaltyAccrued());
+        setPenaltyChargesWaived(installment.getPenaltyChargesWaived());
+        setPenaltyChargesPaid(installment.getPenaltyChargesPaid());
+        setPenaltyChargesWrittenOff(installment.getPenaltyChargesWrittenOff());
+        // paid in advance / late
+        setTotalPaidInAdvance(installment.getTotalPaidInAdvance());
+        setTotalPaidLate(installment.getTotalPaidLate());
+        // Credits (Chargeback)
+        setCreditedFee(installment.getCreditedFee());
+        setCreditedPenalty(installment.getCreditedPenalty());
+        setCreditedInterest(installment.getCreditedInterest());
+        setCreditedPrincipal(installment.getCreditedPrincipal());
+        // Compounding details
+        updateLoanCompoundingDetails(installment.getLoanCompoundingDetails());
+        // Installment charges
+        updateLoaInstallmentCharges(installment.getInstallmentCharges());
+        // Post dated checks
+        updatePostDatedChecks(installment.getPostDatedChecks());
+        // Loan transaction repayment schedule mapping
+        
updateTransactionRepaymentScheduleMapping(installment.getLoanTransactionToRepaymentScheduleMappings());
+    }
+
+    private void 
updateLoanCompoundingDetails(Set<LoanInterestRecalcualtionAdditionalDetails> 
loanCompoundingDetails) {
+        Set<LoanInterestRecalcualtionAdditionalDetails> 
retainedLoanCompoundingDetails = new HashSet<>();
+        if (loanCompoundingDetails != null) {
+            loanCompoundingDetails.forEach(nlcd -> {
+                nlcd.setLoanRepaymentScheduleInstallment(this);
+                getLoanCompoundingDetails().stream().filter(lcd -> 
MathUtil.isEqualTo(lcd.getAmount(), nlcd.getAmount()) //
+                        && DateUtils.isEqual(lcd.getEffectiveDate(), 
nlcd.getEffectiveDate())) //
+                        
.findAny().ifPresentOrElse(retainedLoanCompoundingDetails::add, () -> 
retainedLoanCompoundingDetails.add(nlcd));
+            });
         }
-        if (installment.getLoanCompoundingDetails() != null) {
-            installment.getLoanCompoundingDetails().forEach(lcd -> {
-                lcd.setLoanRepaymentScheduleInstallment(this);
-                getLoanCompoundingDetails().add(lcd);
+        setLoanCompoundingDetails(retainedLoanCompoundingDetails);
+    }
+
+    private void updateLoaInstallmentCharges(Set<LoanInstallmentCharge> 
installmentCharges) {
+        Set<LoanInstallmentCharge> retainedInstallmentCharges = new 
HashSet<>();
+        if (installmentCharges != null) {
+            installmentCharges.forEach(nic -> {
+                nic.setInstallment(this);
+                getInstallmentCharges().stream().filter(ic -> 
MathUtil.isEqualTo(ic.getAmountOutstanding(), nic.getAmountOutstanding()) //
+                        && MathUtil.isEqualTo(ic.getAmountWrittenOff(), 
nic.getAmountWrittenOff()) //
+                        && MathUtil.isEqualTo(ic.getAmountPaid(), 
nic.getAmountPaid()) //
+                        && 
MathUtil.isEqualTo(ic.getAmountThroughChargePayment(), 
nic.getAmountThroughChargePayment()) //
+                        && MathUtil.isEqualTo(ic.getAmountWaived(), 
nic.getAmountWaived()) //
+                        && MathUtil.isEqualTo(ic.getAmount(), nic.getAmount()) 
//
+                        && Boolean.logicalAnd(ic.isPaid(), nic.isPaid()) //
+                        && Boolean.logicalAnd(ic.isWaived(), nic.isWaived()) //
+                        && Boolean.logicalAnd(ic.isPending(), 
nic.isPending())) //
+                        
.findAny().ifPresentOrElse(retainedInstallmentCharges::add, () -> 
retainedInstallmentCharges.add(nic));
             });
         }
-
-        Set<LoanInstallmentCharge> installmentCharges = 
installment.getInstallmentCharges();
-        installmentCharges.forEach(c -> c.setInstallment(this));
-        getInstallmentCharges().addAll(installmentCharges);
-
-        setAdditional(installment.isAdditional());
-        setReAged(installment.isReAged());
-        setDownPayment(installment.isDownPayment());
+        setInstallmentCharges(retainedInstallmentCharges);
+    }
+
+    private void updatePostDatedChecks(Set<PostDatedChecks> postDatedChecks) {
+        Set<PostDatedChecks> retainedPostDatedChecks = new HashSet<>();
+        if (postDatedChecks != null) {
+            postDatedChecks.forEach(npdc -> {
+                npdc.setLoanRepaymentScheduleInstallment(this);
+                getPostDatedChecks().stream().filter(pdc -> 
MathUtil.isEqualTo(pdc.getCheckNo(), npdc.getCheckNo()) //
+                        && MathUtil.isEqualTo(pdc.getAccountNo(), 
npdc.getAccountNo()) //
+                        && MathUtil.isEqualTo(pdc.getAmount(), 
npdc.getAmount()) //
+                        && StringUtils.equals(pdc.getBankName(), 
npdc.getBankName()) //
+                        && MathUtil.isEqualTo(pdc.getStatus(), 
npdc.getStatus()) //
+                        && DateUtils.isEqual(pdc.getRepaymentDate(), 
npdc.getRepaymentDate())) //
+                        
.findAny().ifPresentOrElse(retainedPostDatedChecks::add, () -> 
retainedPostDatedChecks.add(npdc));
+            });
+        }
+        setPostDatedChecks(retainedPostDatedChecks);
+    }
+
+    private void updateTransactionRepaymentScheduleMapping(
+            Set<LoanTransactionToRepaymentScheduleMapping> 
transactionToRepaymentScheduleMappings) {
+        Set<LoanTransactionToRepaymentScheduleMapping> 
retainedTransactionRepaymentScheduleMapping = new HashSet<>();
+        if (transactionToRepaymentScheduleMappings != null) {
+            transactionToRepaymentScheduleMappings.forEach(ntrsm -> {
+                ntrsm.setInstallment(this);
+                getLoanTransactionToRepaymentScheduleMappings().stream()
+                        .filter(trsm -> MathUtil.isEqualTo(trsm.getAmount(), 
ntrsm.getAmount()) //
+                                && 
MathUtil.isEqualTo(trsm.getFeeChargesPortion(), ntrsm.getFeeChargesPortion()) //
+                                && 
MathUtil.isEqualTo(trsm.getInterestPortion(), ntrsm.getInterestPortion()) //
+                                && 
MathUtil.isEqualTo(trsm.getPrincipalPortion(), ntrsm.getPrincipalPortion()) //
+                                && 
MathUtil.isEqualTo(trsm.getPenaltyChargesPortion(), 
ntrsm.getPenaltyChargesPortion())) //
+                        
.findAny().ifPresentOrElse(retainedTransactionRepaymentScheduleMapping::add,
+                                () -> 
retainedTransactionRepaymentScheduleMapping.add(ntrsm));
+            });
+        }
+        
setLoanTransactionToRepaymentScheduleMappings(retainedTransactionRepaymentScheduleMapping);
     }
-
 }
diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransactionToRepaymentScheduleMapping.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransactionToRepaymentScheduleMapping.java
index ec699382a1..f07d0bfda7 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransactionToRepaymentScheduleMapping.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransactionToRepaymentScheduleMapping.java
@@ -25,20 +25,24 @@ import jakarta.persistence.JoinColumn;
 import jakarta.persistence.ManyToOne;
 import jakarta.persistence.Table;
 import java.math.BigDecimal;
+import lombok.Getter;
+import lombok.Setter;
 import 
org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
 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.loanproduct.domain.AllocationType;
 
 @Entity
 @Table(name = "m_loan_transaction_repayment_schedule_mapping")
+@Getter
 public class LoanTransactionToRepaymentScheduleMapping extends 
AbstractPersistableCustom<Long> {
 
+    @Setter
     @ManyToOne(optional = false, cascade = CascadeType.PERSIST)
     @JoinColumn(name = "loan_transaction_id", nullable = false)
     private LoanTransaction loanTransaction;
 
+    @Setter
     @ManyToOne(optional = false, cascade = CascadeType.PERSIST)
     @JoinColumn(name = "loan_repayment_schedule_id", nullable = false)
     private LoanRepaymentScheduleInstallment installment;
@@ -137,36 +141,4 @@ public class LoanTransactionToRepaymentScheduleMapping 
extends AbstractPersistab
         return Money.of(currency, this.penaltyChargesPortion);
     }
 
-    public BigDecimal getPortion(AllocationType allocationType) {
-        return switch (allocationType) {
-            case PRINCIPAL -> getPrincipalPortion();
-            case INTEREST -> getInterestPortion();
-            case FEE -> getFeeChargesPortion();
-            case PENALTY -> getPenaltyChargesPortion();
-        };
-    }
-
-    public LoanTransaction getLoanTransaction() {
-        return loanTransaction;
-    }
-
-    public BigDecimal getPrincipalPortion() {
-        return this.principalPortion;
-    }
-
-    public BigDecimal getInterestPortion() {
-        return this.interestPortion;
-    }
-
-    public BigDecimal getFeeChargesPortion() {
-        return this.feeChargesPortion;
-    }
-
-    public BigDecimal getPenaltyChargesPortion() {
-        return this.penaltyChargesPortion;
-    }
-
-    public void setLoanTransaction(LoanTransaction loanTransaction) {
-        this.loanTransaction = loanTransaction;
-    }
 }
diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/repaymentwithpostdatedchecks/domain/PostDatedChecks.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/repaymentwithpostdatedchecks/domain/PostDatedChecks.java
index ac4f50094c..882194d259 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/repaymentwithpostdatedchecks/domain/PostDatedChecks.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/repaymentwithpostdatedchecks/domain/PostDatedChecks.java
@@ -27,6 +27,8 @@ import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.util.HashMap;
 import java.util.Map;
+import lombok.Getter;
+import lombok.Setter;
 import org.apache.fineract.infrastructure.core.api.JsonCommand;
 import 
org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
 import org.apache.fineract.portfolio.loanaccount.domain.Loan;
@@ -34,11 +36,14 @@ import 
org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleIns
 
 @Entity
 @Table(name = "m_repayment_with_post_dated_checks")
+@Getter
 public class PostDatedChecks extends AbstractPersistableCustom<Long> {
 
+    @Setter
     @ManyToOne(optional = false)
     @JoinColumn(name = "loan_id", referencedColumnName = "id", nullable = 
false)
     private Loan loan;
+    @Setter
     @ManyToOne(optional = false)
     @JoinColumn(name = "repayment_id", referencedColumnName = "id", nullable = 
false)
     private LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment;
@@ -50,6 +55,7 @@ public class PostDatedChecks extends 
AbstractPersistableCustom<Long> {
     private BigDecimal amount;
     @Column(name = "repayment_date", nullable = false)
     private LocalDate repaymentDate;
+    @Setter
     @Column(name = "status", columnDefinition = "0")
     private Integer status;
     @Column(name = "check_no", nullable = false, unique = true)
@@ -75,14 +81,6 @@ public class PostDatedChecks extends 
AbstractPersistableCustom<Long> {
                 loanRepaymentScheduleInstallment.getDueDate(), loan, checkNo);
     }
 
-    public void setLoan(Loan loan) {
-        this.loan = loan;
-    }
-
-    public void setLoanRepaymentScheduleInstallment(final 
LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment) {
-        this.loanRepaymentScheduleInstallment = 
loanRepaymentScheduleInstallment;
-    }
-
     public Map<String, Object> updatePostDatedChecks(JsonCommand command) {
         final Map<String, Object> changes = new HashMap<>();
 
@@ -112,37 +110,4 @@ public class PostDatedChecks extends 
AbstractPersistableCustom<Long> {
 
         return changes;
     }
-
-    public Loan getLoan() {
-        return this.loan;
-    }
-
-    public LoanRepaymentScheduleInstallment 
getLoanRepaymentScheduleInstallment() {
-        return this.loanRepaymentScheduleInstallment;
-    }
-
-    public void setStatus(Integer status) {
-        this.status = status;
-    }
-
-    public String getBankName() {
-        return this.bankName;
-    }
-
-    public Long getCheckNo() {
-        return this.checkNo;
-    }
-
-    public Long getAccountNo() {
-        return this.accountNo;
-    }
-
-    public BigDecimal getAmount() {
-        return this.amount;
-    }
-
-    public Integer getStatus() {
-        return this.status;
-    }
-
 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java
index 4f61df5e9f..03c156be4b 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestWritePlatformServiceImpl.java
@@ -425,8 +425,8 @@ public class LoanRescheduleRequestWritePlatformServiceImpl 
implements LoanResche
                     loanApplicationTerms.getInterestMethod());
             final LoanLifecycleStateMachine loanLifecycleStateMachine = null;
             loan.setHelpers(loanLifecycleStateMachine);
-            final LoanScheduleDTO loanScheduleDTO = 
loanScheduleGenerator.rescheduleNextInstallments(mathContext, 
loanApplicationTerms, loan,
-                    loanApplicationTerms.getHolidayDetailDTO(), 
loanRepaymentScheduleTransactionProcessor, rescheduleFromDate);
+            final LoanScheduleDTO loanScheduleDTO = 
loanScheduleGenerator.rescheduleNextInstallments(mathContext, 
loanApplicationTerms,
+                    loan, loanApplicationTerms.getHolidayDetailDTO(), 
loanRepaymentScheduleTransactionProcessor, rescheduleFromDate);
 
             // Either the installments got recalculated or the model
             if (loanScheduleDTO.getInstallments() != null) {

Reply via email to