FINERACT-2311: Loan product - Buy down fees configuration
This commit is contained in:
+20
-4
@@ -174,6 +174,9 @@ public class LoanAccountData {
|
||||
private List<StringEnumOptionData> capitalizedIncomeCalculationTypeOptions;
|
||||
private List<StringEnumOptionData> capitalizedIncomeStrategyOptions;
|
||||
private List<StringEnumOptionData> capitalizedIncomeTypeOptions;
|
||||
private List<StringEnumOptionData> buyDownFeeCalculationTypeOptions;
|
||||
private List<StringEnumOptionData> buyDownFeeStrategyOptions;
|
||||
private List<StringEnumOptionData> buyDownFeeIncomeTypeOptions;
|
||||
|
||||
@Transient
|
||||
private BigDecimal feeChargesAtDisbursementCharged;
|
||||
@@ -281,6 +284,11 @@ public class LoanAccountData {
|
||||
private StringEnumOptionData capitalizedIncomeStrategy;
|
||||
private StringEnumOptionData capitalizedIncomeType;
|
||||
|
||||
private Boolean enableBuyDownFee;
|
||||
private StringEnumOptionData buyDownFeeCalculationType;
|
||||
private StringEnumOptionData buyDownFeeStrategy;
|
||||
private StringEnumOptionData buyDownFeeIncomeType;
|
||||
|
||||
public static LoanAccountData importInstanceIndividual(EnumOptionData loanTypeEnumOption, Long clientId, Long productId,
|
||||
Long loanOfficerId, LocalDate submittedOnDate, Long fundId, BigDecimal principal, Integer numberOfRepayments,
|
||||
Integer repaymentEvery, EnumOptionData repaidEveryFrequencyEnums, Integer loanTermFrequency,
|
||||
@@ -473,7 +481,9 @@ public class LoanAccountData {
|
||||
final EnumOptionData loanScheduleProcessingType, final Integer fixedLength, final StringEnumOptionData chargeOffBehaviour,
|
||||
final boolean isInterestRecognitionOnDisbursementDate, final StringEnumOptionData daysInYearCustomStrategy,
|
||||
final boolean enableIncomeCapitalization, final StringEnumOptionData capitalizedIncomeCalculationType,
|
||||
final StringEnumOptionData capitalizedIncomeStrategy, StringEnumOptionData capitalizedIncomeType) {
|
||||
final StringEnumOptionData capitalizedIncomeStrategy, StringEnumOptionData capitalizedIncomeType,
|
||||
final boolean enableBuyDownFee, final StringEnumOptionData buyDownFeeCalculationType,
|
||||
final StringEnumOptionData buyDownFeeStrategy, final StringEnumOptionData buyDownFeeIncomeType) {
|
||||
|
||||
final CollectionData delinquent = CollectionData.template();
|
||||
|
||||
@@ -521,7 +531,9 @@ public class LoanAccountData {
|
||||
.setChargeOffBehaviour(chargeOffBehaviour).setInterestRecognitionOnDisbursementDate(isInterestRecognitionOnDisbursementDate)
|
||||
.setDaysInYearCustomStrategy(daysInYearCustomStrategy).setEnableIncomeCapitalization(enableIncomeCapitalization)
|
||||
.setCapitalizedIncomeCalculationType(capitalizedIncomeCalculationType)
|
||||
.setCapitalizedIncomeStrategy(capitalizedIncomeStrategy).setCapitalizedIncomeType(capitalizedIncomeType);
|
||||
.setCapitalizedIncomeStrategy(capitalizedIncomeStrategy).setCapitalizedIncomeType(capitalizedIncomeType)
|
||||
.setEnableBuyDownFee(enableBuyDownFee).setBuyDownFeeCalculationType(buyDownFeeCalculationType)
|
||||
.setBuyDownFeeStrategy(buyDownFeeStrategy).setBuyDownFeeIncomeType(buyDownFeeIncomeType);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -550,7 +562,9 @@ public class LoanAccountData {
|
||||
final List<StringEnumOptionData> daysInYearCustomStrategyOptions,
|
||||
final List<StringEnumOptionData> capitalizedIncomeCalculationTypeOptions,
|
||||
final List<StringEnumOptionData> capitalizedIncomeStrategyOptions,
|
||||
final List<StringEnumOptionData> capitalizedIncomeTypeOptions) {
|
||||
final List<StringEnumOptionData> capitalizedIncomeTypeOptions,
|
||||
final List<StringEnumOptionData> buyDownFeeCalculationTypeOptions, final List<StringEnumOptionData> buyDownFeeStrategyOptions,
|
||||
final List<StringEnumOptionData> buyDownFeeIncomeTypeOptions) {
|
||||
|
||||
// TODO: why are these variables 'calendarData', 'chargeTemplate' never used (see original private constructor)
|
||||
|
||||
@@ -574,7 +588,9 @@ public class LoanAccountData {
|
||||
.setDaysInYearCustomStrategyOptions(daysInYearCustomStrategyOptions)
|
||||
.setCapitalizedIncomeCalculationTypeOptions(capitalizedIncomeCalculationTypeOptions)
|
||||
.setCapitalizedIncomeStrategyOptions(capitalizedIncomeStrategyOptions)
|
||||
.setCapitalizedIncomeTypeOptions(capitalizedIncomeTypeOptions);
|
||||
.setCapitalizedIncomeTypeOptions(capitalizedIncomeTypeOptions)
|
||||
.setBuyDownFeeCalculationTypeOptions(buyDownFeeCalculationTypeOptions)
|
||||
.setBuyDownFeeStrategyOptions(buyDownFeeStrategyOptions).setBuyDownFeeIncomeTypeOptions(buyDownFeeIncomeTypeOptions);
|
||||
}
|
||||
|
||||
public LoanAccountData associationsAndTemplate(final Collection<LoanProductData> productOptions,
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* 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.portfolio.loanaccount.domain;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.infrastructure.core.api.ApiFacingEnum;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum LoanBuyDownFeeCalculationType implements ApiFacingEnum<LoanBuyDownFeeCalculationType> {
|
||||
|
||||
FLAT("loanBuyDownFeeCalculationType.flat", "Flat");
|
||||
|
||||
private final String code;
|
||||
private final String humanReadableName;
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 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.portfolio.loanaccount.domain;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.infrastructure.core.api.ApiFacingEnum;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum LoanBuyDownFeeIncomeType implements ApiFacingEnum<LoanBuyDownFeeIncomeType> {
|
||||
|
||||
FEE("buyDownFee.incomeType.fee", "Fee"), //
|
||||
INTEREST("buyDownFee.incomeType.interest", "Interest"); //
|
||||
|
||||
private final String code;
|
||||
private final String humanReadableName;
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* 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.portfolio.loanaccount.domain;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.infrastructure.core.api.ApiFacingEnum;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum LoanBuyDownFeeStrategy implements ApiFacingEnum<LoanBuyDownFeeStrategy> {
|
||||
|
||||
EQUAL_AMORTIZATION("buyDownFee.strategy.equalAmortization", "Equal amortization");
|
||||
|
||||
private final String code;
|
||||
private final String humanReadableName;
|
||||
}
|
||||
+52
-5
@@ -46,6 +46,9 @@ import org.apache.fineract.portfolio.loanaccount.data.DisbursementData;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.HolidayDetailDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsData;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsDataWrapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeCalculationType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeIncomeType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeStrategy;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeType;
|
||||
@@ -239,6 +242,10 @@ public final class LoanApplicationTerms {
|
||||
private LoanCapitalizedIncomeCalculationType capitalizedIncomeCalculationType;
|
||||
private LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy;
|
||||
private LoanCapitalizedIncomeType capitalizedIncomeType;
|
||||
private boolean enableBuyDownFee;
|
||||
private LoanBuyDownFeeCalculationType buyDownFeeCalculationType;
|
||||
private LoanBuyDownFeeStrategy buyDownFeeStrategy;
|
||||
private LoanBuyDownFeeIncomeType buyDownFeeIncomeType;
|
||||
|
||||
private LoanApplicationTerms(Builder builder) {
|
||||
this.currency = builder.currency;
|
||||
@@ -279,6 +286,10 @@ public final class LoanApplicationTerms {
|
||||
this.capitalizedIncomeCalculationType = builder.capitalizedIncomeCalculationType;
|
||||
this.capitalizedIncomeStrategy = builder.capitalizedIncomeStrategy;
|
||||
this.capitalizedIncomeType = builder.capitalizedIncomeType;
|
||||
this.enableBuyDownFee = builder.enableBuyDownFee;
|
||||
this.buyDownFeeCalculationType = builder.buyDownFeeCalculationType;
|
||||
this.buyDownFeeStrategy = builder.buyDownFeeStrategy;
|
||||
this.buyDownFeeIncomeType = builder.buyDownFeeIncomeType;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
@@ -312,6 +323,10 @@ public final class LoanApplicationTerms {
|
||||
private LoanCapitalizedIncomeCalculationType capitalizedIncomeCalculationType;
|
||||
private LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy;
|
||||
private LoanCapitalizedIncomeType capitalizedIncomeType;
|
||||
private boolean enableBuyDownFee;
|
||||
private LoanBuyDownFeeCalculationType buyDownFeeCalculationType;
|
||||
private LoanBuyDownFeeStrategy buyDownFeeStrategy;
|
||||
private LoanBuyDownFeeIncomeType buyDownFeeIncomeType;
|
||||
|
||||
public Builder currency(CurrencyData currency) {
|
||||
this.currency = currency;
|
||||
@@ -448,6 +463,26 @@ public final class LoanApplicationTerms {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder enableBuyDownFee(boolean value) {
|
||||
this.enableBuyDownFee = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder buyDownFeeCalculationType(LoanBuyDownFeeCalculationType value) {
|
||||
this.buyDownFeeCalculationType = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder buyDownFeeStrategy(LoanBuyDownFeeStrategy value) {
|
||||
this.buyDownFeeStrategy = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder buyDownFeeIncomeType(LoanBuyDownFeeIncomeType value) {
|
||||
this.buyDownFeeIncomeType = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanApplicationTerms build() {
|
||||
return new LoanApplicationTerms(this);
|
||||
}
|
||||
@@ -517,7 +552,9 @@ public final class LoanApplicationTerms {
|
||||
final LoanChargeOffBehaviour chargeOffBehaviour, final boolean interestRecognitionOnDisbursementDate,
|
||||
final DaysInYearCustomStrategyType daysInYearCustomStrategy, final boolean enableIncomeCapitalization,
|
||||
final LoanCapitalizedIncomeCalculationType capitalizedIncomeCalculationType,
|
||||
final LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy, final LoanCapitalizedIncomeType capitalizedIncomeType) {
|
||||
final LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy, final LoanCapitalizedIncomeType capitalizedIncomeType,
|
||||
final boolean enableBuyDownFee, final LoanBuyDownFeeCalculationType buyDownFeeCalculationType,
|
||||
final LoanBuyDownFeeStrategy buyDownFeeStrategy, final LoanBuyDownFeeIncomeType buyDownFeeIncomeType) {
|
||||
|
||||
final LoanRescheduleStrategyMethod rescheduleStrategyMethod = null;
|
||||
final CalendarHistoryDataWrapper calendarHistoryDataWrapper = null;
|
||||
@@ -538,7 +575,8 @@ public final class LoanApplicationTerms {
|
||||
isAutoRepaymentForDownPaymentEnabled, repaymentStartDateType, submittedOnDate, loanScheduleType, loanScheduleProcessingType,
|
||||
fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes, chargeOffBehaviour,
|
||||
interestRecognitionOnDisbursementDate, daysInYearCustomStrategy, enableIncomeCapitalization,
|
||||
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType);
|
||||
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType, enableBuyDownFee,
|
||||
buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType);
|
||||
|
||||
}
|
||||
|
||||
@@ -614,7 +652,9 @@ public final class LoanApplicationTerms {
|
||||
loanProductRelatedDetail.getSupportedInterestRefundTypes(), loanProductRelatedDetail.getChargeOffBehaviour(),
|
||||
loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate(), loanProductRelatedDetail.getDaysInYearCustomStrategy(),
|
||||
loanProductRelatedDetail.isEnableIncomeCapitalization(), loanProductRelatedDetail.getCapitalizedIncomeCalculationType(),
|
||||
loanProductRelatedDetail.getCapitalizedIncomeStrategy(), loanProductRelatedDetail.getCapitalizedIncomeType());
|
||||
loanProductRelatedDetail.getCapitalizedIncomeStrategy(), loanProductRelatedDetail.getCapitalizedIncomeType(),
|
||||
loanProductRelatedDetail.isEnableBuyDownFee(), loanProductRelatedDetail.getBuyDownFeeCalculationType(),
|
||||
loanProductRelatedDetail.getBuyDownFeeStrategy(), loanProductRelatedDetail.getBuyDownFeeIncomeType());
|
||||
}
|
||||
|
||||
private LoanApplicationTerms(final CurrencyData currency, final Integer loanTermFrequency,
|
||||
@@ -647,7 +687,9 @@ public final class LoanApplicationTerms {
|
||||
final List<LoanSupportedInterestRefundTypes> supportedInterestRefundTypes, final LoanChargeOffBehaviour chargeOffBehaviour,
|
||||
final boolean interestRecognitionOnDisbursementDate, final DaysInYearCustomStrategyType daysInYearCustomStrategy,
|
||||
final boolean enableIncomeCapitalization, final LoanCapitalizedIncomeCalculationType capitalizedIncomeCalculationType,
|
||||
final LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy, final LoanCapitalizedIncomeType capitalizedIncomeType) {
|
||||
final LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy, final LoanCapitalizedIncomeType capitalizedIncomeType,
|
||||
final boolean enableBuyDownFee, final LoanBuyDownFeeCalculationType buyDownFeeCalculationType,
|
||||
final LoanBuyDownFeeStrategy buyDownFeeStrategy, final LoanBuyDownFeeIncomeType buyDownFeeIncomeType) {
|
||||
|
||||
this.currency = currency;
|
||||
this.loanTermFrequency = loanTermFrequency;
|
||||
@@ -753,6 +795,10 @@ public final class LoanApplicationTerms {
|
||||
this.capitalizedIncomeCalculationType = capitalizedIncomeCalculationType;
|
||||
this.capitalizedIncomeStrategy = capitalizedIncomeStrategy;
|
||||
this.capitalizedIncomeType = capitalizedIncomeType;
|
||||
this.enableBuyDownFee = enableBuyDownFee;
|
||||
this.buyDownFeeCalculationType = buyDownFeeCalculationType;
|
||||
this.buyDownFeeStrategy = buyDownFeeStrategy;
|
||||
this.buyDownFeeIncomeType = buyDownFeeIncomeType;
|
||||
}
|
||||
|
||||
public Money adjustPrincipalIfLastRepaymentPeriod(final Money principalForPeriod, final Money totalCumulativePrincipalToDate,
|
||||
@@ -1616,7 +1662,8 @@ public final class LoanApplicationTerms {
|
||||
this.loanScheduleProcessingType, this.fixedLength, this.enableAccrualActivityPosting, this.supportedInterestRefundTypes,
|
||||
this.chargeOffBehaviour, this.interestRecognitionOnDisbursementDate, this.daysInYearCustomStrategy,
|
||||
this.enableIncomeCapitalization, this.capitalizedIncomeCalculationType, this.capitalizedIncomeStrategy,
|
||||
this.capitalizedIncomeType, this.installmentAmountInMultiplesOf);
|
||||
this.capitalizedIncomeType, this.installmentAmountInMultiplesOf, this.enableBuyDownFee, this.buyDownFeeCalculationType,
|
||||
this.buyDownFeeStrategy, this.buyDownFeeIncomeType);
|
||||
}
|
||||
|
||||
public LoanProductMinimumRepaymentScheduleRelatedDetail toLoanProductRelatedDetailMinimumData() {
|
||||
|
||||
+6
@@ -177,4 +177,10 @@ public interface LoanProductConstants {
|
||||
String CAPITALIZED_INCOME_CALCULATION_TYPE_PARAM_NAME = "capitalizedIncomeCalculationType";
|
||||
String CAPITALIZED_INCOME_STRATEGY_PARAM_NAME = "capitalizedIncomeStrategy";
|
||||
String CAPITALIZED_INCOME_TYPE_PARAM_NAME = "capitalizedIncomeType";
|
||||
|
||||
// Buy down fee
|
||||
String ENABLE_BUY_DOWN_FEE_PARAM_NAME = "enableBuyDownFee";
|
||||
String BUY_DOWN_FEE_CALCULATION_TYPE_PARAM_NAME = "buyDownFeeCalculationType";
|
||||
String BUY_DOWN_FEE_STRATEGY_PARAM_NAME = "buyDownFeeStrategy";
|
||||
String BUY_DOWN_FEE_INCOME_TYPE_PARAM_NAME = "buyDownFeeIncomeType";
|
||||
}
|
||||
|
||||
+48
@@ -203,6 +203,14 @@ public final class LoanProductsApiResourceSwagger {
|
||||
public String capitalizedIncomeStrategy;
|
||||
@Schema(example = "FEE", allowableValues = { "FEE", "INTEREST" })
|
||||
public String capitalizedIncomeType;
|
||||
@Schema(example = "false")
|
||||
public Boolean enableBuyDownFee;
|
||||
@Schema(example = "FLAT", allowableValues = "FLAT")
|
||||
public String buyDownFeeCalculationType;
|
||||
@Schema(example = "EQUAL_AMORTIZATION", allowableValues = "EQUAL_AMORTIZATION")
|
||||
public String buyDownFeeStrategy;
|
||||
@Schema(example = "FEE", allowableValues = { "FEE", "INTEREST" })
|
||||
public String buyDownFeeIncomeType;
|
||||
|
||||
// Interest Recalculation
|
||||
@Schema(example = "false")
|
||||
@@ -671,6 +679,14 @@ public final class LoanProductsApiResourceSwagger {
|
||||
public StringEnumOptionData capitalizedIncomeStrategy;
|
||||
@Schema(example = "FEE")
|
||||
public StringEnumOptionData capitalizedIncomeType;
|
||||
@Schema(example = "false")
|
||||
public Boolean enableBuyDownFee;
|
||||
@Schema(example = "FLAT")
|
||||
public StringEnumOptionData buyDownFeeCalculationType;
|
||||
@Schema(example = "EQUAL_AMORTIZATION")
|
||||
public StringEnumOptionData buyDownFeeStrategy;
|
||||
@Schema(example = "FEE")
|
||||
public StringEnumOptionData buyDownFeeIncomeType;
|
||||
}
|
||||
|
||||
@Schema(description = "GetLoanProductsTemplateResponse")
|
||||
@@ -1128,6 +1144,18 @@ public final class LoanProductsApiResourceSwagger {
|
||||
public List<StringEnumOptionData> capitalizedIncomeCalculationTypeOptions;
|
||||
public List<StringEnumOptionData> capitalizedIncomeStrategyOptions;
|
||||
public List<StringEnumOptionData> capitalizedIncomeTypeOptions;
|
||||
|
||||
@Schema(example = "false")
|
||||
public Boolean enableBuyDownFee;
|
||||
@Schema(example = "FLAT")
|
||||
public StringEnumOptionData buyDownFeeCalculationType;
|
||||
@Schema(example = "EQUAL_AMORTIZATION")
|
||||
public StringEnumOptionData buyDownFeeStrategy;
|
||||
@Schema(example = "FEE")
|
||||
public StringEnumOptionData buyDownFeeIncomeType;
|
||||
public List<StringEnumOptionData> buyDownFeeCalculationTypeOptions;
|
||||
public List<StringEnumOptionData> buyDownFeeStrategyOptions;
|
||||
public List<StringEnumOptionData> buyDownFeeIncomeTypeOptions;
|
||||
}
|
||||
|
||||
@Schema(description = "GetLoanProductsProductIdResponse")
|
||||
@@ -1460,6 +1488,18 @@ public final class LoanProductsApiResourceSwagger {
|
||||
public List<StringEnumOptionData> capitalizedIncomeCalculationTypeOptions;
|
||||
public List<StringEnumOptionData> capitalizedIncomeStrategyOptions;
|
||||
public List<StringEnumOptionData> capitalizedIncomeTypeOptions;
|
||||
|
||||
@Schema(example = "false")
|
||||
public Boolean enableBuyDownFee;
|
||||
@Schema(example = "FLAT")
|
||||
public StringEnumOptionData buyDownFeeCalculationType;
|
||||
@Schema(example = "EQUAL_AMORTIZATION")
|
||||
public StringEnumOptionData buyDownFeeStrategy;
|
||||
@Schema(example = "FEE")
|
||||
public StringEnumOptionData buyDownFeeIncomeType;
|
||||
public List<StringEnumOptionData> buyDownFeeCalculationTypeOptions;
|
||||
public List<StringEnumOptionData> buyDownFeeStrategyOptions;
|
||||
public List<StringEnumOptionData> buyDownFeeIncomeTypeOptions;
|
||||
}
|
||||
|
||||
@Schema(description = "PutLoanProductsProductIdRequest")
|
||||
@@ -1727,6 +1767,14 @@ public final class LoanProductsApiResourceSwagger {
|
||||
public String capitalizedIncomeStrategy;
|
||||
@Schema(example = "FEE", allowableValues = { "FEE", "INTEREST" })
|
||||
public String capitalizedIncomeType;
|
||||
@Schema(example = "false")
|
||||
public Boolean enableBuyDownFee;
|
||||
@Schema(example = "FLAT", allowableValues = "FLAT")
|
||||
public String buyDownFeeCalculationType;
|
||||
@Schema(example = "EQUAL_AMORTIZATION", allowableValues = "EQUAL_AMORTIZATION")
|
||||
public String buyDownFeeStrategy;
|
||||
@Schema(example = "FEE", allowableValues = { "FEE", "INTEREST" })
|
||||
public String buyDownFeeIncomeType;
|
||||
}
|
||||
|
||||
public static final class AdvancedPaymentData {
|
||||
|
||||
+55
-6
@@ -49,6 +49,9 @@ import org.apache.fineract.portfolio.delinquency.data.DelinquencyBucketData;
|
||||
import org.apache.fineract.portfolio.floatingrates.data.FloatingRateData;
|
||||
import org.apache.fineract.portfolio.fund.data.FundData;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.LoanInterestRecalculationData;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeCalculationType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeIncomeType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeStrategy;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeType;
|
||||
@@ -249,6 +252,13 @@ public class LoanProductData implements Serializable {
|
||||
private List<StringEnumOptionData> capitalizedIncomeCalculationTypeOptions;
|
||||
private List<StringEnumOptionData> capitalizedIncomeStrategyOptions;
|
||||
private List<StringEnumOptionData> capitalizedIncomeTypeOptions;
|
||||
private Boolean enableBuyDownFee;
|
||||
private StringEnumOptionData buyDownFeeCalculationType;
|
||||
private StringEnumOptionData buyDownFeeStrategy;
|
||||
private StringEnumOptionData buyDownFeeIncomeType;
|
||||
private List<StringEnumOptionData> buyDownFeeCalculationTypeOptions;
|
||||
private List<StringEnumOptionData> buyDownFeeStrategyOptions;
|
||||
private List<StringEnumOptionData> buyDownFeeIncomeTypeOptions;
|
||||
|
||||
/**
|
||||
* Used when returning lookup information about loan product for dropdowns.
|
||||
@@ -357,6 +367,10 @@ public class LoanProductData implements Serializable {
|
||||
final StringEnumOptionData capitalizedIncomeCalculationType = null;
|
||||
final StringEnumOptionData capitalizedIncomeStrategy = null;
|
||||
final StringEnumOptionData capitalizedIncomeType = null;
|
||||
final boolean enableBuyDownFee = false;
|
||||
final StringEnumOptionData buyDownFeeCalculationType = null;
|
||||
final StringEnumOptionData buyDownFeeStrategy = null;
|
||||
final StringEnumOptionData buyDownFeeIncomeType = null;
|
||||
|
||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||
@@ -379,7 +393,8 @@ public class LoanProductData implements Serializable {
|
||||
paymentAllocation, creditAllocation, repaymentStartDateType, enableInstallmentLevelDelinquency, loanScheduleType,
|
||||
loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes, chargeOffBehaviour,
|
||||
interestRecognitionOnDisbursementDate, daysInYearTypeCustomStrategy, enableIncomeCapitalization,
|
||||
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType);
|
||||
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType, enableBuyDownFee,
|
||||
buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType);
|
||||
|
||||
}
|
||||
|
||||
@@ -488,6 +503,10 @@ public class LoanProductData implements Serializable {
|
||||
final StringEnumOptionData capitalizedIncomeCalculationType = null;
|
||||
final StringEnumOptionData capitalizedIncomeStrategy = null;
|
||||
final StringEnumOptionData capitalizedIncomeType = null;
|
||||
final boolean enableBuyDownFee = false;
|
||||
final StringEnumOptionData buyDownFeeCalculationType = null;
|
||||
final StringEnumOptionData buyDownFeeStrategy = null;
|
||||
final StringEnumOptionData buyDownFeeIncomeType = null;
|
||||
|
||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||
@@ -510,7 +529,8 @@ public class LoanProductData implements Serializable {
|
||||
paymentAllocation, creditAllocation, repaymentStartDateType, enableInstallmentLevelDelinquency, loanScheduleType,
|
||||
loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes, chargeOffBehaviour,
|
||||
interestRecognitionOnDisbursementDate, daysInYearTypeCustomStrategy, enableIncomeCapitalization,
|
||||
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType);
|
||||
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType, enableBuyDownFee,
|
||||
buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType);
|
||||
|
||||
}
|
||||
|
||||
@@ -626,6 +646,10 @@ public class LoanProductData implements Serializable {
|
||||
final StringEnumOptionData capitalizedIncomeCalculationType = null;
|
||||
final StringEnumOptionData capitalizedIncomeStrategy = null;
|
||||
final StringEnumOptionData capitalizedIncomeType = null;
|
||||
final boolean enableBuyDownFee = false;
|
||||
final StringEnumOptionData buyDownFeeCalculationType = null;
|
||||
final StringEnumOptionData buyDownFeeStrategy = null;
|
||||
final StringEnumOptionData buyDownFeeIncomeType = null;
|
||||
|
||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||
@@ -648,7 +672,8 @@ public class LoanProductData implements Serializable {
|
||||
paymentAllocation, creditAllocation, repaymentStartDateType, enableInstallmentLevelDelinquency, loanScheduleType,
|
||||
loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes, chargeOffBehaviour,
|
||||
interestRecognitionOnDisbursementDate, daysInYearTypeCustomStrategy, enableIncomeCapitalization,
|
||||
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType);
|
||||
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType, enableBuyDownFee,
|
||||
buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType);
|
||||
|
||||
}
|
||||
|
||||
@@ -758,6 +783,10 @@ public class LoanProductData implements Serializable {
|
||||
final StringEnumOptionData capitalizedIncomeCalculationType = null;
|
||||
final StringEnumOptionData capitalizedIncomeStrategy = null;
|
||||
final StringEnumOptionData capitalizedIncomeType = null;
|
||||
final boolean enableBuyDownFee = false;
|
||||
final StringEnumOptionData buyDownFeeCalculationType = null;
|
||||
final StringEnumOptionData buyDownFeeStrategy = null;
|
||||
final StringEnumOptionData buyDownFeeIncomeType = null;
|
||||
|
||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||
@@ -780,7 +809,8 @@ public class LoanProductData implements Serializable {
|
||||
paymentAllocation, creditAllocationData, repaymentStartDateType, enableInstallmentLevelDelinquency, loanScheduleType,
|
||||
loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes, chargeOffBehaviour,
|
||||
interestRecognitionOnDisbursementDate, daysInYearTypeCustomStrategy, enableIncomeCapitalization,
|
||||
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType);
|
||||
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType, enableBuyDownFee,
|
||||
buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType);
|
||||
}
|
||||
|
||||
public static LoanProductData withAccountingDetails(final LoanProductData productData, final Map<String, Object> accountingMappings,
|
||||
@@ -837,7 +867,9 @@ public class LoanProductData implements Serializable {
|
||||
StringEnumOptionData chargeOffBehaviour, final boolean interestRecognitionOnDisbursementDate,
|
||||
final StringEnumOptionData daysInYearCustomStrategy, final boolean enableIncomeCapitalization,
|
||||
final StringEnumOptionData capitalizedIncomeCalculationType, final StringEnumOptionData capitalizedIncomeStrategy,
|
||||
final StringEnumOptionData capitalizedIncomeType) {
|
||||
final StringEnumOptionData capitalizedIncomeType, final boolean enableBuyDownFee,
|
||||
final StringEnumOptionData buyDownFeeCalculationType, final StringEnumOptionData buyDownFeeStrategy,
|
||||
final StringEnumOptionData buyDownFeeIncomeType) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.shortName = shortName;
|
||||
@@ -898,6 +930,10 @@ public class LoanProductData implements Serializable {
|
||||
this.capitalizedIncomeCalculationType = capitalizedIncomeCalculationType;
|
||||
this.capitalizedIncomeStrategy = capitalizedIncomeStrategy;
|
||||
this.capitalizedIncomeType = capitalizedIncomeType;
|
||||
this.enableBuyDownFee = enableBuyDownFee;
|
||||
this.buyDownFeeCalculationType = buyDownFeeCalculationType;
|
||||
this.buyDownFeeStrategy = buyDownFeeStrategy;
|
||||
this.buyDownFeeIncomeType = buyDownFeeIncomeType;
|
||||
|
||||
this.chargeOptions = null;
|
||||
this.penaltyOptions = null;
|
||||
@@ -991,6 +1027,9 @@ public class LoanProductData implements Serializable {
|
||||
.getValuesAsStringEnumOptionDataList(LoanCapitalizedIncomeCalculationType.class);
|
||||
this.capitalizedIncomeStrategyOptions = ApiFacingEnum.getValuesAsStringEnumOptionDataList(LoanCapitalizedIncomeStrategy.class);
|
||||
this.capitalizedIncomeTypeOptions = ApiFacingEnum.getValuesAsStringEnumOptionDataList(LoanCapitalizedIncomeType.class);
|
||||
this.buyDownFeeCalculationTypeOptions = ApiFacingEnum.getValuesAsStringEnumOptionDataList(LoanBuyDownFeeCalculationType.class);
|
||||
this.buyDownFeeStrategyOptions = ApiFacingEnum.getValuesAsStringEnumOptionDataList(LoanBuyDownFeeStrategy.class);
|
||||
this.buyDownFeeIncomeTypeOptions = ApiFacingEnum.getValuesAsStringEnumOptionDataList(LoanBuyDownFeeIncomeType.class);
|
||||
}
|
||||
|
||||
public LoanProductData(final LoanProductData productData, final Collection<ChargeData> chargeOptions,
|
||||
@@ -1018,7 +1057,9 @@ public class LoanProductData implements Serializable {
|
||||
final List<StringEnumOptionData> daysInYearCustomStrategyOptions,
|
||||
final List<StringEnumOptionData> capitalizedIncomeCalculationTypeOptions,
|
||||
final List<StringEnumOptionData> capitalizedIncomeStrategyOptions,
|
||||
final List<StringEnumOptionData> capitalizedIncomeTypeOptions) {
|
||||
final List<StringEnumOptionData> capitalizedIncomeTypeOptions,
|
||||
final List<StringEnumOptionData> buyDownFeeCalculationTypeOptions, final List<StringEnumOptionData> buyDownFeeStrategyOptions,
|
||||
final List<StringEnumOptionData> buyDownFeeIncomeTypeOptions) {
|
||||
|
||||
this.id = productData.id;
|
||||
this.name = productData.name;
|
||||
@@ -1189,6 +1230,14 @@ public class LoanProductData implements Serializable {
|
||||
this.capitalizedIncomeCalculationTypeOptions = capitalizedIncomeCalculationTypeOptions;
|
||||
this.capitalizedIncomeStrategyOptions = capitalizedIncomeStrategyOptions;
|
||||
this.capitalizedIncomeTypeOptions = capitalizedIncomeTypeOptions;
|
||||
|
||||
this.enableBuyDownFee = productData.enableBuyDownFee;
|
||||
this.buyDownFeeCalculationType = productData.buyDownFeeCalculationType;
|
||||
this.buyDownFeeStrategy = productData.buyDownFeeStrategy;
|
||||
this.buyDownFeeIncomeType = productData.buyDownFeeIncomeType;
|
||||
this.buyDownFeeCalculationTypeOptions = buyDownFeeCalculationTypeOptions;
|
||||
this.buyDownFeeStrategyOptions = buyDownFeeStrategyOptions;
|
||||
this.buyDownFeeIncomeTypeOptions = buyDownFeeIncomeTypeOptions;
|
||||
}
|
||||
|
||||
private Collection<ChargeData> nullIfEmpty(final Collection<ChargeData> charges) {
|
||||
|
||||
+7
-2
@@ -59,6 +59,9 @@ import org.apache.fineract.portfolio.floatingrates.data.FloatingRateDTO;
|
||||
import org.apache.fineract.portfolio.floatingrates.data.FloatingRatePeriodData;
|
||||
import org.apache.fineract.portfolio.floatingrates.domain.FloatingRate;
|
||||
import org.apache.fineract.portfolio.fund.domain.Fund;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeCalculationType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeIncomeType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeStrategy;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeType;
|
||||
@@ -282,7 +285,9 @@ public class LoanProduct extends AbstractPersistableCustom<Long> {
|
||||
final LoanChargeOffBehaviour chargeOffBehaviour, final boolean isInterestRecognitionOnDisbursementDate,
|
||||
final DaysInYearCustomStrategyType daysInYearCustomStrategy, final boolean enableIncomeCapitalization,
|
||||
final LoanCapitalizedIncomeCalculationType capitalizedIncomeCalculationType,
|
||||
final LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy, final LoanCapitalizedIncomeType capitalizedIncomeType) {
|
||||
final LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy, final LoanCapitalizedIncomeType capitalizedIncomeType,
|
||||
final boolean enableBuyDownFee, final LoanBuyDownFeeCalculationType buyDownFeeCalculationType,
|
||||
final LoanBuyDownFeeStrategy buyDownFeeStrategy, final LoanBuyDownFeeIncomeType buyDownFeeIncomeType) {
|
||||
this.fund = fund;
|
||||
this.transactionProcessingStrategyCode = transactionProcessingStrategyCode;
|
||||
|
||||
@@ -334,7 +339,7 @@ public class LoanProduct extends AbstractPersistableCustom<Long> {
|
||||
enableAutoRepaymentForDownPayment, loanScheduleType, loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting,
|
||||
supportedInterestRefundTypes, chargeOffBehaviour, isInterestRecognitionOnDisbursementDate, daysInYearCustomStrategy,
|
||||
enableIncomeCapitalization, capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType,
|
||||
installmentAmountInMultiplesOf);
|
||||
installmentAmountInMultiplesOf, enableBuyDownFee, buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType);
|
||||
|
||||
this.loanProductMinMaxConstraints = new LoanProductMinMaxConstraints(defaultMinPrincipal, defaultMaxPrincipal,
|
||||
defaultMinNominalInterestRatePerPeriod, defaultMaxNominalInterestRatePerPeriod, defaultMinNumberOfInstallments,
|
||||
|
||||
+30
-3
@@ -36,6 +36,9 @@ import org.apache.fineract.portfolio.common.domain.DaysInYearCustomStrategyType;
|
||||
import org.apache.fineract.portfolio.common.domain.DaysInYearType;
|
||||
import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeCalculationType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeIncomeType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeStrategy;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeType;
|
||||
@@ -186,6 +189,21 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
@Column(name = "capitalized_income_type")
|
||||
private LoanCapitalizedIncomeType capitalizedIncomeType;
|
||||
|
||||
@Column(name = "enable_buy_down_fee")
|
||||
private boolean enableBuyDownFee = false;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "buy_down_fee_calculation_type")
|
||||
private LoanBuyDownFeeCalculationType buyDownFeeCalculationType;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "buy_down_fee_strategy")
|
||||
private LoanBuyDownFeeStrategy buyDownFeeStrategy;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "buy_down_fee_income_type")
|
||||
private LoanBuyDownFeeIncomeType buyDownFeeIncomeType;
|
||||
|
||||
@Column(name = "installment_amount_in_multiples_of")
|
||||
private Integer installmentAmountInMultiplesOf;
|
||||
|
||||
@@ -206,7 +224,9 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
final DaysInYearCustomStrategyType daysInYearCustomStrategy, final boolean enableIncomeCapitalization,
|
||||
final LoanCapitalizedIncomeCalculationType capitalizedIncomeCalculationType,
|
||||
final LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy, final LoanCapitalizedIncomeType capitalizedIncomeType,
|
||||
final Integer installmentAmountInMultiplesOf) {
|
||||
final Integer installmentAmountInMultiplesOf, final boolean enableBuyDownFee,
|
||||
final LoanBuyDownFeeCalculationType buyDownFeeCalculationType, final LoanBuyDownFeeStrategy buyDownFeeStrategy,
|
||||
final LoanBuyDownFeeIncomeType buyDownFeeIncomeType) {
|
||||
|
||||
final MonetaryCurrency currency = MonetaryCurrency.fromCurrencyData(currencyData);
|
||||
return new LoanProductRelatedDetail(currency, principal, nominalInterestRatePerPeriod, interestRatePeriodFrequencyType,
|
||||
@@ -217,7 +237,8 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
isEqualAmortization, enableDownPayment, disbursedAmountPercentageForDownPayment, enableAutoRepaymentForDownPayment,
|
||||
loanScheduleType, loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes,
|
||||
chargeOffBehaviour, interestRecognitionOnDisbursementDate, daysInYearCustomStrategy, enableIncomeCapitalization,
|
||||
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType, installmentAmountInMultiplesOf);
|
||||
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType, installmentAmountInMultiplesOf,
|
||||
enableBuyDownFee, buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType);
|
||||
}
|
||||
|
||||
protected LoanProductRelatedDetail() {
|
||||
@@ -241,7 +262,9 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
final DaysInYearCustomStrategyType daysInYearCustomStrategy, final boolean enableIncomeCapitalization,
|
||||
final LoanCapitalizedIncomeCalculationType capitalizedIncomeCalculationType,
|
||||
final LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy, final LoanCapitalizedIncomeType capitalizedIncomeType,
|
||||
final Integer installmentAmountInMultiplesOf) {
|
||||
final Integer installmentAmountInMultiplesOf, final boolean enableBuyDownFee,
|
||||
final LoanBuyDownFeeCalculationType buyDownFeeCalculationType, final LoanBuyDownFeeStrategy buyDownFeeStrategy,
|
||||
final LoanBuyDownFeeIncomeType buyDownFeeIncomeType) {
|
||||
this.currency = currency;
|
||||
this.principal = defaultPrincipal;
|
||||
this.nominalInterestRatePerPeriod = defaultNominalInterestRatePerPeriod;
|
||||
@@ -284,6 +307,10 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
this.capitalizedIncomeStrategy = capitalizedIncomeStrategy;
|
||||
this.capitalizedIncomeType = capitalizedIncomeType;
|
||||
this.installmentAmountInMultiplesOf = installmentAmountInMultiplesOf;
|
||||
this.enableBuyDownFee = enableBuyDownFee;
|
||||
this.buyDownFeeCalculationType = buyDownFeeCalculationType;
|
||||
this.buyDownFeeStrategy = buyDownFeeStrategy;
|
||||
this.buyDownFeeIncomeType = buyDownFeeIncomeType;
|
||||
}
|
||||
|
||||
private Integer defaultToNullIfZero(final Integer value) {
|
||||
|
||||
+7
-1
@@ -133,6 +133,9 @@ import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsData;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.LoanTransactionData;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.PaidInAdvanceData;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.RepaymentScheduleRelatedLoanData;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeCalculationType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeIncomeType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeStrategy;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeType;
|
||||
@@ -1169,7 +1172,10 @@ public class LoansApiResource {
|
||||
loanTermVariations, ApiFacingEnum.getValuesAsStringEnumOptionDataList(DaysInYearCustomStrategyType.class),
|
||||
ApiFacingEnum.getValuesAsStringEnumOptionDataList(LoanCapitalizedIncomeCalculationType.class),
|
||||
ApiFacingEnum.getValuesAsStringEnumOptionDataList(LoanCapitalizedIncomeStrategy.class),
|
||||
ApiFacingEnum.getValuesAsStringEnumOptionDataList(LoanCapitalizedIncomeType.class));
|
||||
ApiFacingEnum.getValuesAsStringEnumOptionDataList(LoanCapitalizedIncomeType.class),
|
||||
ApiFacingEnum.getValuesAsStringEnumOptionDataList(LoanBuyDownFeeCalculationType.class),
|
||||
ApiFacingEnum.getValuesAsStringEnumOptionDataList(LoanBuyDownFeeStrategy.class),
|
||||
ApiFacingEnum.getValuesAsStringEnumOptionDataList(LoanBuyDownFeeIncomeType.class));
|
||||
|
||||
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters(),
|
||||
mandatoryResponseParameters);
|
||||
|
||||
+16
@@ -1227,6 +1227,14 @@ final class LoansApiResourceSwagger {
|
||||
public StringEnumOptionData capitalizedIncomeStrategy;
|
||||
@Schema(example = "FEE")
|
||||
public StringEnumOptionData capitalizedIncomeType;
|
||||
@Schema(example = "false")
|
||||
public Boolean enableBuyDownFee;
|
||||
@Schema(example = "FLAT")
|
||||
public StringEnumOptionData buyDownFeeCalculationType;
|
||||
@Schema(example = "EQUAL_AMORTIZATION")
|
||||
public StringEnumOptionData buyDownFeeStrategy;
|
||||
@Schema(example = "FEE")
|
||||
public StringEnumOptionData buyDownFeeIncomeType;
|
||||
}
|
||||
|
||||
@Schema(description = "GetLoansResponse")
|
||||
@@ -1348,6 +1356,14 @@ final class LoansApiResourceSwagger {
|
||||
public String capitalizedIncomeStrategy;
|
||||
@Schema(example = "FEE")
|
||||
public StringEnumOptionData capitalizedIncomeType;
|
||||
@Schema(example = "false")
|
||||
public Boolean enableBuyDownFee;
|
||||
@Schema(example = "FLAT", allowableValues = "FLAT")
|
||||
public String buyDownFeeCalculationType;
|
||||
@Schema(example = "EQUAL_AMORTIZATION", allowableValues = "EQUAL_AMORTIZATION")
|
||||
public String buyDownFeeStrategy;
|
||||
@Schema(example = "FEE", allowableValues = { "FEE", "INTEREST" })
|
||||
public String buyDownFeeIncomeType;
|
||||
@Schema(example = "List of PostLoansDataTable")
|
||||
public List<PostLoansDataTable> datatables;
|
||||
|
||||
|
||||
+5
-1
@@ -550,7 +550,11 @@ public class LoanScheduleAssembler {
|
||||
loanProduct.getLoanProductRelatedDetail().isEnableIncomeCapitalization(),
|
||||
loanProduct.getLoanProductRelatedDetail().getCapitalizedIncomeCalculationType(),
|
||||
loanProduct.getLoanProductRelatedDetail().getCapitalizedIncomeStrategy(),
|
||||
loanProduct.getLoanProductRelatedDetail().getCapitalizedIncomeType());
|
||||
loanProduct.getLoanProductRelatedDetail().getCapitalizedIncomeType(),
|
||||
loanProduct.getLoanProductRelatedDetail().isEnableBuyDownFee(),
|
||||
loanProduct.getLoanProductRelatedDetail().getBuyDownFeeCalculationType(),
|
||||
loanProduct.getLoanProductRelatedDetail().getBuyDownFeeStrategy(),
|
||||
loanProduct.getLoanProductRelatedDetail().getBuyDownFeeIncomeType());
|
||||
}
|
||||
|
||||
private CalendarInstance createCalendarForSameAsRepayment(final Integer repaymentEvery,
|
||||
|
||||
+12
-1
@@ -40,6 +40,9 @@ import org.apache.fineract.portfolio.common.domain.DaysInYearType;
|
||||
import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
|
||||
import org.apache.fineract.portfolio.floatingrates.domain.FloatingRate;
|
||||
import org.apache.fineract.portfolio.fund.domain.Fund;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeCalculationType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeIncomeType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeStrategy;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeType;
|
||||
@@ -317,6 +320,14 @@ public class LoanProductAssembler {
|
||||
final LoanCapitalizedIncomeType capitalizedIncomeType = command
|
||||
.enumValueOfParameterNamed(LoanProductConstants.CAPITALIZED_INCOME_TYPE_PARAM_NAME, LoanCapitalizedIncomeType.class);
|
||||
|
||||
final boolean enableBuyDownFee = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME);
|
||||
final LoanBuyDownFeeCalculationType buyDownFeeCalculationType = command.enumValueOfParameterNamed(
|
||||
LoanProductConstants.BUY_DOWN_FEE_CALCULATION_TYPE_PARAM_NAME, LoanBuyDownFeeCalculationType.class);
|
||||
final LoanBuyDownFeeStrategy buyDownFeeStrategy = command
|
||||
.enumValueOfParameterNamed(LoanProductConstants.BUY_DOWN_FEE_STRATEGY_PARAM_NAME, LoanBuyDownFeeStrategy.class);
|
||||
final LoanBuyDownFeeIncomeType buyDownFeeIncomeType = command
|
||||
.enumValueOfParameterNamed(LoanProductConstants.BUY_DOWN_FEE_INCOME_TYPE_PARAM_NAME, LoanBuyDownFeeIncomeType.class);
|
||||
|
||||
return new LoanProduct(fund, loanTransactionProcessingStrategy, loanProductPaymentAllocationRules, loanProductCreditAllocationRules,
|
||||
name, shortName, description, currency, principal, minPrincipal, maxPrincipal, interestRatePerPeriod,
|
||||
minInterestRatePerPeriod, maxInterestRatePerPeriod, interestFrequencyType, annualInterestRate, interestMethod,
|
||||
@@ -338,7 +349,7 @@ public class LoanProductAssembler {
|
||||
repaymentStartDateType, enableInstallmentLevelDelinquency, loanScheduleType, loanScheduleProcessingType, fixedLength,
|
||||
enableAccrualActivityPosting, supportedInterestRefundTypes, chargeOffBehaviour, interestRecognitionOnDisbursementDate,
|
||||
daysInYearCustomStrategy, enableIncomeCapitalization, capitalizedIncomeCalculationType, capitalizedIncomeStrategy,
|
||||
capitalizedIncomeType);
|
||||
capitalizedIncomeType, enableBuyDownFee, buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType);
|
||||
|
||||
}
|
||||
|
||||
|
||||
+31
@@ -26,6 +26,9 @@ import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.portfolio.common.domain.DaysInYearCustomStrategyType;
|
||||
import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeCalculationType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeIncomeType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeStrategy;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeType;
|
||||
@@ -328,6 +331,34 @@ public class LoanProductRelatedDetailUpdateUtil {
|
||||
loanRepaymentScheduleDetail.setCapitalizedIncomeType(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME,
|
||||
loanRepaymentScheduleDetail.isEnableBuyDownFee())) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME);
|
||||
actualChanges.put(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME, newValue);
|
||||
loanRepaymentScheduleDetail.setEnableBuyDownFee(newValue);
|
||||
}
|
||||
|
||||
if (command.parameterExists(LoanProductConstants.BUY_DOWN_FEE_CALCULATION_TYPE_PARAM_NAME)) {
|
||||
final LoanBuyDownFeeCalculationType newValue = command.enumValueOfParameterNamed(
|
||||
LoanProductConstants.BUY_DOWN_FEE_CALCULATION_TYPE_PARAM_NAME, LoanBuyDownFeeCalculationType.class);
|
||||
actualChanges.put(LoanProductConstants.BUY_DOWN_FEE_CALCULATION_TYPE_PARAM_NAME, newValue);
|
||||
loanRepaymentScheduleDetail.setBuyDownFeeCalculationType(newValue);
|
||||
}
|
||||
|
||||
if (command.parameterExists(LoanProductConstants.BUY_DOWN_FEE_STRATEGY_PARAM_NAME)) {
|
||||
final LoanBuyDownFeeStrategy newValue = command.enumValueOfParameterNamed(LoanProductConstants.BUY_DOWN_FEE_STRATEGY_PARAM_NAME,
|
||||
LoanBuyDownFeeStrategy.class);
|
||||
actualChanges.put(LoanProductConstants.BUY_DOWN_FEE_STRATEGY_PARAM_NAME, newValue);
|
||||
loanRepaymentScheduleDetail.setBuyDownFeeStrategy(newValue);
|
||||
}
|
||||
|
||||
if (command.parameterExists(LoanProductConstants.BUY_DOWN_FEE_INCOME_TYPE_PARAM_NAME)) {
|
||||
final LoanBuyDownFeeIncomeType newValue = command
|
||||
.enumValueOfParameterNamed(LoanProductConstants.BUY_DOWN_FEE_INCOME_TYPE_PARAM_NAME, LoanBuyDownFeeIncomeType.class);
|
||||
actualChanges.put(LoanProductConstants.BUY_DOWN_FEE_INCOME_TYPE_PARAM_NAME, newValue);
|
||||
loanRepaymentScheduleDetail.setBuyDownFeeIncomeType(newValue);
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
|
||||
+14
-1
@@ -109,6 +109,9 @@ import org.apache.fineract.portfolio.loanaccount.data.PaidInAdvanceData;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.RepaymentScheduleRelatedLoanData;
|
||||
import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeCalculationType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeIncomeType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeStrategy;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeBalance;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
|
||||
@@ -819,6 +822,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
|
||||
+ " l.capitalized_income_calculation_type as capitalizedIncomeCalculationType, "
|
||||
+ " l.capitalized_income_strategy as capitalizedIncomeStrategy, "
|
||||
+ " l.capitalized_income_type as capitalizedIncomeType, " //
|
||||
+ " l.enable_buy_down_fee as enableBuyDownFee, " + " l.buy_down_fee_calculation_type as buyDownFeeCalculationType, "
|
||||
+ " l.buy_down_fee_strategy as buyDownFeeStrategy, " + " l.buy_down_fee_income_type as buyDownFeeIncomeType, "
|
||||
+ " l.create_standing_instruction_at_disbursement as createStandingInstructionAtDisbursement, "
|
||||
+ " lpvi.minimum_gap as minimuminstallmentgap, lpvi.maximum_gap as maximuminstallmentgap, "
|
||||
+ " lp.can_use_for_topup as canUseForTopup, l.is_topup as isTopup, topup.closure_loan_id as closureLoanId, "
|
||||
@@ -1208,6 +1213,13 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
|
||||
.getStringEnumOptionData(LoanCapitalizedIncomeStrategy.class, rs.getString("capitalizedIncomeStrategy"));
|
||||
final StringEnumOptionData capitalizedIncomeType = ApiFacingEnum.getStringEnumOptionData(LoanCapitalizedIncomeType.class,
|
||||
rs.getString("capitalizedIncomeType"));
|
||||
final boolean enableBuyDownFee = rs.getBoolean("enableBuyDownFee");
|
||||
final StringEnumOptionData buyDownFeeCalculationType = ApiFacingEnum
|
||||
.getStringEnumOptionData(LoanBuyDownFeeCalculationType.class, rs.getString("buyDownFeeCalculationType"));
|
||||
final StringEnumOptionData buyDownFeeStrategy = ApiFacingEnum.getStringEnumOptionData(LoanBuyDownFeeStrategy.class,
|
||||
rs.getString("buyDownFeeStrategy"));
|
||||
final StringEnumOptionData buyDownFeeIncomeType = ApiFacingEnum.getStringEnumOptionData(LoanBuyDownFeeIncomeType.class,
|
||||
rs.getString("buyDownFeeIncomeType"));
|
||||
|
||||
return LoanAccountData.basicLoanDetails(id, accountNo, status, externalId, clientId, clientAccountNo, clientName,
|
||||
clientOfficeId, clientExternalId, groupData, loanType, loanProductId, loanProductName, loanProductDescription,
|
||||
@@ -1228,7 +1240,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
|
||||
enableAutoRepaymentForDownPayment, enableInstallmentLevelDelinquency, loanScheduleType.asEnumOptionData(),
|
||||
loanScheduleProcessingType.asEnumOptionData(), fixedLength, chargeOffBehaviour.getValueAsStringEnumOptionData(),
|
||||
interestRecognitionOnDisbursementDate, daysInYearCustomStrategy, enableIncomeCapitalization,
|
||||
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType);
|
||||
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType, enableBuyDownFee,
|
||||
buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+13
-2
@@ -82,6 +82,9 @@ import org.apache.fineract.portfolio.floatingrates.service.FloatingRatesReadPlat
|
||||
import org.apache.fineract.portfolio.fund.data.FundData;
|
||||
import org.apache.fineract.portfolio.fund.service.FundReadPlatformService;
|
||||
import org.apache.fineract.portfolio.loanaccount.api.LoanApiConstants;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeCalculationType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeIncomeType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeStrategy;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeType;
|
||||
@@ -134,7 +137,9 @@ public class LoanProductsApiResource {
|
||||
LoanProductConstants.REPAYMENT_START_DATE_TYPE, LoanProductConstants.DAYS_IN_YEAR_CUSTOM_STRATEGY_TYPE_PARAMETER_NAME,
|
||||
LoanProductConstants.ENABLE_INCOME_CAPITALIZATION_PARAM_NAME,
|
||||
LoanProductConstants.CAPITALIZED_INCOME_CALCULATION_TYPE_PARAM_NAME,
|
||||
LoanProductConstants.CAPITALIZED_INCOME_STRATEGY_PARAM_NAME, LoanProductConstants.CAPITALIZED_INCOME_TYPE_PARAM_NAME));
|
||||
LoanProductConstants.CAPITALIZED_INCOME_STRATEGY_PARAM_NAME, LoanProductConstants.CAPITALIZED_INCOME_TYPE_PARAM_NAME,
|
||||
LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME, LoanProductConstants.BUY_DOWN_FEE_CALCULATION_TYPE_PARAM_NAME,
|
||||
LoanProductConstants.BUY_DOWN_FEE_STRATEGY_PARAM_NAME, LoanProductConstants.BUY_DOWN_FEE_INCOME_TYPE_PARAM_NAME));
|
||||
|
||||
private static final Set<String> PRODUCT_MIX_DATA_PARAMETERS = new HashSet<>(
|
||||
Arrays.asList("productId", "productName", "restrictedProducts", "allowedProducts", "productOptions"));
|
||||
@@ -453,6 +458,12 @@ public class LoanProductsApiResource {
|
||||
.getValuesAsStringEnumOptionDataList(LoanCapitalizedIncomeStrategy.class);
|
||||
final List<StringEnumOptionData> capitalizedIncomeTypeOptions = ApiFacingEnum
|
||||
.getValuesAsStringEnumOptionDataList(LoanCapitalizedIncomeType.class);
|
||||
final List<StringEnumOptionData> buyDownFeeCalculationTypeOptions = ApiFacingEnum
|
||||
.getValuesAsStringEnumOptionDataList(LoanBuyDownFeeCalculationType.class);
|
||||
final List<StringEnumOptionData> buyDownFeeStrategyOptions = ApiFacingEnum
|
||||
.getValuesAsStringEnumOptionDataList(LoanBuyDownFeeStrategy.class);
|
||||
final List<StringEnumOptionData> buyDownFeeIncomeTypeOptions = ApiFacingEnum
|
||||
.getValuesAsStringEnumOptionDataList(LoanBuyDownFeeIncomeType.class);
|
||||
|
||||
return new LoanProductData(productData, chargeOptions, penaltyOptions, paymentTypeOptions, currencyOptions, amortizationTypeOptions,
|
||||
interestTypeOptions, interestCalculationPeriodTypeOptions, repaymentFrequencyTypeOptions, interestRateFrequencyTypeOptions,
|
||||
@@ -466,7 +477,7 @@ public class LoanProductsApiResource {
|
||||
LoanScheduleProcessingType.getValuesAsEnumOptionDataList(), creditAllocationTransactionTypes,
|
||||
creditAllocationAllocationTypes, supportedInterestRefundTypesOptions, chargeOffBehaviourOptions, chargeOffReasonOptions,
|
||||
daysInYearCustomStrategyOptions, capitalizedIncomeCalculationTypeOptions, capitalizedIncomeStrategyOptions,
|
||||
capitalizedIncomeTypeOptions);
|
||||
capitalizedIncomeTypeOptions, buyDownFeeCalculationTypeOptions, buyDownFeeStrategyOptions, buyDownFeeIncomeTypeOptions);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+65
-1
@@ -49,6 +49,9 @@ import org.apache.fineract.infrastructure.core.service.MathUtil;
|
||||
import org.apache.fineract.portfolio.calendar.service.CalendarUtils;
|
||||
import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
|
||||
import org.apache.fineract.portfolio.loanaccount.api.LoanApiConstants;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeCalculationType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeIncomeType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeStrategy;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeType;
|
||||
@@ -194,7 +197,9 @@ public final class LoanProductDataValidator {
|
||||
LoanProductConstants.DAYS_IN_YEAR_CUSTOM_STRATEGY_TYPE_PARAMETER_NAME,
|
||||
LoanProductConstants.ENABLE_INCOME_CAPITALIZATION_PARAM_NAME,
|
||||
LoanProductConstants.CAPITALIZED_INCOME_CALCULATION_TYPE_PARAM_NAME,
|
||||
LoanProductConstants.CAPITALIZED_INCOME_STRATEGY_PARAM_NAME, LoanProductConstants.CAPITALIZED_INCOME_TYPE_PARAM_NAME));
|
||||
LoanProductConstants.CAPITALIZED_INCOME_STRATEGY_PARAM_NAME, LoanProductConstants.CAPITALIZED_INCOME_TYPE_PARAM_NAME,
|
||||
LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME, LoanProductConstants.BUY_DOWN_FEE_CALCULATION_TYPE_PARAM_NAME,
|
||||
LoanProductConstants.BUY_DOWN_FEE_STRATEGY_PARAM_NAME, LoanProductConstants.BUY_DOWN_FEE_INCOME_TYPE_PARAM_NAME));
|
||||
|
||||
private static final String[] SUPPORTED_LOAN_CONFIGURABLE_ATTRIBUTES = { LoanProductConstants.amortizationTypeParamName,
|
||||
LoanProductConstants.interestTypeParamName, LoanProductConstants.transactionProcessingStrategyCodeParamName,
|
||||
@@ -887,6 +892,8 @@ public final class LoanProductDataValidator {
|
||||
|
||||
validateIncomeCapitalization(transactionProcessingStrategyCode, element, baseDataValidator, accountingRuleType);
|
||||
|
||||
validateBuyDownFee(transactionProcessingStrategyCode, element, baseDataValidator);
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
@@ -1935,6 +1942,8 @@ public final class LoanProductDataValidator {
|
||||
|
||||
validateIncomeCapitalization(transactionProcessingStrategyCode, element, baseDataValidator, accountingRuleType);
|
||||
|
||||
validateBuyDownFee(transactionProcessingStrategyCode, element, baseDataValidator);
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
@@ -2745,6 +2754,61 @@ public final class LoanProductDataValidator {
|
||||
}
|
||||
}
|
||||
|
||||
private void validateBuyDownFee(String transactionProcessingStrategyCode, JsonElement element, DataValidatorBuilder baseDataValidator) {
|
||||
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.BUY_DOWN_FEE_CALCULATION_TYPE_PARAM_NAME, element)) {
|
||||
final String buyDownFeeCalculationType = this.fromApiJsonHelper
|
||||
.extractStringNamed(LoanProductConstants.BUY_DOWN_FEE_CALCULATION_TYPE_PARAM_NAME, element);
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.BUY_DOWN_FEE_CALCULATION_TYPE_PARAM_NAME)
|
||||
.value(buyDownFeeCalculationType).isOneOfEnumValues(LoanBuyDownFeeCalculationType.class);
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.BUY_DOWN_FEE_STRATEGY_PARAM_NAME, element)) {
|
||||
final String buyDownFeeStrategy = this.fromApiJsonHelper
|
||||
.extractStringNamed(LoanProductConstants.BUY_DOWN_FEE_STRATEGY_PARAM_NAME, element);
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.BUY_DOWN_FEE_STRATEGY_PARAM_NAME).value(buyDownFeeStrategy)
|
||||
.isOneOfEnumValues(LoanBuyDownFeeStrategy.class);
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.BUY_DOWN_FEE_INCOME_TYPE_PARAM_NAME, element)) {
|
||||
final String buyDownFeeIncomeType = this.fromApiJsonHelper
|
||||
.extractStringNamed(LoanProductConstants.BUY_DOWN_FEE_INCOME_TYPE_PARAM_NAME, element);
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.BUY_DOWN_FEE_INCOME_TYPE_PARAM_NAME).value(buyDownFeeIncomeType)
|
||||
.isOneOfEnumValues(LoanBuyDownFeeIncomeType.class);
|
||||
}
|
||||
|
||||
if (AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY.equals(transactionProcessingStrategyCode)
|
||||
&& this.fromApiJsonHelper.parameterExists(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME, element)) {
|
||||
Boolean enableBuyDownFee = this.fromApiJsonHelper.extractBooleanNamed(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME,
|
||||
element);
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME).value(enableBuyDownFee).ignoreIfNull()
|
||||
.validateForBooleanValue();
|
||||
if (enableBuyDownFee) {
|
||||
final String buyDownFeeCalculationType = this.fromApiJsonHelper
|
||||
.extractStringNamed(LoanProductConstants.BUY_DOWN_FEE_CALCULATION_TYPE_PARAM_NAME, element);
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.BUY_DOWN_FEE_CALCULATION_TYPE_PARAM_NAME)
|
||||
.value(buyDownFeeCalculationType).isOneOfEnumValues(LoanBuyDownFeeCalculationType.class)
|
||||
.cantBeBlankWhenParameterProvidedIs(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME, true);
|
||||
final String buyDownFeeStrategy = this.fromApiJsonHelper
|
||||
.extractStringNamed(LoanProductConstants.BUY_DOWN_FEE_STRATEGY_PARAM_NAME, element);
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.BUY_DOWN_FEE_STRATEGY_PARAM_NAME).value(buyDownFeeStrategy)
|
||||
.isOneOfEnumValues(LoanBuyDownFeeStrategy.class)
|
||||
.cantBeBlankWhenParameterProvidedIs(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME, true);
|
||||
final String buyDownFeeIncomeType = this.fromApiJsonHelper
|
||||
.extractStringNamed(LoanProductConstants.BUY_DOWN_FEE_INCOME_TYPE_PARAM_NAME, element);
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.BUY_DOWN_FEE_INCOME_TYPE_PARAM_NAME).value(buyDownFeeIncomeType)
|
||||
.isOneOfEnumValues(LoanBuyDownFeeIncomeType.class)
|
||||
.cantBeBlankWhenParameterProvidedIs(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME, true);
|
||||
}
|
||||
} else if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME, element)) {
|
||||
Boolean enableBuyDownFee = this.fromApiJsonHelper.extractBooleanNamed(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME,
|
||||
element);
|
||||
if (Boolean.TRUE.equals(enableBuyDownFee)) {
|
||||
baseDataValidator.reset().parameter(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME).failWithCode(
|
||||
"supported.only.for.progressive.loan.buyDownFee", "Buy down fee is only supported for Progressive loans");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Integer defaultToZeroIfNull(Integer value) {
|
||||
return value != null ? value : 0;
|
||||
}
|
||||
|
||||
+14
-2
@@ -46,6 +46,9 @@ import org.apache.fineract.portfolio.common.domain.DaysInYearCustomStrategyType;
|
||||
import org.apache.fineract.portfolio.common.service.CommonEnumerations;
|
||||
import org.apache.fineract.portfolio.delinquency.data.DelinquencyBucketData;
|
||||
import org.apache.fineract.portfolio.delinquency.service.DelinquencyReadPlatformService;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeCalculationType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeIncomeType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeStrategy;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeType;
|
||||
@@ -296,7 +299,9 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
||||
+ "lp.enable_income_capitalization as enableIncomeCapitalization, " //
|
||||
+ "lp.capitalized_income_calculation_type as capitalizedIncomeCalculationType, " //
|
||||
+ "lp.capitalized_income_strategy as capitalizedIncomeStrategy, " //
|
||||
+ "lp.capitalized_income_type as capitalizedIncomeType " //
|
||||
+ "lp.capitalized_income_type as capitalizedIncomeType, " //
|
||||
+ "lp.enable_buy_down_fee as enableBuyDownFee, " + "lp.buy_down_fee_calculation_type as buyDownFeeCalculationType, "
|
||||
+ "lp.buy_down_fee_strategy as buyDownFeeStrategy, " + "lp.buy_down_fee_income_type as buyDownFeeIncomeType "
|
||||
+ " from m_product_loan lp " + " left join m_fund f on f.id = lp.fund_id "
|
||||
+ " left join m_product_loan_recalculation_details lpr on lpr.product_id=lp.id "
|
||||
+ " left join m_product_loan_guarantee_details lpg on lpg.loan_product_id=lp.id "
|
||||
@@ -567,6 +572,13 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
||||
.getStringEnumOptionData(LoanCapitalizedIncomeStrategy.class, rs.getString("capitalizedIncomeStrategy"));
|
||||
final StringEnumOptionData capitalizedIncome = ApiFacingEnum.getStringEnumOptionData(LoanCapitalizedIncomeType.class,
|
||||
rs.getString("capitalizedIncomeType"));
|
||||
final boolean enableBuyDownFee = rs.getBoolean("enableBuyDownFee");
|
||||
final StringEnumOptionData buyDownFeeCalculationType = ApiFacingEnum
|
||||
.getStringEnumOptionData(LoanBuyDownFeeCalculationType.class, rs.getString("buyDownFeeCalculationType"));
|
||||
final StringEnumOptionData buyDownFeeStrategy = ApiFacingEnum.getStringEnumOptionData(LoanBuyDownFeeStrategy.class,
|
||||
rs.getString("buyDownFeeStrategy"));
|
||||
final StringEnumOptionData buyDownFeeIncomeType = ApiFacingEnum.getStringEnumOptionData(LoanBuyDownFeeIncomeType.class,
|
||||
rs.getString("buyDownFeeIncomeType"));
|
||||
|
||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||
@@ -592,7 +604,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
||||
fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes,
|
||||
loanChargeOffBehaviour.getValueAsStringEnumOptionData(), interestRecognitionOnDisbursementDate,
|
||||
daysInYearCustomStrategy, enableIncomeCapitalization, capitalizedIncomeCalculationType, capitalizedIncomeStrategy,
|
||||
capitalizedIncome);
|
||||
capitalizedIncome, enableBuyDownFee, buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -203,4 +203,5 @@
|
||||
<include file="parts/0182_transaction_summary_with_asset_owner_report_fix_charge_reason_and_add_buyback_intermediate.xml" relativeToChangelogFile="true" />
|
||||
<include file="parts/0183_add_LoanCapitalizedIncomeTransactionCreatedBusinessEvent.xml" relativeToChangelogFile="true" />
|
||||
<include file="parts/0184_add_document_event_configuration.xml" relativeToChangelogFile="true" />
|
||||
<include file="parts/0185_loan_buy_down_fee.xml" relativeToChangelogFile="true" />
|
||||
</databaseChangeLog>
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
<?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.3.xsd">
|
||||
<changeSet author="fineract" id="1">
|
||||
<addColumn tableName="m_loan">
|
||||
<column name="enable_buy_down_fee" type="boolean" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="buy_down_fee_calculation_type" type="VARCHAR(100)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="buy_down_fee_strategy" type="VARCHAR(100)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="buy_down_fee_income_type" type="VARCHAR(100)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
<addColumn tableName="m_product_loan">
|
||||
<column name="enable_buy_down_fee" type="boolean" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="buy_down_fee_calculation_type" type="VARCHAR(100)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="buy_down_fee_strategy" type="VARCHAR(100)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="buy_down_fee_income_type" type="VARCHAR(100)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
+2
-2
@@ -99,7 +99,7 @@ public class DefaultScheduledDateGeneratorTest {
|
||||
DaysInMonthType.ACTUAL, DaysInYearType.ACTUAL, false, null, null, null, null, null, ZERO, null, NONE, null, ZERO,
|
||||
EMPTY_LIST, true, 0, false, holidayDetailDTO, false, false, false, null, false, false, null, false, DISBURSEMENT_DATE,
|
||||
submittedOnDate, CUMULATIVE, LoanScheduleProcessingType.HORIZONTAL, null, false, null, null, false, null, false, null, null,
|
||||
null);
|
||||
null, false, null, null, null);
|
||||
|
||||
// when
|
||||
List<? extends LoanScheduleModelPeriod> result = underTest.generateRepaymentPeriods(mathContext, expectedDisbursementDate,
|
||||
@@ -180,7 +180,7 @@ public class DefaultScheduledDateGeneratorTest {
|
||||
EMPTY_LIST, BigDecimal.valueOf(36_000L), null, DaysInMonthType.ACTUAL, DaysInYearType.ACTUAL, false, null, null, null, null,
|
||||
null, ZERO, null, NONE, null, ZERO, EMPTY_LIST, true, 0, false, holidayDetailDTO, false, false, false, null, false, false,
|
||||
null, false, DISBURSEMENT_DATE, submittedOnDate, CUMULATIVE, LoanScheduleProcessingType.HORIZONTAL, null, false, null, null,
|
||||
false, null, false, null, null, null);
|
||||
false, null, false, null, null, null, false, null, null, null);
|
||||
}
|
||||
|
||||
private HolidayDetailDTO createHolidayDTO() {
|
||||
|
||||
+155
@@ -26,6 +26,9 @@ import org.apache.fineract.client.models.PostLoanProductsRequest;
|
||||
import org.apache.fineract.client.models.PostLoanProductsResponse;
|
||||
import org.apache.fineract.client.models.PutLoanProductsProductIdRequest;
|
||||
import org.apache.fineract.integrationtests.common.ClientHelper;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeCalculationType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeIncomeType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanBuyDownFeeStrategy;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeType;
|
||||
@@ -237,4 +240,156 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
|
||||
.incomeFromCapitalizationAccountId(feeIncomeAccount.getAccountID().longValue())));
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
public class BuyDownFeeTest {
|
||||
|
||||
@Test
|
||||
public void testBuyDownFeeEnabled() {
|
||||
final PostClientsResponse client = clientHelper.createClient(ClientHelper.defaultClientCreationRequest());
|
||||
|
||||
final PostLoanProductsResponse loanProductsResponse = loanProductHelper.createLoanProduct(create4IProgressive()
|
||||
.enableBuyDownFee(true).buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
|
||||
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
|
||||
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE));
|
||||
|
||||
final GetLoanProductsProductIdResponse loanProductsProductIdResponse = loanProductHelper
|
||||
.retrieveLoanProductById(loanProductsResponse.getResourceId());
|
||||
Assertions.assertEquals(Boolean.TRUE, loanProductsProductIdResponse.getEnableBuyDownFee());
|
||||
Assertions.assertNotNull(loanProductsProductIdResponse.getBuyDownFeeCalculationType());
|
||||
Assertions.assertEquals(LoanBuyDownFeeCalculationType.FLAT.getCode(),
|
||||
loanProductsProductIdResponse.getBuyDownFeeCalculationType().getCode());
|
||||
Assertions.assertNotNull(loanProductsProductIdResponse.getBuyDownFeeStrategy());
|
||||
Assertions.assertEquals(LoanBuyDownFeeStrategy.EQUAL_AMORTIZATION.getCode(),
|
||||
loanProductsProductIdResponse.getBuyDownFeeStrategy().getCode());
|
||||
Assertions.assertNotNull(loanProductsProductIdResponse.getBuyDownFeeIncomeType());
|
||||
Assertions.assertEquals(LoanBuyDownFeeIncomeType.FEE.getCode(),
|
||||
loanProductsProductIdResponse.getBuyDownFeeIncomeType().getCode());
|
||||
|
||||
runAt("20 December 2024", () -> {
|
||||
Long loanId = applyAndApproveProgressiveLoan(client.getClientId(), loanProductsResponse.getResourceId(), "20 December 2024",
|
||||
430.0, 7.0, 6, null);
|
||||
|
||||
final GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
|
||||
Assertions.assertEquals(Boolean.TRUE, loanDetails.getEnableBuyDownFee());
|
||||
Assertions.assertNotNull(loanDetails.getBuyDownFeeCalculationType());
|
||||
Assertions.assertEquals(LoanBuyDownFeeCalculationType.FLAT.getCode(), loanDetails.getBuyDownFeeCalculationType().getCode());
|
||||
Assertions.assertNotNull(loanDetails.getBuyDownFeeStrategy());
|
||||
Assertions.assertEquals(LoanBuyDownFeeStrategy.EQUAL_AMORTIZATION.getCode(), loanDetails.getBuyDownFeeStrategy().getCode());
|
||||
Assertions.assertNotNull(loanDetails.getBuyDownFeeIncomeType());
|
||||
Assertions.assertEquals(LoanBuyDownFeeIncomeType.FEE.getCode(), loanDetails.getBuyDownFeeIncomeType().getCode());
|
||||
|
||||
Assertions.assertDoesNotThrow(() -> disburseLoan(loanId, BigDecimal.valueOf(430), "20 December 2024"));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuyDownFeeDisabled() {
|
||||
final PostClientsResponse client = clientHelper.createClient(ClientHelper.defaultClientCreationRequest());
|
||||
|
||||
final PostLoanProductsResponse loanProductsResponse = loanProductHelper.createLoanProduct(create4IProgressive()
|
||||
.enableBuyDownFee(false).buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
|
||||
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
|
||||
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE));
|
||||
|
||||
final GetLoanProductsProductIdResponse loanProductsProductIdResponse = loanProductHelper
|
||||
.retrieveLoanProductById(loanProductsResponse.getResourceId());
|
||||
Assertions.assertEquals(Boolean.FALSE, loanProductsProductIdResponse.getEnableBuyDownFee());
|
||||
Assertions.assertNotNull(loanProductsProductIdResponse.getBuyDownFeeCalculationType());
|
||||
Assertions.assertEquals(LoanBuyDownFeeCalculationType.FLAT.getCode(),
|
||||
loanProductsProductIdResponse.getBuyDownFeeCalculationType().getCode());
|
||||
Assertions.assertNotNull(loanProductsProductIdResponse.getBuyDownFeeStrategy());
|
||||
Assertions.assertEquals(LoanBuyDownFeeStrategy.EQUAL_AMORTIZATION.getCode(),
|
||||
loanProductsProductIdResponse.getBuyDownFeeStrategy().getCode());
|
||||
Assertions.assertNotNull(loanProductsProductIdResponse.getBuyDownFeeIncomeType());
|
||||
Assertions.assertEquals(LoanBuyDownFeeIncomeType.FEE.getCode(),
|
||||
loanProductsProductIdResponse.getBuyDownFeeIncomeType().getCode());
|
||||
|
||||
runAt("20 December 2024", () -> {
|
||||
Long loanId = applyAndApproveProgressiveLoan(client.getClientId(), loanProductsResponse.getResourceId(), "20 December 2024",
|
||||
430.0, 7.0, 6, null);
|
||||
|
||||
final GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
|
||||
Assertions.assertEquals(Boolean.FALSE, loanDetails.getEnableBuyDownFee());
|
||||
Assertions.assertNotNull(loanDetails.getBuyDownFeeCalculationType());
|
||||
Assertions.assertEquals(LoanBuyDownFeeCalculationType.FLAT.getCode(), loanDetails.getBuyDownFeeCalculationType().getCode());
|
||||
Assertions.assertNotNull(loanDetails.getBuyDownFeeStrategy());
|
||||
Assertions.assertEquals(LoanBuyDownFeeStrategy.EQUAL_AMORTIZATION.getCode(), loanDetails.getBuyDownFeeStrategy().getCode());
|
||||
Assertions.assertNotNull(loanDetails.getBuyDownFeeIncomeType());
|
||||
Assertions.assertEquals(LoanBuyDownFeeIncomeType.FEE.getCode(), loanDetails.getBuyDownFeeIncomeType().getCode());
|
||||
|
||||
Assertions.assertDoesNotThrow(() -> disburseLoan(loanId, BigDecimal.valueOf(430), "20 December 2024"));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuyDownFeeUpdateProduct() {
|
||||
final PostLoanProductsResponse loanProductsResponse = loanProductHelper.createLoanProduct(create4IProgressive()
|
||||
.enableBuyDownFee(true).buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
|
||||
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
|
||||
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE));
|
||||
|
||||
final GetLoanProductsProductIdResponse loanProductsProductIdResponse = loanProductHelper
|
||||
.retrieveLoanProductById(loanProductsResponse.getResourceId());
|
||||
Assertions.assertEquals(Boolean.TRUE, loanProductsProductIdResponse.getEnableBuyDownFee());
|
||||
Assertions.assertNotNull(loanProductsProductIdResponse.getBuyDownFeeCalculationType());
|
||||
Assertions.assertEquals(LoanBuyDownFeeCalculationType.FLAT.getCode(),
|
||||
loanProductsProductIdResponse.getBuyDownFeeCalculationType().getCode());
|
||||
Assertions.assertNotNull(loanProductsProductIdResponse.getBuyDownFeeStrategy());
|
||||
Assertions.assertEquals(LoanBuyDownFeeStrategy.EQUAL_AMORTIZATION.getCode(),
|
||||
loanProductsProductIdResponse.getBuyDownFeeStrategy().getCode());
|
||||
Assertions.assertNotNull(loanProductsProductIdResponse.getBuyDownFeeIncomeType());
|
||||
Assertions.assertEquals(LoanBuyDownFeeIncomeType.FEE.getCode(),
|
||||
loanProductsProductIdResponse.getBuyDownFeeIncomeType().getCode());
|
||||
|
||||
loanProductHelper.updateLoanProductById(loanProductsResponse.getResourceId(), new PutLoanProductsProductIdRequest()
|
||||
.enableBuyDownFee(false).buyDownFeeIncomeType(PutLoanProductsProductIdRequest.BuyDownFeeIncomeTypeEnum.INTEREST));
|
||||
|
||||
final GetLoanProductsProductIdResponse updatedLoanProductsProductIdResponse = loanProductHelper
|
||||
.retrieveLoanProductById(loanProductsResponse.getResourceId());
|
||||
Assertions.assertEquals(Boolean.FALSE, updatedLoanProductsProductIdResponse.getEnableBuyDownFee());
|
||||
Assertions.assertNotNull(updatedLoanProductsProductIdResponse.getBuyDownFeeCalculationType());
|
||||
Assertions.assertEquals(LoanBuyDownFeeCalculationType.FLAT.getCode(),
|
||||
updatedLoanProductsProductIdResponse.getBuyDownFeeCalculationType().getCode());
|
||||
Assertions.assertNotNull(updatedLoanProductsProductIdResponse.getBuyDownFeeStrategy());
|
||||
Assertions.assertEquals(LoanBuyDownFeeStrategy.EQUAL_AMORTIZATION.getCode(),
|
||||
updatedLoanProductsProductIdResponse.getBuyDownFeeStrategy().getCode());
|
||||
Assertions.assertNotNull(updatedLoanProductsProductIdResponse.getBuyDownFeeIncomeType());
|
||||
Assertions.assertEquals(LoanBuyDownFeeIncomeType.INTEREST.getCode(),
|
||||
updatedLoanProductsProductIdResponse.getBuyDownFeeIncomeType().getCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuyDownFeeCumulativeNotSupported() {
|
||||
Assertions.assertThrows(RuntimeException.class,
|
||||
() -> loanProductHelper.createLoanProduct(createOnePeriod30DaysPeriodicAccrualProduct(7.0).enableBuyDownFee(true)
|
||||
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
|
||||
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
|
||||
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuyDownFeeEnabledCalculationTypeNotProvided() {
|
||||
Assertions.assertThrows(RuntimeException.class,
|
||||
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
|
||||
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
|
||||
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuyDownFeeEnabledStrategyNotProvided() {
|
||||
Assertions.assertThrows(RuntimeException.class,
|
||||
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
|
||||
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
|
||||
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuyDownFeeEnabledIncomeTypeNotProvided() {
|
||||
Assertions.assertThrows(RuntimeException.class,
|
||||
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
|
||||
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
|
||||
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user