adding global config for interest charged from date same as disbursement date

This commit is contained in:
sachinkulkarni12
2016-03-15 18:06:24 +05:30
parent bf6d0eaa5b
commit 04fe104dde
11 changed files with 140 additions and 16 deletions
@@ -0,0 +1,79 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.integrationtests;
import java.util.ArrayList;
import java.util.HashMap;
import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper;
import org.apache.fineract.integrationtests.common.Utils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import com.jayway.restassured.builder.RequestSpecBuilder;
import com.jayway.restassured.builder.ResponseSpecBuilder;
import com.jayway.restassured.http.ContentType;
import com.jayway.restassured.specification.RequestSpecification;
import com.jayway.restassured.specification.ResponseSpecification;
public class GlobalConfigInterestChargedFromDateSameAsDisbursalDateTest {
private ResponseSpecification responseSpec;
private RequestSpecification requestSpec;
private GlobalConfigurationHelper globalConfigurationHelper;
@Before
public void setup() {
Utils.initializeRESTAssured();
this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
}
@SuppressWarnings( {"static-access", "rawtypes", "unchecked"})
@Test
public void testInterestChargedFromDateSameAsDisbursalDate(){
this.globalConfigurationHelper = new GlobalConfigurationHelper(this.requestSpec, this.responseSpec);
// Retrieving All Global Configuration details
final ArrayList<HashMap> globalConfig = this.globalConfigurationHelper
.getAllGlobalConfigurations(this.requestSpec, this.responseSpec);
Assert.assertNotNull(globalConfig);
String configName = "interest-charged-from-date-same-as-disbursal-date";
boolean newBooleanValue = true;
for (Integer configIndex = 0; configIndex < (globalConfig.size()); configIndex++) {
if (globalConfig.get(configIndex).get("name")
.equals(configName)) {
String configId = (globalConfig.get(configIndex).get("id"))
.toString();
Integer updateConfigId = this.globalConfigurationHelper
.updateEnabledFlagForGlobalConfiguration(this.requestSpec, this.responseSpec,
configId.toString(), newBooleanValue);;
Assert.assertNotNull(updateConfigId);
break;
}
}
}
}
@@ -70,4 +70,6 @@ public interface ConfigurationDomainService {
Date retrieveOrganisationStartDate(); Date retrieveOrganisationStartDate();
boolean isPaymnetypeApplicableforDisbursementCharge(); boolean isPaymnetypeApplicableforDisbursementCharge();
boolean isInterestChargedFromDateSameAsDisbursementDate();
} }
@@ -236,4 +236,12 @@ public class ConfigurationDomainServiceJpa implements ConfigurationDomainService
return property.isEnabled(); return property.isEnabled();
} }
@Override
public boolean isInterestChargedFromDateSameAsDisbursementDate() {
final String propertyName = "interest-charged-from-date-same-as-disbursal-date";
final GlobalConfigurationProperty property = this.globalConfigurationRepository.findOneByNameWithNotFoundDetection(propertyName);
return property.isEnabled();
}
} }
@@ -39,12 +39,14 @@ public class ScheduleGeneratorDTO {
final FloatingRateDTO floatingRateDTO; final FloatingRateDTO floatingRateDTO;
final Calendar calendar; final Calendar calendar;
final CalendarHistoryDataWrapper calendarHistoryDataWrapper; final CalendarHistoryDataWrapper calendarHistoryDataWrapper;
final Boolean isInterestChargedFromDateAsDisbursementDateEnabled;
public ScheduleGeneratorDTO(final LoanScheduleGeneratorFactory loanScheduleFactory, final ApplicationCurrency applicationCurrency, public ScheduleGeneratorDTO(final LoanScheduleGeneratorFactory loanScheduleFactory, final ApplicationCurrency applicationCurrency,
final LocalDate calculatedRepaymentsStartingFromDate, final HolidayDetailDTO holidayDetailDTO, final LocalDate calculatedRepaymentsStartingFromDate, final HolidayDetailDTO holidayDetailDTO,
final CalendarInstance calendarInstanceForInterestRecalculation, final CalendarInstance compoundingCalendarInstance, final CalendarInstance calendarInstanceForInterestRecalculation, final CalendarInstance compoundingCalendarInstance,
final LocalDate recalculateFrom, final Long overdurPenaltyWaitPeriod, final FloatingRateDTO floatingRateDTO, final LocalDate recalculateFrom, final Long overdurPenaltyWaitPeriod, final FloatingRateDTO floatingRateDTO,
final Calendar calendar, final CalendarHistoryDataWrapper calendarHistoryDataWrapper) { final Calendar calendar, final CalendarHistoryDataWrapper calendarHistoryDataWrapper,
final Boolean isInterestChargedFromDateAsDisbursementDateEnabled) {
this.loanScheduleFactory = loanScheduleFactory; this.loanScheduleFactory = loanScheduleFactory;
this.applicationCurrency = applicationCurrency; this.applicationCurrency = applicationCurrency;
@@ -57,6 +59,7 @@ public class ScheduleGeneratorDTO {
this.floatingRateDTO = floatingRateDTO; this.floatingRateDTO = floatingRateDTO;
this.calendar = calendar; this.calendar = calendar;
this.calendarHistoryDataWrapper = calendarHistoryDataWrapper; this.calendarHistoryDataWrapper = calendarHistoryDataWrapper;
this.isInterestChargedFromDateAsDisbursementDateEnabled = isInterestChargedFromDateAsDisbursementDateEnabled;
} }
@@ -115,5 +118,9 @@ public class ScheduleGeneratorDTO {
public CalendarHistoryDataWrapper getCalendarHistoryDataWrapper(){ public CalendarHistoryDataWrapper getCalendarHistoryDataWrapper(){
return this.calendarHistoryDataWrapper; return this.calendarHistoryDataWrapper;
} }
public Boolean isInterestChargedFromDateAsDisbursementDateEnabled(){
return this.isInterestChargedFromDateAsDisbursementDateEnabled;
}
} }
@@ -5052,12 +5052,16 @@ public class Loan extends AbstractPersistable<Long> {
FloatingRateDTO floatingRateDTO = scheduleGeneratorDTO.getFloatingRateDTO(); FloatingRateDTO floatingRateDTO = scheduleGeneratorDTO.getFloatingRateDTO();
List<LoanTermVariationsData> loanTermVariations = new ArrayList<>(); List<LoanTermVariationsData> loanTermVariations = new ArrayList<>();
annualNominalInterestRate = constructLoanTermVariations(floatingRateDTO, annualNominalInterestRate, loanTermVariations); annualNominalInterestRate = constructLoanTermVariations(floatingRateDTO, annualNominalInterestRate, loanTermVariations);
LocalDate interestChargedFromDate = getInterestChargedFromDate();
if(interestChargedFromDate == null && scheduleGeneratorDTO.isInterestChargedFromDateAsDisbursementDateEnabled()){
interestChargedFromDate = getDisbursementDate();
}
final LoanApplicationTerms loanApplicationTerms = LoanApplicationTerms.assembleFrom(scheduleGeneratorDTO.getApplicationCurrency(), final LoanApplicationTerms loanApplicationTerms = LoanApplicationTerms.assembleFrom(scheduleGeneratorDTO.getApplicationCurrency(),
loanTermFrequency, loanTermPeriodFrequencyType, nthDayType, dayOfWeekType, getDisbursementDate(), loanTermFrequency, loanTermPeriodFrequencyType, nthDayType, dayOfWeekType, getDisbursementDate(),
getExpectedFirstRepaymentOnDate(), scheduleGeneratorDTO.getCalculatedRepaymentsStartingFromDate(), getInArrearsTolerance(), getExpectedFirstRepaymentOnDate(), scheduleGeneratorDTO.getCalculatedRepaymentsStartingFromDate(), getInArrearsTolerance(),
this.loanRepaymentScheduleDetail, this.loanProduct.isMultiDisburseLoan(), this.fixedEmiAmount, disbursementData, this.loanRepaymentScheduleDetail, this.loanProduct.isMultiDisburseLoan(), this.fixedEmiAmount, disbursementData,
this.maxOutstandingLoanBalance, getInterestChargedFromDate(), this.loanProduct.getPrincipalThresholdForLastInstallment(), this.maxOutstandingLoanBalance, interestChargedFromDate, this.loanProduct.getPrincipalThresholdForLastInstallment(),
this.loanProduct.getInstallmentAmountInMultiplesOf(), recalculationFrequencyType, restCalendarInstance, compoundingMethod, this.loanProduct.getInstallmentAmountInMultiplesOf(), recalculationFrequencyType, restCalendarInstance, compoundingMethod,
compoundingCalendarInstance, compoundingFrequencyType, this.loanProduct.preCloseInterestCalculationStrategy(), compoundingCalendarInstance, compoundingFrequencyType, this.loanProduct.preCloseInterestCalculationStrategy(),
rescheduleStrategyMethod, calendar, getApprovedPrincipal(), annualNominalInterestRate, loanTermVariations, calendarHistoryDataWrapper); rescheduleStrategyMethod, calendar, getApprovedPrincipal(), annualNominalInterestRate, loanTermVariations, calendarHistoryDataWrapper);
@@ -185,7 +185,8 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
// calculated interest start date for the period // calculated interest start date for the period
LocalDate periodStartDateApplicableForInterest = calculateInterestStartDateForPeriod(loanApplicationTerms, LocalDate periodStartDateApplicableForInterest = calculateInterestStartDateForPeriod(loanApplicationTerms,
scheduleParams.getPeriodStartDate(), idealDisbursementDate, firstRepaymentdate); scheduleParams.getPeriodStartDate(), idealDisbursementDate, firstRepaymentdate,
loanApplicationTerms.isInterestChargedFromDateSameAsDisbursalDateEnabled(), loanApplicationTerms.getExpectedDisbursementDate());
// Loan Schedule Exceptions that need to be applied for Loan Account // Loan Schedule Exceptions that need to be applied for Loan Account
LoanTermVariationParams termVariationParams = applyLoanTermVariations(loanApplicationTerms, scheduleParams, LoanTermVariationParams termVariationParams = applyLoanTermVariations(loanApplicationTerms, scheduleParams,
@@ -249,7 +250,8 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
continue; continue;
} }
periodStartDateApplicableForInterest = calculateInterestStartDateForPeriod(loanApplicationTerms, periodStartDateApplicableForInterest = calculateInterestStartDateForPeriod(loanApplicationTerms,
scheduleParams.getPeriodStartDate(), idealDisbursementDate, firstRepaymentdate); scheduleParams.getPeriodStartDate(), idealDisbursementDate, firstRepaymentdate,
loanApplicationTerms.isInterestChargedFromDateSameAsDisbursalDateEnabled(), loanApplicationTerms.getExpectedDisbursementDate());
// backup for pre-close transaction // backup for pre-close transaction
updateCompoundingDetails(scheduleParams, periodStartDateApplicableForInterest); updateCompoundingDetails(scheduleParams, periodStartDateApplicableForInterest);
@@ -632,7 +634,8 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
// calculates period start date for interest // calculates period start date for interest
// calculation as per the configuration // calculation as per the configuration
periodStartDateApplicableForInterest = calculateInterestStartDateForPeriod(loanApplicationTerms, periodStartDateApplicableForInterest = calculateInterestStartDateForPeriod(loanApplicationTerms,
scheduleParams.getPeriodStartDate(), idealDisbursementDate, firstRepaymentdate); scheduleParams.getPeriodStartDate(), idealDisbursementDate, firstRepaymentdate,
loanApplicationTerms.isInterestChargedFromDateSameAsDisbursalDateEnabled(), loanApplicationTerms.getExpectedDisbursementDate());
int daysInPeriodApplicable = Days.daysBetween(periodStartDateApplicableForInterest, transactionDate).getDays(); int daysInPeriodApplicable = Days.daysBetween(periodStartDateApplicableForInterest, transactionDate).getDays();
Money interestForThisinstallment = Money.zero(currency); Money interestForThisinstallment = Money.zero(currency);
@@ -1534,9 +1537,12 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
* *
* @param firstRepaymentdate * @param firstRepaymentdate
* TODO * TODO
* @param boolean1
* @param localDate
*/ */
private LocalDate calculateInterestStartDateForPeriod(final LoanApplicationTerms loanApplicationTerms, LocalDate periodStartDate, private LocalDate calculateInterestStartDateForPeriod(final LoanApplicationTerms loanApplicationTerms, LocalDate periodStartDate,
final LocalDate idealDisbursementDate, final LocalDate firstRepaymentdate) { final LocalDate idealDisbursementDate, final LocalDate firstRepaymentdate, final Boolean isInterestChargedFromDateSameAsDisbursalDateEnabled,
final LocalDate expectedDisbursementDate) {
LocalDate periodStartDateApplicableForInterest = periodStartDate; LocalDate periodStartDateApplicableForInterest = periodStartDate;
if (periodStartDate.isBefore(idealDisbursementDate) || firstRepaymentdate.isAfter(periodStartDate)) { if (periodStartDate.isBefore(idealDisbursementDate) || firstRepaymentdate.isAfter(periodStartDate)) {
if (loanApplicationTerms.getInterestChargedFromLocalDate() != null) { if (loanApplicationTerms.getInterestChargedFromLocalDate() != null) {
@@ -1544,9 +1550,11 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|| loanApplicationTerms.getInterestChargedFromLocalDate().isAfter(periodStartDate)) { || loanApplicationTerms.getInterestChargedFromLocalDate().isAfter(periodStartDate)) {
periodStartDateApplicableForInterest = loanApplicationTerms.getInterestChargedFromLocalDate(); periodStartDateApplicableForInterest = loanApplicationTerms.getInterestChargedFromLocalDate();
} }
} else if(loanApplicationTerms.getInterestChargedFromLocalDate() == null && isInterestChargedFromDateSameAsDisbursalDateEnabled) {
periodStartDateApplicableForInterest = expectedDisbursementDate;
} else if (periodStartDate.isEqual(loanApplicationTerms.getExpectedDisbursementDate())) { } else if (periodStartDate.isEqual(loanApplicationTerms.getExpectedDisbursementDate())) {
periodStartDateApplicableForInterest = idealDisbursementDate; periodStartDateApplicableForInterest = idealDisbursementDate;
} }
} }
return periodStartDateApplicableForInterest; return periodStartDateApplicableForInterest;
} }
@@ -180,6 +180,8 @@ public final class LoanApplicationTerms {
private final LocalDate seedDate; private final LocalDate seedDate;
private final CalendarHistoryDataWrapper calendarHistoryDataWrapper; private final CalendarHistoryDataWrapper calendarHistoryDataWrapper;
private final Boolean isInterestChargedFromDateSameAsDisbursalDateEnabled;
public static LoanApplicationTerms assembleFrom(final ApplicationCurrency currency, final Integer loanTermFrequency, public static LoanApplicationTerms assembleFrom(final ApplicationCurrency currency, final Integer loanTermFrequency,
final PeriodFrequencyType loanTermPeriodFrequencyType, final Integer numberOfRepayments, final Integer repaymentEvery, final PeriodFrequencyType loanTermPeriodFrequencyType, final Integer numberOfRepayments, final Integer repaymentEvery,
@@ -197,7 +199,7 @@ public final class LoanApplicationTerms {
final CalendarInstance compoundingCalendarInstance, final RecalculationFrequencyType compoundingFrequencyType, final CalendarInstance compoundingCalendarInstance, final RecalculationFrequencyType compoundingFrequencyType,
final BigDecimal principalThresholdForLastInstalment, final Integer installmentAmountInMultiplesOf, final BigDecimal principalThresholdForLastInstalment, final Integer installmentAmountInMultiplesOf,
final LoanPreClosureInterestCalculationStrategy preClosureInterestCalculationStrategy, final Calendar loanCalendar, final LoanPreClosureInterestCalculationStrategy preClosureInterestCalculationStrategy, final Calendar loanCalendar,
BigDecimal approvedAmount, List<LoanTermVariationsData> loanTermVariations) { BigDecimal approvedAmount, List<LoanTermVariationsData> loanTermVariations, Boolean isInterestChargedFromDateSameAsDisbursalDateEnabled) {
final LoanRescheduleStrategyMethod rescheduleStrategyMethod = null; final LoanRescheduleStrategyMethod rescheduleStrategyMethod = null;
final InterestRecalculationCompoundingMethod interestRecalculationCompoundingMethod = null; final InterestRecalculationCompoundingMethod interestRecalculationCompoundingMethod = null;
@@ -211,7 +213,8 @@ public final class LoanApplicationTerms {
graceOnArrearsAgeing, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, rescheduleStrategyMethod, graceOnArrearsAgeing, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, rescheduleStrategyMethod,
interestRecalculationCompoundingMethod, restCalendarInstance, recalculationFrequencyType, compoundingCalendarInstance, interestRecalculationCompoundingMethod, restCalendarInstance, recalculationFrequencyType, compoundingCalendarInstance,
compoundingFrequencyType, principalThresholdForLastInstalment, installmentAmountInMultiplesOf, compoundingFrequencyType, principalThresholdForLastInstalment, installmentAmountInMultiplesOf,
preClosureInterestCalculationStrategy, loanCalendar, approvedAmount, loanTermVariations, calendarHistoryDataWrapper); preClosureInterestCalculationStrategy, loanCalendar, approvedAmount, loanTermVariations, calendarHistoryDataWrapper,
isInterestChargedFromDateSameAsDisbursalDateEnabled);
} }
public static LoanApplicationTerms assembleFrom(final ApplicationCurrency applicationCurrency, final Integer loanTermFrequency, public static LoanApplicationTerms assembleFrom(final ApplicationCurrency applicationCurrency, final Integer loanTermFrequency,
@@ -275,6 +278,7 @@ public final class LoanApplicationTerms {
final DaysInMonthType daysInMonthType = loanProductRelatedDetail.fetchDaysInMonthType(); final DaysInMonthType daysInMonthType = loanProductRelatedDetail.fetchDaysInMonthType();
final DaysInYearType daysInYearType = loanProductRelatedDetail.fetchDaysInYearType(); final DaysInYearType daysInYearType = loanProductRelatedDetail.fetchDaysInYearType();
final boolean isInterestRecalculationEnabled = loanProductRelatedDetail.isInterestRecalculationEnabled(); final boolean isInterestRecalculationEnabled = loanProductRelatedDetail.isInterestRecalculationEnabled();
final boolean isInterestChargedFromDateSameAsDisbursalDateEnabled = false;
return new LoanApplicationTerms(applicationCurrency, loanTermFrequency, loanTermPeriodFrequencyType, numberOfRepayments, return new LoanApplicationTerms(applicationCurrency, loanTermFrequency, loanTermPeriodFrequencyType, numberOfRepayments,
repaymentEvery, repaymentPeriodFrequencyType, nthDay.getValue(), dayOfWeek, amortizationMethod, interestMethod, repaymentEvery, repaymentPeriodFrequencyType, nthDay.getValue(), dayOfWeek, amortizationMethod, interestMethod,
interestRatePerPeriod, interestRatePeriodFrequencyType, annualNominalInterestRate, interestCalculationPeriodMethod, interestRatePerPeriod, interestRatePeriodFrequencyType, annualNominalInterestRate, interestCalculationPeriodMethod,
@@ -284,7 +288,8 @@ public final class LoanApplicationTerms {
loanProductRelatedDetail.getGraceOnDueDate(), daysInMonthType, daysInYearType, isInterestRecalculationEnabled, loanProductRelatedDetail.getGraceOnDueDate(), daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
rescheduleStrategyMethod, compoundingMethod, restCalendarInstance, recalculationFrequencyType, compoundingCalendarInstance, rescheduleStrategyMethod, compoundingMethod, restCalendarInstance, recalculationFrequencyType, compoundingCalendarInstance,
compoundingFrequencyType, principalThresholdForLastInstalment, installmentAmountInMultiplesOf, compoundingFrequencyType, principalThresholdForLastInstalment, installmentAmountInMultiplesOf,
loanPreClosureInterestCalculationStrategy, loanCalendar, approvedAmount, loanTermVariations, calendarHistoryDataWrapper); loanPreClosureInterestCalculationStrategy, loanCalendar, approvedAmount, loanTermVariations, calendarHistoryDataWrapper,
isInterestChargedFromDateSameAsDisbursalDateEnabled);
} }
public static LoanApplicationTerms assembleFrom(final ApplicationCurrency applicationCurrency, final Integer loanTermFrequency, public static LoanApplicationTerms assembleFrom(final ApplicationCurrency applicationCurrency, final Integer loanTermFrequency,
@@ -327,6 +332,7 @@ public final class LoanApplicationTerms {
interestRecalculationCompoundingMethod = interestRecalculationDetails.getInterestRecalculationCompoundingMethod(); interestRecalculationCompoundingMethod = interestRecalculationDetails.getInterestRecalculationCompoundingMethod();
} }
final CalendarHistoryDataWrapper calendarHistoryDataWrapper = null; final CalendarHistoryDataWrapper calendarHistoryDataWrapper = null;
final boolean isInterestChargedFromDateSameAsDisbursalDateEnabled = false;
return new LoanApplicationTerms(applicationCurrency, loanTermFrequency, loanTermPeriodFrequencyType, numberOfRepayments, return new LoanApplicationTerms(applicationCurrency, loanTermFrequency, loanTermPeriodFrequencyType, numberOfRepayments,
repaymentEvery, repaymentPeriodFrequencyType, null, null, amortizationMethod, interestMethod, interestRatePerPeriod, repaymentEvery, repaymentPeriodFrequencyType, null, null, amortizationMethod, interestMethod, interestRatePerPeriod,
@@ -337,7 +343,8 @@ public final class LoanApplicationTerms {
loanProductRelatedDetail.getGraceOnDueDate(), daysInMonthType, daysInYearType, isInterestRecalculationEnabled, loanProductRelatedDetail.getGraceOnDueDate(), daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
rescheduleStrategyMethod, interestRecalculationCompoundingMethod, restCalendarInstance, recalculationFrequencyType, rescheduleStrategyMethod, interestRecalculationCompoundingMethod, restCalendarInstance, recalculationFrequencyType,
compoundingCalendarInstance, compoundingFrequencyType, principalThresholdForLastInstalment, installmentAmountInMultiplesOf, compoundingCalendarInstance, compoundingFrequencyType, principalThresholdForLastInstalment, installmentAmountInMultiplesOf,
loanPreClosureInterestCalculationStrategy, loanCalendar, approvedAmount, loanTermVariations, calendarHistoryDataWrapper); loanPreClosureInterestCalculationStrategy, loanCalendar, approvedAmount, loanTermVariations, calendarHistoryDataWrapper,
isInterestChargedFromDateSameAsDisbursalDateEnabled);
} }
public static LoanApplicationTerms assembleFrom(final LoanApplicationTerms applicationTerms, public static LoanApplicationTerms assembleFrom(final LoanApplicationTerms applicationTerms,
@@ -359,7 +366,8 @@ public final class LoanApplicationTerms {
applicationTerms.compoundingCalendarInstance, applicationTerms.compoundingFrequencyType, applicationTerms.compoundingCalendarInstance, applicationTerms.compoundingFrequencyType,
applicationTerms.principalThresholdForLastInstalment, applicationTerms.installmentAmountInMultiplesOf, applicationTerms.principalThresholdForLastInstalment, applicationTerms.installmentAmountInMultiplesOf,
applicationTerms.preClosureInterestCalculationStrategy, applicationTerms.loanCalendar, applicationTerms.preClosureInterestCalculationStrategy, applicationTerms.loanCalendar,
applicationTerms.approvedPrincipal.getAmount(), loanTermVariations, applicationTerms.calendarHistoryDataWrapper); applicationTerms.approvedPrincipal.getAmount(), loanTermVariations, applicationTerms.calendarHistoryDataWrapper,
applicationTerms.isInterestChargedFromDateSameAsDisbursalDateEnabled);
} }
private LoanApplicationTerms(final ApplicationCurrency currency, final Integer loanTermFrequency, private LoanApplicationTerms(final ApplicationCurrency currency, final Integer loanTermFrequency,
@@ -381,7 +389,7 @@ public final class LoanApplicationTerms {
final BigDecimal principalThresholdForLastInstalment, final Integer installmentAmountInMultiplesOf, final BigDecimal principalThresholdForLastInstalment, final Integer installmentAmountInMultiplesOf,
final LoanPreClosureInterestCalculationStrategy preClosureInterestCalculationStrategy, final Calendar loanCalendar, final LoanPreClosureInterestCalculationStrategy preClosureInterestCalculationStrategy, final Calendar loanCalendar,
BigDecimal approvedAmount, List<LoanTermVariationsData> loanTermVariations, BigDecimal approvedAmount, List<LoanTermVariationsData> loanTermVariations,
final CalendarHistoryDataWrapper calendarHistoryDataWrapper) { final CalendarHistoryDataWrapper calendarHistoryDataWrapper, Boolean isInterestChargedFromDateSameAsDisbursalDateEnabled) {
this.currency = currency; this.currency = currency;
this.loanTermFrequency = loanTermFrequency; this.loanTermFrequency = loanTermFrequency;
this.loanTermPeriodFrequencyType = loanTermPeriodFrequencyType; this.loanTermPeriodFrequencyType = loanTermPeriodFrequencyType;
@@ -440,6 +448,7 @@ public final class LoanApplicationTerms {
this.seedDate = this.calculatedRepaymentsStartingFromDate; this.seedDate = this.calculatedRepaymentsStartingFromDate;
} }
this.calendarHistoryDataWrapper = calendarHistoryDataWrapper; this.calendarHistoryDataWrapper = calendarHistoryDataWrapper;
this.isInterestChargedFromDateSameAsDisbursalDateEnabled = isInterestChargedFromDateSameAsDisbursalDateEnabled;
} }
public Money adjustPrincipalIfLastRepaymentPeriod(final Money principalForPeriod, final Money totalCumulativePrincipalToDate, public Money adjustPrincipalIfLastRepaymentPeriod(final Money principalForPeriod, final Money totalCumulativePrincipalToDate,
@@ -1440,5 +1449,9 @@ public final class LoanApplicationTerms {
public CalendarHistoryDataWrapper getCalendarHistoryDataWrapper() { public CalendarHistoryDataWrapper getCalendarHistoryDataWrapper() {
return this.calendarHistoryDataWrapper; return this.calendarHistoryDataWrapper;
} }
public Boolean isInterestChargedFromDateSameAsDisbursalDateEnabled(){
return this.isInterestChargedFromDateSameAsDisbursalDateEnabled;
}
} }
@@ -289,6 +289,7 @@ public class LoanScheduleAssembler {
final Integer graceOnInterestPayment = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("graceOnInterestPayment", element); final Integer graceOnInterestPayment = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("graceOnInterestPayment", element);
final Integer graceOnInterestCharged = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("graceOnInterestCharged", element); final Integer graceOnInterestCharged = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("graceOnInterestCharged", element);
final LocalDate interestChargedFromDate = this.fromApiJsonHelper.extractLocalDateNamed("interestChargedFromDate", element); final LocalDate interestChargedFromDate = this.fromApiJsonHelper.extractLocalDateNamed("interestChargedFromDate", element);
final Boolean isInterestChargedFromDateSameAsDisbursalDateEnabled = this.configurationDomainService.isInterestChargedFromDateSameAsDisbursementDate();
final Integer graceOnArrearsAgeing = this.fromApiJsonHelper.extractIntegerWithLocaleNamed( final Integer graceOnArrearsAgeing = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(
LoanProductConstants.graceOnArrearsAgeingParameterName, element); LoanProductConstants.graceOnArrearsAgeingParameterName, element);
@@ -396,7 +397,7 @@ public class LoanScheduleAssembler {
maxOutstandingBalance, graceOnArrearsAgeing, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, maxOutstandingBalance, graceOnArrearsAgeing, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
recalculationFrequencyType, restCalendarInstance, compoundingCalendarInstance, compoundingFrequencyType, recalculationFrequencyType, restCalendarInstance, compoundingCalendarInstance, compoundingFrequencyType,
principalThresholdForLastInstalment, installmentAmountInMultiplesOf, loanProduct.preCloseInterestCalculationStrategy(), principalThresholdForLastInstalment, installmentAmountInMultiplesOf, loanProduct.preCloseInterestCalculationStrategy(),
calendar, BigDecimal.ZERO, loanTermVariations); calendar, BigDecimal.ZERO, loanTermVariations, isInterestChargedFromDateSameAsDisbursalDateEnabled);
} }
private CalendarInstance createCalendarForSameAsRepayment(final Integer repaymentEvery, private CalendarInstance createCalendarForSameAsRepayment(final Integer repaymentEvery,
@@ -550,7 +550,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
} }
} }
} }
final Set<LoanCollateral> possiblyModifedLoanCollateralItems = this.loanCollateralAssembler final Set<LoanCollateral> possiblyModifedLoanCollateralItems = this.loanCollateralAssembler
.fromParsedJson(command.parsedJson()); .fromParsedJson(command.parsedJson());
@@ -123,10 +123,11 @@ public class LoanUtilService {
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue()); loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
overdurPenaltyWaitPeriod = this.configurationDomainService.retrievePenaltyWaitPeriod(); overdurPenaltyWaitPeriod = this.configurationDomainService.retrievePenaltyWaitPeriod();
} }
final Boolean isInterestChargedFromDateAsDisbursementDateEnabled = this.configurationDomainService.isInterestChargedFromDateSameAsDisbursementDate();
FloatingRateDTO floatingRateDTO = constructFloatingRateDTO(loan); FloatingRateDTO floatingRateDTO = constructFloatingRateDTO(loan);
ScheduleGeneratorDTO scheduleGeneratorDTO = new ScheduleGeneratorDTO(loanScheduleFactory, applicationCurrency, ScheduleGeneratorDTO scheduleGeneratorDTO = new ScheduleGeneratorDTO(loanScheduleFactory, applicationCurrency,
calculatedRepaymentsStartingFromDate, holidayDetails, restCalendarInstance, compoundingCalendarInstance, recalculateFrom, calculatedRepaymentsStartingFromDate, holidayDetails, restCalendarInstance, compoundingCalendarInstance, recalculateFrom,
overdurPenaltyWaitPeriod, floatingRateDTO, calendar, calendarHistoryDataWrapper); overdurPenaltyWaitPeriod, floatingRateDTO, calendar, calendarHistoryDataWrapper, isInterestChargedFromDateAsDisbursementDateEnabled);
return scheduleGeneratorDTO; return scheduleGeneratorDTO;
} }
@@ -0,0 +1 @@
INSERT INTO `c_configuration` (`name`, `value`, `date_value`, `enabled`, `is_trap_door`, `description`) VALUES ('interest-charged-from-date-same-as-disbursal-date', 0, NULL, 0, 0, NULL);