Merge pull request #1220 from fynmanoj/AL-14
FINERACT-1109 appropriate-interest-larger-than-emi
This commit is contained in:
+220
@@ -0,0 +1,220 @@
|
|||||||
|
/**
|
||||||
|
* 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 static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import io.restassured.builder.RequestSpecBuilder;
|
||||||
|
import io.restassured.builder.ResponseSpecBuilder;
|
||||||
|
import io.restassured.http.ContentType;
|
||||||
|
import io.restassured.specification.RequestSpecification;
|
||||||
|
import io.restassured.specification.ResponseSpecification;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.apache.fineract.integrationtests.common.ClientHelper;
|
||||||
|
import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper;
|
||||||
|
import org.apache.fineract.integrationtests.common.LoanRescheduleRequestHelper;
|
||||||
|
import org.apache.fineract.integrationtests.common.Utils;
|
||||||
|
import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder;
|
||||||
|
import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
|
||||||
|
import org.apache.fineract.integrationtests.common.loans.LoanRescheduleRequestTestBuilder;
|
||||||
|
import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class LoanRescheduleOnDecliningBalanceLoanTest {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(LoanRescheduleOnDecliningBalanceLoanTest.class);
|
||||||
|
private ResponseSpecification responseSpec;
|
||||||
|
private ResponseSpecification generalResponseSpec;
|
||||||
|
private RequestSpecification requestSpec;
|
||||||
|
private LoanTransactionHelper loanTransactionHelper;
|
||||||
|
private LoanRescheduleRequestHelper loanRescheduleRequestHelper;
|
||||||
|
private Integer clientId;
|
||||||
|
private Integer loanProductId;
|
||||||
|
private Integer loanId;
|
||||||
|
private Integer loanRescheduleRequestId;
|
||||||
|
private final String loanPrincipalAmount = "100000.00";
|
||||||
|
private final String numberOfRepayments = "12";
|
||||||
|
private final String interestRatePerPeriod = "18";
|
||||||
|
private final String dateString = "4 September 2014";
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void initialize() {
|
||||||
|
Utils.initializeRESTAssured();
|
||||||
|
this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
|
||||||
|
this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
|
||||||
|
this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
|
||||||
|
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
|
||||||
|
this.loanRescheduleRequestHelper = new LoanRescheduleRequestHelper(this.requestSpec, this.responseSpec);
|
||||||
|
|
||||||
|
this.generalResponseSpec = new ResponseSpecBuilder().build();
|
||||||
|
|
||||||
|
// create all required entities
|
||||||
|
this.createRequiredEntities();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void tearDown() {
|
||||||
|
disableConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the client, loan product, and loan entities
|
||||||
|
**/
|
||||||
|
private void createRequiredEntities() {
|
||||||
|
this.createClientEntity();
|
||||||
|
this.createLoanProductEntity();
|
||||||
|
this.createLoanEntity();
|
||||||
|
this.enableConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a new client
|
||||||
|
**/
|
||||||
|
private void createClientEntity() {
|
||||||
|
this.clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec);
|
||||||
|
|
||||||
|
ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, this.clientId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a new loan product
|
||||||
|
**/
|
||||||
|
private void createLoanProductEntity() {
|
||||||
|
LOG.info("---------------------------------CREATING LOAN PRODUCT------------------------------------------");
|
||||||
|
|
||||||
|
final String loanProductJSON = new LoanProductTestBuilder().withPrincipal(loanPrincipalAmount)
|
||||||
|
.withNumberOfRepayments(numberOfRepayments).withinterestRatePerPeriod(interestRatePerPeriod)
|
||||||
|
.withInterestRateFrequencyTypeAsYear().withInterestTypeAsDecliningBalance().withInterestCalculationPeriodTypeAsDays()
|
||||||
|
.build(null);
|
||||||
|
|
||||||
|
this.loanProductId = this.loanTransactionHelper.getLoanProductId(loanProductJSON);
|
||||||
|
LOG.info("Successfully created loan product (ID:{}) ", this.loanProductId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* submit a new loan application, approve and disburse the loan
|
||||||
|
**/
|
||||||
|
private void createLoanEntity() {
|
||||||
|
LOG.info("---------------------------------NEW LOAN APPLICATION------------------------------------------");
|
||||||
|
|
||||||
|
final String loanApplicationJSON = new LoanApplicationTestBuilder().withPrincipal(loanPrincipalAmount)
|
||||||
|
.withLoanTermFrequency(numberOfRepayments).withLoanTermFrequencyAsMonths().withNumberOfRepayments(numberOfRepayments)
|
||||||
|
.withRepaymentEveryAfter("1").withRepaymentFrequencyTypeAsMonths().withAmortizationTypeAsEqualInstallments()
|
||||||
|
.withInterestCalculationPeriodTypeAsDays().withInterestRatePerPeriod(interestRatePerPeriod)
|
||||||
|
.withInterestTypeAsDecliningBalance().withSubmittedOnDate(dateString).withExpectedDisbursementDate(dateString)
|
||||||
|
.withPrincipalGrace("2").withInterestGrace("2").build(this.clientId.toString(), this.loanProductId.toString(), null);
|
||||||
|
|
||||||
|
this.loanId = this.loanTransactionHelper.getLoanId(loanApplicationJSON);
|
||||||
|
|
||||||
|
LOG.info("Sucessfully created loan (ID: {} )", this.loanId);
|
||||||
|
|
||||||
|
this.approveLoanApplication();
|
||||||
|
this.disburseLoan();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* approve the loan application
|
||||||
|
**/
|
||||||
|
private void approveLoanApplication() {
|
||||||
|
|
||||||
|
if (this.loanId != null) {
|
||||||
|
this.loanTransactionHelper.approveLoan(this.dateString, this.loanId);
|
||||||
|
LOG.info("Successfully approved loan (ID: {} )", this.loanId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* disburse the newly created loan
|
||||||
|
**/
|
||||||
|
private void disburseLoan() {
|
||||||
|
|
||||||
|
if (this.loanId != null) {
|
||||||
|
this.loanTransactionHelper.disburseLoan(this.dateString, this.loanId);
|
||||||
|
LOG.info("Successfully disbursed loan (ID: {} )", this.loanId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enables the configuration `is-interest-to-be-appropriated-equally-when-greater-than-emi`
|
||||||
|
**/
|
||||||
|
private void enableConfig() {
|
||||||
|
GlobalConfigurationHelper.updateEnabledFlagForGlobalConfiguration(this.requestSpec, this.responseSpec, "34", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* disables the configuration `is-interest-to-be-appropriated-equally-when-greater-than-emi`
|
||||||
|
**/
|
||||||
|
private void disableConfig() {
|
||||||
|
GlobalConfigurationHelper.updateEnabledFlagForGlobalConfiguration(this.requestSpec, this.responseSpec, "34", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateLoanRescheduleRequestWithInterestAppropriation() {
|
||||||
|
this.createAndApproveLoanRescheduleRequestForInterestAppropriation();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create new loan reschedule request
|
||||||
|
**/
|
||||||
|
private void createAndApproveLoanRescheduleRequestForInterestAppropriation() {
|
||||||
|
LOG.info(
|
||||||
|
"---------------------------------CREATING LOAN RESCHEDULE REQUEST FOR INTEREST APPROPRIATTION-------------------------------------");
|
||||||
|
|
||||||
|
final String requestJSON = new LoanRescheduleRequestTestBuilder().updateGraceOnPrincipal(null).updateGraceOnInterest(null)
|
||||||
|
.updateExtraTerms(null).updateRescheduleFromDate("04 January 2015").updateAdjustedDueDate("04 October 2015")
|
||||||
|
.updateRecalculateInterest(true).build(this.loanId.toString());
|
||||||
|
|
||||||
|
this.loanRescheduleRequestId = this.loanRescheduleRequestHelper.createLoanRescheduleRequest(requestJSON);
|
||||||
|
this.loanRescheduleRequestHelper.verifyCreationOfLoanRescheduleRequest(this.loanRescheduleRequestId);
|
||||||
|
|
||||||
|
LOG.info("Successfully created loan reschedule request (ID: {} )", this.loanRescheduleRequestId);
|
||||||
|
|
||||||
|
final String aproveRequestJSON = new LoanRescheduleRequestTestBuilder().getApproveLoanRescheduleRequestJSON();
|
||||||
|
this.loanRescheduleRequestHelper.approveLoanRescheduleRequest(this.loanRescheduleRequestId, aproveRequestJSON);
|
||||||
|
final HashMap response = (HashMap) this.loanRescheduleRequestHelper.getLoanRescheduleRequest(loanRescheduleRequestId, "statusEnum");
|
||||||
|
assertTrue((Boolean) response.get("approved"));
|
||||||
|
|
||||||
|
LOG.info("Successfully approved loan reschedule request (ID: {})", this.loanRescheduleRequestId);
|
||||||
|
|
||||||
|
final Map repaymentSchedule = (Map) this.loanTransactionHelper.getLoanDetail(requestSpec, generalResponseSpec, loanId,
|
||||||
|
"repaymentSchedule");
|
||||||
|
final ArrayList periods = (ArrayList) repaymentSchedule.get("periods");
|
||||||
|
|
||||||
|
HashMap period = (HashMap) periods.get(5);
|
||||||
|
Float totalDueForPeriod = (Float) period.get("totalDueForPeriod");
|
||||||
|
|
||||||
|
final HashMap loanSummary = this.loanTransactionHelper.getLoanSummary(requestSpec, generalResponseSpec, loanId);
|
||||||
|
final Float totalExpectedRepayment = (Float) loanSummary.get("totalExpectedRepayment");
|
||||||
|
|
||||||
|
assertEquals(12186, totalDueForPeriod.intValue(), "TOTAL EXPECTED LAST REPAYMENT is NOK");
|
||||||
|
assertEquals(123682, totalExpectedRepayment.intValue(), "TOTAL EXPECTED LAST REPAYMENT is NOK");
|
||||||
|
|
||||||
|
LOG.info("Successfully approved loan reschedule request (ID: {})", this.loanRescheduleRequestId);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+11
-3
@@ -88,9 +88,9 @@ public class GlobalConfigurationHelper {
|
|||||||
ArrayList<HashMap> expectedGlobalConfigurations = getAllDefaultGlobalConfigurations();
|
ArrayList<HashMap> expectedGlobalConfigurations = getAllDefaultGlobalConfigurations();
|
||||||
ArrayList<HashMap> actualGlobalConfigurations = getAllGlobalConfigurations(requestSpec, responseSpec);
|
ArrayList<HashMap> actualGlobalConfigurations = getAllGlobalConfigurations(requestSpec, responseSpec);
|
||||||
|
|
||||||
// There are currently 29 global configurations.
|
// There are currently 30 global configurations.
|
||||||
Assertions.assertEquals(29, expectedGlobalConfigurations.size());
|
Assertions.assertEquals(30, expectedGlobalConfigurations.size());
|
||||||
Assertions.assertEquals(29, actualGlobalConfigurations.size());
|
Assertions.assertEquals(30, actualGlobalConfigurations.size());
|
||||||
|
|
||||||
for (int i = 0; i < expectedGlobalConfigurations.size(); i++) {
|
for (int i = 0; i < expectedGlobalConfigurations.size(); i++) {
|
||||||
|
|
||||||
@@ -354,6 +354,14 @@ public class GlobalConfigurationHelper {
|
|||||||
isFirstPaydayAllowedOnHoliday.put("trapDoor", false);
|
isFirstPaydayAllowedOnHoliday.put("trapDoor", false);
|
||||||
defaults.add(isFirstPaydayAllowedOnHoliday);
|
defaults.add(isFirstPaydayAllowedOnHoliday);
|
||||||
|
|
||||||
|
HashMap<String, Object> isInterestAppropriationEnabled = new HashMap<>();
|
||||||
|
isInterestAppropriationEnabled.put("id", 34);
|
||||||
|
isInterestAppropriationEnabled.put("name", "is-interest-to-be-appropriated-equally-when-greater-than-emi");
|
||||||
|
isInterestAppropriationEnabled.put("value", 0);
|
||||||
|
isInterestAppropriationEnabled.put("enabled", false);
|
||||||
|
isInterestAppropriationEnabled.put("trapDoor", false);
|
||||||
|
defaults.add(isInterestAppropriationEnabled);
|
||||||
|
|
||||||
return defaults;
|
return defaults;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
@@ -96,4 +96,6 @@ public interface ConfigurationDomainService {
|
|||||||
boolean isSubRatesEnabled();
|
boolean isSubRatesEnabled();
|
||||||
|
|
||||||
boolean isFirstRepaymentDateAfterRescheduleAllowedOnHoliday();
|
boolean isFirstRepaymentDateAfterRescheduleAllowedOnHoliday();
|
||||||
|
|
||||||
|
boolean isInterestToBeAppropriatedEquallyWhenGreaterThanEMI();
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -257,6 +257,11 @@ public class ConfigurationDomainServiceJpa implements ConfigurationDomainService
|
|||||||
return getGlobalConfigurationPropertyData("loan-reschedule-is-first-payday-allowed-on-holiday").isEnabled();
|
return getGlobalConfigurationPropertyData("loan-reschedule-is-first-payday-allowed-on-holiday").isEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInterestToBeAppropriatedEquallyWhenGreaterThanEMI() {
|
||||||
|
return getGlobalConfigurationPropertyData("is-interest-to-be-appropriated-equally-when-greater-than-emi").isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long retreivePeroidInNumberOfDaysForSkipMeetingDate() {
|
public Long retreivePeroidInNumberOfDaysForSkipMeetingDate() {
|
||||||
final String propertyName = "skip-repayment-on-first-day-of-month";
|
final String propertyName = "skip-repayment-on-first-day-of-month";
|
||||||
|
|||||||
+6
-1
@@ -44,6 +44,7 @@ public class ScheduleGeneratorDTO {
|
|||||||
final boolean isSkipRepaymentOnFirstDayofMonth;
|
final boolean isSkipRepaymentOnFirstDayofMonth;
|
||||||
final Boolean isChangeEmiIfRepaymentDateSameAsDisbursementDateEnabled;
|
final Boolean isChangeEmiIfRepaymentDateSameAsDisbursementDateEnabled;
|
||||||
final boolean isFirstRepaymentDateAllowedOnHoliday;
|
final boolean isFirstRepaymentDateAllowedOnHoliday;
|
||||||
|
final boolean isInterestToBeAppropriatedEquallyWhenGreaterThanEMI;
|
||||||
|
|
||||||
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,
|
||||||
@@ -52,7 +53,7 @@ public class ScheduleGeneratorDTO {
|
|||||||
final Calendar calendar, final CalendarHistoryDataWrapper calendarHistoryDataWrapper,
|
final Calendar calendar, final CalendarHistoryDataWrapper calendarHistoryDataWrapper,
|
||||||
final Boolean isInterestChargedFromDateAsDisbursementDateEnabled, final Integer numberOfdays,
|
final Boolean isInterestChargedFromDateAsDisbursementDateEnabled, final Integer numberOfdays,
|
||||||
final boolean isSkipRepaymentOnFirstDayofMonth, final Boolean isChangeEmiIfRepaymentDateSameAsDisbursementDateEnabled,
|
final boolean isSkipRepaymentOnFirstDayofMonth, final Boolean isChangeEmiIfRepaymentDateSameAsDisbursementDateEnabled,
|
||||||
final boolean isFirstRepaymentDateAllowedOnHoliday) {
|
final boolean isFirstRepaymentDateAllowedOnHoliday, final boolean isInterestToBeAppropriatedEquallyWhenGreaterThanEMI) {
|
||||||
|
|
||||||
this.loanScheduleFactory = loanScheduleFactory;
|
this.loanScheduleFactory = loanScheduleFactory;
|
||||||
this.applicationCurrency = applicationCurrency;
|
this.applicationCurrency = applicationCurrency;
|
||||||
@@ -70,6 +71,7 @@ public class ScheduleGeneratorDTO {
|
|||||||
this.isSkipRepaymentOnFirstDayofMonth = isSkipRepaymentOnFirstDayofMonth;
|
this.isSkipRepaymentOnFirstDayofMonth = isSkipRepaymentOnFirstDayofMonth;
|
||||||
this.isChangeEmiIfRepaymentDateSameAsDisbursementDateEnabled = isChangeEmiIfRepaymentDateSameAsDisbursementDateEnabled;
|
this.isChangeEmiIfRepaymentDateSameAsDisbursementDateEnabled = isChangeEmiIfRepaymentDateSameAsDisbursementDateEnabled;
|
||||||
this.isFirstRepaymentDateAllowedOnHoliday = isFirstRepaymentDateAllowedOnHoliday;
|
this.isFirstRepaymentDateAllowedOnHoliday = isFirstRepaymentDateAllowedOnHoliday;
|
||||||
|
this.isInterestToBeAppropriatedEquallyWhenGreaterThanEMI = isInterestToBeAppropriatedEquallyWhenGreaterThanEMI;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoanScheduleGeneratorFactory getLoanScheduleFactory() {
|
public LoanScheduleGeneratorFactory getLoanScheduleFactory() {
|
||||||
@@ -148,4 +150,7 @@ public class ScheduleGeneratorDTO {
|
|||||||
return isFirstRepaymentDateAllowedOnHoliday;
|
return isFirstRepaymentDateAllowedOnHoliday;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isInterestToBeAppropriatedEquallyWhenGreaterThanEMI() {
|
||||||
|
return isInterestToBeAppropriatedEquallyWhenGreaterThanEMI;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -5486,7 +5486,8 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
compoundingCalendarInstance, compoundingFrequencyType, this.loanProduct.preCloseInterestCalculationStrategy(),
|
compoundingCalendarInstance, compoundingFrequencyType, this.loanProduct.preCloseInterestCalculationStrategy(),
|
||||||
rescheduleStrategyMethod, calendar, getApprovedPrincipal(), annualNominalInterestRate, loanTermVariations,
|
rescheduleStrategyMethod, calendar, getApprovedPrincipal(), annualNominalInterestRate, loanTermVariations,
|
||||||
calendarHistoryDataWrapper, scheduleGeneratorDTO.getNumberOfdays(), scheduleGeneratorDTO.isSkipRepaymentOnFirstDayofMonth(),
|
calendarHistoryDataWrapper, scheduleGeneratorDTO.getNumberOfdays(), scheduleGeneratorDTO.isSkipRepaymentOnFirstDayofMonth(),
|
||||||
holidayDetailDTO, allowCompoundingOnEod, scheduleGeneratorDTO.isFirstRepaymentDateAllowedOnHoliday());
|
holidayDetailDTO, allowCompoundingOnEod, scheduleGeneratorDTO.isFirstRepaymentDateAllowedOnHoliday(),
|
||||||
|
scheduleGeneratorDTO.isInterestToBeAppropriatedEquallyWhenGreaterThanEMI());
|
||||||
return loanApplicationTerms;
|
return loanApplicationTerms;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5764,7 +5765,8 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
this.loanProduct.getInstallmentAmountInMultiplesOf(), recalculationFrequencyType, restCalendarInstance, compoundingMethod,
|
this.loanProduct.getInstallmentAmountInMultiplesOf(), recalculationFrequencyType, restCalendarInstance, compoundingMethod,
|
||||||
compoundingCalendarInstance, compoundingFrequencyType, this.loanProduct.preCloseInterestCalculationStrategy(),
|
compoundingCalendarInstance, compoundingFrequencyType, this.loanProduct.preCloseInterestCalculationStrategy(),
|
||||||
rescheduleStrategyMethod, loanCalendar, getApprovedPrincipal(), annualNominalInterestRate, loanTermVariations,
|
rescheduleStrategyMethod, loanCalendar, getApprovedPrincipal(), annualNominalInterestRate, loanTermVariations,
|
||||||
calendarHistoryDataWrapper, numberofdays, isSkipRepaymentonmonthFirst, holidayDetailDTO, allowCompoundingOnEod, false);
|
calendarHistoryDataWrapper, numberofdays, isSkipRepaymentonmonthFirst, holidayDetailDTO, allowCompoundingOnEod, false,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+20
-2
@@ -60,7 +60,7 @@ import org.joda.time.LocalDate;
|
|||||||
|
|
||||||
public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGenerator {
|
public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGenerator {
|
||||||
|
|
||||||
private final ScheduledDateGenerator scheduledDateGenerator = new DefaultScheduledDateGenerator();
|
protected final ScheduledDateGenerator scheduledDateGenerator = new DefaultScheduledDateGenerator();
|
||||||
private final PaymentPeriodsInOneYearCalculator paymentPeriodsInOneYearCalculator = new DefaultPaymentPeriodsInOneYearCalculator();
|
private final PaymentPeriodsInOneYearCalculator paymentPeriodsInOneYearCalculator = new DefaultPaymentPeriodsInOneYearCalculator();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -282,7 +282,8 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
|
|
||||||
// will check for EMI amount greater than interest calculated
|
// will check for EMI amount greater than interest calculated
|
||||||
if (loanApplicationTerms.getFixedEmiAmount() != null
|
if (loanApplicationTerms.getFixedEmiAmount() != null
|
||||||
&& loanApplicationTerms.getFixedEmiAmount().compareTo(principalInterestForThisPeriod.interest().getAmount()) < 0) {
|
&& loanApplicationTerms.getFixedEmiAmount().compareTo(principalInterestForThisPeriod.interest().getAmount()) < 0
|
||||||
|
&& !loanApplicationTerms.isInterestToBeAppropriatedEquallyWhenGreaterThanEMIEnabled()) {
|
||||||
String errorMsg = "EMI amount must be greater than : " + principalInterestForThisPeriod.interest().getAmount();
|
String errorMsg = "EMI amount must be greater than : " + principalInterestForThisPeriod.interest().getAmount();
|
||||||
throw new MultiDisbursementEmiAmountException(errorMsg, principalInterestForThisPeriod.interest().getAmount(),
|
throw new MultiDisbursementEmiAmountException(errorMsg, principalInterestForThisPeriod.interest().getAmount(),
|
||||||
loanApplicationTerms.getFixedEmiAmount());
|
loanApplicationTerms.getFixedEmiAmount());
|
||||||
@@ -369,6 +370,23 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
scheduleParams.setTotalOutstandingInterestPaymentDueToGrace(Money.zero(currency));
|
scheduleParams.setTotalOutstandingInterestPaymentDueToGrace(Money.zero(currency));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (loanApplicationTerms.isInterestToBeAppropriatedEquallyWhenGreaterThanEMIEnabled()
|
||||||
|
&& loanApplicationTerms.getInterestTobeApproppriated() != null
|
||||||
|
&& loanApplicationTerms.getInterestTobeApproppriated().isGreaterThanZero()) {
|
||||||
|
Money interestFraction = loanApplicationTerms.getInterestTobeApproppriated().dividedBy(periods.size(), mc.getRoundingMode());
|
||||||
|
BigDecimal roundFraction = interestFraction.getAmount().remainder(BigDecimal.ONE);
|
||||||
|
interestFraction = interestFraction.minus(roundFraction);
|
||||||
|
roundFraction = roundFraction.multiply(new BigDecimal(periods.size()));
|
||||||
|
for (LoanScheduleModelPeriod installment : (List<LoanScheduleModelPeriod>) periods) {
|
||||||
|
installment.addInterestAmount(interestFraction);
|
||||||
|
}
|
||||||
|
LoanScheduleModelPeriod installment = ((List<LoanScheduleModelPeriod>) periods).get(periods.size() - 1);
|
||||||
|
installment.addInterestAmount(Money.of(currency, roundFraction));
|
||||||
|
scheduleParams.addTotalRepaymentExpected(loanApplicationTerms.getInterestTobeApproppriated());
|
||||||
|
scheduleParams.addTotalCumulativeInterest(loanApplicationTerms.getInterestTobeApproppriated());
|
||||||
|
loanApplicationTerms.setInterestTobeApproppriated(Money.zero(currency));
|
||||||
|
}
|
||||||
|
|
||||||
// determine fees and penalties for charges which depends on total
|
// determine fees and penalties for charges which depends on total
|
||||||
// loan interest
|
// loan interest
|
||||||
updatePeriodsWithCharges(currency, scheduleParams, periods, nonCompoundingCharges);
|
updatePeriodsWithCharges(currency, scheduleParams, periods, nonCompoundingCharges);
|
||||||
|
|||||||
+28
@@ -128,6 +128,34 @@ public class DecliningBalanceInterestLoanScheduleGenerator extends AbstractLoanS
|
|||||||
interestForThisInstallment = interestForThisInstallment.plus(result.interest());
|
interestForThisInstallment = interestForThisInstallment.plus(result.interest());
|
||||||
cumulatingInterestDueToGrace = result.interestPaymentDueToGrace();
|
cumulatingInterestDueToGrace = result.interestPaymentDueToGrace();
|
||||||
|
|
||||||
|
Money interestTobeApproppriated = loanApplicationTerms.getInterestTobeApproppriated() == null
|
||||||
|
? Money.zero(interestForThisInstallment.getCurrency())
|
||||||
|
: loanApplicationTerms.getInterestTobeApproppriated();
|
||||||
|
|
||||||
|
if (loanApplicationTerms.getFixedEmiAmount() != null
|
||||||
|
&& loanApplicationTerms.isInterestToBeAppropriatedEquallyWhenGreaterThanEMIEnabled() && interestForThisInstallment
|
||||||
|
.isGreaterThan(Money.of(interestForThisInstallment.getCurrency(), loanApplicationTerms.getFixedEmiAmount()))) {
|
||||||
|
LocalDate actualPeriodEndDate = this.scheduledDateGenerator.generateNextRepaymentDate(interestStartDate, loanApplicationTerms,
|
||||||
|
false);
|
||||||
|
PrincipalInterest tempInterest = loanApplicationTerms.calculateTotalInterestForPeriod(calculator,
|
||||||
|
interestCalculationGraceOnRepaymentPeriodFraction, periodNumber, mc, cumulatingInterestDueToGrace,
|
||||||
|
balanceForInterestCalculation, interestStartDate, actualPeriodEndDate);
|
||||||
|
|
||||||
|
Money fixedEmi = Money.of(interestForThisInstallment.getCurrency(), loanApplicationTerms.getFixedEmiAmount());
|
||||||
|
|
||||||
|
if (tempInterest.interest().isGreaterThan(fixedEmi)) {
|
||||||
|
loanApplicationTerms
|
||||||
|
.setInterestTobeApproppriated(interestTobeApproppriated.plus(interestForThisInstallment.minus(fixedEmi)));
|
||||||
|
interestForThisInstallment = fixedEmi;
|
||||||
|
} else {
|
||||||
|
loanApplicationTerms.setInterestTobeApproppriated(
|
||||||
|
interestTobeApproppriated.plus(interestForThisInstallment.minus(tempInterest.interest())));
|
||||||
|
interestForThisInstallment = tempInterest.interest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cumulatingInterestDueToGrace = result.interestPaymentDueToGrace();
|
||||||
|
|
||||||
Money interestForPeriod = interestForThisInstallment;
|
Money interestForPeriod = interestForThisInstallment;
|
||||||
if (interestForPeriod.isGreaterThanZero()) {
|
if (interestForPeriod.isGreaterThanZero()) {
|
||||||
interestForPeriod = interestForPeriod.minus(cumulatingInterestPaymentDueToGrace);
|
interestForPeriod = interestForPeriod.minus(cumulatingInterestPaymentDueToGrace);
|
||||||
|
|||||||
+27
-7
@@ -192,6 +192,8 @@ public final class LoanApplicationTerms {
|
|||||||
|
|
||||||
private final boolean isFirstRepaymentDateAllowedOnHoliday;
|
private final boolean isFirstRepaymentDateAllowedOnHoliday;
|
||||||
|
|
||||||
|
private final boolean isInterestToBeAppropriatedEquallyWhenGreaterThanEMI;
|
||||||
|
|
||||||
private final HolidayDetailDTO holidayDetailDTO;
|
private final HolidayDetailDTO holidayDetailDTO;
|
||||||
|
|
||||||
private final Set<Integer> periodNumbersApplicableForPrincipalGrace = new HashSet<>();
|
private final Set<Integer> periodNumbersApplicableForPrincipalGrace = new HashSet<>();
|
||||||
@@ -208,6 +210,7 @@ public final class LoanApplicationTerms {
|
|||||||
private int periodsCompleted = 0;
|
private int periodsCompleted = 0;
|
||||||
private int extraPeriods = 0;
|
private int extraPeriods = 0;
|
||||||
private boolean isEqualAmortization;
|
private boolean isEqualAmortization;
|
||||||
|
private Money interestTobeApproppriated;
|
||||||
|
|
||||||
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,
|
||||||
@@ -245,7 +248,7 @@ public final class LoanApplicationTerms {
|
|||||||
recalculationFrequencyType, compoundingCalendarInstance, compoundingFrequencyType, principalThresholdForLastInstalment,
|
recalculationFrequencyType, compoundingCalendarInstance, compoundingFrequencyType, principalThresholdForLastInstalment,
|
||||||
installmentAmountInMultiplesOf, preClosureInterestCalculationStrategy, loanCalendar, approvedAmount, loanTermVariations,
|
installmentAmountInMultiplesOf, preClosureInterestCalculationStrategy, loanCalendar, approvedAmount, loanTermVariations,
|
||||||
calendarHistoryDataWrapper, isInterestChargedFromDateSameAsDisbursalDateEnabled, numberOfDays,
|
calendarHistoryDataWrapper, isInterestChargedFromDateSameAsDisbursalDateEnabled, numberOfDays,
|
||||||
isSkipRepaymentOnFirstDayOfMonth, holidayDetailDTO, allowCompoundingOnEod, isEqualAmortization, false);
|
isSkipRepaymentOnFirstDayOfMonth, holidayDetailDTO, allowCompoundingOnEod, isEqualAmortization, false, false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,7 +274,8 @@ public final class LoanApplicationTerms {
|
|||||||
principalThresholdForLastInstalment, installmentAmountInMultiplesOf, recalculationFrequencyType, restCalendarInstance,
|
principalThresholdForLastInstalment, installmentAmountInMultiplesOf, recalculationFrequencyType, restCalendarInstance,
|
||||||
compoundingMethod, compoundingCalendarInstance, compoundingFrequencyType, loanPreClosureInterestCalculationStrategy,
|
compoundingMethod, compoundingCalendarInstance, compoundingFrequencyType, loanPreClosureInterestCalculationStrategy,
|
||||||
rescheduleStrategyMethod, loanCalendar, approvedAmount, annualNominalInterestRate, loanTermVariations,
|
rescheduleStrategyMethod, loanCalendar, approvedAmount, annualNominalInterestRate, loanTermVariations,
|
||||||
calendarHistoryDataWrapper, numberOfDays, isSkipRepaymentOnFirstDayOfMonth, holidayDetailDTO, allowCompoundingOnEod, false);
|
calendarHistoryDataWrapper, numberOfDays, isSkipRepaymentOnFirstDayOfMonth, holidayDetailDTO, allowCompoundingOnEod, false,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanApplicationTerms assembleFrom(final ApplicationCurrency applicationCurrency, final Integer loanTermFrequency,
|
public static LoanApplicationTerms assembleFrom(final ApplicationCurrency applicationCurrency, final Integer loanTermFrequency,
|
||||||
@@ -289,7 +293,7 @@ public final class LoanApplicationTerms {
|
|||||||
BigDecimal annualNominalInterestRate, final List<LoanTermVariationsData> loanTermVariations,
|
BigDecimal annualNominalInterestRate, final List<LoanTermVariationsData> loanTermVariations,
|
||||||
final CalendarHistoryDataWrapper calendarHistoryDataWrapper, final Integer numberOfDays,
|
final CalendarHistoryDataWrapper calendarHistoryDataWrapper, final Integer numberOfDays,
|
||||||
final boolean isSkipRepaymentOnFirstDayOfMonth, final HolidayDetailDTO holidayDetailDTO, final boolean allowCompoundingOnEod,
|
final boolean isSkipRepaymentOnFirstDayOfMonth, final HolidayDetailDTO holidayDetailDTO, final boolean allowCompoundingOnEod,
|
||||||
final boolean isFirstRepaymentDateAllowedOnHoliday) {
|
final boolean isFirstRepaymentDateAllowedOnHoliday, final boolean isInterestToBeAppropriatedEquallyWhenGreaterThanEMI) {
|
||||||
|
|
||||||
final Integer numberOfRepayments = loanProductRelatedDetail.getNumberOfRepayments();
|
final Integer numberOfRepayments = loanProductRelatedDetail.getNumberOfRepayments();
|
||||||
final Integer repaymentEvery = loanProductRelatedDetail.getRepayEvery();
|
final Integer repaymentEvery = loanProductRelatedDetail.getRepayEvery();
|
||||||
@@ -327,7 +331,8 @@ public final class LoanApplicationTerms {
|
|||||||
compoundingFrequencyType, principalThresholdForLastInstalment, installmentAmountInMultiplesOf,
|
compoundingFrequencyType, principalThresholdForLastInstalment, installmentAmountInMultiplesOf,
|
||||||
loanPreClosureInterestCalculationStrategy, loanCalendar, approvedAmount, loanTermVariations, calendarHistoryDataWrapper,
|
loanPreClosureInterestCalculationStrategy, loanCalendar, approvedAmount, loanTermVariations, calendarHistoryDataWrapper,
|
||||||
isInterestChargedFromDateSameAsDisbursalDateEnabled, numberOfDays, isSkipRepaymentOnFirstDayOfMonth, holidayDetailDTO,
|
isInterestChargedFromDateSameAsDisbursalDateEnabled, numberOfDays, isSkipRepaymentOnFirstDayOfMonth, holidayDetailDTO,
|
||||||
allowCompoundingOnEod, isEqualAmortization, isFirstRepaymentDateAllowedOnHoliday);
|
allowCompoundingOnEod, isEqualAmortization, isFirstRepaymentDateAllowedOnHoliday,
|
||||||
|
isInterestToBeAppropriatedEquallyWhenGreaterThanEMI);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanApplicationTerms assembleFrom(final ApplicationCurrency applicationCurrency, final Integer loanTermFrequency,
|
public static LoanApplicationTerms assembleFrom(final ApplicationCurrency applicationCurrency, final Integer loanTermFrequency,
|
||||||
@@ -386,7 +391,7 @@ public final class LoanApplicationTerms {
|
|||||||
recalculationFrequencyType, compoundingCalendarInstance, compoundingFrequencyType, principalThresholdForLastInstalment,
|
recalculationFrequencyType, compoundingCalendarInstance, compoundingFrequencyType, principalThresholdForLastInstalment,
|
||||||
installmentAmountInMultiplesOf, loanPreClosureInterestCalculationStrategy, loanCalendar, approvedAmount, loanTermVariations,
|
installmentAmountInMultiplesOf, loanPreClosureInterestCalculationStrategy, loanCalendar, approvedAmount, loanTermVariations,
|
||||||
calendarHistoryDataWrapper, isInterestChargedFromDateSameAsDisbursalDateEnabled, numberOfDays,
|
calendarHistoryDataWrapper, isInterestChargedFromDateSameAsDisbursalDateEnabled, numberOfDays,
|
||||||
isSkipRepaymentOnFirstDayOfMonth, holidayDetailDTO, allowCompoundingOnEod, isEqualAmortization, false);
|
isSkipRepaymentOnFirstDayOfMonth, holidayDetailDTO, allowCompoundingOnEod, isEqualAmortization, false, false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,7 +418,8 @@ public final class LoanApplicationTerms {
|
|||||||
applicationTerms.calendarHistoryDataWrapper, applicationTerms.isInterestChargedFromDateSameAsDisbursalDateEnabled,
|
applicationTerms.calendarHistoryDataWrapper, applicationTerms.isInterestChargedFromDateSameAsDisbursalDateEnabled,
|
||||||
applicationTerms.numberOfDays, applicationTerms.isSkipRepaymentOnFirstDayOfMonth, applicationTerms.holidayDetailDTO,
|
applicationTerms.numberOfDays, applicationTerms.isSkipRepaymentOnFirstDayOfMonth, applicationTerms.holidayDetailDTO,
|
||||||
applicationTerms.allowCompoundingOnEod, applicationTerms.isEqualAmortization,
|
applicationTerms.allowCompoundingOnEod, applicationTerms.isEqualAmortization,
|
||||||
applicationTerms.isFirstRepaymentDateAllowedOnHoliday);
|
applicationTerms.isFirstRepaymentDateAllowedOnHoliday,
|
||||||
|
applicationTerms.isInterestToBeAppropriatedEquallyWhenGreaterThanEMI);
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoanApplicationTerms(final ApplicationCurrency currency, final Integer loanTermFrequency,
|
private LoanApplicationTerms(final ApplicationCurrency currency, final Integer loanTermFrequency,
|
||||||
@@ -437,7 +443,8 @@ public final class LoanApplicationTerms {
|
|||||||
BigDecimal approvedAmount, List<LoanTermVariationsData> loanTermVariations,
|
BigDecimal approvedAmount, List<LoanTermVariationsData> loanTermVariations,
|
||||||
final CalendarHistoryDataWrapper calendarHistoryDataWrapper, Boolean isInterestChargedFromDateSameAsDisbursalDateEnabled,
|
final CalendarHistoryDataWrapper calendarHistoryDataWrapper, Boolean isInterestChargedFromDateSameAsDisbursalDateEnabled,
|
||||||
final Integer numberOfDays, final boolean isSkipRepaymentOnFirstDayOfMonth, final HolidayDetailDTO holidayDetailDTO,
|
final Integer numberOfDays, final boolean isSkipRepaymentOnFirstDayOfMonth, final HolidayDetailDTO holidayDetailDTO,
|
||||||
final boolean allowCompoundingOnEod, final boolean isEqualAmortization, final boolean isFirstRepaymentDateAllowedOnHoliday) {
|
final boolean allowCompoundingOnEod, final boolean isEqualAmortization, final boolean isFirstRepaymentDateAllowedOnHoliday,
|
||||||
|
final boolean isInterestToBeAppropriatedEquallyWhenGreaterThanEMI) {
|
||||||
|
|
||||||
this.currency = currency;
|
this.currency = currency;
|
||||||
this.loanTermFrequency = loanTermFrequency;
|
this.loanTermFrequency = loanTermFrequency;
|
||||||
@@ -511,6 +518,7 @@ public final class LoanApplicationTerms {
|
|||||||
this.totalPrincipalAccounted = principal.zero();
|
this.totalPrincipalAccounted = principal.zero();
|
||||||
this.isEqualAmortization = isEqualAmortization;
|
this.isEqualAmortization = isEqualAmortization;
|
||||||
this.isFirstRepaymentDateAllowedOnHoliday = isFirstRepaymentDateAllowedOnHoliday;
|
this.isFirstRepaymentDateAllowedOnHoliday = isFirstRepaymentDateAllowedOnHoliday;
|
||||||
|
this.isInterestToBeAppropriatedEquallyWhenGreaterThanEMI = isInterestToBeAppropriatedEquallyWhenGreaterThanEMI;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Money adjustPrincipalIfLastRepaymentPeriod(final Money principalForPeriod, final Money totalCumulativePrincipalToDate,
|
public Money adjustPrincipalIfLastRepaymentPeriod(final Money principalForPeriod, final Money totalCumulativePrincipalToDate,
|
||||||
@@ -1778,4 +1786,16 @@ public final class LoanApplicationTerms {
|
|||||||
return isFirstRepaymentDateAllowedOnHoliday;
|
return isFirstRepaymentDateAllowedOnHoliday;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Money getInterestTobeApproppriated() {
|
||||||
|
return interestTobeApproppriated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInterestTobeApproppriated(Money interestTobeApproppriated) {
|
||||||
|
this.interestTobeApproppriated = interestTobeApproppriated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInterestToBeAppropriatedEquallyWhenGreaterThanEMIEnabled() {
|
||||||
|
return isInterestToBeAppropriatedEquallyWhenGreaterThanEMI;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -154,7 +154,7 @@ public final class LoanScheduleModelRepaymentPeriod implements LoanScheduleModel
|
|||||||
@Override
|
@Override
|
||||||
public void addInterestAmount(Money interestDue) {
|
public void addInterestAmount(Money interestDue) {
|
||||||
this.interestDue = this.interestDue.plus(interestDue);
|
this.interestDue = this.interestDue.plus(interestDue);
|
||||||
this.totalDue = this.totalDue.plus(principalDue);
|
this.totalDue = this.totalDue.plus(interestDue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
-1
@@ -52,7 +52,6 @@ public class RescheduleLoansApiConstants {
|
|||||||
public static final String approveCommandParamName = "approve";
|
public static final String approveCommandParamName = "approve";
|
||||||
public static final String pendingCommandParamName = "pending";
|
public static final String pendingCommandParamName = "pending";
|
||||||
public static final String rejectCommandParamName = "reject";
|
public static final String rejectCommandParamName = "reject";
|
||||||
|
|
||||||
public static final String endDateParamName = "endDate";
|
public static final String endDateParamName = "endDate";
|
||||||
public static final String emiParamName = "emi";
|
public static final String emiParamName = "emi";
|
||||||
|
|
||||||
|
|||||||
+5
-1
@@ -143,11 +143,15 @@ public class LoanUtilService {
|
|||||||
boolean isFirstRepaymentDateAllowedOnHoliday = this.configurationDomainService
|
boolean isFirstRepaymentDateAllowedOnHoliday = this.configurationDomainService
|
||||||
.isFirstRepaymentDateAfterRescheduleAllowedOnHoliday();
|
.isFirstRepaymentDateAfterRescheduleAllowedOnHoliday();
|
||||||
|
|
||||||
|
boolean isInterestToBeAppropriatedEquallyWhenGreaterThanEMI = this.configurationDomainService
|
||||||
|
.isInterestToBeAppropriatedEquallyWhenGreaterThanEMI();
|
||||||
|
|
||||||
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, numberOfDays, isSkipRepaymentOnFirstMonth,
|
isInterestChargedFromDateAsDisbursementDateEnabled, numberOfDays, isSkipRepaymentOnFirstMonth,
|
||||||
isChangeEmiIfRepaymentDateSameAsDisbursementDateEnabled, isFirstRepaymentDateAllowedOnHoliday);
|
isChangeEmiIfRepaymentDateSameAsDisbursementDateEnabled, isFirstRepaymentDateAllowedOnHoliday,
|
||||||
|
isInterestToBeAppropriatedEquallyWhenGreaterThanEMI);
|
||||||
|
|
||||||
return scheduleGeneratorDTO;
|
return scheduleGeneratorDTO;
|
||||||
}
|
}
|
||||||
|
|||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
--
|
||||||
|
-- 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.
|
||||||
|
--
|
||||||
|
|
||||||
|
INSERT INTO `c_configuration` (`name`, `value`, `date_value`, `enabled`, `is_trap_door`, `description`)
|
||||||
|
VALUES
|
||||||
|
('is-interest-to-be-appropriated-equally-when-greater-than-emi', 0, NULL, 0, 0, 'If enabled, while loan reschedule when interest amount is greater than EMI, the additional interest is spread equally over remaining installments');
|
||||||
Reference in New Issue
Block a user