Repository: incubator-fineract
Updated Branches:
  refs/heads/develop 92286b391 -> ffe6a139f


http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/serialization/LoanProductDataValidator.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/serialization/LoanProductDataValidator.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/serialization/LoanProductDataValidator.java
index 3437b94..3529323 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/serialization/LoanProductDataValidator.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/serialization/LoanProductDataValidator.java
@@ -30,13 +30,14 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.commons.lang.StringUtils;
-import org.apache.fineract.accounting.common.AccountingRuleType;
 import 
org.apache.fineract.accounting.common.AccountingConstants.LOAN_PRODUCT_ACCOUNTING_PARAMS;
+import org.apache.fineract.accounting.common.AccountingRuleType;
 import org.apache.fineract.infrastructure.core.data.ApiParameterError;
 import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
 import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
 import 
org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
 import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
+import org.apache.fineract.portfolio.calendar.service.CalendarUtils;
 import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
 import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
 import 
org.apache.fineract.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
@@ -47,7 +48,6 @@ import 
org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
 import 
org.apache.fineract.portfolio.loanproduct.domain.LoanProductConfigurableAttributes;
 import 
org.apache.fineract.portfolio.loanproduct.domain.LoanProductValueConditionType;
 import 
org.apache.fineract.portfolio.loanproduct.domain.RecalculationFrequencyType;
-import org.joda.time.LocalDate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
@@ -90,10 +90,8 @@ public final class LoanProductDataValidator {
             LoanProductConstants.daysInYearTypeParameterName, 
LoanProductConstants.daysInMonthTypeParameterName,
             LoanProductConstants.rescheduleStrategyMethodParameterName,
             
LoanProductConstants.interestRecalculationCompoundingMethodParameterName,
-            LoanProductConstants.recalculationRestFrequencyDateParamName,
             
LoanProductConstants.recalculationRestFrequencyIntervalParameterName,
             LoanProductConstants.recalculationRestFrequencyTypeParameterName,
-            
LoanProductConstants.recalculationCompoundingFrequencyDateParamName,
             
LoanProductConstants.recalculationCompoundingFrequencyIntervalParameterName,
             
LoanProductConstants.recalculationCompoundingFrequencyTypeParameterName,
             LoanProductConstants.isArrearsBasedOnOriginalScheduleParamName,
@@ -104,7 +102,12 @@ public final class LoanProductDataValidator {
             LoanProductConstants.installmentAmountInMultiplesOfParamName,
             
LoanProductConstants.preClosureInterestCalculationStrategyParamName, 
LoanProductConstants.allowAttributeOverridesParamName,
             LoanProductConstants.allowVariableInstallmentsParamName, 
LoanProductConstants.minimumGapBetweenInstallments,
-            LoanProductConstants.maximumGapBetweenInstallments));
+            LoanProductConstants.maximumGapBetweenInstallments, 
LoanProductConstants.recalculationCompoundingFrequencyWeekdayParamName,
+            
LoanProductConstants.recalculationCompoundingFrequencyNthDayParamName,
+            
LoanProductConstants.recalculationCompoundingFrequencyOnDayParamName,
+            LoanProductConstants.recalculationRestFrequencyWeekdayParamName,
+            LoanProductConstants.recalculationRestFrequencyNthDayParamName, 
LoanProductConstants.recalculationRestFrequencyOnDayParamName,
+            
LoanProductConstants.isCompoundingToBePostedAsTransactionParamName, 
LoanProductConstants.allowCompoundingOnEodParamName));
 
     private final FromJsonHelper fromApiJsonHelper;
 
@@ -787,13 +790,6 @@ public final class LoanProductDataValidator {
 
         if (!frequencyType.isSameAsRepayment()) {
             if (loanProduct == null
-                    || 
this.fromApiJsonHelper.parameterExists(LoanProductConstants.recalculationRestFrequencyDateParamName,
 element)) {
-                final LocalDate recurrenceOnLocalDate = 
this.fromApiJsonHelper.extractLocalDateNamed(
-                        
LoanProductConstants.recalculationRestFrequencyDateParamName, element);
-                
baseDataValidator.reset().parameter(LoanProductConstants.recalculationRestFrequencyDateParamName)
-                        .value(recurrenceOnLocalDate).notNull();
-            }
-            if (loanProduct == null
                     || this.fromApiJsonHelper
                             
.parameterExists(LoanProductConstants.recalculationRestFrequencyIntervalParameterName,
 element)) {
                 final Integer recurrenceInterval = 
this.fromApiJsonHelper.extractIntegerNamed(
@@ -801,6 +797,20 @@ public final class LoanProductDataValidator {
                 
baseDataValidator.reset().parameter(LoanProductConstants.recalculationRestFrequencyIntervalParameterName)
                         .value(recurrenceInterval).notNull();
             }
+            if (loanProduct == null
+                    || 
this.fromApiJsonHelper.parameterExists(LoanProductConstants.recalculationRestFrequencyNthDayParamName,
 element)
+                    || 
this.fromApiJsonHelper.parameterExists(LoanProductConstants.recalculationRestFrequencyWeekdayParamName,
 element)) {
+                CalendarUtils.validateNthDayOfMonthFrequency(baseDataValidator,
+                        
LoanProductConstants.recalculationRestFrequencyNthDayParamName,
+                        
LoanProductConstants.recalculationRestFrequencyWeekdayParamName, element, 
this.fromApiJsonHelper);
+            }
+            if (loanProduct == null
+                    || 
this.fromApiJsonHelper.parameterExists(LoanProductConstants.recalculationRestFrequencyOnDayParamName,
 element)) {
+                final Integer recalculationRestFrequencyOnDay = 
this.fromApiJsonHelper.extractIntegerNamed(
+                        
LoanProductConstants.recalculationRestFrequencyOnDayParamName, element, 
Locale.getDefault());
+                
baseDataValidator.reset().parameter(LoanProductConstants.recalculationRestFrequencyOnDayParamName)
+                        
.value(recalculationRestFrequencyOnDay).ignoreIfNull().inMinMaxRange(1, 28);
+            }
         }
 
         if (compoundingMethod.isCompoundingEnabled()) {
@@ -817,11 +827,11 @@ public final class LoanProductDataValidator {
                     compoundingfrequencyType = 
RecalculationFrequencyType.fromInt(recalculationCompoundingFrequencyType);
                     if (!compoundingfrequencyType.isSameAsRepayment()) {
                         PeriodFrequencyType repaymentFrequencyType = null;
-                        if (loanProduct == null) {
+                        if 
(this.fromApiJsonHelper.parameterExists("repaymentFrequencyType", element)) {
                             Integer repaymentFrequencyTypeVal = 
this.fromApiJsonHelper.extractIntegerNamed("repaymentFrequencyType",
                                     element, Locale.getDefault());
                             repaymentFrequencyType = 
PeriodFrequencyType.fromInt(repaymentFrequencyTypeVal);
-                        } else {
+                        } else if (loanProduct != null) {
                             repaymentFrequencyType = 
loanProduct.getLoanProductRelatedDetail().getRepaymentPeriodFrequencyType();
                         }
                         if 
(!compoundingfrequencyType.isSameFrequency(repaymentFrequencyType)) {
@@ -842,14 +852,6 @@ public final class LoanProductDataValidator {
 
             if (!compoundingfrequencyType.isSameAsRepayment()) {
                 if (loanProduct == null
-                        || 
this.fromApiJsonHelper.parameterExists(LoanProductConstants.recalculationCompoundingFrequencyDateParamName,
-                                element)) {
-                    final LocalDate recurrenceOnLocalDate = 
this.fromApiJsonHelper.extractLocalDateNamed(
-                            
LoanProductConstants.recalculationCompoundingFrequencyDateParamName, element);
-                    
baseDataValidator.reset().parameter(LoanProductConstants.recalculationCompoundingFrequencyDateParamName)
-                            .value(recurrenceOnLocalDate).notNull();
-                }
-                if (loanProduct == null
                         || this.fromApiJsonHelper.parameterExists(
                                 
LoanProductConstants.recalculationCompoundingFrequencyIntervalParameterName, 
element)) {
                     final Integer recurrenceInterval = 
this.fromApiJsonHelper.extractIntegerNamed(
@@ -864,6 +866,23 @@ public final class LoanProductDataValidator {
                     
baseDataValidator.reset().parameter(LoanProductConstants.recalculationCompoundingFrequencyIntervalParameterName)
                             
.value(recurrenceInterval).notNull().integerInMultiplesOfNumber(repaymentEvery);
                 }
+                if (loanProduct == null
+                        || 
this.fromApiJsonHelper.parameterExists(LoanProductConstants.recalculationCompoundingFrequencyNthDayParamName,
+                                element)
+                        || 
this.fromApiJsonHelper.parameterExists(LoanProductConstants.recalculationCompoundingFrequencyWeekdayParamName,
+                                element)) {
+                    
CalendarUtils.validateNthDayOfMonthFrequency(baseDataValidator,
+                            
LoanProductConstants.recalculationCompoundingFrequencyNthDayParamName,
+                            
LoanProductConstants.recalculationCompoundingFrequencyWeekdayParamName, 
element, this.fromApiJsonHelper);
+                }
+                if (loanProduct == null
+                        || 
this.fromApiJsonHelper.parameterExists(LoanProductConstants.recalculationCompoundingFrequencyOnDayParamName,
+                                element)) {
+                    final Integer recalculationRestFrequencyOnDay = 
this.fromApiJsonHelper.extractIntegerNamed(
+                            
LoanProductConstants.recalculationCompoundingFrequencyOnDayParamName, element, 
Locale.getDefault());
+                    
baseDataValidator.reset().parameter(LoanProductConstants.recalculationCompoundingFrequencyOnDayParamName)
+                            
.value(recalculationRestFrequencyOnDay).ignoreIfNull().inMinMaxRange(1, 28);
+                }
             }
         }
 
@@ -873,6 +892,12 @@ public final class LoanProductDataValidator {
             
baseDataValidator.reset().parameter(LoanProductConstants.isArrearsBasedOnOriginalScheduleParamName)
                     
.value(isArrearsBasedOnOriginalSchedule).notNull().isOneOfTheseValues(true, 
false);
         }
+        if 
(this.fromApiJsonHelper.parameterExists(LoanProductConstants.isCompoundingToBePostedAsTransactionParamName,
 element)) {
+            final Boolean isCompoundingToBePostedAsTransactions = 
this.fromApiJsonHelper.extractBooleanNamed(
+                    
LoanProductConstants.isCompoundingToBePostedAsTransactionParamName, element);
+            
baseDataValidator.reset().parameter(LoanProductConstants.isCompoundingToBePostedAsTransactionParamName)
+                    
.value(isCompoundingToBePostedAsTransactions).notNull().isOneOfTheseValues(true,
 false);
+        }
 
         final Integer preCloseInterestCalculationStrategy = 
this.fromApiJsonHelper.extractIntegerWithLocaleNamed(
                 
LoanProductConstants.preClosureInterestCalculationStrategyParamName, element);

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanDropdownReadPlatformService.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanDropdownReadPlatformService.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanDropdownReadPlatformService.java
index 376e092..b0761d7 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanDropdownReadPlatformService.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanDropdownReadPlatformService.java
@@ -47,6 +47,8 @@ public interface LoanDropdownReadPlatformService {
     List<EnumOptionData> retrieveLoanCycleValueConditionTypeOptions();
 
     List<EnumOptionData> retrieveInterestRecalculationCompoundingTypeOptions();
+    List<EnumOptionData> retrieveInterestRecalculationNthDayTypeOptions();
+    List<EnumOptionData> retrieveInterestRecalculationDayOfWeekTypeOptions();
 
     List<EnumOptionData> retrieveRescheduleStrategyTypeOptions();
     

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanDropdownReadPlatformServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanDropdownReadPlatformServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanDropdownReadPlatformServiceImpl.java
index e2d8ed5..b82763f 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanDropdownReadPlatformServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanDropdownReadPlatformServiceImpl.java
@@ -31,6 +31,8 @@ import static 
org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations
 import static 
org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations.repaymentFrequencyNthDayType;
 import static 
org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations.repaymentFrequencyType;
 import static 
org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations.rescheduleStrategyType;
+import static 
org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations.interestRecalculationCompoundingNthDayType;
+import static 
org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations.interestRecalculationCompoundingDayOfWeekType;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -112,7 +114,7 @@ public class LoanDropdownReadPlatformServiceImpl implements 
LoanDropdownReadPlat
     public List<EnumOptionData> 
retrieveRepaymentFrequencyOptionsForNthDayOfMonth() {
         final List<EnumOptionData> repaymentFrequencyOptions = 
Arrays.asList(repaymentFrequencyNthDayType(NthDayType.ONE),
                 repaymentFrequencyNthDayType(NthDayType.TWO), 
repaymentFrequencyNthDayType(NthDayType.THREE),
-                repaymentFrequencyNthDayType(NthDayType.FOUR));
+                repaymentFrequencyNthDayType(NthDayType.FOUR), 
repaymentFrequencyNthDayType(NthDayType.LAST));
         return repaymentFrequencyOptions;
     }
 
@@ -138,7 +140,7 @@ public class LoanDropdownReadPlatformServiceImpl implements 
LoanDropdownReadPlat
     public Collection<TransactionProcessingStrategyData> 
retreiveTransactionProcessingStrategies() {
 
         final Collection<TransactionProcessingStrategyData> strategyOptions = 
new ArrayList<>();
-        Sort sort = new Sort("sortOrder") ;
+        Sort sort = new Sort("sortOrder");
         final List<LoanTransactionProcessingStrategy> strategies = 
this.loanTransactionProcessingStrategyRepository.findAll(sort);
         for (final LoanTransactionProcessingStrategy strategy : strategies) {
             strategyOptions.add(strategy.toData());
@@ -168,6 +170,28 @@ public class LoanDropdownReadPlatformServiceImpl 
implements LoanDropdownReadPlat
     }
 
     @Override
+    public List<EnumOptionData> 
retrieveInterestRecalculationNthDayTypeOptions() {
+        final List<EnumOptionData> 
interestRecalculationCompoundingNthDayTypeOptions = Arrays.asList(
+                interestRecalculationCompoundingNthDayType(NthDayType.ONE), 
interestRecalculationCompoundingNthDayType(NthDayType.TWO),
+                interestRecalculationCompoundingNthDayType(NthDayType.THREE), 
interestRecalculationCompoundingNthDayType(NthDayType.FOUR),
+                interestRecalculationCompoundingNthDayType(NthDayType.LAST));
+        return interestRecalculationCompoundingNthDayTypeOptions;
+    }
+
+    @Override
+    public List<EnumOptionData> 
retrieveInterestRecalculationDayOfWeekTypeOptions() {
+        final List<EnumOptionData> 
interestRecalculationCompoundingNthDayTypeOptions = Arrays.asList(
+                
interestRecalculationCompoundingDayOfWeekType(DayOfWeekType.SUNDAY),
+                
interestRecalculationCompoundingDayOfWeekType(DayOfWeekType.MONDAY),
+                
interestRecalculationCompoundingDayOfWeekType(DayOfWeekType.TUESDAY),
+                
interestRecalculationCompoundingDayOfWeekType(DayOfWeekType.WEDNESDAY),
+                
interestRecalculationCompoundingDayOfWeekType(DayOfWeekType.THURSDAY),
+                
interestRecalculationCompoundingDayOfWeekType(DayOfWeekType.FRIDAY),
+                
interestRecalculationCompoundingDayOfWeekType(DayOfWeekType.SATURDAY));
+        return interestRecalculationCompoundingNthDayTypeOptions;
+    }
+
+    @Override
     public List<EnumOptionData> retrieveRescheduleStrategyTypeOptions() {
 
         final List<EnumOptionData> rescheduleStrategyTypeOptions = 
Arrays.asList(

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanEnumerations.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanEnumerations.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanEnumerations.java
index c5466e6..dffd39c 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanEnumerations.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanEnumerations.java
@@ -172,6 +172,9 @@ public class LoanEnumerations {
             case FIVE:
                 optionData = new EnumOptionData(nthDayValue, codePrefix + 
type.getCode(), "fifth");
             break;
+            case LAST:
+                optionData = new EnumOptionData(nthDayValue, codePrefix + 
type.getCode(), "last");
+            break;
             default:
                 optionData = new EnumOptionData(new Integer(0).longValue(), 
codePrefix + type.getCode(), "invalid");
             break;
@@ -390,6 +393,10 @@ public class LoanEnumerations {
                 optionData = new 
LoanTransactionEnumData(LoanTransactionType.REFUND_FOR_ACTIVE_LOAN.getValue().longValue(),
                         LoanTransactionType.REFUND_FOR_ACTIVE_LOAN.getCode(), 
"Refund");
             break;
+            case INCOME_POSTING:
+                optionData = new 
LoanTransactionEnumData(LoanTransactionType.INCOME_POSTING.getValue().longValue(),
+                        LoanTransactionType.INCOME_POSTING.getCode(), "Income 
Posting");
+            break;
             default:
             break;
         }
@@ -578,6 +585,48 @@ public class LoanEnumerations {
         }
         return optionData;
     }
+    public static EnumOptionData 
interestRecalculationCompoundingNthDayType(final Integer id) {
+        if (id == null) { return null; }
+        return 
interestRecalculationCompoundingNthDayType(NthDayType.fromInt(id));
+    }
+    public static EnumOptionData 
interestRecalculationCompoundingNthDayType(final NthDayType type) {
+       final String codePrefix = "interestRecalculationCompounding.";
+        long nthDayValue = type.getValue().longValue();
+        EnumOptionData optionData = null;
+        switch (type) {
+            case ONE:
+                optionData = new EnumOptionData(nthDayValue, codePrefix + 
type.getCode(), "first");
+            break;
+            case TWO:
+                optionData = new EnumOptionData(nthDayValue, codePrefix + 
type.getCode(), "second");
+            break;
+            case THREE:
+                optionData = new EnumOptionData(nthDayValue, codePrefix + 
type.getCode(), "third");
+            break;
+            case FOUR:
+                optionData = new EnumOptionData(nthDayValue, codePrefix + 
type.getCode(), "fourth");
+            break;
+            case FIVE:
+                optionData = new EnumOptionData(nthDayValue, codePrefix + 
type.getCode(), "fifth");
+            break;
+            case LAST:
+                optionData = new EnumOptionData(nthDayValue, codePrefix + 
type.getCode(), "last");
+            break;
+            default:
+                optionData = new EnumOptionData(new Integer(0).longValue(), 
codePrefix + type.getCode(), "invalid");
+            break;
+        }
+        return optionData;
+    }
+    public static EnumOptionData 
interestRecalculationCompoundingDayOfWeekType(final Integer id) {
+        if (id == null) { return null; }
+        return 
interestRecalculationCompoundingDayOfWeekType(DayOfWeekType.fromInt(id));
+    }
+    public static EnumOptionData 
interestRecalculationCompoundingDayOfWeekType(final DayOfWeekType type) {
+        final String codePrefix = "interestRecalculationCompounding.";
+        EnumOptionData optionData = new 
EnumOptionData(type.getValue().longValue(), codePrefix + type.getCode(), 
type.toString());
+        return optionData;
+    }
 
     public static EnumOptionData rescheduleStrategyType(final int id) {
         return 
rescheduleStrategyType(LoanRescheduleStrategyMethod.fromInt(id));

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java
index 47f5493..31c7903 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java
@@ -194,9 +194,16 @@ public class LoanProductReadPlatformServiceImpl implements 
LoanProductReadPlatfo
                     + "lpr.pre_close_interest_calculation_strategy as 
preCloseInterestCalculationStrategy, "
                     + "lpr.id as lprId, lpr.product_id as productId, 
lpr.compound_type_enum as compoundType, lpr.reschedule_strategy_enum as 
rescheduleStrategy, "
                     + "lpr.rest_frequency_type_enum as restFrequencyEnum, 
lpr.rest_frequency_interval as restFrequencyInterval, "
-                    + "lpr.rest_freqency_date as restFrequencyDate, 
lpr.arrears_based_on_original_schedule as isArrearsBasedOnOriginalSchedule, "
+                    + "lpr.rest_frequency_nth_day_enum as 
restFrequencyNthDayEnum, "
+                    + "lpr.rest_frequency_weekday_enum as 
restFrequencyWeekDayEnum, "
+                    + "lpr.rest_frequency_on_day as restFrequencyOnDay, "
+                    + "lpr.arrears_based_on_original_schedule as 
isArrearsBasedOnOriginalSchedule, "
                     + "lpr.compounding_frequency_type_enum as 
compoundingFrequencyTypeEnum, lpr.compounding_frequency_interval as 
compoundingInterval, "
-                    + "lpr.compounding_freqency_date as 
compoundingFrequencyDate,  "
+                    + "lpr.compounding_frequency_nth_day_enum as 
compoundingFrequencyNthDayEnum, "
+                    + "lpr.compounding_frequency_weekday_enum as 
compoundingFrequencyWeekDayEnum, "
+                    + "lpr.compounding_frequency_on_day as 
compoundingFrequencyOnDay, "
+                    + "lpr.is_compounding_to_be_posted_as_transaction as 
isCompoundingToBePostedAsTransaction, "
+                    + "lpr.allow_compounding_on_eod as allowCompoundingOnEod, "
                     + "lp.hold_guarantee_funds as holdGuaranteeFunds, "
                     + "lp.principal_threshold_for_last_installment as 
principalThresholdForLastInstallment, "
                     + "lpg.id as lpgId, lpg.mandatory_guarantee as 
mandatoryGuarantee, "
@@ -361,23 +368,50 @@ public class LoanProductReadPlatformServiceImpl 
implements LoanProductReadPlatfo
                 final int restFrequencyEnumValue = JdbcSupport.getInteger(rs, 
"restFrequencyEnum");
                 final EnumOptionData restFrequencyType = 
LoanEnumerations.interestRecalculationFrequencyType(restFrequencyEnumValue);
                 final int restFrequencyInterval = JdbcSupport.getInteger(rs, 
"restFrequencyInterval");
-                final LocalDate restFrequencyDate = 
JdbcSupport.getLocalDate(rs, "restFrequencyDate");
+                final Integer restFrequencyNthDayEnumValue = 
JdbcSupport.getInteger(rs, "restFrequencyNthDayEnum");
+                EnumOptionData restFrequencyNthDayEnum = null;
+                if (restFrequencyNthDayEnumValue != null) {
+                    restFrequencyNthDayEnum = 
LoanEnumerations.interestRecalculationCompoundingNthDayType(restFrequencyNthDayEnumValue);
+                }
+                final Integer restFrequencyWeekDayEnumValue = 
JdbcSupport.getInteger(rs, "restFrequencyWeekDayEnum");
+                EnumOptionData restFrequencyWeekDayEnum = null;
+                if (restFrequencyWeekDayEnumValue != null) {
+                    restFrequencyWeekDayEnum = LoanEnumerations
+                            
.interestRecalculationCompoundingDayOfWeekType(restFrequencyWeekDayEnumValue);
+                }
+                final Integer restFrequencyOnDay = JdbcSupport.getInteger(rs, 
"restFrequencyOnDay");
                 final Integer compoundingFrequencyEnumValue = 
JdbcSupport.getInteger(rs, "compoundingFrequencyTypeEnum");
                 EnumOptionData compoundingFrequencyType = null;
                 if (compoundingFrequencyEnumValue != null) {
                     compoundingFrequencyType = 
LoanEnumerations.interestRecalculationFrequencyType(compoundingFrequencyEnumValue);
                 }
                 final Integer compoundingInterval = JdbcSupport.getInteger(rs, 
"compoundingInterval");
-                final LocalDate compoundingFrequencyDate = 
JdbcSupport.getLocalDate(rs, "compoundingFrequencyDate");
+                final Integer compoundingFrequencyNthDayEnumValue = 
JdbcSupport.getInteger(rs, "compoundingFrequencyNthDayEnum");
+                EnumOptionData compoundingFrequencyNthDayEnum = null;
+                if (compoundingFrequencyNthDayEnumValue != null) {
+                    compoundingFrequencyNthDayEnum = LoanEnumerations
+                            
.interestRecalculationCompoundingNthDayType(compoundingFrequencyNthDayEnumValue);
+                }
+                final Integer compoundingFrequencyWeekDayEnumValue = 
JdbcSupport.getInteger(rs, "compoundingFrequencyWeekDayEnum");
+                EnumOptionData compoundingFrequencyWeekDayEnum = null;
+                if (compoundingFrequencyWeekDayEnumValue != null) {
+                    compoundingFrequencyWeekDayEnum = LoanEnumerations
+                            
.interestRecalculationCompoundingDayOfWeekType(compoundingFrequencyWeekDayEnumValue);
+                }
+                final Integer compoundingFrequencyOnDay = 
JdbcSupport.getInteger(rs, "compoundingFrequencyOnDay");
                 final boolean isArrearsBasedOnOriginalSchedule = 
rs.getBoolean("isArrearsBasedOnOriginalSchedule");
+                final boolean isCompoundingToBePostedAsTransaction = 
rs.getBoolean("isCompoundingToBePostedAsTransaction");
                 final int preCloseInterestCalculationStrategyEnumValue = 
JdbcSupport.getInteger(rs, "preCloseInterestCalculationStrategy");
                 final EnumOptionData preCloseInterestCalculationStrategy = 
LoanEnumerations
                         
.preCloseInterestCalculationStrategy(preCloseInterestCalculationStrategyEnumValue);
+                final boolean allowCompoundingOnEod = 
rs.getBoolean("allowCompoundingOnEod");
 
                 interestRecalculationData = new 
LoanProductInterestRecalculationData(lprId, productId,
                         interestRecalculationCompoundingType, 
rescheduleStrategyType, restFrequencyType, restFrequencyInterval,
-                        restFrequencyDate, compoundingFrequencyType, 
compoundingInterval, compoundingFrequencyDate,
-                        isArrearsBasedOnOriginalSchedule, 
preCloseInterestCalculationStrategy);
+                        restFrequencyNthDayEnum, restFrequencyWeekDayEnum, 
restFrequencyOnDay, compoundingFrequencyType,
+                        compoundingInterval, compoundingFrequencyNthDayEnum, 
compoundingFrequencyWeekDayEnum, compoundingFrequencyOnDay,
+                        isArrearsBasedOnOriginalSchedule, 
isCompoundingToBePostedAsTransaction, preCloseInterestCalculationStrategy, 
+                        allowCompoundingOnEod);
             }
 
             final boolean amortization = rs.getBoolean("amortizationBoolean");

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl.java
index 2c105f4..9dac460 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl.java
@@ -342,7 +342,7 @@ public class 
DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
             final String title = "recurring_savings_" + account.getId();
             
             final Calendar calendar = Calendar.createRepeatingCalendar(title, 
calendarStartDate, CalendarType.COLLECTION.getValue(),
-                    CalendarFrequencyType.from(periodFrequencyType), 
frequency, repeatsOnDay);
+                    CalendarFrequencyType.from(periodFrequencyType), 
frequency, repeatsOnDay, null);
             calendarInstance = CalendarInstance.from(calendar, 
account.getId(), CalendarEntityType.SAVINGS.getValue());
         }
         if (calendarInstance == null) {
@@ -488,7 +488,7 @@ public class 
DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
                         accountId, CalendarEntityType.SAVINGS.getValue(), 
CalendarType.COLLECTION.getValue());
                 Calendar calendar = calendarInstance.getCalendar();
                 calendar.updateRepeatingCalendar(calendarStartDate, 
CalendarFrequencyType.from(periodFrequencyType), frequency,
-                        repeatsOnDay);
+                        repeatsOnDay, null);
                 this.calendarInstanceRepository.save(calendarInstance);
             }
 

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/main/resources/sql/migrations/core_db/V305__compounding_and_rest_frequency_nth_day_freq_and_insertion_script_for_accrual_job.sql
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/resources/sql/migrations/core_db/V305__compounding_and_rest_frequency_nth_day_freq_and_insertion_script_for_accrual_job.sql
 
b/fineract-provider/src/main/resources/sql/migrations/core_db/V305__compounding_and_rest_frequency_nth_day_freq_and_insertion_script_for_accrual_job.sql
new file mode 100644
index 0000000..fba505b
--- /dev/null
+++ 
b/fineract-provider/src/main/resources/sql/migrations/core_db/V305__compounding_and_rest_frequency_nth_day_freq_and_insertion_script_for_accrual_job.sql
@@ -0,0 +1,60 @@
+CREATE TABLE `m_loan_interest_recalculation_additional_details` (
+       `id` BIGINT NOT NULL AUTO_INCREMENT,
+       `loan_repayment_schedule_id` BIGINT NOT NULL,
+       `effective_date` DATE NOT NULL,
+       `amount` DECIMAL(19,6) NOT NULL,
+       PRIMARY KEY (`id`),
+       CONSTRAINT `FK_additional_details_repayment_schedule_id` FOREIGN KEY 
(`loan_repayment_schedule_id`) REFERENCES `m_loan_repayment_schedule` (`id`)
+);
+
+
+ALTER TABLE `m_loan` DROP `repayment_frequency_nth_day_enum`, DROP 
`repayment_frequency_day_of_week_enum`;
+
+
+ALTER TABLE `m_product_loan_recalculation_details` ADD 
`rest_frequency_nth_day_enum` INT(5), ADD `rest_frequency_on_day` INT(5), ADD 
`rest_frequency_weekday_enum` INT(5),
+ADD `compounding_frequency_nth_day_enum` INT(5), ADD 
`compounding_frequency_on_day` INT(5), ADD `compounding_frequency_weekday_enum` 
INT(5), ADD `is_compounding_to_be_posted_as_transaction` TINYINT(1) NOT NULL 
DEFAULT '0', ADD `allow_compounding_on_eod` TINYINT(1) NOT NULL DEFAULT '0';
+
+
+ALTER TABLE `m_loan_recalculation_details` ADD `rest_frequency_nth_day_enum` 
INT(5), ADD `rest_frequency_on_day` INT(5), ADD `rest_frequency_weekday_enum` 
INT(5),
+ADD `compounding_frequency_nth_day_enum` INT(5), ADD 
`compounding_frequency_on_day` INT(5), 
+ADD `is_compounding_to_be_posted_as_transaction` TINYINT(1) NOT NULL DEFAULT 
'0',
+ADD `compounding_frequency_weekday_enum` INT(5), ADD 
`allow_compounding_on_eod` TINYINT(1) NOT NULL DEFAULT '0';
+
+
+UPDATE m_product_loan_recalculation_details plr SET 
plr.compounding_frequency_weekday_enum = 
(WEEKDAY(plr.compounding_freqency_date) + 1) WHERE 
plr.compounding_frequency_type_enum = 3 AND plr.compounding_freqency_date IS 
NOT NULL;
+
+
+UPDATE m_product_loan_recalculation_details plr SET 
plr.compounding_frequency_on_day = DAYOFMONTH(plr.compounding_freqency_date) 
WHERE plr.compounding_frequency_type_enum = 4 AND plr.compounding_freqency_date 
IS NOT NULL;
+
+
+UPDATE m_loan_recalculation_details lrd SET 
lrd.compounding_frequency_weekday_enum = 
(WEEKDAY(lrd.compounding_freqency_date) + 1) WHERE 
lrd.compounding_frequency_type_enum = 3 AND lrd.compounding_freqency_date IS 
NOT NULL;
+
+
+UPDATE m_loan_recalculation_details lrd SET lrd.compounding_frequency_on_day = 
DAYOFMONTH(lrd.compounding_freqency_date) WHERE 
lrd.compounding_frequency_type_enum = 4 AND lrd.compounding_freqency_date IS 
NOT NULL;
+
+
+UPDATE m_product_loan_recalculation_details plr SET 
plr.rest_frequency_weekday_enum = (WEEKDAY(plr.rest_freqency_date) + 1) WHERE 
plr.rest_frequency_type_enum = 3 AND plr.rest_freqency_date IS NOT NULL;
+
+
+UPDATE m_product_loan_recalculation_details plr SET plr.rest_frequency_on_day 
= DAYOFMONTH(plr.rest_freqency_date) WHERE plr.rest_frequency_type_enum = 4 AND 
plr.rest_freqency_date IS NOT NULL;
+
+
+UPDATE m_loan_recalculation_details lrd SET lrd.rest_frequency_weekday_enum = 
(WEEKDAY(lrd.rest_freqency_date) + 1) WHERE lrd.rest_frequency_type_enum = 3 
AND lrd.rest_freqency_date IS NOT NULL;
+
+
+UPDATE m_loan_recalculation_details lrd SET lrd.rest_frequency_on_day = 
DAYOFMONTH(lrd.rest_freqency_date) WHERE lrd.rest_frequency_type_enum = 4 AND 
lrd.rest_freqency_date IS NOT NULL;
+
+
+ALTER TABLE `m_product_loan_recalculation_details` DROP `rest_freqency_date`, 
DROP `compounding_freqency_date`;
+
+
+ALTER TABLE `m_loan_recalculation_details` DROP `rest_freqency_date`, DROP 
`compounding_freqency_date`;
+
+
+ALTER TABLE `job`
+       CHANGE COLUMN `name` `name` VARCHAR(100) NOT NULL AFTER `id`,
+       CHANGE COLUMN `display_name` `display_name` VARCHAR(100) NOT NULL AFTER 
`name`;
+
+INSERT INTO `job` (`name`, `display_name`, `cron_expression`, `create_time`, 
`task_priority`, `group_name`, `previous_run_start_time`, `next_run_time`, 
`job_key`, `initializing_errorlog`, `is_active`, `currently_running`, 
`updates_allowed`, `scheduler_group`, `is_misfired`) VALUES ('Add Accrual 
Transactions For Loans With Income Posted As Transactions', 'Add Accrual 
Transactions For Loans With Income Posted As Transactions', '0 1 0 1/1 * ? *', 
now(), 5, NULL, NULL, NULL, NULL, NULL, 1, 0, 1, 3, 0);
+
+UPDATE `job` SET `task_priority`=6 WHERE  `name`='Update Non Performing 
Assets';
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/763cf18b/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/LoanRepaymentScheduleInstallmentBuilder.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/LoanRepaymentScheduleInstallmentBuilder.java
 
b/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/LoanRepaymentScheduleInstallmentBuilder.java
index c8a1bba..5e6ee29 100644
--- 
a/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/LoanRepaymentScheduleInstallmentBuilder.java
+++ 
b/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/LoanRepaymentScheduleInstallmentBuilder.java
@@ -18,9 +18,12 @@
  */
 package org.apache.fineract.portfolio.loanaccount;
 
+import java.util.List;
+
 import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
 import org.apache.fineract.organisation.monetary.domain.Money;
 import org.apache.fineract.portfolio.loanaccount.domain.Loan;
+import 
org.apache.fineract.portfolio.loanaccount.domain.LoanInterestRecalcualtionAdditionalDetails;
 import 
org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
 import org.joda.time.LocalDate;
 
@@ -46,9 +49,10 @@ public class LoanRepaymentScheduleInstallmentBuilder {
     }
 
     public LoanRepaymentScheduleInstallment build() {
+        final List<LoanInterestRecalcualtionAdditionalDetails> 
compoundingDetails = null;
         final LoanRepaymentScheduleInstallment installment = new 
LoanRepaymentScheduleInstallment(this.loan, this.installmentNumber,
                 this.fromDate, this.dueDate, this.principal.getAmount(), 
this.interest.getAmount(), this.feeCharges.getAmount(),
-                this.penaltyCharges.getAmount(), 
this.recalculatedInterestComponent);
+                this.penaltyCharges.getAmount(), 
this.recalculatedInterestComponent, compoundingDetails);
         if (this.completed) {
             installment.payPrincipalComponent(this.latestTransactionDate, 
this.principal);
             installment.payInterestComponent(this.latestTransactionDate, 
this.interest);


Reply via email to