Repository: incubator-fineract
Updated Branches:
  refs/heads/develop b4a43e6e9 -> 0b81e8023


[MIFOSX-2652] Correcting repayment schedule for the loans with variable 
installments enabled


Project: http://git-wip-us.apache.org/repos/asf/incubator-fineract/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-fineract/commit/0b81e802
Tree: http://git-wip-us.apache.org/repos/asf/incubator-fineract/tree/0b81e802
Diff: http://git-wip-us.apache.org/repos/asf/incubator-fineract/diff/0b81e802

Branch: refs/heads/develop
Commit: 0b81e8023305e9cbd06f2b0c3c6335b01f441077
Parents: b4a43e6
Author: Vishwa <vishwan...@confluxtechnologies.com>
Authored: Fri May 13 12:37:53 2016 +0530
Committer: Vishwa <vishwan...@confluxtechnologies.com>
Committed: Fri May 13 12:37:53 2016 +0530

----------------------------------------------------------------------
 .../data/LoanTermVariationsDataWrapper.java     |  5 +
 .../domain/AbstractLoanScheduleGenerator.java   | 99 +++++++++++++++++---
 ...LoanApplicationCommandFromApiJsonHelper.java |  3 +-
 3 files changed, 92 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/0b81e802/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTermVariationsDataWrapper.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTermVariationsDataWrapper.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTermVariationsDataWrapper.java
index 510dd1d..65730e7 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTermVariationsDataWrapper.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTermVariationsDataWrapper.java
@@ -120,4 +120,9 @@ public class LoanTermVariationsDataWrapper {
         return data;
     }
 
+    public boolean hasExceptionVariation(final LocalDate date, 
ListIterator<LoanTermVariationsData> exceptionDataListIterator) {
+        ListIterator<LoanTermVariationsData> iterator = 
exceptionDataListIterator;
+        return hasNext(date, iterator);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/0b81e802/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java
index 474b852..080689e 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java
@@ -26,6 +26,7 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.ListIterator;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
@@ -957,6 +958,7 @@ public abstract class AbstractLoanScheduleGenerator 
implements LoanScheduleGener
         boolean skipPeriod = false;
         boolean recalculateAmounts = false;
         LocalDate modifiedScheduledDueDate = scheduledDueDate;
+        ArrayList<LoanTermVariationsData> variationsData = null;
 
         // due date changes should be applied only for that dueDate
         if 
(loanApplicationTerms.getLoanTermVariations().hasDueDateVariation(scheduledDueDate))
 {
@@ -1019,7 +1021,48 @@ public abstract class AbstractLoanScheduleGenerator 
implements LoanScheduleGener
 
             }
         }
-        LoanTermVariationParams termVariationParams = new 
LoanTermVariationParams(skipPeriod, recalculateAmounts, 
modifiedScheduledDueDate);
+        LoanTermVariationParams termVariationParams = new 
LoanTermVariationParams(skipPeriod, recalculateAmounts, 
modifiedScheduledDueDate,
+                variationsData);
+        return termVariationParams;
+    }
+
+    /**
+     * @param loanApplicationTerms
+     * @param scheduledDueDate
+     * @param exceptionDataListIterator
+     * @return
+     */
+    private LoanTermVariationParams applyExceptionLoanTermVariations(final 
LoanApplicationTerms loanApplicationTerms,
+            final LocalDate scheduledDueDate, final 
ListIterator<LoanTermVariationsData> exceptionDataListIterator) {
+        boolean skipPeriod = false;
+        boolean recalculateAmounts = false;
+        LocalDate modifiedScheduledDueDate = scheduledDueDate;
+        ArrayList<LoanTermVariationsData> variationsData = new ArrayList<>();
+
+        while 
(loanApplicationTerms.getLoanTermVariations().hasExceptionVariation(modifiedScheduledDueDate,
 exceptionDataListIterator)) {
+            LoanTermVariationsData loanTermVariationsData = 
exceptionDataListIterator.next();
+            if (loanTermVariationsData.isProcessed()) {
+                continue;
+            }
+            switch (loanTermVariationsData.getTermVariationType()) {
+                case INSERT_INSTALLMENT:
+                    modifiedScheduledDueDate = 
loanTermVariationsData.getTermApplicableFrom();
+                    variationsData.add(loanTermVariationsData) ;
+                break;
+                case DELETE_INSTALLMENT:
+                    if 
(loanTermVariationsData.getTermApplicableFrom().isEqual(modifiedScheduledDueDate))
 {
+                        skipPeriod = true;
+                        variationsData.add(loanTermVariationsData) ;
+                    }
+                    
+                break;
+                default:
+                break;
+
+            }
+        }
+        LoanTermVariationParams termVariationParams = new 
LoanTermVariationParams(skipPeriod, recalculateAmounts, 
modifiedScheduledDueDate,
+                variationsData);
         return termVariationParams;
     }
 
@@ -2276,6 +2319,10 @@ public abstract class AbstractLoanScheduleGenerator 
implements LoanScheduleGener
             }
             int loanTermInDays = 0;
 
+            List<LoanTermVariationsData> exceptionDataList = 
loanApplicationTerms.getLoanTermVariations().getExceptionData();
+            final ListIterator<LoanTermVariationsData> 
exceptionDataListIterator = exceptionDataList.listIterator();
+            LoanTermVariationParams loanTermVariationParams = null;
+
             // Block process the installment and creates the period if it falls
             // before reschedule from date
             // This will create the recalculation details by applying the
@@ -2289,23 +2336,42 @@ public abstract class AbstractLoanScheduleGenerator 
implements LoanScheduleGener
                         break;
                     }
                     LocalDate previousRepaymentDate = actualRepaymentDate;
-                    actualRepaymentDate = 
this.scheduledDateGenerator.generateNextRepaymentDate(actualRepaymentDate, 
loanApplicationTerms,
-                            isFirstRepayment, holidayDetailDTO);
-                    isFirstRepayment = false;
-                    lastInstallmentDate = 
this.scheduledDateGenerator.adjustRepaymentDate(actualRepaymentDate, 
loanApplicationTerms,
-                            holidayDetailDTO);
+                    ArrayList<LoanTermVariationsData> 
dueDateVariationsDataList = new ArrayList<>();
+
+                 // check for date changes
+                    while 
(loanApplicationTerms.getLoanTermVariations().hasDueDateVariation(lastInstallmentDate))
 {
+                        LoanTermVariationsData variation = 
loanApplicationTerms.getLoanTermVariations().nextDueDateVariation();
+                        if (!variation.isSpecificToInstallment()) {
+                            actualRepaymentDate = variation.getDateValue();
+                        }
+                        dueDateVariationsDataList.add(variation);
+                    }
+
+                    do {
+                        actualRepaymentDate = 
this.scheduledDateGenerator.generateNextRepaymentDate(actualRepaymentDate,
+                                loanApplicationTerms, isFirstRepayment, 
holidayDetailDTO);
+                        isFirstRepayment = false;
+                        lastInstallmentDate = 
this.scheduledDateGenerator.adjustRepaymentDate(actualRepaymentDate, 
loanApplicationTerms,
+                                holidayDetailDTO);
+                        loanTermVariationParams = 
applyExceptionLoanTermVariations(loanApplicationTerms, lastInstallmentDate,
+                                exceptionDataListIterator);
+                    } while (loanTermVariationParams != null && 
loanTermVariationParams.isSkipPeriod());
+
                     if (!lastInstallmentDate.isBefore(rescheduleFrom)) {
                         actualRepaymentDate = previousRepaymentDate;
                         break;
                     }
                     periodNumber++;
-                    // check for date changes
-                    while 
(loanApplicationTerms.getLoanTermVariations().hasDueDateVariation(lastInstallmentDate))
 {
-                        LoanTermVariationsData variation = 
loanApplicationTerms.getLoanTermVariations().nextDueDateVariation();
-                        if (!variation.isSpecificToInstallment()) {
-                            actualRepaymentDate = variation.getDateValue();
+
+                    for (LoanTermVariationsData dueDateVariation : 
dueDateVariationsDataList) {
+                        dueDateVariation.setProcessed(true);
+                    }
+
+                    if (loanTermVariationParams != null && 
loanTermVariationParams.isSkipPeriod()) {
+                        ArrayList<LoanTermVariationsData> variationsDataList = 
loanTermVariationParams.getVariationsDataList();
+                        for (LoanTermVariationsData variationsData : 
variationsDataList) {
+                            variationsData.setProcessed(true);
                         }
-                        variation.setProcessed(true);
                     }
                 }
 
@@ -2690,11 +2756,14 @@ public abstract class AbstractLoanScheduleGenerator 
implements LoanScheduleGener
         private final boolean skipPeriod;
         private final boolean recalculateAmounts;
         private final LocalDate scheduledDueDate;
+        private final ArrayList<LoanTermVariationsData> variationsData;
 
-        public LoanTermVariationParams(final boolean skipPeriod, final boolean 
recalculateAmounts, final LocalDate scheduledDueDate) {
+        public LoanTermVariationParams(final boolean skipPeriod, final boolean 
recalculateAmounts, final LocalDate scheduledDueDate,
+                final ArrayList<LoanTermVariationsData> variationsData) {
             this.skipPeriod = skipPeriod;
             this.recalculateAmounts = recalculateAmounts;
             this.scheduledDueDate = scheduledDueDate;
+            this.variationsData = variationsData;
         }
 
         public boolean isSkipPeriod() {
@@ -2709,6 +2778,10 @@ public abstract class AbstractLoanScheduleGenerator 
implements LoanScheduleGener
             return this.scheduledDueDate;
         }
 
+        public ArrayList<LoanTermVariationsData> getVariationsDataList() {
+            return this.variationsData;
+        }
+
     }
 
     private final class ScheduleCurrentPeriodParams {

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/0b81e802/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java
index 0eaf4af..f2dd3d9 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java
@@ -762,8 +762,7 @@ public final class LoanApplicationCommandFromApiJsonHelper {
                     repaymentsStartingFromDateParameterName, element);
             
baseDataValidator.reset().parameter(repaymentsStartingFromDateParameterName).value(repaymentsStartingFromDate).ignoreIfNull();
             if (!existingLoanApplication.getLoanTermVariations().isEmpty()) {
-                
baseDataValidator.reset().parameter(repaymentsStartingFromDateParameterName).value(repaymentsStartingFromDate)
-                        .failWithCode("invalid.due.to.variable.installments");
+                
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("cannot.modify.application.due.to.variable.installments");
             }
         }
 

Reply via email to