FINERACT-1958-Loan-Product-repayment-start-date-configuration
This commit is contained in:
committed by
Adam Saghy
parent
b1cde8a809
commit
3c6fc1e47b
+18
-8
@@ -57,6 +57,7 @@ import org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanScheduleP
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.exception.MultiDisbursementEmiAmountException;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.exception.MultiDisbursementOutstandingAmoutException;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.exception.ScheduleDateException;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.RepaymentStartDateType;
|
||||
|
||||
public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGenerator {
|
||||
|
||||
@@ -91,14 +92,16 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
|
||||
final MonetaryCurrency currency = loanApplicationTerms.getCurrency();
|
||||
final int numberOfRepayments = loanApplicationTerms.fetchNumberOfRepaymentsAfterExceptions();
|
||||
LoanScheduleParams scheduleParams;
|
||||
LoanScheduleParams scheduleParams = null;
|
||||
LocalDate periodStartDate = RepaymentStartDateType.DISBURSEMENT_DATE.equals(loanApplicationTerms.getRepaymentStartDateType())
|
||||
? loanApplicationTerms.getExpectedDisbursementDate()
|
||||
: loanApplicationTerms.getSubmittedOnDate();
|
||||
if (loanScheduleParams == null) {
|
||||
scheduleParams = LoanScheduleParams.createLoanScheduleParams(currency, Money.of(currency, chargesDueAtTimeOfDisbursement),
|
||||
loanApplicationTerms.getExpectedDisbursementDate(), getPrincipalToBeScheduled(loanApplicationTerms));
|
||||
periodStartDate, getPrincipalToBeScheduled(loanApplicationTerms));
|
||||
} else if (!loanScheduleParams.isPartialUpdate()) {
|
||||
scheduleParams = LoanScheduleParams.createLoanScheduleParams(currency, Money.of(currency, chargesDueAtTimeOfDisbursement),
|
||||
loanApplicationTerms.getExpectedDisbursementDate(), getPrincipalToBeScheduled(loanApplicationTerms),
|
||||
loanScheduleParams);
|
||||
periodStartDate, getPrincipalToBeScheduled(loanApplicationTerms), loanScheduleParams);
|
||||
} else {
|
||||
scheduleParams = loanScheduleParams;
|
||||
}
|
||||
@@ -124,8 +127,11 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
}
|
||||
|
||||
boolean isFirstRepayment = true;
|
||||
LocalDate firstRepaymentdate = this.scheduledDateGenerator
|
||||
.generateNextRepaymentDate(loanApplicationTerms.getExpectedDisbursementDate(), loanApplicationTerms, isFirstRepayment);
|
||||
LocalDate lastRepaymentDate = RepaymentStartDateType.DISBURSEMENT_DATE.equals(loanApplicationTerms.getRepaymentStartDateType())
|
||||
? loanApplicationTerms.getExpectedDisbursementDate()
|
||||
: loanApplicationTerms.getSubmittedOnDate();
|
||||
LocalDate firstRepaymentdate = this.scheduledDateGenerator.generateNextRepaymentDate(lastRepaymentDate, loanApplicationTerms,
|
||||
isFirstRepayment);
|
||||
final LocalDate idealDisbursementDate = this.scheduledDateGenerator.idealDisbursementDateBasedOnFirstRepaymentDate(
|
||||
loanApplicationTerms.getLoanTermPeriodFrequencyType(), loanApplicationTerms.getRepaymentEvery(), firstRepaymentdate,
|
||||
loanApplicationTerms.getLoanCalendar(), loanApplicationTerms.getHolidayDetailDTO(), loanApplicationTerms);
|
||||
@@ -2207,7 +2213,9 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
if (loanApplicationTerms.isInterestRecalculationEnabled()) {
|
||||
lastRestDate = getNextRestScheduleDate(currentDate.minusDays(1), loanApplicationTerms, holidayDetailDTO);
|
||||
}
|
||||
LocalDate actualRepaymentDate = loanApplicationTerms.getExpectedDisbursementDate();
|
||||
LocalDate actualRepaymentDate = RepaymentStartDateType.DISBURSEMENT_DATE
|
||||
.equals(loanApplicationTerms.getRepaymentStartDateType()) ? loanApplicationTerms.getExpectedDisbursementDate()
|
||||
: loanApplicationTerms.getSubmittedOnDate();
|
||||
boolean isFirstRepayment = true;
|
||||
|
||||
// cumulative fields
|
||||
@@ -2222,7 +2230,9 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
// Actual period Number plus interest only repayments
|
||||
int instalmentNumber = 1;
|
||||
LocalDate lastInstallmentDate = actualRepaymentDate;
|
||||
LocalDate periodStartDate = loanApplicationTerms.getExpectedDisbursementDate();
|
||||
LocalDate periodStartDate = RepaymentStartDateType.DISBURSEMENT_DATE.equals(loanApplicationTerms.getRepaymentStartDateType())
|
||||
? loanApplicationTerms.getExpectedDisbursementDate()
|
||||
: loanApplicationTerms.getSubmittedOnDate();
|
||||
// Set fixed Amortization Amounts(either EMI or Principal )
|
||||
updateAmortization(mc, loanApplicationTerms, periodNumber, outstandingBalance);
|
||||
|
||||
|
||||
+6
-3
@@ -32,6 +32,7 @@ import org.apache.fineract.portfolio.calendar.domain.CalendarHistory;
|
||||
import org.apache.fineract.portfolio.calendar.service.CalendarUtils;
|
||||
import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.HolidayDetailDTO;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.RepaymentStartDateType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -44,7 +45,11 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
|
||||
|
||||
final int numberOfRepayments = loanApplicationTerms.getNumberOfRepayments();
|
||||
|
||||
LocalDate lastRepaymentDate = loanApplicationTerms.getExpectedDisbursementDate();
|
||||
RepaymentStartDateType repaymentStartDateType = loanApplicationTerms.getRepaymentStartDateType();
|
||||
|
||||
LocalDate lastRepaymentDate = RepaymentStartDateType.DISBURSEMENT_DATE.equals(repaymentStartDateType)
|
||||
? loanApplicationTerms.getExpectedDisbursementDate()
|
||||
: loanApplicationTerms.getSubmittedOnDate();
|
||||
boolean isFirstRepayment = true;
|
||||
for (int repaymentPeriod = 1; repaymentPeriod <= numberOfRepayments; repaymentPeriod++) {
|
||||
lastRepaymentDate = generateNextRepaymentDate(lastRepaymentDate, loanApplicationTerms, isFirstRepayment);
|
||||
@@ -125,8 +130,6 @@ public class DefaultScheduledDateGenerator implements ScheduledDateGenerator {
|
||||
* @param adjustedDateDetailsDTO
|
||||
* @param loanApplicationTerms
|
||||
* @param holidayDetailDTO
|
||||
* @param nextRepaymentPeriodDueDate
|
||||
* @param rescheduleType
|
||||
* @param isFirstRepayment
|
||||
* @return
|
||||
*/
|
||||
|
||||
+43
-17
@@ -112,6 +112,7 @@ import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRelatedDetail
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRepository;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductVariableInstallmentConfig;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.RecalculationFrequencyType;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.RepaymentStartDateType;
|
||||
import org.apache.fineract.portfolio.loanproduct.exception.LoanProductNotFoundException;
|
||||
import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -234,7 +235,11 @@ public class LoanScheduleAssembler {
|
||||
final Money principalMoney = Money.of(currency, principal);
|
||||
|
||||
final LocalDate expectedDisbursementDate = this.fromApiJsonHelper.extractLocalDateNamed("expectedDisbursementDate", element);
|
||||
final LocalDate repaymentsStartingFromDate = this.fromApiJsonHelper.extractLocalDateNamed("repaymentsStartingFromDate", element);
|
||||
LocalDate repaymentsStartingFromDate = this.fromApiJsonHelper.extractLocalDateNamed("repaymentsStartingFromDate", element);
|
||||
final LocalDate submittedOnDate = this.fromApiJsonHelper.extractLocalDateNamed("submittedOnDate", element);
|
||||
|
||||
final RepaymentStartDateType repaymentStartDateType = loanProduct.getRepaymentStartDateType();
|
||||
|
||||
LocalDate calculatedRepaymentsStartingFromDate = repaymentsStartingFromDate;
|
||||
|
||||
final Boolean synchDisbursement = this.fromApiJsonHelper.extractBooleanNamed("syncDisbursementWithMeeting", element);
|
||||
@@ -261,7 +266,8 @@ public class LoanScheduleAssembler {
|
||||
&& !nthDay.equals(NthDayType.INVALID.getValue())) {
|
||||
LocalDate calendarStartDate = repaymentsStartingFromDate;
|
||||
if (calendarStartDate == null) {
|
||||
calendarStartDate = expectedDisbursementDate;
|
||||
calendarStartDate = RepaymentStartDateType.DISBURSEMENT_DATE.equals(repaymentStartDateType) ? expectedDisbursementDate
|
||||
: submittedOnDate;
|
||||
}
|
||||
calendar = createLoanCalendar(calendarStartDate, repaymentEvery, CalendarFrequencyType.MONTHLY, dayOfWeek, nthDay);
|
||||
}
|
||||
@@ -272,7 +278,8 @@ public class LoanScheduleAssembler {
|
||||
*/
|
||||
if (calculatedRepaymentsStartingFromDate == null) {
|
||||
calculatedRepaymentsStartingFromDate = deriveFirstRepaymentDate(loanType, repaymentEvery, expectedDisbursementDate,
|
||||
repaymentPeriodFrequencyType, loanProduct.getMinimumDaysBetweenDisbursalAndFirstRepayment(), calendar);
|
||||
repaymentPeriodFrequencyType, loanProduct.getMinimumDaysBetweenDisbursalAndFirstRepayment(), calendar, submittedOnDate,
|
||||
repaymentStartDateType);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -305,8 +312,10 @@ public class LoanScheduleAssembler {
|
||||
}
|
||||
}
|
||||
|
||||
validateMinimumDaysBetweenDisbursalAndFirstRepayment(expectedDisbursementDate, calculatedRepaymentsStartingFromDate,
|
||||
loanProduct.getMinimumDaysBetweenDisbursalAndFirstRepayment());
|
||||
if (RepaymentStartDateType.DISBURSEMENT_DATE.equals(repaymentStartDateType)) {
|
||||
validateMinimumDaysBetweenDisbursalAndFirstRepayment(expectedDisbursementDate, calculatedRepaymentsStartingFromDate,
|
||||
loanProduct.getMinimumDaysBetweenDisbursalAndFirstRepayment());
|
||||
}
|
||||
|
||||
// grace details
|
||||
final Integer graceOnPrincipalPayment = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("graceOnPrincipalPayment", element);
|
||||
@@ -471,7 +480,7 @@ public class LoanScheduleAssembler {
|
||||
loanTermVariations, isInterestChargedFromDateSameAsDisbursalDateEnabled, numberOfDays, isSkipMeetingOnFirstDay, detailDTO,
|
||||
allowCompoundingOnEod, isEqualAmortization, isInterestToBeRecoveredFirstWhenGreaterThanEMI,
|
||||
fixedPrincipalPercentagePerInstallment, isPrincipalCompoundingDisabledForOverdueLoans, isDownPaymentEnabled,
|
||||
disbursedAmountPercentageForDownPayment, isAutoRepaymentForDownPaymentEnabled);
|
||||
disbursedAmountPercentageForDownPayment, isAutoRepaymentForDownPaymentEnabled, repaymentStartDateType, submittedOnDate);
|
||||
}
|
||||
|
||||
private CalendarInstance createCalendarForSameAsRepayment(final Integer repaymentEvery,
|
||||
@@ -1070,19 +1079,20 @@ public class LoanScheduleAssembler {
|
||||
|
||||
private LocalDate deriveFirstRepaymentDate(final AccountType loanType, final Integer repaymentEvery,
|
||||
final LocalDate expectedDisbursementDate, final PeriodFrequencyType repaymentPeriodFrequencyType,
|
||||
final Integer minimumDaysBetweenDisbursalAndFirstRepayment, final Calendar calendar) {
|
||||
final Integer minimumDaysBetweenDisbursalAndFirstRepayment, final Calendar calendar, final LocalDate submittedOnDate,
|
||||
final RepaymentStartDateType repaymentStartDateType) {
|
||||
|
||||
LocalDate derivedFirstRepayment = null;
|
||||
|
||||
final LocalDate dateBasedOnMinimumDaysBetweenDisbursalAndFirstRepayment = expectedDisbursementDate
|
||||
.plusDays(minimumDaysBetweenDisbursalAndFirstRepayment);
|
||||
final LocalDate dateBasedOnMinimumDaysBetweenDisbursalAndFirstRepayment = RepaymentStartDateType.DISBURSEMENT_DATE.equals(
|
||||
repaymentStartDateType) ? expectedDisbursementDate.plusDays(minimumDaysBetweenDisbursalAndFirstRepayment) : submittedOnDate;
|
||||
|
||||
if (calendar != null) {
|
||||
|
||||
final LocalDate refernceDateForCalculatingFirstRepaymentDate = expectedDisbursementDate;
|
||||
derivedFirstRepayment = deriveFirstRepaymentDateForLoans(repaymentEvery, expectedDisbursementDate,
|
||||
refernceDateForCalculatingFirstRepaymentDate, repaymentPeriodFrequencyType,
|
||||
minimumDaysBetweenDisbursalAndFirstRepayment, calendar);
|
||||
minimumDaysBetweenDisbursalAndFirstRepayment, calendar, submittedOnDate, repaymentStartDateType);
|
||||
|
||||
} /*** Individual or group account, or JLG not linked to a meeting ***/
|
||||
else {
|
||||
@@ -1092,14 +1102,26 @@ public class LoanScheduleAssembler {
|
||||
// (disbursement date + minimum between disbursal and first
|
||||
// repayment )
|
||||
if (repaymentPeriodFrequencyType.isDaily()) {
|
||||
dateBasedOnRepaymentFrequency = expectedDisbursementDate.plusDays(repaymentEvery);
|
||||
dateBasedOnRepaymentFrequency = RepaymentStartDateType.DISBURSEMENT_DATE.equals(repaymentStartDateType)
|
||||
? expectedDisbursementDate.plusDays(repaymentEvery)
|
||||
: submittedOnDate.plusDays(repaymentEvery);
|
||||
|
||||
} else if (repaymentPeriodFrequencyType.isWeekly()) {
|
||||
dateBasedOnRepaymentFrequency = expectedDisbursementDate.plusWeeks(repaymentEvery);
|
||||
dateBasedOnRepaymentFrequency = RepaymentStartDateType.DISBURSEMENT_DATE.equals(repaymentStartDateType)
|
||||
? expectedDisbursementDate.plusWeeks(repaymentEvery)
|
||||
: submittedOnDate.plusWeeks(repaymentEvery);
|
||||
|
||||
} else if (repaymentPeriodFrequencyType.isMonthly()) {
|
||||
dateBasedOnRepaymentFrequency = expectedDisbursementDate.plusMonths(repaymentEvery);
|
||||
dateBasedOnRepaymentFrequency = RepaymentStartDateType.DISBURSEMENT_DATE.equals(repaymentStartDateType)
|
||||
? expectedDisbursementDate.plusMonths(repaymentEvery)
|
||||
: submittedOnDate.plusMonths(repaymentEvery);
|
||||
|
||||
} /** yearly loan **/
|
||||
else {
|
||||
dateBasedOnRepaymentFrequency = expectedDisbursementDate.plusYears(repaymentEvery);
|
||||
dateBasedOnRepaymentFrequency = RepaymentStartDateType.DISBURSEMENT_DATE.equals(repaymentStartDateType)
|
||||
? expectedDisbursementDate.plusYears(repaymentEvery)
|
||||
: submittedOnDate.plusYears(repaymentEvery);
|
||||
|
||||
}
|
||||
derivedFirstRepayment = dateBasedOnRepaymentFrequency.isAfter(dateBasedOnMinimumDaysBetweenDisbursalAndFirstRepayment)
|
||||
? dateBasedOnRepaymentFrequency
|
||||
@@ -1111,16 +1133,20 @@ public class LoanScheduleAssembler {
|
||||
|
||||
private LocalDate deriveFirstRepaymentDateForLoans(final Integer repaymentEvery, final LocalDate expectedDisbursementDate,
|
||||
final LocalDate refernceDateForCalculatingFirstRepaymentDate, final PeriodFrequencyType repaymentPeriodFrequencyType,
|
||||
final Integer minimumDaysBetweenDisbursalAndFirstRepayment, final Calendar calendar) {
|
||||
final Integer minimumDaysBetweenDisbursalAndFirstRepayment, final Calendar calendar, final LocalDate submittedOnDate,
|
||||
final RepaymentStartDateType repaymentStartDateType) {
|
||||
boolean isMeetingSkipOnFirstDayOfMonth = configurationDomainService.isSkippingMeetingOnFirstDayOfMonthEnabled();
|
||||
int numberOfDays = configurationDomainService.retreivePeroidInNumberOfDaysForSkipMeetingDate().intValue();
|
||||
final String frequency = CalendarUtils.getMeetingFrequencyFromPeriodFrequencyType(repaymentPeriodFrequencyType);
|
||||
final LocalDate derivedFirstRepayment = CalendarUtils.getFirstRepaymentMeetingDate(calendar,
|
||||
refernceDateForCalculatingFirstRepaymentDate, repaymentEvery, frequency, isMeetingSkipOnFirstDayOfMonth, numberOfDays);
|
||||
final LocalDate minimumFirstRepaymentDate = expectedDisbursementDate.plusDays(minimumDaysBetweenDisbursalAndFirstRepayment);
|
||||
final LocalDate minimumFirstRepaymentDate = RepaymentStartDateType.DISBURSEMENT_DATE.equals(repaymentStartDateType)
|
||||
? expectedDisbursementDate.plusDays(minimumDaysBetweenDisbursalAndFirstRepayment)
|
||||
: submittedOnDate;
|
||||
return minimumFirstRepaymentDate.isBefore(derivedFirstRepayment) ? derivedFirstRepayment
|
||||
: deriveFirstRepaymentDateForLoans(repaymentEvery, expectedDisbursementDate, derivedFirstRepayment,
|
||||
repaymentPeriodFrequencyType, minimumDaysBetweenDisbursalAndFirstRepayment, calendar);
|
||||
repaymentPeriodFrequencyType, minimumDaysBetweenDisbursalAndFirstRepayment, calendar, submittedOnDate,
|
||||
repaymentStartDateType);
|
||||
}
|
||||
|
||||
private void validateMinimumDaysBetweenDisbursalAndFirstRepayment(final LocalDate disbursalDate, final LocalDate firstRepaymentDate,
|
||||
|
||||
+5
-3
@@ -112,7 +112,8 @@ public class LoanProductsApiResource {
|
||||
LoanProductConstants.CAN_USE_FOR_TOPUP, LoanProductConstants.IS_EQUAL_AMORTIZATION_PARAM, LoanProductConstants.RATES_PARAM_NAME,
|
||||
LoanApiConstants.fixedPrincipalPercentagePerInstallmentParamName, LoanProductConstants.DUE_DAYS_FOR_REPAYMENT_EVENT,
|
||||
LoanProductConstants.OVER_DUE_DAYS_FOR_REPAYMENT_EVENT, LoanProductConstants.ENABLE_DOWN_PAYMENT,
|
||||
LoanProductConstants.DISBURSED_AMOUNT_PERCENTAGE_DOWN_PAYMENT, LoanProductConstants.ENABLE_AUTO_REPAYMENT_DOWN_PAYMENT));
|
||||
LoanProductConstants.DISBURSED_AMOUNT_PERCENTAGE_DOWN_PAYMENT, LoanProductConstants.ENABLE_AUTO_REPAYMENT_DOWN_PAYMENT,
|
||||
LoanProductConstants.REPAYMENT_START_DATE_TYPE));
|
||||
|
||||
private static final Set<String> PRODUCT_MIX_DATA_PARAMETERS = new HashSet<>(
|
||||
Arrays.asList("productId", "productName", "restrictedProducts", "allowedProducts", "productOptions"));
|
||||
@@ -147,7 +148,7 @@ public class LoanProductsApiResource {
|
||||
@Operation(summary = "Create a Loan Product", description = "Depending of the Accounting Rule (accountingRule) selected, additional fields with details of the appropriate Ledger Account identifiers would need to be passed in.\n"
|
||||
+ "\n" + "Refer MifosX Accounting Specs Draft for more details regarding the significance of the selected accounting rule\n\n"
|
||||
+ "Mandatory Fields: name, shortName, currencyCode, digitsAfterDecimal, inMultiplesOf, principal, numberOfRepayments, repaymentEvery, repaymentFrequencyType, interestRatePerPeriod, interestRateFrequencyType, amortizationType, interestType, interestCalculationPeriodType, transactionProcessingStrategyCode, accountingRule, isInterestRecalculationEnabled, daysInYearType, daysInMonthType\n\n"
|
||||
+ "Optional Fields: inArrearsTolerance, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, graceOnArrearsAgeing, charges, paymentChannelToFundSourceMappings, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, includeInBorrowerCycle, useBorrowerCycle,principalVariationsForBorrowerCycle, numberOfRepaymentVariationsForBorrowerCycle, interestRateVariationsForBorrowerCycle, multiDisburseLoan,maxTrancheCount, outstandingLoanBalance,overdueDaysForNPA,holdGuaranteeFunds, principalThresholdForLastInstalment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount, installmentAmountInMultiplesOf, allowAttributeOverrides, allowPartialPeriodInterestCalcualtion,dueDaysForRepaymentEvent,overDueDaysForRepaymentEvent,enableDownPayment,disbursedAmountPercentageDownPayment,enableAutoRepaymentForDownPayment\n\n"
|
||||
+ "Optional Fields: inArrearsTolerance, graceOnPrincipalPayment, graceOnInterestPayment, graceOnInterestCharged, graceOnArrearsAgeing, charges, paymentChannelToFundSourceMappings, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, includeInBorrowerCycle, useBorrowerCycle,principalVariationsForBorrowerCycle, numberOfRepaymentVariationsForBorrowerCycle, interestRateVariationsForBorrowerCycle, multiDisburseLoan,maxTrancheCount, outstandingLoanBalance,overdueDaysForNPA,holdGuaranteeFunds, principalThresholdForLastInstalment, accountMovesOutOfNPAOnlyOnArrearsCompletion, canDefineInstallmentAmount, installmentAmountInMultiplesOf, allowAttributeOverrides, allowPartialPeriodInterestCalcualtion,dueDaysForRepaymentEvent,overDueDaysForRepaymentEvent,enableDownPayment,disbursedAmountPercentageDownPayment,enableAutoRepaymentForDownPayment,repaymentStartDateType\n\n"
|
||||
+ "Additional Mandatory Fields for Cash(2) based accounting: fundSourceAccountId, loanPortfolioAccountId, interestOnLoanAccountId, incomeFromFeeAccountId, incomeFromPenaltyAccountId, writeOffAccountId, transfersInSuspenseAccountId, overpaymentLiabilityAccountId\n\n"
|
||||
+ "Additional Mandatory Fields for periodic (3) and upfront (4)accrual accounting: fundSourceAccountId, loanPortfolioAccountId, interestOnLoanAccountId, incomeFromFeeAccountId, incomeFromPenaltyAccountId, writeOffAccountId, receivableInterestAccountId, receivableFeeAccountId, receivablePenaltyAccountId, transfersInSuspenseAccountId, overpaymentLiabilityAccountId\n\n"
|
||||
+ "Additional Mandatory Fields if interest recalculation is enabled(true): interestRecalculationCompoundingMethod, rescheduleStrategyMethod, recalculationRestFrequencyType\n\n"
|
||||
@@ -405,6 +406,7 @@ public class LoanProductsApiResource {
|
||||
final List<EnumOptionData> preCloseInterestCalculationStrategyOptions = dropdownReadPlatformService
|
||||
.retrievePreCloseInterestCalculationStrategyOptions();
|
||||
final List<FloatingRateData> floatingRateOptions = this.floatingRateReadPlatformService.retrieveLookupActive();
|
||||
final List<EnumOptionData> repaymentStartDateTypeOptions = dropdownReadPlatformService.retrieveRepaymentStartDateTypeOptions();
|
||||
|
||||
return new LoanProductData(productData, chargeOptions, penaltyOptions, paymentTypeOptions, currencyOptions, amortizationTypeOptions,
|
||||
interestTypeOptions, interestCalculationPeriodTypeOptions, repaymentFrequencyTypeOptions, interestRateFrequencyTypeOptions,
|
||||
@@ -412,7 +414,7 @@ public class LoanProductsApiResource {
|
||||
loanCycleValueConditionTypeOptions, daysInMonthTypeOptions, daysInYearTypeOptions,
|
||||
interestRecalculationCompoundingTypeOptions, rescheduleStrategyTypeOptions, interestRecalculationFrequencyTypeOptions,
|
||||
preCloseInterestCalculationStrategyOptions, floatingRateOptions, interestRecalculationNthDayTypeOptions,
|
||||
interestRecalculationDayOfWeekTypeOptions, isRatesEnabled, delinquencyBucketOptions);
|
||||
interestRecalculationDayOfWeekTypeOptions, isRatesEnabled, delinquencyBucketOptions, repaymentStartDateTypeOptions);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+31
@@ -162,6 +162,8 @@ final class LoanProductsApiResourceSwagger {
|
||||
public BigDecimal disbursedAmountPercentageForDownPayment;
|
||||
@Schema(example = "false")
|
||||
public Boolean enableAutoRepaymentForDownPayment;
|
||||
@Schema(example = "1")
|
||||
public Integer repaymentStartDateType;
|
||||
|
||||
// Interest Recalculation
|
||||
@Schema(example = "false")
|
||||
@@ -419,6 +421,18 @@ final class LoanProductsApiResourceSwagger {
|
||||
public String description;
|
||||
}
|
||||
|
||||
static final class GetLoanProductsRepaymentStartDateType {
|
||||
|
||||
private GetLoanProductsRepaymentStartDateType() {}
|
||||
|
||||
@Schema(example = "1")
|
||||
public Long id;
|
||||
@Schema(example = "repaymentStartDateType.disbursementDate")
|
||||
public String code;
|
||||
@Schema(example = "Disbursement Date")
|
||||
public String description;
|
||||
}
|
||||
|
||||
static final class GetLoanProductsInterestRecalculationData {
|
||||
|
||||
private GetLoanProductsInterestRecalculationData() {}
|
||||
@@ -562,6 +576,7 @@ final class LoanProductsApiResourceSwagger {
|
||||
public GetLoanProductsResponse.GetLoanProductsAccountingRule accountingRule;
|
||||
@Schema(example = "0")
|
||||
public Integer principalThresholdForLastInstalment;
|
||||
public GetLoanProductsResponse.GetLoanProductsRepaymentStartDateType repaymentStartDateType;
|
||||
}
|
||||
|
||||
@Schema(description = "GetLoanProductsTemplateResponse")
|
||||
@@ -1015,6 +1030,7 @@ final class LoanProductsApiResourceSwagger {
|
||||
public Set<GetLoanProductsResponse.GetLoanProductsInterestRecalculationData.GetLoanProductsInterestRecalculationCompoundingType> interestRecalculationCompoundingTypeOptions;
|
||||
public Set<GetLoanProductsResponse.GetLoanProductsInterestRecalculationData.GetLoanProductsRescheduleStrategyType> rescheduleStrategyTypeOptions;
|
||||
public Set<GetLoanProductsResponse.GetLoanProductsInterestRecalculationData.GetLoanProductsInterestRecalculationCompoundingFrequencyType> interestRecalculationFrequencyTypeOptions;
|
||||
public Set<GetLoanProductsResponse.GetLoanProductsRepaymentStartDateType> repaymentStartDateTypeOptions;
|
||||
}
|
||||
|
||||
@Schema(description = "GetLoanProductsProductIdResponse")
|
||||
@@ -1034,6 +1050,18 @@ final class LoanProductsApiResourceSwagger {
|
||||
public String description;
|
||||
}
|
||||
|
||||
static final class GetLoanProductsRepaymentStartDateType {
|
||||
|
||||
private GetLoanProductsRepaymentStartDateType() {}
|
||||
|
||||
@Schema(example = "1")
|
||||
public Long id;
|
||||
@Schema(example = "repaymentStartDateType.disbursementDate")
|
||||
public String code;
|
||||
@Schema(example = "Disbursement Date")
|
||||
public String description;
|
||||
}
|
||||
|
||||
static final class GetLoanProductsPrincipalVariationsForBorrowerCycle {
|
||||
|
||||
private GetLoanProductsPrincipalVariationsForBorrowerCycle() {}
|
||||
@@ -1218,6 +1246,7 @@ final class LoanProductsApiResourceSwagger {
|
||||
public BigDecimal disbursedAmountPercentageForDownPayment;
|
||||
@Schema(example = "false")
|
||||
public Boolean enableAutoRepaymentForDownPayment;
|
||||
public GetLoanProductsRepaymentStartDateType repaymentStartDateType;
|
||||
}
|
||||
|
||||
@Schema(description = "PutLoanProductsProductIdRequest")
|
||||
@@ -1346,6 +1375,8 @@ final class LoanProductsApiResourceSwagger {
|
||||
public BigDecimal disbursedAmountPercentageForDownPayment;
|
||||
@Schema(example = "false")
|
||||
public Boolean enableAutoRepaymentForDownPayment;
|
||||
@Schema(example = "1")
|
||||
public Integer repaymentStartDateType;
|
||||
|
||||
// Interest Recalculation
|
||||
@Schema(example = "false")
|
||||
|
||||
+17
-6
@@ -48,6 +48,7 @@ import org.apache.fineract.portfolio.loanproduct.domain.AmortizationMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.InterestMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductConfigurableAttributes;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.RepaymentStartDateType;
|
||||
import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations;
|
||||
import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
|
||||
import org.apache.fineract.portfolio.rate.data.RateData;
|
||||
@@ -123,6 +124,7 @@ public class LoanProductData implements Serializable {
|
||||
private final Integer minimumDaysBetweenDisbursalAndFirstRepayment;
|
||||
private final boolean canDefineInstallmentAmount;
|
||||
private final Integer installmentAmountInMultiplesOf;
|
||||
private final EnumOptionData repaymentStartDateType;
|
||||
|
||||
// charges
|
||||
private final Collection<ChargeData> charges;
|
||||
@@ -168,6 +170,7 @@ public class LoanProductData implements Serializable {
|
||||
|
||||
private final List<EnumOptionData> interestRecalculationFrequencyTypeOptions;
|
||||
private final List<FloatingRateData> floatingRateOptions;
|
||||
private final List<EnumOptionData> repaymentStartDateTypeOptions;
|
||||
|
||||
private final Boolean multiDisburseLoan;
|
||||
private final Integer maxTrancheCount;
|
||||
@@ -290,6 +293,7 @@ public class LoanProductData implements Serializable {
|
||||
final BigDecimal disbursedAmountPercentageDownPayment = null;
|
||||
final Collection<AdvancedPaymentData> paymentAllocation = null;
|
||||
final boolean enableAutoRepaymentForDownPayment = false;
|
||||
final EnumOptionData repaymentStartDateType = null;
|
||||
|
||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||
@@ -309,7 +313,7 @@ public class LoanProductData implements Serializable {
|
||||
syncExpectedWithDisbursementDate, canUseForTopup, isEqualAmortization, rateOptions, rates, isRatesEnabled,
|
||||
fixedPrincipalPercentagePerInstallment, delinquencyBucketOptions, delinquencyBucket, dueDaysForRepaymentEvent,
|
||||
overDueDaysForRepaymentEvent, enableDownPayment, disbursedAmountPercentageDownPayment, enableAutoRepaymentForDownPayment,
|
||||
paymentAllocation);
|
||||
paymentAllocation, repaymentStartDateType);
|
||||
|
||||
}
|
||||
|
||||
@@ -403,6 +407,7 @@ public class LoanProductData implements Serializable {
|
||||
final BigDecimal disbursedAmountPercentageDownPayment = null;
|
||||
final boolean enableAutoRepaymentForDownPayment = false;
|
||||
final Collection<AdvancedPaymentData> paymentAllocation = null;
|
||||
final EnumOptionData repaymentStartDateType = null;
|
||||
|
||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||
@@ -422,7 +427,7 @@ public class LoanProductData implements Serializable {
|
||||
syncExpectedWithDisbursementDate, canUseForTopup, isEqualAmortization, rateOptions, rates, isRatesEnabled,
|
||||
fixedPrincipalPercentagePerInstallment, delinquencyBucketOptions, delinquencyBucket, dueDaysForRepaymentEvent,
|
||||
overDueDaysForRepaymentEvent, enableDownPayment, disbursedAmountPercentageDownPayment, enableAutoRepaymentForDownPayment,
|
||||
paymentAllocation);
|
||||
paymentAllocation, repaymentStartDateType);
|
||||
|
||||
}
|
||||
|
||||
@@ -523,6 +528,7 @@ public class LoanProductData implements Serializable {
|
||||
final BigDecimal disbursedAmountPercentageDownPayment = null;
|
||||
final boolean enableAutoRepaymentForDownPayment = false;
|
||||
final Collection<AdvancedPaymentData> paymentAllocation = null;
|
||||
final EnumOptionData repaymentStartDateType = LoanEnumerations.repaymentStartDateType(RepaymentStartDateType.DISBURSEMENT_DATE);
|
||||
|
||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||
@@ -542,7 +548,7 @@ public class LoanProductData implements Serializable {
|
||||
syncExpectedWithDisbursementDate, canUseForTopup, isEqualAmortization, rateOptions, rates, isRatesEnabled,
|
||||
fixedPrincipalPercentagePerInstallment, delinquencyBucketOptions, delinquencyBucket, dueDaysForRepaymentEvent,
|
||||
overDueDaysForRepaymentEvent, enableDownPayment, disbursedAmountPercentageDownPayment, enableAutoRepaymentForDownPayment,
|
||||
paymentAllocation);
|
||||
paymentAllocation, repaymentStartDateType);
|
||||
|
||||
}
|
||||
|
||||
@@ -637,6 +643,7 @@ public class LoanProductData implements Serializable {
|
||||
final BigDecimal disbursedAmountPercentageDownPayment = null;
|
||||
final boolean enableAutoRepaymentForDownPayment = false;
|
||||
final Collection<AdvancedPaymentData> paymentAllocation = null;
|
||||
final EnumOptionData repaymentStartDateType = LoanEnumerations.repaymentStartDateType(RepaymentStartDateType.DISBURSEMENT_DATE);
|
||||
|
||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||
@@ -656,7 +663,7 @@ public class LoanProductData implements Serializable {
|
||||
syncExpectedWithDisbursementDate, canUseForTopup, isEqualAmortization, rateOptions, rates, isRatesEnabled,
|
||||
fixedPrincipalPercentagePerInstallment, delinquencyBucketOptions, delinquencyBucket, dueDaysForRepaymentEvent,
|
||||
overDueDaysForRepaymentEvent, enableDownPayment, disbursedAmountPercentageDownPayment, enableAutoRepaymentForDownPayment,
|
||||
paymentAllocation);
|
||||
paymentAllocation, repaymentStartDateType);
|
||||
}
|
||||
|
||||
public static LoanProductData withAccountingDetails(final LoanProductData productData, final Map<String, Object> accountingMappings,
|
||||
@@ -704,7 +711,7 @@ public class LoanProductData implements Serializable {
|
||||
final DelinquencyBucketData delinquencyBucket, final Integer dueDaysForRepaymentEvent,
|
||||
final Integer overDueDaysForRepaymentEvent, final boolean enableDownPayment,
|
||||
final BigDecimal disbursedAmountPercentageForDownPayment, final boolean enableAutoRepaymentForDownPayment,
|
||||
final Collection<AdvancedPaymentData> paymentAllocation) {
|
||||
final Collection<AdvancedPaymentData> paymentAllocation, final EnumOptionData repaymentStartDateType) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.shortName = shortName;
|
||||
@@ -826,6 +833,8 @@ public class LoanProductData implements Serializable {
|
||||
this.disbursedAmountPercentageForDownPayment = disbursedAmountPercentageForDownPayment;
|
||||
this.paymentAllocation = paymentAllocation;
|
||||
this.enableAutoRepaymentForDownPayment = enableAutoRepaymentForDownPayment;
|
||||
this.repaymentStartDateType = repaymentStartDateType;
|
||||
this.repaymentStartDateTypeOptions = null;
|
||||
}
|
||||
|
||||
public LoanProductData(final LoanProductData productData, final Collection<ChargeData> chargeOptions,
|
||||
@@ -842,7 +851,7 @@ public class LoanProductData implements Serializable {
|
||||
final List<EnumOptionData> preCloseInterestCalculationStrategyOptions, final List<FloatingRateData> floatingRateOptions,
|
||||
final List<EnumOptionData> interestRecalculationNthDayTypeOptions,
|
||||
final List<EnumOptionData> interestRecalculationDayOfWeekTypeOptions, final boolean isRatesEnabled,
|
||||
final Collection<DelinquencyBucketData> delinquencyBucketOptions) {
|
||||
final Collection<DelinquencyBucketData> delinquencyBucketOptions, final List<EnumOptionData> repaymentStartDateTypeOptions) {
|
||||
this.id = productData.id;
|
||||
this.name = productData.name;
|
||||
this.shortName = productData.shortName;
|
||||
@@ -981,6 +990,8 @@ public class LoanProductData implements Serializable {
|
||||
this.disbursedAmountPercentageForDownPayment = productData.disbursedAmountPercentageForDownPayment;
|
||||
this.enableAutoRepaymentForDownPayment = productData.enableAutoRepaymentForDownPayment;
|
||||
this.paymentAllocation = productData.paymentAllocation;
|
||||
this.repaymentStartDateType = productData.repaymentStartDateType;
|
||||
this.repaymentStartDateTypeOptions = repaymentStartDateTypeOptions;
|
||||
}
|
||||
|
||||
private Collection<ChargeData> nullIfEmpty(final Collection<ChargeData> charges) {
|
||||
|
||||
+17
-1
@@ -162,7 +162,7 @@ public final class LoanProductDataValidator {
|
||||
LoanProductConstants.OVER_APPLIED_NUMBER, LoanProductConstants.DELINQUENCY_BUCKET_PARAM_NAME,
|
||||
LoanProductConstants.DUE_DAYS_FOR_REPAYMENT_EVENT, LoanProductConstants.OVER_DUE_DAYS_FOR_REPAYMENT_EVENT,
|
||||
LoanProductConstants.ENABLE_DOWN_PAYMENT, LoanProductConstants.DISBURSED_AMOUNT_PERCENTAGE_DOWN_PAYMENT,
|
||||
LoanProductConstants.ENABLE_AUTO_REPAYMENT_DOWN_PAYMENT));
|
||||
LoanProductConstants.ENABLE_AUTO_REPAYMENT_DOWN_PAYMENT, LoanProductConstants.REPAYMENT_START_DATE_TYPE));
|
||||
|
||||
private static final String[] SUPPORTED_LOAN_CONFIGURABLE_ATTRIBUTES = { LoanProductConstants.amortizationTypeParamName,
|
||||
LoanProductConstants.interestTypeParamName, LoanProductConstants.transactionProcessingStrategyCodeParamName,
|
||||
@@ -755,6 +755,13 @@ public final class LoanProductDataValidator {
|
||||
validateAutoRepaymentForDownPayment(enableDownPayment, baseDataValidator, element);
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.REPAYMENT_START_DATE_TYPE, element)) {
|
||||
final Integer repaymentStartDateType = this.fromApiJsonHelper
|
||||
.extractIntegerNamed(LoanProductConstants.REPAYMENT_START_DATE_TYPE, element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.REPAYMENT_START_DATE_TYPE).value(repaymentStartDateType).notNull()
|
||||
.isOneOfTheseValues(1, 2);
|
||||
}
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
@@ -1679,6 +1686,15 @@ public final class LoanProductDataValidator {
|
||||
validateDownPaymentPercentage(enableDownPayment, baseDataValidator, element);
|
||||
validateAutoRepaymentForDownPayment(enableDownPayment, baseDataValidator, element);
|
||||
}
|
||||
|
||||
Integer repaymentStartDateType = loanProduct.getRepaymentStartDateType().getValue();
|
||||
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.REPAYMENT_START_DATE_TYPE, element)) {
|
||||
repaymentStartDateType = this.fromApiJsonHelper.extractIntegerNamed(LoanProductConstants.REPAYMENT_START_DATE_TYPE, element,
|
||||
Locale.getDefault());
|
||||
}
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.REPAYMENT_START_DATE_TYPE).value(repaymentStartDateType).notNull()
|
||||
.isOneOfTheseValues(1, 2);
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -57,4 +57,5 @@ public interface LoanDropdownReadPlatformService {
|
||||
|
||||
List<EnumOptionData> retrievePreCloseInterestCalculationStrategyOptions();
|
||||
|
||||
List<EnumOptionData> retrieveRepaymentStartDateTypeOptions();
|
||||
}
|
||||
|
||||
+8
@@ -32,6 +32,7 @@ import static org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations
|
||||
import static org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations.repaymentFrequencyDayOfWeekType;
|
||||
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.repaymentStartDateType;
|
||||
import static org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations.rescheduleStrategyType;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -52,6 +53,7 @@ import org.apache.fineract.portfolio.loanproduct.domain.LoanPreClosureInterestCa
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductValueConditionType;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanRescheduleStrategyMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.RecalculationFrequencyType;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.RepaymentStartDateType;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@@ -177,4 +179,10 @@ public class LoanDropdownReadPlatformServiceImpl implements LoanDropdownReadPlat
|
||||
return Arrays.asList(preCloseInterestCalculationStrategy(LoanPreClosureInterestCalculationStrategy.TILL_PRE_CLOSURE_DATE),
|
||||
preCloseInterestCalculationStrategy(LoanPreClosureInterestCalculationStrategy.TILL_REST_FREQUENCY_DATE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EnumOptionData> retrieveRepaymentStartDateTypeOptions() {
|
||||
return Arrays.asList(repaymentStartDateType(RepaymentStartDateType.DISBURSEMENT_DATE),
|
||||
repaymentStartDateType(RepaymentStartDateType.SUBMITTED_ON_DATE));
|
||||
}
|
||||
}
|
||||
|
||||
+4
-2
@@ -229,7 +229,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
||||
+ "lp.disallow_expected_disbursements as disallowExpectedDisbursements, lp.allow_approved_disbursed_amounts_over_applied as allowApprovedDisbursedAmountsOverApplied, lp.over_applied_calculation_type as overAppliedCalculationType, over_applied_number as overAppliedNumber, "
|
||||
+ "lp.days_in_month_enum as daysInMonth, lp.days_in_year_enum as daysInYear, lp.interest_recalculation_enabled as isInterestRecalculationEnabled, "
|
||||
+ "lp.can_define_fixed_emi_amount as canDefineInstallmentAmount, lp.instalment_amount_in_multiples_of as installmentAmountInMultiplesOf, "
|
||||
+ "lp.due_days_for_repayment_event as dueDaysForRepaymentEvent, lp.overdue_days_for_repayment_event as overDueDaysForRepaymentEvent, lp.enable_down_payment as enableDownPayment, lp.disbursed_amount_percentage_for_down_payment as disbursedAmountPercentageForDownPayment, lp.enable_auto_repayment_for_down_payment as enableAutoRepaymentForDownPayment, "
|
||||
+ "lp.due_days_for_repayment_event as dueDaysForRepaymentEvent, lp.overdue_days_for_repayment_event as overDueDaysForRepaymentEvent, lp.enable_down_payment as enableDownPayment, lp.disbursed_amount_percentage_for_down_payment as disbursedAmountPercentageForDownPayment, lp.enable_auto_repayment_for_down_payment as enableAutoRepaymentForDownPayment, lp.repayment_start_date_type_enum as repaymentStartDateType, "
|
||||
+ "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, "
|
||||
@@ -364,6 +364,8 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
||||
final boolean enableDownPayment = rs.getBoolean("enableDownPayment");
|
||||
final BigDecimal disbursedAmountPercentageForDownPayment = rs.getBigDecimal("disbursedAmountPercentageForDownPayment");
|
||||
final boolean enableAutoRepaymentForDownPayment = rs.getBoolean("enableAutoRepaymentForDownPayment");
|
||||
final Integer repaymentStartDateTypeId = JdbcSupport.getInteger(rs, "repaymentStartDateType");
|
||||
final EnumOptionData repaymentStartDateType = LoanEnumerations.repaymentStartDateType(repaymentStartDateTypeId);
|
||||
|
||||
String status = "";
|
||||
if (closeDate != null && closeDate.isBefore(DateUtils.getBusinessLocalDate())) {
|
||||
@@ -521,7 +523,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
||||
maximumGap, syncExpectedWithDisbursementDate, canUseForTopup, isEqualAmortization, rateOptions, this.rates,
|
||||
isRatesEnabled, fixedPrincipalPercentagePerInstallment, delinquencyBucketOptions, delinquencyBucket,
|
||||
dueDaysForRepaymentEvent, overDueDaysForRepaymentEvent, enableDownPayment, disbursedAmountPercentageForDownPayment,
|
||||
enableAutoRepaymentForDownPayment, advancedPaymentData);
|
||||
enableAutoRepaymentForDownPayment, advancedPaymentData, repaymentStartDateType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user