FINERACT-1992: Multi-dlnqcy - Configuration of Installment level delinquency

This commit is contained in:
Jose Alberto Hernandez
2023-10-18 09:27:52 +02:00
committed by Adam Saghy
parent e0d087320a
commit 73b77b9414
14 changed files with 142 additions and 20 deletions
@@ -460,6 +460,9 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
@JoinColumn(name = "charged_off_by_userid")
private AppUser chargedOffBy;
@Column(name = "enable_installment_level_delinquency", nullable = false)
private boolean enableInstallmentLevelDelinquency = false;
public static Loan newIndividualLoanApplication(final String accountNo, final Client client, final Integer loanType,
final LoanProduct loanProduct, final Fund fund, final Staff officer, final CodeValue loanPurpose,
final String transactionProcessingStrategyCode, final LoanProductRelatedDetail loanRepaymentScheduleDetail,
@@ -7146,4 +7149,13 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
public String getTransactionProcessingStrategyName() {
return transactionProcessingStrategyName;
}
public boolean isEnableInstallmentLevelDelinquency() {
return this.enableInstallmentLevelDelinquency;
}
public void updateEnableInstallmentLevelDelinquency(boolean enableInstallmentLevelDelinquency) {
this.enableInstallmentLevelDelinquency = enableInstallmentLevelDelinquency;
}
}
@@ -154,4 +154,6 @@ public interface LoanProductConstants {
String REPAYMENT_START_DATE_TYPE = "repaymentStartDateType";
String DISABLE_SCHEDULE_EXTENSION_FOR_DOWN_PAYMENT = "disableScheduleExtensionForDownPayment";
String ENABLE_INSTALLMENT_LEVEL_DELINQUENCY = "enableInstallmentLevelDelinquency";
}
@@ -207,6 +207,9 @@ public class LoanProduct extends AbstractPersistableCustom {
@JoinColumn(name = "delinquency_bucket_id")
private DelinquencyBucket delinquencyBucket;
@Column(name = "enable_installment_level_delinquency", nullable = false)
private boolean enableInstallmentLevelDelinquency = false;
@Column(name = "due_days_for_repayment_event")
private Integer dueDaysForRepaymentEvent;
@@ -403,6 +406,9 @@ public class LoanProduct extends AbstractPersistableCustom {
final boolean disableScheduleExtensionForDownPayment = command
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.DISABLE_SCHEDULE_EXTENSION_FOR_DOWN_PAYMENT);
final boolean enableInstallmentLevelDelinquency = command
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY);
return new LoanProduct(fund, loanTransactionProcessingStrategy, loanProductPaymentAllocationRules, name, shortName, description,
currency, principal, minPrincipal, maxPrincipal, interestRatePerPeriod, minInterestRatePerPeriod, maxInterestRatePerPeriod,
interestFrequencyType, annualInterestRate, interestMethod, interestCalculationPeriodMethod,
@@ -420,7 +426,8 @@ public class LoanProduct extends AbstractPersistableCustom {
syncExpectedWithDisbursementDate, canUseForTopup, isEqualAmortization, productRates, fixedPrincipalPercentagePerInstallment,
disallowExpectedDisbursements, allowApprovedDisbursedAmountsOverApplied, overAppliedCalculationType, overAppliedNumber,
dueDaysForRepaymentEvent, overDueDaysForRepaymentEvent, enableDownPayment, disbursedAmountPercentageDownPayment,
enableAutoRepaymentForDownPayment, repaymentStartDateType, disableScheduleExtensionForDownPayment);
enableAutoRepaymentForDownPayment, repaymentStartDateType, disableScheduleExtensionForDownPayment,
enableInstallmentLevelDelinquency);
}
@@ -635,7 +642,7 @@ public class LoanProduct extends AbstractPersistableCustom {
final Integer overAppliedNumber, final Integer dueDaysForRepaymentEvent, final Integer overDueDaysForRepaymentEvent,
final boolean enableDownPayment, final BigDecimal disbursedAmountPercentageForDownPayment,
final boolean enableAutoRepaymentForDownPayment, final RepaymentStartDateType repaymentStartDateType,
final boolean disableScheduleExtensionForDownPayment) {
final boolean disableScheduleExtensionForDownPayment, final boolean enableInstallmentLevelDelinquency) {
this.fund = fund;
this.transactionProcessingStrategyCode = transactionProcessingStrategyCode;
@@ -731,6 +738,8 @@ public class LoanProduct extends AbstractPersistableCustom {
this.overDueDaysForRepaymentEvent = overDueDaysForRepaymentEvent;
this.repaymentStartDateType = repaymentStartDateType;
this.enableInstallmentLevelDelinquency = enableInstallmentLevelDelinquency;
validateLoanProductPreSave();
}
@@ -1307,6 +1316,14 @@ public class LoanProduct extends AbstractPersistableCustom {
this.loanProductRelatedDetail.updateDisableScheduleExtensionForDownPayment(newValue);
}
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY,
this.isEnableInstallmentLevelDelinquency())) {
final boolean newValue = command
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY);
actualChanges.put(LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY, newValue);
this.updateEnableInstallmentLevelDelinquency(newValue);
}
return actualChanges;
}
@@ -1706,4 +1723,12 @@ public class LoanProduct extends AbstractPersistableCustom {
return this.repaymentStartDateType == null ? RepaymentStartDateType.INVALID : this.repaymentStartDateType;
}
public boolean isEnableInstallmentLevelDelinquency() {
return enableInstallmentLevelDelinquency;
}
public void updateEnableInstallmentLevelDelinquency(boolean enableInstallmentLevelDelinquency) {
this.enableInstallmentLevelDelinquency = enableInstallmentLevelDelinquency;
}
}
@@ -728,4 +728,5 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
public void updateDisableScheduleExtensionForDownPayment(boolean disableScheduleExtensionForDownPayment) {
this.disableScheduleExtensionForDownPayment = disableScheduleExtensionForDownPayment;
}
}
@@ -1067,6 +1067,8 @@ final class LoansApiResourceSwagger {
public GetDelinquencyRangesResponse delinquencyRange;
@Schema(example = "false")
public Boolean fraud;
@Schema(example = "false")
public Boolean enableInstallmentLevelDelinquency;
@Schema(example = "250.000000")
public Double totalOverpaid;
public LocalDate lastClosedBusinessDate;
@@ -253,6 +253,7 @@ public class LoanAccountData {
private LocalDate overpaidOnDate;
private CollectionData delinquent;
private DelinquencyRangeData delinquencyRange;
private Boolean enableInstallmentLevelDelinquency;
private LocalDate lastClosedBusinessDate;
private Boolean chargedOff;
@@ -663,7 +664,7 @@ public class LoanAccountData {
final DelinquencyRangeData delinquencyRange, final boolean disallowExpectedDisbursements, final boolean fraud,
LocalDate lastClosedBusinessDate, LocalDate overpaidOnDate, final boolean chargedOff, final boolean enableDownPayment,
final BigDecimal disbursedAmountPercentageForDownPayment, final boolean enableAutoRepaymentForDownPayment,
final boolean disableScheduleExtensionForDownPayment) {
final boolean disableScheduleExtensionForDownPayment, final boolean enableInstallmentLevelDelinquency) {
final CollectionData delinquent = CollectionData.template();
@@ -706,7 +707,8 @@ public class LoanAccountData {
.setLastClosedBusinessDate(lastClosedBusinessDate).setOverpaidOnDate(overpaidOnDate).setChargedOff(chargedOff)
.setEnableDownPayment(enableDownPayment).setDisbursedAmountPercentageForDownPayment(disbursedAmountPercentageForDownPayment)
.setEnableAutoRepaymentForDownPayment(enableAutoRepaymentForDownPayment)
.setDisableScheduleExtensionForDownPayment(disableScheduleExtensionForDownPayment);
.setDisableScheduleExtensionForDownPayment(disableScheduleExtensionForDownPayment)
.setEnableInstallmentLevelDelinquency(enableInstallmentLevelDelinquency);
}
/*
@@ -794,7 +796,8 @@ public class LoanAccountData {
.setChargedOff(acc.chargedOff).setEnableDownPayment(acc.enableDownPayment)
.setDisbursedAmountPercentageForDownPayment(acc.disbursedAmountPercentageForDownPayment)
.setEnableAutoRepaymentForDownPayment(acc.enableAutoRepaymentForDownPayment)
.setDisableScheduleExtensionForDownPayment(acc.disableScheduleExtensionForDownPayment);
.setDisableScheduleExtensionForDownPayment(acc.disableScheduleExtensionForDownPayment)
.setEnableInstallmentLevelDelinquency(acc.enableInstallmentLevelDelinquency);
}
public static LoanAccountData associationsAndTemplate(final LoanAccountData acc, final Collection<LoanProductData> productOptions,
@@ -869,7 +872,8 @@ public class LoanAccountData {
.setIsEqualAmortization(acc.isEqualAmortization).setRates(acc.rates).setIsRatesEnabled(acc.isRatesEnabled)
.setFixedPrincipalPercentagePerInstallment(acc.fixedPrincipalPercentagePerInstallment).setDelinquent(acc.delinquent)
.setDelinquencyRange(acc.delinquencyRange).setDisallowExpectedDisbursements(acc.disallowExpectedDisbursements)
.setFraud(acc.fraud).setOverpaidOnDate(acc.overpaidOnDate).setChargedOff(acc.chargedOff);
.setFraud(acc.fraud).setOverpaidOnDate(acc.overpaidOnDate).setChargedOff(acc.chargedOff)
.setEnableInstallmentLevelDelinquency(acc.enableInstallmentLevelDelinquency);
}
public static LoanAccountData associateMemberVariations(final LoanAccountData acc, final Map<Long, Integer> memberLoanCycle) {
@@ -966,7 +970,8 @@ public class LoanAccountData {
.setIsEqualAmortization(acc.isEqualAmortization).setRates(acc.rates).setIsRatesEnabled(acc.isRatesEnabled)
.setFixedPrincipalPercentagePerInstallment(acc.fixedPrincipalPercentagePerInstallment).setDelinquent(acc.delinquent)
.setDelinquencyRange(acc.delinquencyRange).setDisallowExpectedDisbursements(acc.disallowExpectedDisbursements)
.setFraud(acc.fraud).setOverpaidOnDate(acc.overpaidOnDate).setChargedOff(acc.chargedOff);
.setFraud(acc.fraud).setOverpaidOnDate(acc.overpaidOnDate).setChargedOff(acc.chargedOff)
.setEnableInstallmentLevelDelinquency(acc.enableInstallmentLevelDelinquency);
}
public static LoanAccountData withInterestRecalculationCalendarData(final LoanAccountData acc, final CalendarData calendarData,
@@ -1031,7 +1036,8 @@ public class LoanAccountData {
.setIsEqualAmortization(acc.isEqualAmortization).setRates(acc.rates).setIsRatesEnabled(acc.isRatesEnabled)
.setFixedPrincipalPercentagePerInstallment(acc.fixedPrincipalPercentagePerInstallment).setDelinquent(acc.delinquent)
.setDelinquencyRange(acc.delinquencyRange).setDisallowExpectedDisbursements(acc.disallowExpectedDisbursements)
.setFraud(acc.fraud).setOverpaidOnDate(acc.overpaidOnDate).setChargedOff(acc.chargedOff);
.setFraud(acc.fraud).setOverpaidOnDate(acc.overpaidOnDate).setChargedOff(acc.chargedOff)
.setEnableInstallmentLevelDelinquency(acc.enableInstallmentLevelDelinquency);
}
public static LoanAccountData withLoanCalendarData(final LoanAccountData acc, final CalendarData calendarData) {
@@ -1089,7 +1095,8 @@ public class LoanAccountData {
.setIsEqualAmortization(acc.isEqualAmortization).setRates(acc.rates).setIsRatesEnabled(acc.isRatesEnabled)
.setFixedPrincipalPercentagePerInstallment(acc.fixedPrincipalPercentagePerInstallment).setDelinquent(acc.delinquent)
.setDelinquencyRange(acc.delinquencyRange).setDisallowExpectedDisbursements(acc.disallowExpectedDisbursements)
.setFraud(acc.fraud).setOverpaidOnDate(acc.overpaidOnDate).setChargedOff(acc.chargedOff);
.setFraud(acc.fraud).setOverpaidOnDate(acc.overpaidOnDate).setChargedOff(acc.chargedOff)
.setEnableInstallmentLevelDelinquency(acc.enableInstallmentLevelDelinquency);
}
public static LoanAccountData withOriginalSchedule(final LoanAccountData acc, final LoanScheduleData originalSchedule) {
@@ -1150,7 +1157,8 @@ public class LoanAccountData {
.setIsEqualAmortization(acc.isEqualAmortization).setRates(acc.rates).setIsRatesEnabled(acc.isRatesEnabled)
.setFixedPrincipalPercentagePerInstallment(acc.fixedPrincipalPercentagePerInstallment).setDelinquent(acc.delinquent)
.setDelinquencyRange(acc.delinquencyRange).setDisallowExpectedDisbursements(acc.disallowExpectedDisbursements)
.setFraud(acc.fraud).setOverpaidOnDate(acc.overpaidOnDate).setChargedOff(acc.chargedOff);
.setFraud(acc.fraud).setOverpaidOnDate(acc.overpaidOnDate).setChargedOff(acc.chargedOff)
.setEnableInstallmentLevelDelinquency(acc.enableInstallmentLevelDelinquency);
}
public static final Comparator<LoanAccountData> ClientNameComparator = (loan1, loan2) -> {
@@ -306,6 +306,8 @@ public class LoanAssembler {
}
}
loanApplication.updateEnableInstallmentLevelDelinquency(loanProduct.isEnableInstallmentLevelDelinquency());
final LoanApplicationTerms loanApplicationTerms = this.loanScheduleAssembler.assembleLoanTerms(element);
final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loanApplication.getOfficeId(),
@@ -643,7 +643,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
+ " l.fixed_principal_percentage_per_installment fixedPrincipalPercentagePerInstallment, "
+ " l.allow_partial_period_interest_calcualtion as allowPartialPeriodInterestCalcualtion,"
+ " l.loan_status_id as lifeCycleStatusId, l.loan_transaction_strategy_code as transactionStrategyCode, "
+ " l.loan_transaction_strategy_name as transactionStrategyName, "
+ " l.loan_transaction_strategy_name as transactionStrategyName, l.enable_installment_level_delinquency as enableInstallmentLevelDelinquency, "
+ " l.currency_code as currencyCode, l.currency_digits as currencyDigits, l.currency_multiplesof as inMultiplesOf, rc."
+ sqlGenerator.escape("name")
+ " as currencyName, rc.display_symbol as currencyDisplaySymbol, rc.internationalized_name_code as currencyNameCode, "
@@ -1043,6 +1043,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
final BigDecimal disbursedAmountPercentageForDownPayment = rs.getBigDecimal("disbursedAmountPercentageForDownPayment");
final boolean enableAutoRepaymentForDownPayment = rs.getBoolean("enableAutoRepaymentForDownPayment");
final boolean disableScheduleExtensionForDownPayment = rs.getBoolean("disableScheduleExtensionForDownPayment");
final boolean enableInstallmentLevelDelinquency = rs.getBoolean("enableInstallmentLevelDelinquency");
return LoanAccountData.basicLoanDetails(id, accountNo, status, externalId, clientId, clientAccountNo, clientName,
clientOfficeId, clientExternalId, groupData, loanType, loanProductId, loanProductName, loanProductDescription,
@@ -1060,7 +1061,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
canUseForTopup, isTopup, closureLoanId, closureLoanAccountNo, topupAmount, isEqualAmortization,
fixedPrincipalPercentagePerInstallment, delinquencyRange, disallowExpectedDisbursements, isFraud,
lastClosedBusinessDate, overpaidOnDate, isChargedOff, enableDownPayment, disbursedAmountPercentageForDownPayment,
enableAutoRepaymentForDownPayment, disableScheduleExtensionForDownPayment);
enableAutoRepaymentForDownPayment, disableScheduleExtensionForDownPayment, enableInstallmentLevelDelinquency);
}
}
@@ -152,6 +152,8 @@ final class LoanProductsApiResourceSwagger {
public Boolean holdGuaranteeFunds;
@Schema(example = "1")
public Long delinquencyBucketId;
@Schema(example = "false")
public Boolean enableInstallmentLevelDelinquency;
@Schema(example = "3")
public Integer dueDaysForRepaymentEvent;
@Schema(example = "3")
@@ -1237,6 +1239,8 @@ final class LoanProductsApiResourceSwagger {
@Schema(example = "50")
public Integer principalThresholdForLastInstalment;
public GetDelinquencyBucketsResponse delinquencyBucket;
@Schema(example = "false")
public Boolean enableInstallmentLevelDelinquency;
@Schema(example = "true")
public Boolean disallowExpectedDisbursements;
@Schema(example = "3")
@@ -1372,6 +1376,8 @@ final class LoanProductsApiResourceSwagger {
public Boolean holdGuaranteeFunds;
@Schema(example = "1")
public Long delinquencyBucketId;
@Schema(example = "false")
public Boolean enableInstallmentLevelDelinquency;
@Schema(example = "3")
public Integer dueDaysForRepaymentEvent;
@Schema(example = "3")
@@ -207,6 +207,7 @@ public class LoanProductData implements Serializable {
private final BigDecimal disbursedAmountPercentageForDownPayment;
private final boolean enableAutoRepaymentForDownPayment;
private final boolean disableScheduleExtensionForDownPayment;
private final boolean enableInstallmentLevelDelinquency;
/**
* Used when returning lookup information about loan product for dropdowns.
@@ -302,6 +303,7 @@ public class LoanProductData implements Serializable {
final boolean enableAutoRepaymentForDownPayment = false;
final EnumOptionData repaymentStartDateType = null;
final boolean disableScheduleExtensionForDownPayment = false;
final boolean enableInstallmentLevelDelinquency = false;
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
@@ -321,7 +323,7 @@ public class LoanProductData implements Serializable {
syncExpectedWithDisbursementDate, canUseForTopup, isEqualAmortization, rateOptions, rates, isRatesEnabled,
fixedPrincipalPercentagePerInstallment, delinquencyBucketOptions, delinquencyBucket, dueDaysForRepaymentEvent,
overDueDaysForRepaymentEvent, enableDownPayment, disbursedAmountPercentageDownPayment, enableAutoRepaymentForDownPayment,
paymentAllocation, repaymentStartDateType, disableScheduleExtensionForDownPayment);
paymentAllocation, repaymentStartDateType, disableScheduleExtensionForDownPayment, enableInstallmentLevelDelinquency);
}
@@ -417,6 +419,7 @@ public class LoanProductData implements Serializable {
final Collection<AdvancedPaymentData> paymentAllocation = null;
final EnumOptionData repaymentStartDateType = null;
final boolean disableScheduleExtensionForDownPayment = false;
final boolean enableInstallmentLevelDelinquency = false;
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
@@ -436,7 +439,7 @@ public class LoanProductData implements Serializable {
syncExpectedWithDisbursementDate, canUseForTopup, isEqualAmortization, rateOptions, rates, isRatesEnabled,
fixedPrincipalPercentagePerInstallment, delinquencyBucketOptions, delinquencyBucket, dueDaysForRepaymentEvent,
overDueDaysForRepaymentEvent, enableDownPayment, disbursedAmountPercentageDownPayment, enableAutoRepaymentForDownPayment,
paymentAllocation, repaymentStartDateType, disableScheduleExtensionForDownPayment);
paymentAllocation, repaymentStartDateType, disableScheduleExtensionForDownPayment, enableInstallmentLevelDelinquency);
}
@@ -539,6 +542,7 @@ public class LoanProductData implements Serializable {
final Collection<AdvancedPaymentData> paymentAllocation = null;
final EnumOptionData repaymentStartDateType = LoanEnumerations.repaymentStartDateType(RepaymentStartDateType.DISBURSEMENT_DATE);
final boolean disableScheduleExtensionForDownPayment = false;
final boolean enableInstallmentLevelDelinquency = false;
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
@@ -558,7 +562,7 @@ public class LoanProductData implements Serializable {
syncExpectedWithDisbursementDate, canUseForTopup, isEqualAmortization, rateOptions, rates, isRatesEnabled,
fixedPrincipalPercentagePerInstallment, delinquencyBucketOptions, delinquencyBucket, dueDaysForRepaymentEvent,
overDueDaysForRepaymentEvent, enableDownPayment, disbursedAmountPercentageDownPayment, enableAutoRepaymentForDownPayment,
paymentAllocation, repaymentStartDateType, disableScheduleExtensionForDownPayment);
paymentAllocation, repaymentStartDateType, disableScheduleExtensionForDownPayment, enableInstallmentLevelDelinquency);
}
@@ -655,6 +659,7 @@ public class LoanProductData implements Serializable {
final Collection<AdvancedPaymentData> paymentAllocation = null;
final EnumOptionData repaymentStartDateType = LoanEnumerations.repaymentStartDateType(RepaymentStartDateType.DISBURSEMENT_DATE);
final boolean disableScheduleExtensionForDownPayment = false;
final boolean enableInstallmentLevelDelinquency = false;
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
@@ -674,7 +679,7 @@ public class LoanProductData implements Serializable {
syncExpectedWithDisbursementDate, canUseForTopup, isEqualAmortization, rateOptions, rates, isRatesEnabled,
fixedPrincipalPercentagePerInstallment, delinquencyBucketOptions, delinquencyBucket, dueDaysForRepaymentEvent,
overDueDaysForRepaymentEvent, enableDownPayment, disbursedAmountPercentageDownPayment, enableAutoRepaymentForDownPayment,
paymentAllocation, repaymentStartDateType, disableScheduleExtensionForDownPayment);
paymentAllocation, repaymentStartDateType, disableScheduleExtensionForDownPayment, enableInstallmentLevelDelinquency);
}
public static LoanProductData withAccountingDetails(final LoanProductData productData, final Map<String, Object> accountingMappings,
@@ -723,7 +728,7 @@ public class LoanProductData implements Serializable {
final Integer overDueDaysForRepaymentEvent, final boolean enableDownPayment,
final BigDecimal disbursedAmountPercentageForDownPayment, final boolean enableAutoRepaymentForDownPayment,
final Collection<AdvancedPaymentData> paymentAllocation, final EnumOptionData repaymentStartDateType,
final boolean disableScheduleExtensionForDownPayment) {
final boolean disableScheduleExtensionForDownPayment, final boolean enableInstallmentLevelDelinquency) {
this.id = id;
this.name = name;
this.shortName = shortName;
@@ -851,6 +856,7 @@ public class LoanProductData implements Serializable {
this.advancedPaymentAllocationFutureInstallmentAllocationRules = FutureInstallmentAllocationRule.getValuesAsEnumOptionDataList();
this.advancedPaymentAllocationTypes = PaymentAllocationType.getValuesAsEnumOptionDataList();
this.disableScheduleExtensionForDownPayment = disableScheduleExtensionForDownPayment;
this.enableInstallmentLevelDelinquency = enableInstallmentLevelDelinquency;
}
public LoanProductData(final LoanProductData productData, final Collection<ChargeData> chargeOptions,
@@ -1015,6 +1021,7 @@ public class LoanProductData implements Serializable {
this.advancedPaymentAllocationFutureInstallmentAllocationRules = advancedPaymentAllocationFutureInstallmentAllocationRules;
this.advancedPaymentAllocationTypes = advancedPaymentAllocationTypes;
this.disableScheduleExtensionForDownPayment = productData.disableScheduleExtensionForDownPayment;
this.enableInstallmentLevelDelinquency = productData.enableInstallmentLevelDelinquency;
}
private Collection<ChargeData> nullIfEmpty(final Collection<ChargeData> charges) {
@@ -163,7 +163,7 @@ public final class LoanProductDataValidator {
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.REPAYMENT_START_DATE_TYPE,
LoanProductConstants.DISABLE_SCHEDULE_EXTENSION_FOR_DOWN_PAYMENT));
LoanProductConstants.DISABLE_SCHEDULE_EXTENSION_FOR_DOWN_PAYMENT, LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY));
private static final String[] SUPPORTED_LOAN_CONFIGURABLE_ATTRIBUTES = { LoanProductConstants.amortizationTypeParamName,
LoanProductConstants.interestTypeParamName, LoanProductConstants.transactionProcessingStrategyCodeParamName,
@@ -764,6 +764,13 @@ public final class LoanProductDataValidator {
.isOneOfTheseValues(1, 2);
}
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY, element)) {
final Boolean enableInstallmentLevelDelinquency = this.fromApiJsonHelper
.extractBooleanNamed(LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY, element);
baseDataValidator.reset().parameter(LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY)
.value(enableInstallmentLevelDelinquency).ignoreIfNull().validateForBooleanValue();
}
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
@@ -1733,6 +1740,13 @@ public final class LoanProductDataValidator {
baseDataValidator.reset().parameter(LoanProductConstants.REPAYMENT_START_DATE_TYPE).value(repaymentStartDateType).notNull()
.isOneOfTheseValues(1, 2);
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY, element)) {
final Boolean enableInstallmentLevelDelinquency = this.fromApiJsonHelper
.extractBooleanNamed(LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY, element);
baseDataValidator.reset().parameter(LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY)
.value(enableInstallmentLevelDelinquency).ignoreIfNull().validateForBooleanValue();
}
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
@@ -228,7 +228,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
+ "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.repayment_start_date_type_enum as repaymentStartDateType, "
+ "lp.disable_schedule_extension_for_down_payment as disableScheduleExtensionForDownPayment, "
+ "lp.disable_schedule_extension_for_down_payment as disableScheduleExtensionForDownPayment, lp.enable_installment_level_delinquency as enableInstallmentLevelDelinquency, "
+ "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, "
@@ -366,6 +366,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
final Integer repaymentStartDateTypeId = JdbcSupport.getInteger(rs, "repaymentStartDateType");
final EnumOptionData repaymentStartDateType = LoanEnumerations.repaymentStartDateType(repaymentStartDateTypeId);
final boolean disableScheduleExtensionForDownPayment = rs.getBoolean("disableScheduleExtensionForDownPayment");
final boolean enableInstallmentLevelDelinquency = rs.getBoolean("enableInstallmentLevelDelinquency");
String status = "";
if (closeDate != null && closeDate.isBefore(DateUtils.getBusinessLocalDate())) {
@@ -523,7 +524,8 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
maximumGap, syncExpectedWithDisbursementDate, canUseForTopup, isEqualAmortization, rateOptions, this.rates,
isRatesEnabled, fixedPrincipalPercentagePerInstallment, delinquencyBucketOptions, delinquencyBucket,
dueDaysForRepaymentEvent, overDueDaysForRepaymentEvent, enableDownPayment, disbursedAmountPercentageForDownPayment,
enableAutoRepaymentForDownPayment, advancedPaymentData, repaymentStartDateType, disableScheduleExtensionForDownPayment);
enableAutoRepaymentForDownPayment, advancedPaymentData, repaymentStartDateType, disableScheduleExtensionForDownPayment,
enableInstallmentLevelDelinquency);
}
}
@@ -145,4 +145,5 @@
<include file="parts/0123_add_is_down_payment_to_repayment_schedule.xml" relativeToChangelogFile="true" />
<include file="parts/0124_transaction_summary_with_asset_owner_report_typo_fix_3.xml" relativeToChangelogFile="true" />
<include file="parts/0125_transaction_summary_with_asset_owner_report_chargeoff_reason.xml" relativeToChangelogFile="true" />
<include file="parts/0126_add_loan_product_installment_level_delinquency.xml" relativeToChangelogFile="true" />
</databaseChangeLog>
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
<changeSet author="fineract" id="1">
<addColumn tableName="m_product_loan">
<column defaultValueBoolean="false" type="boolean" name="enable_installment_level_delinquency">
<constraints nullable="false"/>
</column>
</addColumn>
</changeSet>
<changeSet author="fineract" id="2">
<addColumn tableName="m_loan">
<column defaultValueBoolean="false" type="boolean" name="enable_installment_level_delinquency">
<constraints nullable="false"/>
</column>
</addColumn>
</changeSet>
</databaseChangeLog>