FINERACT-2080: extracted json based workflows from Loan and other Loan related entities
This commit is contained in:
+1
-1
@@ -1233,7 +1233,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
|
||||
|| disbursementDetails.stream().anyMatch(it -> it.actualDisbursementDate() == null);
|
||||
boolean isMultiDisburseLoanDisbursementAllowed = isMultiDisburmentLoan()
|
||||
&& (disbursementDetails == null || disbursementDetails.stream().filter(it -> it.actualDisbursementDate() != null)
|
||||
.count() < loanProduct.getLoanProductTrancheDetails().maxTrancheCount());
|
||||
.count() < loanProduct.getLoanProductTrancheDetails().getMaxTrancheCount());
|
||||
return isSingleDisburseLoanDisbursementAllowed || isMultiDisburseLoanDisbursementAllowed;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -140,8 +140,8 @@ public class LoanInterestRecalculationDetails extends AbstractPersistableCustom<
|
||||
loanProductInterestRecalculationDetails.getCompoundingFrequencyWeekday(),
|
||||
loanProductInterestRecalculationDetails.getCompoundingFrequencyOnDay(),
|
||||
loanProductInterestRecalculationDetails.getIsCompoundingToBePostedAsTransaction(),
|
||||
loanProductInterestRecalculationDetails.allowCompoundingOnEod(),
|
||||
loanProductInterestRecalculationDetails.disallowInterestCalculationOnPastDue(),
|
||||
loanProductInterestRecalculationDetails.getAllowCompoundingOnEod(),
|
||||
loanProductInterestRecalculationDetails.getDisallowInterestCalculationOnPastDue(),
|
||||
loanProductInterestRecalculationDetails.getPreCloseInterestCalculationStrategy());
|
||||
}
|
||||
|
||||
|
||||
+3
-894
@@ -18,8 +18,6 @@
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanproduct.domain;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Embedded;
|
||||
@@ -40,7 +38,6 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -48,10 +45,8 @@ import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.fineract.accounting.common.AccountingRuleType;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
import org.apache.fineract.portfolio.charge.domain.Charge;
|
||||
@@ -65,7 +60,6 @@ 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.LoanChargeOffBehaviour;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.AprCalculator;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
|
||||
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||
@@ -234,267 +228,6 @@ public class LoanProduct extends AbstractPersistableCustom<Long> {
|
||||
@Column(name = "repayment_start_date_type_enum", nullable = false)
|
||||
private RepaymentStartDateType repaymentStartDateType;
|
||||
|
||||
public static LoanProduct assembleFromJson(final Fund fund, final String loanTransactionProcessingStrategy,
|
||||
final List<Charge> productCharges, final JsonCommand command, final AprCalculator aprCalculator, FloatingRate floatingRate,
|
||||
final List<Rate> productRates, List<LoanProductPaymentAllocationRule> loanProductPaymentAllocationRules,
|
||||
List<LoanProductCreditAllocationRule> loanProductCreditAllocationRules) {
|
||||
|
||||
final String name = command.stringValueOfParameterNamed("name");
|
||||
final String shortName = command.stringValueOfParameterNamed(LoanProductConstants.SHORT_NAME);
|
||||
final String description = command.stringValueOfParameterNamed("description");
|
||||
final String currencyCode = command.stringValueOfParameterNamed("currencyCode");
|
||||
final Integer digitsAfterDecimal = command.integerValueOfParameterNamed("digitsAfterDecimal");
|
||||
final Integer inMultiplesOf = command.integerValueOfParameterNamed("inMultiplesOf");
|
||||
|
||||
final MonetaryCurrency currency = new MonetaryCurrency(currencyCode, digitsAfterDecimal, inMultiplesOf);
|
||||
final BigDecimal principal = command.bigDecimalValueOfParameterNamed("principal");
|
||||
final BigDecimal minPrincipal = command.bigDecimalValueOfParameterNamed("minPrincipal");
|
||||
final BigDecimal maxPrincipal = command.bigDecimalValueOfParameterNamed("maxPrincipal");
|
||||
|
||||
final InterestMethod interestMethod = InterestMethod.fromInt(command.integerValueOfParameterNamed("interestType"));
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod = InterestCalculationPeriodMethod
|
||||
.fromInt(command.integerValueOfParameterNamed("interestCalculationPeriodType"));
|
||||
final boolean allowPartialPeriodInterestCalcualtion = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ALLOW_PARTIAL_PERIOD_INTEREST_CALCUALTION_PARAM_NAME);
|
||||
final AmortizationMethod amortizationMethod = AmortizationMethod.fromInt(command.integerValueOfParameterNamed("amortizationType"));
|
||||
final PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType
|
||||
.fromInt(command.integerValueOfParameterNamed("repaymentFrequencyType"));
|
||||
PeriodFrequencyType interestFrequencyType = PeriodFrequencyType.INVALID;
|
||||
BigDecimal interestRatePerPeriod = null;
|
||||
BigDecimal minInterestRatePerPeriod = null;
|
||||
BigDecimal maxInterestRatePerPeriod = null;
|
||||
BigDecimal annualInterestRate = null;
|
||||
BigDecimal interestRateDifferential = null;
|
||||
BigDecimal minDifferentialLendingRate = null;
|
||||
BigDecimal maxDifferentialLendingRate = null;
|
||||
BigDecimal defaultDifferentialLendingRate = null;
|
||||
Boolean isFloatingInterestRateCalculationAllowed = null;
|
||||
|
||||
Integer minimumGapBetweenInstallments = null;
|
||||
Integer maximumGapBetweenInstallments = null;
|
||||
|
||||
final Integer repaymentEvery = command.integerValueOfParameterNamed("repaymentEvery");
|
||||
final Integer numberOfRepayments = command.integerValueOfParameterNamed("numberOfRepayments");
|
||||
final Boolean isLinkedToFloatingInterestRates = command.booleanObjectValueOfParameterNamed("isLinkedToFloatingInterestRates");
|
||||
if (isLinkedToFloatingInterestRates != null && isLinkedToFloatingInterestRates) {
|
||||
interestRateDifferential = command.bigDecimalValueOfParameterNamed("interestRateDifferential");
|
||||
minDifferentialLendingRate = command.bigDecimalValueOfParameterNamed("minDifferentialLendingRate");
|
||||
maxDifferentialLendingRate = command.bigDecimalValueOfParameterNamed("maxDifferentialLendingRate");
|
||||
defaultDifferentialLendingRate = command.bigDecimalValueOfParameterNamed("defaultDifferentialLendingRate");
|
||||
isFloatingInterestRateCalculationAllowed = command
|
||||
.booleanObjectValueOfParameterNamed("isFloatingInterestRateCalculationAllowed");
|
||||
} else {
|
||||
interestFrequencyType = PeriodFrequencyType.fromInt(command.integerValueOfParameterNamed("interestRateFrequencyType"));
|
||||
interestRatePerPeriod = command.bigDecimalValueOfParameterNamed("interestRatePerPeriod");
|
||||
minInterestRatePerPeriod = command.bigDecimalValueOfParameterNamed("minInterestRatePerPeriod");
|
||||
maxInterestRatePerPeriod = command.bigDecimalValueOfParameterNamed("maxInterestRatePerPeriod");
|
||||
annualInterestRate = aprCalculator.calculateFrom(interestFrequencyType, interestRatePerPeriod, numberOfRepayments,
|
||||
repaymentEvery, repaymentFrequencyType);
|
||||
|
||||
}
|
||||
|
||||
final Boolean isVariableInstallmentsAllowed = command
|
||||
.booleanObjectValueOfParameterNamed(LoanProductConstants.allowVariableInstallmentsParamName);
|
||||
if (isVariableInstallmentsAllowed != null && isVariableInstallmentsAllowed) {
|
||||
minimumGapBetweenInstallments = command.integerValueOfParameterNamed(LoanProductConstants.minimumGapBetweenInstallments);
|
||||
maximumGapBetweenInstallments = command.integerValueOfParameterNamed(LoanProductConstants.maximumGapBetweenInstallments);
|
||||
}
|
||||
|
||||
final Integer minNumberOfRepayments = command.integerValueOfParameterNamed("minNumberOfRepayments");
|
||||
final Integer maxNumberOfRepayments = command.integerValueOfParameterNamed("maxNumberOfRepayments");
|
||||
final BigDecimal inArrearsTolerance = command.bigDecimalValueOfParameterNamed("inArrearsTolerance");
|
||||
|
||||
// grace details
|
||||
final Integer graceOnPrincipalPayment = command.integerValueOfParameterNamed("graceOnPrincipalPayment");
|
||||
final Integer recurringMoratoriumOnPrincipalPeriods = command.integerValueOfParameterNamed("recurringMoratoriumOnPrincipalPeriods");
|
||||
final Integer graceOnInterestPayment = command.integerValueOfParameterNamed("graceOnInterestPayment");
|
||||
final Integer graceOnInterestCharged = command.integerValueOfParameterNamed("graceOnInterestCharged");
|
||||
final Integer minimumDaysBetweenDisbursalAndFirstRepayment = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.MINIMUM_DAYS_BETWEEN_DISBURSAL_AND_FIRST_REPAYMENT);
|
||||
|
||||
final AccountingRuleType accountingRuleType = AccountingRuleType.fromInt(command.integerValueOfParameterNamed("accountingRule"));
|
||||
final boolean includeInBorrowerCycle = command.booleanPrimitiveValueOfParameterNamed("includeInBorrowerCycle");
|
||||
|
||||
final LocalDate startDate = command.localDateValueOfParameterNamed("startDate");
|
||||
final LocalDate closeDate = command.localDateValueOfParameterNamed("closeDate");
|
||||
final ExternalId externalId = ExternalIdFactory.produce(command.stringValueOfParameterNamedAllowingNull("externalId"));
|
||||
|
||||
final LoanScheduleType loanScheduleType;
|
||||
if (command.hasParameter("loanScheduleType")) {
|
||||
loanScheduleType = LoanScheduleType.valueOf(command.stringValueOfParameterNamed("loanScheduleType"));
|
||||
} else {
|
||||
// For backward compatibility
|
||||
loanScheduleType = LoanScheduleType.CUMULATIVE;
|
||||
}
|
||||
|
||||
final LoanScheduleProcessingType loanScheduleProcessingType;
|
||||
if (LoanScheduleType.PROGRESSIVE.equals(loanScheduleType) && command.hasParameter("loanScheduleProcessingType")) {
|
||||
loanScheduleProcessingType = LoanScheduleProcessingType
|
||||
.valueOf(command.stringValueOfParameterNamed("loanScheduleProcessingType"));
|
||||
} else {
|
||||
// For backward compatibility
|
||||
loanScheduleProcessingType = LoanScheduleProcessingType.HORIZONTAL;
|
||||
}
|
||||
|
||||
final boolean useBorrowerCycle = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.USE_BORROWER_CYCLE_PARAMETER_NAME);
|
||||
final Set<LoanProductBorrowerCycleVariations> loanProductBorrowerCycleVariations = new HashSet<>();
|
||||
|
||||
if (useBorrowerCycle) {
|
||||
populateBorrowerCycleVariations(command, loanProductBorrowerCycleVariations);
|
||||
}
|
||||
|
||||
final boolean multiDisburseLoan = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.MULTI_DISBURSE_LOAN_PARAMETER_NAME);
|
||||
Integer maxTrancheCount = null;
|
||||
BigDecimal outstandingLoanBalance = null;
|
||||
if (multiDisburseLoan) {
|
||||
outstandingLoanBalance = command.bigDecimalValueOfParameterNamed(LoanProductConstants.OUTSTANDING_LOAN_BALANCE_PARAMETER_NAME);
|
||||
maxTrancheCount = command.integerValueOfParameterNamed(LoanProductConstants.MAX_TRANCHE_COUNT_PARAMETER_NAME);
|
||||
}
|
||||
|
||||
final Integer graceOnArrearsAgeing = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME);
|
||||
|
||||
final Integer overdueDaysForNPA = command.integerValueOfParameterNamed(LoanProductConstants.OVERDUE_DAYS_FOR_NPA_PARAMETER_NAME);
|
||||
|
||||
// Interest recalculation settings
|
||||
final boolean isInterestRecalculationEnabled = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.IS_INTEREST_RECALCULATION_ENABLED_PARAMETER_NAME);
|
||||
final DaysInMonthType daysInMonthType = DaysInMonthType
|
||||
.fromInt(command.integerValueOfParameterNamed(LoanProductConstants.DAYS_IN_MONTH_TYPE_PARAMETER_NAME));
|
||||
|
||||
final DaysInYearType daysInYearType = DaysInYearType
|
||||
.fromInt(command.integerValueOfParameterNamed(LoanProductConstants.DAYS_IN_YEAR_TYPE_PARAMETER_NAME));
|
||||
|
||||
final DaysInYearCustomStrategyType daysInYearCustomStrategy = command.enumValueOfParameterNamed(
|
||||
LoanProductConstants.DAYS_IN_YEAR_CUSTOM_STRATEGY_TYPE_PARAMETER_NAME, DaysInYearCustomStrategyType.class);
|
||||
|
||||
LoanProductInterestRecalculationDetails interestRecalculationSettings = null;
|
||||
|
||||
if (isInterestRecalculationEnabled) {
|
||||
interestRecalculationSettings = LoanProductInterestRecalculationDetails.createFrom(command);
|
||||
}
|
||||
|
||||
final boolean holdGuarantorFunds = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.holdGuaranteeFundsParamName);
|
||||
LoanProductGuaranteeDetails loanProductGuaranteeDetails = null;
|
||||
if (holdGuarantorFunds) {
|
||||
loanProductGuaranteeDetails = LoanProductGuaranteeDetails.createFrom(command);
|
||||
}
|
||||
|
||||
LoanProductConfigurableAttributes loanConfigurableAttributes = null;
|
||||
if (command.parameterExists(LoanProductConstants.allowAttributeOverridesParamName)) {
|
||||
loanConfigurableAttributes = LoanProductConfigurableAttributes.createFrom(command);
|
||||
} else {
|
||||
loanConfigurableAttributes = LoanProductConfigurableAttributes.populateDefaultsForConfigurableAttributes();
|
||||
}
|
||||
|
||||
BigDecimal principalThresholdForLastInstallment = command
|
||||
.bigDecimalValueOfParameterNamed(LoanProductConstants.principalThresholdForLastInstallmentParamName);
|
||||
|
||||
if (principalThresholdForLastInstallment == null) {
|
||||
principalThresholdForLastInstallment = multiDisburseLoan
|
||||
? LoanProductConstants.DEFAULT_PRINCIPAL_THRESHOLD_FOR_MULTI_DISBURSE_LOAN
|
||||
: LoanProductConstants.DEFAULT_PRINCIPAL_THRESHOLD_FOR_SINGLE_DISBURSE_LOAN;
|
||||
}
|
||||
final boolean accountMovesOutOfNPAOnlyOnArrearsCompletion = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ACCOUNT_MOVES_OUT_OF_NPA_ONLY_ON_ARREARS_COMPLETION_PARAM_NAME);
|
||||
final boolean canDefineEmiAmount = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.canDefineEmiAmountParamName);
|
||||
final Integer installmentAmountInMultiplesOf = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.installmentAmountInMultiplesOfParamName);
|
||||
|
||||
final boolean syncExpectedWithDisbursementDate = command.booleanPrimitiveValueOfParameterNamed("syncExpectedWithDisbursementDate");
|
||||
|
||||
final boolean canUseForTopup = command.parameterExists(LoanProductConstants.CAN_USE_FOR_TOPUP)
|
||||
&& command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.CAN_USE_FOR_TOPUP);
|
||||
|
||||
final boolean isEqualAmortization = command.parameterExists(LoanProductConstants.IS_EQUAL_AMORTIZATION_PARAM)
|
||||
&& command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.IS_EQUAL_AMORTIZATION_PARAM);
|
||||
|
||||
BigDecimal fixedPrincipalPercentagePerInstallment = command
|
||||
.bigDecimalValueOfParameterNamed(LoanProductConstants.fixedPrincipalPercentagePerInstallmentParamName);
|
||||
|
||||
final boolean disallowExpectedDisbursements = command.parameterExists(LoanProductConstants.DISALLOW_EXPECTED_DISBURSEMENTS)
|
||||
&& command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.DISALLOW_EXPECTED_DISBURSEMENTS);
|
||||
|
||||
final boolean allowApprovedDisbursedAmountsOverApplied = command
|
||||
.parameterExists(LoanProductConstants.ALLOW_APPROVED_DISBURSED_AMOUNTS_OVER_APPLIED)
|
||||
&& command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ALLOW_APPROVED_DISBURSED_AMOUNTS_OVER_APPLIED);
|
||||
|
||||
final String overAppliedCalculationType = command
|
||||
.stringValueOfParameterNamedAllowingNull(LoanProductConstants.OVER_APPLIED_CALCULATION_TYPE);
|
||||
|
||||
final Integer overAppliedNumber = command.integerValueOfParameterNamed(LoanProductConstants.OVER_APPLIED_NUMBER);
|
||||
|
||||
final Integer dueDaysForRepaymentEvent = command.integerValueOfParameterNamed(LoanProductConstants.DUE_DAYS_FOR_REPAYMENT_EVENT);
|
||||
final Integer overDueDaysForRepaymentEvent = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.OVER_DUE_DAYS_FOR_REPAYMENT_EVENT);
|
||||
|
||||
final boolean enableDownPayment = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ENABLE_DOWN_PAYMENT);
|
||||
final BigDecimal disbursedAmountPercentageDownPayment = command
|
||||
.bigDecimalValueOfParameterNamed(LoanProductConstants.DISBURSED_AMOUNT_PERCENTAGE_DOWN_PAYMENT);
|
||||
final boolean enableAutoRepaymentForDownPayment = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ENABLE_AUTO_REPAYMENT_DOWN_PAYMENT);
|
||||
|
||||
final RepaymentStartDateType repaymentStartDateType = RepaymentStartDateType
|
||||
.fromInt(command.integerValueOfParameterNamed(LoanProductConstants.REPAYMENT_START_DATE_TYPE));
|
||||
|
||||
final boolean enableInstallmentLevelDelinquency = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY);
|
||||
|
||||
final Integer fixedLength = command.integerValueOfParameterNamed(LoanProductConstants.FIXED_LENGTH);
|
||||
|
||||
final boolean enableAccrualActivityPosting = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ENABLE_ACCRUAL_ACTIVITY_POSTING);
|
||||
|
||||
boolean interestRecognitionOnDisbursementDate = false;
|
||||
if (command.parameterExists(LoanProductConstants.INTEREST_RECOGNITION_ON_DISBURSEMENT_DATE)) {
|
||||
interestRecognitionOnDisbursementDate = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.INTEREST_RECOGNITION_ON_DISBURSEMENT_DATE);
|
||||
}
|
||||
|
||||
List<LoanSupportedInterestRefundTypes> supportedInterestRefundTypes = new ArrayList<>();
|
||||
if (command.parameterExists(LoanProductConstants.SUPPORTED_INTEREST_REFUND_TYPES)) {
|
||||
JsonArray supportedTransactionsForInterestRefund = command
|
||||
.arrayOfParameterNamed(LoanProductConstants.SUPPORTED_INTEREST_REFUND_TYPES);
|
||||
supportedTransactionsForInterestRefund.iterator().forEachRemaining(value -> {
|
||||
supportedInterestRefundTypes.add(LoanSupportedInterestRefundTypes.valueOf(value.getAsString()));
|
||||
});
|
||||
}
|
||||
|
||||
final LoanChargeOffBehaviour chargeOffBehaviour;
|
||||
if (command.parameterExists(LoanProductConstants.CHARGE_OFF_BEHAVIOUR)) {
|
||||
chargeOffBehaviour = LoanChargeOffBehaviour
|
||||
.valueOf(command.stringValueOfParameterNamed(LoanProductConstants.CHARGE_OFF_BEHAVIOUR));
|
||||
} else {
|
||||
// For backward compatibility
|
||||
chargeOffBehaviour = LoanChargeOffBehaviour.REGULAR;
|
||||
}
|
||||
|
||||
return new LoanProduct(fund, loanTransactionProcessingStrategy, loanProductPaymentAllocationRules, loanProductCreditAllocationRules,
|
||||
name, shortName, description, currency, principal, minPrincipal, maxPrincipal, interestRatePerPeriod,
|
||||
minInterestRatePerPeriod, maxInterestRatePerPeriod, interestFrequencyType, annualInterestRate, interestMethod,
|
||||
interestCalculationPeriodMethod, allowPartialPeriodInterestCalcualtion, repaymentEvery, repaymentFrequencyType,
|
||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, graceOnPrincipalPayment,
|
||||
recurringMoratoriumOnPrincipalPeriods, graceOnInterestPayment, graceOnInterestCharged, amortizationMethod,
|
||||
inArrearsTolerance, productCharges, accountingRuleType, includeInBorrowerCycle, startDate, closeDate, externalId,
|
||||
useBorrowerCycle, loanProductBorrowerCycleVariations, multiDisburseLoan, maxTrancheCount, outstandingLoanBalance,
|
||||
graceOnArrearsAgeing, overdueDaysForNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
|
||||
interestRecalculationSettings, minimumDaysBetweenDisbursalAndFirstRepayment, holdGuarantorFunds,
|
||||
loanProductGuaranteeDetails, principalThresholdForLastInstallment, accountMovesOutOfNPAOnlyOnArrearsCompletion,
|
||||
canDefineEmiAmount, installmentAmountInMultiplesOf, loanConfigurableAttributes, isLinkedToFloatingInterestRates,
|
||||
floatingRate, interestRateDifferential, minDifferentialLendingRate, maxDifferentialLendingRate,
|
||||
defaultDifferentialLendingRate, isFloatingInterestRateCalculationAllowed, isVariableInstallmentsAllowed,
|
||||
minimumGapBetweenInstallments, maximumGapBetweenInstallments, syncExpectedWithDisbursementDate, canUseForTopup,
|
||||
isEqualAmortization, productRates, fixedPrincipalPercentagePerInstallment, disallowExpectedDisbursements,
|
||||
allowApprovedDisbursedAmountsOverApplied, overAppliedCalculationType, overAppliedNumber, dueDaysForRepaymentEvent,
|
||||
overDueDaysForRepaymentEvent, enableDownPayment, disbursedAmountPercentageDownPayment, enableAutoRepaymentForDownPayment,
|
||||
repaymentStartDateType, enableInstallmentLevelDelinquency, loanScheduleType, loanScheduleProcessingType, fixedLength,
|
||||
enableAccrualActivityPosting, supportedInterestRefundTypes, chargeOffBehaviour, interestRecognitionOnDisbursementDate,
|
||||
daysInYearCustomStrategy);
|
||||
|
||||
}
|
||||
|
||||
public void updateLoanProductInRelatedClasses() {
|
||||
if (this.isInterestRecalculationEnabled()) {
|
||||
this.productInterestRecalculationDetails.updateProduct(this);
|
||||
@@ -504,170 +237,6 @@ public class LoanProduct extends AbstractPersistableCustom<Long> {
|
||||
}
|
||||
}
|
||||
|
||||
private static void populateBorrowerCycleVariations(final JsonCommand command,
|
||||
final Set<LoanProductBorrowerCycleVariations> loanProductBorrowerCycleVariations) {
|
||||
assemblePrincipalVariations(command, loanProductBorrowerCycleVariations);
|
||||
|
||||
assembleRepaymentVariations(command, loanProductBorrowerCycleVariations);
|
||||
|
||||
assembleInterestRateVariations(command, loanProductBorrowerCycleVariations);
|
||||
}
|
||||
|
||||
private static void assembleInterestRateVariations(final JsonCommand command,
|
||||
final Set<LoanProductBorrowerCycleVariations> loanProductBorrowerCycleVariations) {
|
||||
assembleVariations(command, loanProductBorrowerCycleVariations, LoanProductParamType.INTERESTRATE.getValue(),
|
||||
LoanProductConstants.INTEREST_RATE_VARIATIONS_FOR_BORROWER_CYCLE_PARAMETER_NAME);
|
||||
|
||||
}
|
||||
|
||||
private static void assembleRepaymentVariations(final JsonCommand command,
|
||||
final Set<LoanProductBorrowerCycleVariations> loanProductBorrowerCycleVariations) {
|
||||
assembleVariations(command, loanProductBorrowerCycleVariations, LoanProductParamType.REPAYMENT.getValue(),
|
||||
LoanProductConstants.NUMBER_OF_REPAYMENT_VARIATIONS_FOR_BORROWER_CYCLE_PARAMETER_NAME);
|
||||
|
||||
}
|
||||
|
||||
private static void assemblePrincipalVariations(final JsonCommand command,
|
||||
final Set<LoanProductBorrowerCycleVariations> loanProductBorrowerCycleVariations) {
|
||||
assembleVariations(command, loanProductBorrowerCycleVariations, LoanProductParamType.PRINCIPAL.getValue(),
|
||||
LoanProductConstants.PRINCIPAL_VARIATIONS_FOR_BORROWER_CYCLE_PARAMETER_NAME);
|
||||
}
|
||||
|
||||
private static void assembleVariations(final JsonCommand command,
|
||||
final Set<LoanProductBorrowerCycleVariations> loanProductBorrowerCycleVariations, Integer paramType,
|
||||
String variationParameterName) {
|
||||
if (command.parameterExists(variationParameterName)) {
|
||||
final JsonArray variationArray = command.arrayOfParameterNamed(variationParameterName);
|
||||
if (variationArray != null && variationArray.size() > 0) {
|
||||
int i = 0;
|
||||
do {
|
||||
final JsonObject jsonObject = variationArray.get(i).getAsJsonObject();
|
||||
BigDecimal defaultValue = null;
|
||||
BigDecimal minValue = null;
|
||||
BigDecimal maxValue = null;
|
||||
Integer cycleNumber = null;
|
||||
Integer valueUsageCondition = null;
|
||||
if (jsonObject.has(LoanProductConstants.DEFAULT_VALUE_PARAMETER_NAME)
|
||||
&& jsonObject.get(LoanProductConstants.DEFAULT_VALUE_PARAMETER_NAME).isJsonPrimitive()) {
|
||||
defaultValue = jsonObject.getAsJsonPrimitive(LoanProductConstants.DEFAULT_VALUE_PARAMETER_NAME).getAsBigDecimal();
|
||||
}
|
||||
if (jsonObject.has(LoanProductConstants.MIN_VALUE_PARAMETER_NAME)
|
||||
&& jsonObject.get(LoanProductConstants.MIN_VALUE_PARAMETER_NAME).isJsonPrimitive()
|
||||
&& StringUtils.isNotBlank(jsonObject.get(LoanProductConstants.MIN_VALUE_PARAMETER_NAME).getAsString())) {
|
||||
minValue = jsonObject.getAsJsonPrimitive(LoanProductConstants.MIN_VALUE_PARAMETER_NAME).getAsBigDecimal();
|
||||
}
|
||||
if (jsonObject.has(LoanProductConstants.MAX_VALUE_PARAMETER_NAME)
|
||||
&& jsonObject.get(LoanProductConstants.MAX_VALUE_PARAMETER_NAME).isJsonPrimitive()
|
||||
&& StringUtils.isNotBlank(jsonObject.get(LoanProductConstants.MAX_VALUE_PARAMETER_NAME).getAsString())) {
|
||||
maxValue = jsonObject.getAsJsonPrimitive(LoanProductConstants.MAX_VALUE_PARAMETER_NAME).getAsBigDecimal();
|
||||
}
|
||||
if (jsonObject.has(LoanProductConstants.BORROWER_CYCLE_NUMBER_PARAM_NAME)
|
||||
&& jsonObject.get(LoanProductConstants.BORROWER_CYCLE_NUMBER_PARAM_NAME).isJsonPrimitive()) {
|
||||
cycleNumber = jsonObject.getAsJsonPrimitive(LoanProductConstants.BORROWER_CYCLE_NUMBER_PARAM_NAME).getAsInt();
|
||||
}
|
||||
if (jsonObject.has(LoanProductConstants.VALUE_CONDITION_TYPE_PARAM_NAME)
|
||||
&& jsonObject.get(LoanProductConstants.VALUE_CONDITION_TYPE_PARAM_NAME).isJsonPrimitive()) {
|
||||
valueUsageCondition = jsonObject.getAsJsonPrimitive(LoanProductConstants.VALUE_CONDITION_TYPE_PARAM_NAME)
|
||||
.getAsInt();
|
||||
}
|
||||
LoanProductBorrowerCycleVariations borrowerCycleVariations = new LoanProductBorrowerCycleVariations(cycleNumber,
|
||||
paramType, valueUsageCondition, minValue, maxValue, defaultValue);
|
||||
loanProductBorrowerCycleVariations.add(borrowerCycleVariations);
|
||||
i++;
|
||||
} while (i < variationArray.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Object> updateBorrowerCycleVariations(final JsonCommand command) {
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<>(20);
|
||||
List<Long> variationIds = fetchAllVariationIds();
|
||||
updateBorrowerCycleVariations(command, LoanProductParamType.PRINCIPAL.getValue(),
|
||||
LoanProductConstants.PRINCIPAL_VARIATIONS_FOR_BORROWER_CYCLE_PARAMETER_NAME, actualChanges, variationIds);
|
||||
updateBorrowerCycleVariations(command, LoanProductParamType.INTERESTRATE.getValue(),
|
||||
LoanProductConstants.INTEREST_RATE_VARIATIONS_FOR_BORROWER_CYCLE_PARAMETER_NAME, actualChanges, variationIds);
|
||||
updateBorrowerCycleVariations(command, LoanProductParamType.REPAYMENT.getValue(),
|
||||
LoanProductConstants.NUMBER_OF_REPAYMENT_VARIATIONS_FOR_BORROWER_CYCLE_PARAMETER_NAME, actualChanges, variationIds);
|
||||
for (Long id : variationIds) {
|
||||
this.borrowerCycleVariations.remove(fetchLoanProductBorrowerCycleVariationById(id));
|
||||
}
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
private List<Long> fetchAllVariationIds() {
|
||||
List<Long> list = new ArrayList<>();
|
||||
for (LoanProductBorrowerCycleVariations cycleVariation : this.borrowerCycleVariations) {
|
||||
list.add(cycleVariation.getId());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private void updateBorrowerCycleVariations(final JsonCommand command, Integer paramType, String variationParameterName,
|
||||
final Map<String, Object> actualChanges, List<Long> variationIds) {
|
||||
if (command.parameterExists(variationParameterName)) {
|
||||
final JsonArray variationArray = command.arrayOfParameterNamed(variationParameterName);
|
||||
if (variationArray != null && variationArray.size() > 0) {
|
||||
int i = 0;
|
||||
do {
|
||||
final JsonObject jsonObject = variationArray.get(i).getAsJsonObject();
|
||||
BigDecimal defaultValue = null;
|
||||
BigDecimal minValue = null;
|
||||
BigDecimal maxValue = null;
|
||||
Integer cycleNumber = null;
|
||||
Integer valueUsageCondition = null;
|
||||
Long id = null;
|
||||
if (jsonObject.has(LoanProductConstants.DEFAULT_VALUE_PARAMETER_NAME)
|
||||
&& jsonObject.get(LoanProductConstants.DEFAULT_VALUE_PARAMETER_NAME).isJsonPrimitive()) {
|
||||
defaultValue = jsonObject.getAsJsonPrimitive(LoanProductConstants.DEFAULT_VALUE_PARAMETER_NAME).getAsBigDecimal();
|
||||
}
|
||||
if (jsonObject.has(LoanProductConstants.MIN_VALUE_PARAMETER_NAME)
|
||||
&& jsonObject.get(LoanProductConstants.MIN_VALUE_PARAMETER_NAME).isJsonPrimitive()
|
||||
&& StringUtils.isNotBlank(jsonObject.get(LoanProductConstants.MIN_VALUE_PARAMETER_NAME).getAsString())) {
|
||||
minValue = jsonObject.getAsJsonPrimitive(LoanProductConstants.MIN_VALUE_PARAMETER_NAME).getAsBigDecimal();
|
||||
}
|
||||
if (jsonObject.has(LoanProductConstants.MAX_VALUE_PARAMETER_NAME)
|
||||
&& jsonObject.get(LoanProductConstants.MAX_VALUE_PARAMETER_NAME).isJsonPrimitive()
|
||||
&& StringUtils.isNotBlank(jsonObject.get(LoanProductConstants.MAX_VALUE_PARAMETER_NAME).getAsString())) {
|
||||
maxValue = jsonObject.getAsJsonPrimitive(LoanProductConstants.MAX_VALUE_PARAMETER_NAME).getAsBigDecimal();
|
||||
}
|
||||
if (jsonObject.has(LoanProductConstants.BORROWER_CYCLE_NUMBER_PARAM_NAME)
|
||||
&& jsonObject.get(LoanProductConstants.BORROWER_CYCLE_NUMBER_PARAM_NAME).isJsonPrimitive()) {
|
||||
cycleNumber = jsonObject.getAsJsonPrimitive(LoanProductConstants.BORROWER_CYCLE_NUMBER_PARAM_NAME).getAsInt();
|
||||
}
|
||||
if (jsonObject.has(LoanProductConstants.VALUE_CONDITION_TYPE_PARAM_NAME)
|
||||
&& jsonObject.get(LoanProductConstants.VALUE_CONDITION_TYPE_PARAM_NAME).isJsonPrimitive()) {
|
||||
valueUsageCondition = jsonObject.getAsJsonPrimitive(LoanProductConstants.VALUE_CONDITION_TYPE_PARAM_NAME)
|
||||
.getAsInt();
|
||||
}
|
||||
if (jsonObject.has(LoanProductConstants.BORROWER_CYCLE_ID_PARAMETER_NAME)
|
||||
&& jsonObject.get(LoanProductConstants.BORROWER_CYCLE_ID_PARAMETER_NAME).isJsonPrimitive() && StringUtils
|
||||
.isNotBlank(jsonObject.get(LoanProductConstants.BORROWER_CYCLE_ID_PARAMETER_NAME).getAsString())) {
|
||||
id = jsonObject.getAsJsonPrimitive(LoanProductConstants.BORROWER_CYCLE_ID_PARAMETER_NAME).getAsLong();
|
||||
}
|
||||
LoanProductBorrowerCycleVariations borrowerCycleVariations = new LoanProductBorrowerCycleVariations(cycleNumber,
|
||||
paramType, valueUsageCondition, minValue, maxValue, defaultValue);
|
||||
if (id == null) {
|
||||
borrowerCycleVariations.updateLoanProduct(this);
|
||||
this.borrowerCycleVariations.add(borrowerCycleVariations);
|
||||
actualChanges.put("borrowerCycleParamType", paramType);
|
||||
} else {
|
||||
variationIds.remove(id);
|
||||
LoanProductBorrowerCycleVariations existingCycleVariation = fetchLoanProductBorrowerCycleVariationById(id);
|
||||
if (!existingCycleVariation.equals(borrowerCycleVariations)) {
|
||||
existingCycleVariation.copy(borrowerCycleVariations);
|
||||
actualChanges.put("borrowerCycleId", id);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
} while (i < variationArray.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void clearVariations() {
|
||||
this.borrowerCycleVariations.clear();
|
||||
}
|
||||
|
||||
public LoanProduct() {
|
||||
this.loanProductRelatedDetail = null;
|
||||
this.loanProductMinMaxConstraints = null;
|
||||
@@ -951,456 +520,7 @@ public class LoanProduct extends AbstractPersistableCustom<Long> {
|
||||
return updated;
|
||||
}
|
||||
|
||||
public Map<String, Object> update(final JsonCommand command, final AprCalculator aprCalculator, FloatingRate floatingRate) {
|
||||
|
||||
final Map<String, Object> actualChanges = this.loanProductRelatedDetail.update(command, aprCalculator);
|
||||
actualChanges.putAll(loanProductMinMaxConstraints().update(command));
|
||||
|
||||
final String isLinkedToFloatingInterestRates = "isLinkedToFloatingInterestRates";
|
||||
if (command.isChangeInBooleanParameterNamed(isLinkedToFloatingInterestRates, this.isLinkedToFloatingInterestRate)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(isLinkedToFloatingInterestRates);
|
||||
actualChanges.put(isLinkedToFloatingInterestRates, newValue);
|
||||
this.isLinkedToFloatingInterestRate = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.ENABLE_ACCRUAL_ACTIVITY_POSTING,
|
||||
this.getLoanProductRelatedDetail().isEnableAccrualActivityPosting())) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ENABLE_ACCRUAL_ACTIVITY_POSTING);
|
||||
actualChanges.put(LoanProductConstants.ENABLE_ACCRUAL_ACTIVITY_POSTING, newValue);
|
||||
this.getLoanProductRelatedDetail().setEnableAccrualActivityPosting(newValue);
|
||||
}
|
||||
|
||||
if (this.isLinkedToFloatingInterestRate) {
|
||||
actualChanges.putAll(loanProductFloatingRates().update(command, floatingRate));
|
||||
this.loanProductRelatedDetail.updateForFloatingInterestRates();
|
||||
this.loanProductMinMaxConstraints.updateForFloatingInterestRates();
|
||||
} else {
|
||||
this.floatingRates = null;
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.allowVariableInstallmentsParamName,
|
||||
this.allowVariabeInstallments)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.allowVariableInstallmentsParamName);
|
||||
actualChanges.put(LoanProductConstants.allowVariableInstallmentsParamName, newValue);
|
||||
this.allowVariabeInstallments = newValue;
|
||||
}
|
||||
|
||||
if (this.allowVariabeInstallments) {
|
||||
actualChanges.putAll(loanProductVariableInstallmentConfig().update(command));
|
||||
} else {
|
||||
this.variableInstallmentConfig = null;
|
||||
}
|
||||
|
||||
final String accountingTypeParamName = "accountingRule";
|
||||
Integer currentValue = this.accountingRule == null ? null : this.accountingRule.getValue();
|
||||
if (command.isChangeInIntegerParameterNamed(accountingTypeParamName, currentValue)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(accountingTypeParamName);
|
||||
actualChanges.put(accountingTypeParamName, newValue);
|
||||
this.accountingRule = AccountingRuleType.fromInt(newValue);
|
||||
}
|
||||
|
||||
final String nameParamName = "name";
|
||||
if (command.isChangeInStringParameterNamed(nameParamName, this.name)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(nameParamName);
|
||||
actualChanges.put(nameParamName, newValue);
|
||||
this.name = newValue;
|
||||
}
|
||||
|
||||
final String shortNameParamName = LoanProductConstants.SHORT_NAME;
|
||||
if (command.isChangeInStringParameterNamed(shortNameParamName, this.shortName)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(shortNameParamName);
|
||||
actualChanges.put(shortNameParamName, newValue);
|
||||
this.shortName = newValue;
|
||||
}
|
||||
|
||||
final String descriptionParamName = "description";
|
||||
if (command.isChangeInStringParameterNamed(descriptionParamName, this.description)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(descriptionParamName);
|
||||
actualChanges.put(descriptionParamName, newValue);
|
||||
this.description = newValue;
|
||||
}
|
||||
|
||||
Long existingFundId = null;
|
||||
if (this.fund != null) {
|
||||
existingFundId = this.fund.getId();
|
||||
}
|
||||
final String fundIdParamName = "fundId";
|
||||
if (command.isChangeInLongParameterNamed(fundIdParamName, existingFundId)) {
|
||||
final Long newValue = command.longValueOfParameterNamed(fundIdParamName);
|
||||
actualChanges.put(fundIdParamName, newValue);
|
||||
}
|
||||
|
||||
final String transactionProcessingStrategyCodeParamName = "transactionProcessingStrategyCode";
|
||||
if (command.isChangeInStringParameterNamed(transactionProcessingStrategyCodeParamName, this.transactionProcessingStrategyCode)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(transactionProcessingStrategyCodeParamName);
|
||||
actualChanges.put(transactionProcessingStrategyCodeParamName, newValue);
|
||||
}
|
||||
|
||||
final String paymentAllocationParamName = "paymentAllocation";
|
||||
if (command.hasParameter(paymentAllocationParamName)) {
|
||||
final JsonArray jsonArray = command.arrayOfParameterNamed(paymentAllocationParamName);
|
||||
if (jsonArray != null) {
|
||||
actualChanges.put(paymentAllocationParamName, command.jsonFragment(paymentAllocationParamName));
|
||||
}
|
||||
}
|
||||
|
||||
final String creditAllocationParamName = "creditAllocation";
|
||||
if (command.hasParameter(creditAllocationParamName)) {
|
||||
final JsonArray jsonArray = command.arrayOfParameterNamed(creditAllocationParamName);
|
||||
if (jsonArray != null) {
|
||||
actualChanges.put(creditAllocationParamName, command.jsonFragment(creditAllocationParamName));
|
||||
}
|
||||
}
|
||||
|
||||
final String chargesParamName = "charges";
|
||||
if (command.hasParameter(chargesParamName)) {
|
||||
final JsonArray jsonArray = command.arrayOfParameterNamed(chargesParamName);
|
||||
if (jsonArray != null) {
|
||||
actualChanges.put(chargesParamName, command.jsonFragment(chargesParamName));
|
||||
}
|
||||
}
|
||||
|
||||
final String includeInBorrowerCycleParamName = "includeInBorrowerCycle";
|
||||
if (command.isChangeInBooleanParameterNamed(includeInBorrowerCycleParamName, this.includeInBorrowerCycle)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(includeInBorrowerCycleParamName);
|
||||
actualChanges.put(includeInBorrowerCycleParamName, newValue);
|
||||
this.includeInBorrowerCycle = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.USE_BORROWER_CYCLE_PARAMETER_NAME, this.useBorrowerCycle)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.USE_BORROWER_CYCLE_PARAMETER_NAME);
|
||||
actualChanges.put(LoanProductConstants.USE_BORROWER_CYCLE_PARAMETER_NAME, newValue);
|
||||
this.useBorrowerCycle = newValue;
|
||||
}
|
||||
|
||||
if (this.useBorrowerCycle) {
|
||||
actualChanges.putAll(updateBorrowerCycleVariations(command));
|
||||
} else {
|
||||
clearVariations();
|
||||
}
|
||||
final String dateFormatAsInput = command.dateFormat();
|
||||
final String localeAsInput = command.locale();
|
||||
|
||||
final String localeParamName = "locale";
|
||||
final String dateFormatParamName = "dateFormat";
|
||||
|
||||
final String startDateParamName = "startDate";
|
||||
if (command.isChangeInLocalDateParameterNamed(startDateParamName, getStartDate())) {
|
||||
final String valueAsInput = command.stringValueOfParameterNamed(startDateParamName);
|
||||
actualChanges.put(startDateParamName, valueAsInput);
|
||||
actualChanges.put(dateFormatParamName, dateFormatAsInput);
|
||||
actualChanges.put(localeParamName, localeAsInput);
|
||||
|
||||
this.startDate = command.localDateValueOfParameterNamed(startDateParamName);
|
||||
}
|
||||
|
||||
final String closeDateParamName = "closeDate";
|
||||
if (command.isChangeInLocalDateParameterNamed(closeDateParamName, getCloseDate())) {
|
||||
final String valueAsInput = command.stringValueOfParameterNamed(closeDateParamName);
|
||||
actualChanges.put(closeDateParamName, valueAsInput);
|
||||
actualChanges.put(dateFormatParamName, dateFormatAsInput);
|
||||
actualChanges.put(localeParamName, localeAsInput);
|
||||
|
||||
this.closeDate = command.localDateValueOfParameterNamed(closeDateParamName);
|
||||
}
|
||||
|
||||
final String externalIdTypeParamName = "externalId";
|
||||
if (command.isChangeInExternalIdParameterNamed(externalIdTypeParamName, this.externalId)) {
|
||||
final ExternalId newValue = ExternalIdFactory.produce(command.stringValueOfParameterNamed(externalIdTypeParamName));
|
||||
actualChanges.put(accountingTypeParamName, newValue);
|
||||
this.externalId = newValue;
|
||||
}
|
||||
loanProductTrancheDetails.update(command, actualChanges, localeAsInput);
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.OVERDUE_DAYS_FOR_NPA_PARAMETER_NAME, this.overdueDaysForNPA)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.OVERDUE_DAYS_FOR_NPA_PARAMETER_NAME);
|
||||
actualChanges.put(LoanProductConstants.OVERDUE_DAYS_FOR_NPA_PARAMETER_NAME, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.overdueDaysForNPA = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.MINIMUM_DAYS_BETWEEN_DISBURSAL_AND_FIRST_REPAYMENT,
|
||||
this.minimumDaysBetweenDisbursalAndFirstRepayment)) {
|
||||
final Integer newValue = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.MINIMUM_DAYS_BETWEEN_DISBURSAL_AND_FIRST_REPAYMENT);
|
||||
actualChanges.put(LoanProductConstants.MINIMUM_DAYS_BETWEEN_DISBURSAL_AND_FIRST_REPAYMENT, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.minimumDaysBetweenDisbursalAndFirstRepayment = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed("syncExpectedWithDisbursementDate", this.syncExpectedWithDisbursementDate)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed("syncExpectedWithDisbursementDate");
|
||||
actualChanges.put("syncExpectedWithDisbursementDate", newValue);
|
||||
this.syncExpectedWithDisbursementDate = newValue;
|
||||
}
|
||||
|
||||
Long delinquencyBucketId = null;
|
||||
if (this.delinquencyBucket != null) {
|
||||
delinquencyBucketId = this.delinquencyBucket.getId();
|
||||
}
|
||||
if (command.isChangeInLongParameterNamed(LoanProductConstants.DELINQUENCY_BUCKET_PARAM_NAME, delinquencyBucketId)) {
|
||||
final Long newValue = command.longValueOfParameterNamed(LoanProductConstants.DELINQUENCY_BUCKET_PARAM_NAME);
|
||||
actualChanges.put(LoanProductConstants.DELINQUENCY_BUCKET_PARAM_NAME, newValue);
|
||||
}
|
||||
|
||||
// Update interest recalculation settings
|
||||
final boolean isInterestRecalculationEnabledChanged = actualChanges
|
||||
.containsKey(LoanProductConstants.IS_INTEREST_RECALCULATION_ENABLED_PARAMETER_NAME);
|
||||
|
||||
if (isInterestRecalculationEnabledChanged) {
|
||||
if (this.isInterestRecalculationEnabled()) {
|
||||
this.productInterestRecalculationDetails = LoanProductInterestRecalculationDetails.createFrom(command);
|
||||
this.productInterestRecalculationDetails.updateProduct(this);
|
||||
actualChanges.put(LoanProductConstants.interestRecalculationCompoundingMethodParameterName,
|
||||
command.integerValueOfParameterNamed(LoanProductConstants.interestRecalculationCompoundingMethodParameterName));
|
||||
actualChanges.put(LoanProductConstants.rescheduleStrategyMethodParameterName,
|
||||
command.integerValueOfParameterNamed(LoanProductConstants.rescheduleStrategyMethodParameterName));
|
||||
} else {
|
||||
this.productInterestRecalculationDetails = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isInterestRecalculationEnabledChanged && this.isInterestRecalculationEnabled()) {
|
||||
this.productInterestRecalculationDetails.update(command, actualChanges, localeAsInput);
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.holdGuaranteeFundsParamName, this.holdGuaranteeFunds)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.holdGuaranteeFundsParamName);
|
||||
actualChanges.put(LoanProductConstants.holdGuaranteeFundsParamName, newValue);
|
||||
this.holdGuaranteeFunds = newValue;
|
||||
}
|
||||
|
||||
final String configurableAttributesChanges = LoanProductConstants.allowAttributeOverridesParamName;
|
||||
if (command.hasParameter(configurableAttributesChanges)) {
|
||||
if (!command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.isJsonNull()) {
|
||||
actualChanges.put(configurableAttributesChanges, command.jsonFragment(configurableAttributesChanges));
|
||||
|
||||
if (command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.amortizationTypeParamName)
|
||||
.getAsBoolean() != this.loanConfigurableAttributes.getAmortizationBoolean()) {
|
||||
this.loanConfigurableAttributes.setAmortizationType(
|
||||
command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.amortizationTypeParamName).getAsBoolean());
|
||||
}
|
||||
|
||||
if (command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.interestTypeParamName)
|
||||
.getAsBoolean() != this.loanConfigurableAttributes.getInterestMethodBoolean()) {
|
||||
this.loanConfigurableAttributes.setInterestType(
|
||||
command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.interestTypeParamName).getAsBoolean());
|
||||
}
|
||||
|
||||
if (command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.transactionProcessingStrategyCodeParamName)
|
||||
.getAsBoolean() != this.loanConfigurableAttributes.getTransactionProcessingStrategyBoolean()) {
|
||||
this.loanConfigurableAttributes.setTransactionProcessingStrategyCode(
|
||||
command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.transactionProcessingStrategyCodeParamName).getAsBoolean());
|
||||
}
|
||||
|
||||
if (command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.interestCalculationPeriodTypeParamName)
|
||||
.getAsBoolean() != this.loanConfigurableAttributes.getInterestCalcPeriodBoolean()) {
|
||||
this.loanConfigurableAttributes.setInterestCalculationPeriodType(
|
||||
command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.interestCalculationPeriodTypeParamName).getAsBoolean());
|
||||
}
|
||||
|
||||
if (command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.inArrearsToleranceParamName)
|
||||
.getAsBoolean() != this.loanConfigurableAttributes.getArrearsToleranceBoolean()) {
|
||||
this.loanConfigurableAttributes.setInArrearsTolerance(
|
||||
command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.inArrearsToleranceParamName).getAsBoolean());
|
||||
}
|
||||
|
||||
if (command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.repaymentEveryParamName)
|
||||
.getAsBoolean() != this.loanConfigurableAttributes.getRepaymentEveryBoolean()) {
|
||||
this.loanConfigurableAttributes.setRepaymentEvery(
|
||||
command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.repaymentEveryParamName).getAsBoolean());
|
||||
}
|
||||
|
||||
if (command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.graceOnPrincipalAndInterestPaymentParamName)
|
||||
.getAsBoolean() != this.loanConfigurableAttributes.getGraceOnPrincipalAndInterestPaymentBoolean()) {
|
||||
this.loanConfigurableAttributes.setGraceOnPrincipalAndInterestPayment(
|
||||
command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.graceOnPrincipalAndInterestPaymentParamName).getAsBoolean());
|
||||
}
|
||||
|
||||
if (command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME)
|
||||
.getAsBoolean() != this.loanConfigurableAttributes.getGraceOnArrearsAgingBoolean()) {
|
||||
this.loanConfigurableAttributes.setGraceOnArrearsAgeing(
|
||||
command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME).getAsBoolean());
|
||||
}
|
||||
} else {
|
||||
this.loanConfigurableAttributes = LoanProductConfigurableAttributes.populateDefaultsForConfigurableAttributes();
|
||||
this.loanConfigurableAttributes.updateLoanProduct(this);
|
||||
}
|
||||
}
|
||||
|
||||
if (actualChanges.containsKey(LoanProductConstants.holdGuaranteeFundsParamName)) {
|
||||
if (this.holdGuaranteeFunds) {
|
||||
this.loanProductGuaranteeDetails = LoanProductGuaranteeDetails.createFrom(command);
|
||||
this.loanProductGuaranteeDetails.updateProduct(this);
|
||||
actualChanges.put(LoanProductConstants.mandatoryGuaranteeParamName,
|
||||
this.loanProductGuaranteeDetails.getMandatoryGuarantee());
|
||||
actualChanges.put(LoanProductConstants.minimumGuaranteeFromGuarantorParamName,
|
||||
this.loanProductGuaranteeDetails.getMinimumGuaranteeFromGuarantor());
|
||||
actualChanges.put(LoanProductConstants.minimumGuaranteeFromOwnFundsParamName,
|
||||
this.loanProductGuaranteeDetails.getMinimumGuaranteeFromOwnFunds());
|
||||
} else {
|
||||
this.loanProductGuaranteeDetails = null;
|
||||
}
|
||||
|
||||
} else if (this.holdGuaranteeFunds) {
|
||||
this.loanProductGuaranteeDetails.update(command, actualChanges);
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamed(LoanProductConstants.principalThresholdForLastInstallmentParamName,
|
||||
this.principalThresholdForLastInstallment)) {
|
||||
BigDecimal newValue = command
|
||||
.bigDecimalValueOfParameterNamed(LoanProductConstants.principalThresholdForLastInstallmentParamName);
|
||||
actualChanges.put(LoanProductConstants.principalThresholdForLastInstallmentParamName, newValue);
|
||||
this.principalThresholdForLastInstallment = newValue;
|
||||
}
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.ACCOUNT_MOVES_OUT_OF_NPA_ONLY_ON_ARREARS_COMPLETION_PARAM_NAME,
|
||||
this.accountMovesOutOfNPAOnlyOnArrearsCompletion)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(
|
||||
LoanProductConstants.ACCOUNT_MOVES_OUT_OF_NPA_ONLY_ON_ARREARS_COMPLETION_PARAM_NAME);
|
||||
actualChanges.put(LoanProductConstants.ACCOUNT_MOVES_OUT_OF_NPA_ONLY_ON_ARREARS_COMPLETION_PARAM_NAME, newValue);
|
||||
this.accountMovesOutOfNPAOnlyOnArrearsCompletion = newValue;
|
||||
}
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.canDefineEmiAmountParamName, this.canDefineInstallmentAmount)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.canDefineEmiAmountParamName);
|
||||
actualChanges.put(LoanProductConstants.canDefineEmiAmountParamName, newValue);
|
||||
this.canDefineInstallmentAmount = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamedWithNullCheck(LoanProductConstants.installmentAmountInMultiplesOfParamName,
|
||||
this.installmentAmountInMultiplesOf)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.installmentAmountInMultiplesOfParamName);
|
||||
actualChanges.put(LoanProductConstants.installmentAmountInMultiplesOfParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.installmentAmountInMultiplesOf = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.CAN_USE_FOR_TOPUP, this.canUseForTopup)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.CAN_USE_FOR_TOPUP);
|
||||
actualChanges.put(LoanProductConstants.CAN_USE_FOR_TOPUP, newValue);
|
||||
this.canUseForTopup = newValue;
|
||||
}
|
||||
|
||||
if (command.hasParameter(LoanProductConstants.RATES_PARAM_NAME)) {
|
||||
final JsonArray jsonArray = command.arrayOfParameterNamed(LoanProductConstants.RATES_PARAM_NAME);
|
||||
if (jsonArray != null) {
|
||||
actualChanges.put(LoanProductConstants.RATES_PARAM_NAME, command.jsonFragment(LoanProductConstants.RATES_PARAM_NAME));
|
||||
}
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamed(LoanProductConstants.fixedPrincipalPercentagePerInstallmentParamName,
|
||||
this.fixedPrincipalPercentagePerInstallment)) {
|
||||
BigDecimal newValue = command
|
||||
.bigDecimalValueOfParameterNamed(LoanProductConstants.fixedPrincipalPercentagePerInstallmentParamName);
|
||||
actualChanges.put(LoanProductConstants.fixedPrincipalPercentagePerInstallmentParamName, newValue);
|
||||
this.fixedPrincipalPercentagePerInstallment = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.DISALLOW_EXPECTED_DISBURSEMENTS,
|
||||
this.disallowExpectedDisbursements)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.DISALLOW_EXPECTED_DISBURSEMENTS);
|
||||
actualChanges.put(LoanProductConstants.DISALLOW_EXPECTED_DISBURSEMENTS, newValue);
|
||||
this.disallowExpectedDisbursements = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.ALLOW_APPROVED_DISBURSED_AMOUNTS_OVER_APPLIED,
|
||||
this.allowApprovedDisbursedAmountsOverApplied)) {
|
||||
final boolean newValue = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ALLOW_APPROVED_DISBURSED_AMOUNTS_OVER_APPLIED);
|
||||
actualChanges.put(LoanProductConstants.ALLOW_APPROVED_DISBURSED_AMOUNTS_OVER_APPLIED, newValue);
|
||||
this.allowApprovedDisbursedAmountsOverApplied = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInStringParameterNamed(LoanProductConstants.OVER_APPLIED_CALCULATION_TYPE, this.overAppliedCalculationType)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(LoanProductConstants.OVER_APPLIED_CALCULATION_TYPE);
|
||||
actualChanges.put(LoanProductConstants.OVER_APPLIED_CALCULATION_TYPE, newValue);
|
||||
this.overAppliedCalculationType = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.OVER_APPLIED_NUMBER, this.overAppliedNumber)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.OVER_APPLIED_NUMBER);
|
||||
actualChanges.put(LoanProductConstants.OVER_APPLIED_NUMBER, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.overAppliedNumber = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.DUE_DAYS_FOR_REPAYMENT_EVENT, this.dueDaysForRepaymentEvent)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.DUE_DAYS_FOR_REPAYMENT_EVENT);
|
||||
actualChanges.put(LoanProductConstants.DUE_DAYS_FOR_REPAYMENT_EVENT, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.dueDaysForRepaymentEvent = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.OVER_DUE_DAYS_FOR_REPAYMENT_EVENT,
|
||||
this.overDueDaysForRepaymentEvent)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.OVER_DUE_DAYS_FOR_REPAYMENT_EVENT);
|
||||
actualChanges.put(LoanProductConstants.OVER_DUE_DAYS_FOR_REPAYMENT_EVENT, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.overDueDaysForRepaymentEvent = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.ENABLE_DOWN_PAYMENT,
|
||||
this.loanProductRelatedDetail.isEnableDownPayment())) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ENABLE_DOWN_PAYMENT);
|
||||
actualChanges.put(LoanProductConstants.ENABLE_DOWN_PAYMENT, newValue);
|
||||
this.loanProductRelatedDetail.setEnableDownPayment(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamed(LoanProductConstants.DISBURSED_AMOUNT_PERCENTAGE_DOWN_PAYMENT,
|
||||
this.loanProductRelatedDetail.getDisbursedAmountPercentageForDownPayment())) {
|
||||
BigDecimal newValue = command.bigDecimalValueOfParameterNamed(LoanProductConstants.DISBURSED_AMOUNT_PERCENTAGE_DOWN_PAYMENT);
|
||||
actualChanges.put(LoanProductConstants.DISBURSED_AMOUNT_PERCENTAGE_DOWN_PAYMENT, newValue);
|
||||
this.loanProductRelatedDetail.setDisbursedAmountPercentageForDownPayment(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.ENABLE_AUTO_REPAYMENT_DOWN_PAYMENT,
|
||||
this.loanProductRelatedDetail.isEnableAutoRepaymentForDownPayment())) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ENABLE_AUTO_REPAYMENT_DOWN_PAYMENT);
|
||||
actualChanges.put(LoanProductConstants.ENABLE_AUTO_REPAYMENT_DOWN_PAYMENT, newValue);
|
||||
this.loanProductRelatedDetail.setEnableAutoRepaymentForDownPayment(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.REPAYMENT_START_DATE_TYPE,
|
||||
this.repaymentStartDateType.getValue())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.REPAYMENT_START_DATE_TYPE);
|
||||
actualChanges.put(LoanProductConstants.REPAYMENT_START_DATE_TYPE, newValue);
|
||||
this.repaymentStartDateType = RepaymentStartDateType.fromInt(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);
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.FIXED_LENGTH, loanProductRelatedDetail.getFixedLength())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.FIXED_LENGTH);
|
||||
actualChanges.put(LoanProductConstants.FIXED_LENGTH, newValue);
|
||||
loanProductRelatedDetail.setFixedLength(newValue);
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
private LoanProductFloatingRates loanProductFloatingRates() {
|
||||
public LoanProductFloatingRates loanProductFloatingRates() {
|
||||
this.floatingRates = this.floatingRates == null ? new LoanProductFloatingRates(null, this, null, null, null, null, false)
|
||||
: this.floatingRates;
|
||||
return this.floatingRates;
|
||||
@@ -1483,11 +603,11 @@ public class LoanProduct extends AbstractPersistableCustom<Long> {
|
||||
}
|
||||
|
||||
public BigDecimal outstandingLoanBalance() {
|
||||
return this.loanProductTrancheDetails.outstandingLoanBalance();
|
||||
return this.loanProductTrancheDetails.getOutstandingLoanBalance();
|
||||
}
|
||||
|
||||
public Integer maxTrancheCount() {
|
||||
return this.loanProductTrancheDetails.maxTrancheCount();
|
||||
return this.loanProductTrancheDetails.getMaxTrancheCount();
|
||||
}
|
||||
|
||||
public boolean isInterestRecalculationEnabled() {
|
||||
@@ -1498,17 +618,6 @@ public class LoanProduct extends AbstractPersistableCustom<Long> {
|
||||
return this.minimumDaysBetweenDisbursalAndFirstRepayment == null ? 0 : this.minimumDaysBetweenDisbursalAndFirstRepayment;
|
||||
}
|
||||
|
||||
public LoanProductBorrowerCycleVariations fetchLoanProductBorrowerCycleVariationById(Long id) {
|
||||
LoanProductBorrowerCycleVariations borrowerCycleVariation = null;
|
||||
for (LoanProductBorrowerCycleVariations cycleVariation : this.borrowerCycleVariations) {
|
||||
if (id.equals(cycleVariation.getId())) {
|
||||
borrowerCycleVariation = cycleVariation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return borrowerCycleVariation;
|
||||
}
|
||||
|
||||
public Map<String, BigDecimal> fetchBorrowerCycleVariationsForCycleNumber(final Integer cycleNumber) {
|
||||
Map<String, BigDecimal> borrowerCycleVariations = new HashMap<>();
|
||||
borrowerCycleVariations.put(LoanProductConstants.PRINCIPAL, this.loanProductRelatedDetail.getPrincipal().getAmount());
|
||||
|
||||
+4
-77
@@ -26,14 +26,15 @@ import jakarta.persistence.OneToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
import org.apache.fineract.portfolio.floatingrates.data.FloatingRateDTO;
|
||||
import org.apache.fineract.portfolio.floatingrates.data.FloatingRatePeriodData;
|
||||
import org.apache.fineract.portfolio.floatingrates.domain.FloatingRate;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Entity
|
||||
@Table(name = "m_product_loan_floating_rates")
|
||||
public class LoanProductFloatingRates extends AbstractPersistableCustom<Long> {
|
||||
@@ -77,80 +78,6 @@ public class LoanProductFloatingRates extends AbstractPersistableCustom<Long> {
|
||||
this.isFloatingInterestRateCalculationAllowed = isFloatingInterestRateCalculationAllowed;
|
||||
}
|
||||
|
||||
public LoanProduct getLoanProduct() {
|
||||
return this.loanProduct;
|
||||
}
|
||||
|
||||
public FloatingRate getFloatingRate() {
|
||||
return this.floatingRate;
|
||||
}
|
||||
|
||||
public BigDecimal getInterestRateDifferential() {
|
||||
return this.interestRateDifferential;
|
||||
}
|
||||
|
||||
public BigDecimal getMinDifferentialLendingRate() {
|
||||
return this.minDifferentialLendingRate;
|
||||
}
|
||||
|
||||
public BigDecimal getDefaultDifferentialLendingRate() {
|
||||
return this.defaultDifferentialLendingRate;
|
||||
}
|
||||
|
||||
public BigDecimal getMaxDifferentialLendingRate() {
|
||||
return this.maxDifferentialLendingRate;
|
||||
}
|
||||
|
||||
public boolean isFloatingInterestRateCalculationAllowed() {
|
||||
return this.isFloatingInterestRateCalculationAllowed;
|
||||
}
|
||||
|
||||
public Map<? extends String, ?> update(JsonCommand command, FloatingRate floatingRate) {
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<>(20);
|
||||
if (floatingRate != null) {
|
||||
final String floatingRatesId = "floatingRatesId";
|
||||
if (this.floatingRate == null || command.isChangeInLongParameterNamed(floatingRatesId, this.floatingRate.getId())) {
|
||||
final long newValue = command.longValueOfParameterNamed(floatingRatesId);
|
||||
actualChanges.put(floatingRatesId, newValue);
|
||||
this.floatingRate = floatingRate;
|
||||
}
|
||||
}
|
||||
|
||||
final String interestRateDifferential = "interestRateDifferential";
|
||||
if (command.isChangeInBigDecimalParameterNamed(interestRateDifferential, this.interestRateDifferential)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(interestRateDifferential);
|
||||
actualChanges.put(interestRateDifferential, newValue);
|
||||
this.interestRateDifferential = newValue;
|
||||
}
|
||||
final String minDifferentialLendingRate = "minDifferentialLendingRate";
|
||||
if (command.isChangeInBigDecimalParameterNamed(minDifferentialLendingRate, this.minDifferentialLendingRate)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(minDifferentialLendingRate);
|
||||
actualChanges.put(minDifferentialLendingRate, newValue);
|
||||
this.minDifferentialLendingRate = newValue;
|
||||
}
|
||||
final String defaultDifferentialLendingRate = "defaultDifferentialLendingRate";
|
||||
if (command.isChangeInBigDecimalParameterNamed(defaultDifferentialLendingRate, this.defaultDifferentialLendingRate)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(defaultDifferentialLendingRate);
|
||||
actualChanges.put(defaultDifferentialLendingRate, newValue);
|
||||
this.defaultDifferentialLendingRate = newValue;
|
||||
}
|
||||
final String maxDifferentialLendingRate = "maxDifferentialLendingRate";
|
||||
if (command.isChangeInBigDecimalParameterNamed(maxDifferentialLendingRate, this.maxDifferentialLendingRate)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(maxDifferentialLendingRate);
|
||||
actualChanges.put(maxDifferentialLendingRate, newValue);
|
||||
this.maxDifferentialLendingRate = newValue;
|
||||
}
|
||||
final String isFloatingInterestRateCalculationAllowed = "isFloatingInterestRateCalculationAllowed";
|
||||
if (command.isChangeInBooleanParameterNamed(isFloatingInterestRateCalculationAllowed,
|
||||
this.isFloatingInterestRateCalculationAllowed)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(isFloatingInterestRateCalculationAllowed);
|
||||
actualChanges.put(isFloatingInterestRateCalculationAllowed, newValue);
|
||||
this.isFloatingInterestRateCalculationAllowed = newValue;
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
public Collection<FloatingRatePeriodData> fetchInterestRates(final FloatingRateDTO floatingRateDTO) {
|
||||
floatingRateDTO.addInterestRateDiff(this.interestRateDifferential);
|
||||
return floatingRate.fetchInterestRates(floatingRateDTO);
|
||||
|
||||
+5
-52
@@ -24,10 +24,9 @@ import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Map;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||
|
||||
/**
|
||||
* Entity for capturing interest recalculation settings
|
||||
@@ -35,6 +34,8 @@ import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||
* @author conflux
|
||||
*/
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Table(name = "m_product_loan_guarantee_details")
|
||||
public class LoanProductGuaranteeDetails extends AbstractPersistableCustom<Long> {
|
||||
@@ -56,18 +57,7 @@ public class LoanProductGuaranteeDetails extends AbstractPersistableCustom<Long>
|
||||
//
|
||||
}
|
||||
|
||||
public static LoanProductGuaranteeDetails createFrom(final JsonCommand command) {
|
||||
|
||||
final BigDecimal mandatoryGuarantee = command.bigDecimalValueOfParameterNamed(LoanProductConstants.mandatoryGuaranteeParamName);
|
||||
final BigDecimal minimumGuaranteeFromGuarantor = command
|
||||
.bigDecimalValueOfParameterNamed(LoanProductConstants.minimumGuaranteeFromGuarantorParamName);
|
||||
final BigDecimal minimumGuaranteeFromOwnFunds = command
|
||||
.bigDecimalValueOfParameterNamed(LoanProductConstants.minimumGuaranteeFromOwnFundsParamName);
|
||||
|
||||
return new LoanProductGuaranteeDetails(mandatoryGuarantee, minimumGuaranteeFromOwnFunds, minimumGuaranteeFromGuarantor);
|
||||
}
|
||||
|
||||
private LoanProductGuaranteeDetails(final BigDecimal mandatoryGuarantee, final BigDecimal minimumGuaranteeFromOwnFunds,
|
||||
public LoanProductGuaranteeDetails(final BigDecimal mandatoryGuarantee, final BigDecimal minimumGuaranteeFromOwnFunds,
|
||||
final BigDecimal minimumGuaranteeFromGuarantor) {
|
||||
this.mandatoryGuarantee = mandatoryGuarantee;
|
||||
this.minimumGuaranteeFromGuarantor = minimumGuaranteeFromGuarantor;
|
||||
@@ -78,41 +68,4 @@ public class LoanProductGuaranteeDetails extends AbstractPersistableCustom<Long>
|
||||
this.loanProduct = loanProduct;
|
||||
}
|
||||
|
||||
public void update(final JsonCommand command, final Map<String, Object> actualChanges) {
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamed(LoanProductConstants.mandatoryGuaranteeParamName, this.mandatoryGuarantee)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(LoanProductConstants.mandatoryGuaranteeParamName);
|
||||
actualChanges.put(LoanProductConstants.mandatoryGuaranteeParamName, newValue);
|
||||
this.mandatoryGuarantee = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamed(LoanProductConstants.minimumGuaranteeFromGuarantorParamName,
|
||||
this.minimumGuaranteeFromGuarantor)) {
|
||||
final BigDecimal newValue = command
|
||||
.bigDecimalValueOfParameterNamed(LoanProductConstants.minimumGuaranteeFromGuarantorParamName);
|
||||
actualChanges.put(LoanProductConstants.minimumGuaranteeFromGuarantorParamName, newValue);
|
||||
this.minimumGuaranteeFromGuarantor = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamed(LoanProductConstants.minimumGuaranteeFromOwnFundsParamName,
|
||||
this.minimumGuaranteeFromOwnFunds)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(LoanProductConstants.minimumGuaranteeFromOwnFundsParamName);
|
||||
actualChanges.put(LoanProductConstants.minimumGuaranteeFromOwnFundsParamName, newValue);
|
||||
this.minimumGuaranteeFromOwnFunds = newValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public BigDecimal getMandatoryGuarantee() {
|
||||
return this.mandatoryGuarantee;
|
||||
}
|
||||
|
||||
public BigDecimal getMinimumGuaranteeFromOwnFunds() {
|
||||
return this.minimumGuaranteeFromOwnFunds;
|
||||
}
|
||||
|
||||
public BigDecimal getMinimumGuaranteeFromGuarantor() {
|
||||
return this.minimumGuaranteeFromGuarantor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+5
-341
@@ -23,10 +23,9 @@ import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import java.util.Map;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||
|
||||
/**
|
||||
* Entity for capturing interest recalculation settings
|
||||
@@ -34,6 +33,8 @@ import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||
* @author conflux
|
||||
*/
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Table(name = "m_product_loan_recalculation_details")
|
||||
public class LoanProductInterestRecalculationDetails extends AbstractPersistableCustom<Long> {
|
||||
@@ -103,79 +104,7 @@ public class LoanProductInterestRecalculationDetails extends AbstractPersistable
|
||||
//
|
||||
}
|
||||
|
||||
public static LoanProductInterestRecalculationDetails createFrom(final JsonCommand command) {
|
||||
|
||||
final Integer interestRecalculationCompoundingMethod = InterestRecalculationCompoundingMethod
|
||||
.fromInt(command.integerValueOfParameterNamed(LoanProductConstants.interestRecalculationCompoundingMethodParameterName))
|
||||
.getValue();
|
||||
|
||||
final Integer loanRescheduleStrategyMethod = LoanRescheduleStrategyMethod
|
||||
.fromInt(command.integerValueOfParameterNamed(LoanProductConstants.rescheduleStrategyMethodParameterName)).getValue();
|
||||
|
||||
final Integer recurrenceFrequency = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyTypeParameterName);
|
||||
final Integer recurrenceOnNthDay = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyNthDayParamName);
|
||||
final Integer recurrenceOnDay = command.integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyOnDayParamName);
|
||||
final Integer recurrenceOnWeekday = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyWeekdayParamName);
|
||||
Integer recurrenceInterval = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyIntervalParameterName);
|
||||
final boolean isArrearsBasedOnOriginalSchedule = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.isArrearsBasedOnOriginalScheduleParamName);
|
||||
RecalculationFrequencyType frequencyType = RecalculationFrequencyType.fromInt(recurrenceFrequency);
|
||||
if (frequencyType.isSameAsRepayment()) {
|
||||
recurrenceInterval = 0;
|
||||
}
|
||||
|
||||
InterestRecalculationCompoundingMethod compoundingMethod = InterestRecalculationCompoundingMethod
|
||||
.fromInt(interestRecalculationCompoundingMethod);
|
||||
Integer compoundingRecurrenceFrequency = null;
|
||||
Integer compoundingInterval = null;
|
||||
Integer compoundingRecurrenceOnNthDay = null;
|
||||
Integer compoundingRecurrenceOnDay = null;
|
||||
Integer compoundingRecurrenceOnWeekday = null;
|
||||
boolean allowCompoundingOnEod = false;
|
||||
if (compoundingMethod.isCompoundingEnabled()) {
|
||||
compoundingRecurrenceFrequency = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyTypeParameterName);
|
||||
compoundingInterval = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyIntervalParameterName);
|
||||
RecalculationFrequencyType compoundingFrequencyType = RecalculationFrequencyType.fromInt(compoundingRecurrenceFrequency);
|
||||
if (compoundingFrequencyType.isSameAsRepayment()) {
|
||||
recurrenceInterval = 0;
|
||||
}
|
||||
compoundingRecurrenceOnNthDay = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyNthDayParamName);
|
||||
compoundingRecurrenceOnDay = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyOnDayParamName);
|
||||
compoundingRecurrenceOnWeekday = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyWeekdayParamName);
|
||||
if (!compoundingFrequencyType.isDaily()) {
|
||||
allowCompoundingOnEod = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.allowCompoundingOnEodParamName);
|
||||
}
|
||||
}
|
||||
|
||||
Integer preCloseInterestCalculationStrategy = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.preClosureInterestCalculationStrategyParamName);
|
||||
if (preCloseInterestCalculationStrategy == null) {
|
||||
preCloseInterestCalculationStrategy = LoanPreCloseInterestCalculationStrategy.TILL_PRE_CLOSURE_DATE.getValue();
|
||||
}
|
||||
|
||||
final boolean isCompoundingToBePostedAsTransaction = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.isCompoundingToBePostedAsTransactionParamName);
|
||||
|
||||
final boolean disallowInterestCalculationOnPastDue = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.disallowInterestCalculationOnPastDueParamName);
|
||||
|
||||
return new LoanProductInterestRecalculationDetails(interestRecalculationCompoundingMethod, loanRescheduleStrategyMethod,
|
||||
recurrenceFrequency, recurrenceInterval, recurrenceOnNthDay, recurrenceOnDay, recurrenceOnWeekday,
|
||||
compoundingRecurrenceFrequency, compoundingInterval, compoundingRecurrenceOnNthDay, compoundingRecurrenceOnDay,
|
||||
compoundingRecurrenceOnWeekday, isArrearsBasedOnOriginalSchedule, preCloseInterestCalculationStrategy,
|
||||
isCompoundingToBePostedAsTransaction, allowCompoundingOnEod, disallowInterestCalculationOnPastDue);
|
||||
}
|
||||
|
||||
private LoanProductInterestRecalculationDetails(final Integer interestRecalculationCompoundingMethod,
|
||||
public LoanProductInterestRecalculationDetails(final Integer interestRecalculationCompoundingMethod,
|
||||
final Integer rescheduleStrategyMethod, final Integer restFrequencyType, final Integer restInterval,
|
||||
final Integer restFrequencyNthDay, final Integer restFrequencyOnDay, final Integer restFrequencyWeekday,
|
||||
Integer compoundingFrequencyType, Integer compoundingInterval, final Integer compoundingFrequencyNthDay,
|
||||
@@ -206,280 +135,15 @@ public class LoanProductInterestRecalculationDetails extends AbstractPersistable
|
||||
this.loanProduct = loanProduct;
|
||||
}
|
||||
|
||||
public Integer getInterestRecalculationCompoundingMethod() {
|
||||
return this.interestRecalculationCompoundingMethod;
|
||||
}
|
||||
|
||||
public Integer getRescheduleStrategyMethod() {
|
||||
return this.rescheduleStrategyMethod;
|
||||
}
|
||||
|
||||
public void update(final JsonCommand command, final Map<String, Object> actualChanges, final String localeAsInput) {
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.interestRecalculationCompoundingMethodParameterName,
|
||||
this.interestRecalculationCompoundingMethod)) {
|
||||
final Integer newValue = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.interestRecalculationCompoundingMethodParameterName);
|
||||
actualChanges.put(LoanProductConstants.interestRecalculationCompoundingMethodParameterName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.interestRecalculationCompoundingMethod = InterestRecalculationCompoundingMethod.fromInt(newValue).getValue();
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.rescheduleStrategyMethodParameterName,
|
||||
this.rescheduleStrategyMethod)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.rescheduleStrategyMethodParameterName);
|
||||
actualChanges.put(LoanProductConstants.rescheduleStrategyMethodParameterName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.rescheduleStrategyMethod = LoanRescheduleStrategyMethod.fromInt(newValue).getValue();
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationRestFrequencyTypeParameterName,
|
||||
this.restFrequencyType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyTypeParameterName);
|
||||
actualChanges.put(LoanProductConstants.recalculationRestFrequencyTypeParameterName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.restFrequencyType = RecalculationFrequencyType.fromInt(newValue).getValue();
|
||||
}
|
||||
RecalculationFrequencyType frequencyType = RecalculationFrequencyType.fromInt(this.restFrequencyType);
|
||||
if (frequencyType.isSameAsRepayment()) {
|
||||
this.restInterval = 0;
|
||||
this.restFrequencyNthDay = null;
|
||||
this.restFrequencyWeekday = null;
|
||||
this.restFrequencyOnDay = null;
|
||||
} else {
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationRestFrequencyIntervalParameterName,
|
||||
this.restInterval)) {
|
||||
Integer newValue = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyIntervalParameterName);
|
||||
actualChanges.put(LoanProductConstants.recalculationRestFrequencyIntervalParameterName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.restInterval = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationRestFrequencyNthDayParamName,
|
||||
getRestFrequencyNthDay())) {
|
||||
Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyNthDayParamName);
|
||||
actualChanges.put(LoanProductConstants.recalculationRestFrequencyNthDayParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.restFrequencyNthDay = newValue;
|
||||
this.restFrequencyOnDay = null;
|
||||
}
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationRestFrequencyWeekdayParamName,
|
||||
getRestFrequencyWeekday())) {
|
||||
Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyWeekdayParamName);
|
||||
actualChanges.put(LoanProductConstants.recalculationRestFrequencyWeekdayParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.restFrequencyWeekday = newValue;
|
||||
this.restFrequencyOnDay = null;
|
||||
}
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationRestFrequencyOnDayParamName,
|
||||
getRestFrequencyOnDay())) {
|
||||
Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyOnDayParamName);
|
||||
actualChanges.put(LoanProductConstants.recalculationRestFrequencyOnDayParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.restFrequencyOnDay = newValue;
|
||||
this.restFrequencyNthDay = null;
|
||||
this.restFrequencyWeekday = null;
|
||||
}
|
||||
|
||||
if (frequencyType.isWeekly()) {
|
||||
this.restFrequencyNthDay = null;
|
||||
this.restFrequencyOnDay = null;
|
||||
} else if (frequencyType.isMonthly()) {
|
||||
if (command.integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyOnDayParamName) != null) {
|
||||
this.restFrequencyNthDay = null;
|
||||
this.restFrequencyWeekday = null;
|
||||
} else {
|
||||
this.restFrequencyOnDay = null;
|
||||
}
|
||||
} else if (frequencyType.isDaily()) {
|
||||
this.restFrequencyNthDay = null;
|
||||
this.restFrequencyWeekday = null;
|
||||
this.restFrequencyOnDay = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyTypeParameterName,
|
||||
this.compoundingFrequencyType)) {
|
||||
final Integer newValue = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyTypeParameterName);
|
||||
actualChanges.put(LoanProductConstants.recalculationCompoundingFrequencyTypeParameterName, newValue);
|
||||
this.compoundingFrequencyType = RecalculationFrequencyType.fromInt(newValue).getValue();
|
||||
}
|
||||
|
||||
InterestRecalculationCompoundingMethod compoundingMethod = InterestRecalculationCompoundingMethod
|
||||
.fromInt(this.interestRecalculationCompoundingMethod);
|
||||
if (compoundingMethod.isCompoundingEnabled()) {
|
||||
RecalculationFrequencyType compoundingFrequencyType = RecalculationFrequencyType.fromInt(this.compoundingFrequencyType);
|
||||
if (compoundingFrequencyType.isSameAsRepayment()) {
|
||||
this.compoundingInterval = null;
|
||||
this.compoundingFrequencyNthDay = null;
|
||||
this.compoundingFrequencyWeekday = null;
|
||||
this.compoundingFrequencyOnDay = null;
|
||||
} else {
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyIntervalParameterName,
|
||||
this.compoundingInterval)) {
|
||||
Integer newValue = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyIntervalParameterName);
|
||||
actualChanges.put(LoanProductConstants.recalculationCompoundingFrequencyIntervalParameterName, newValue);
|
||||
this.compoundingInterval = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyNthDayParamName,
|
||||
getCompoundingFrequencyNthDay())) {
|
||||
Integer newValue = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyNthDayParamName);
|
||||
actualChanges.put(LoanProductConstants.recalculationCompoundingFrequencyNthDayParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.compoundingFrequencyNthDay = newValue;
|
||||
this.compoundingFrequencyOnDay = null;
|
||||
}
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyWeekdayParamName,
|
||||
getCompoundingFrequencyWeekday())) {
|
||||
Integer newValue = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyWeekdayParamName);
|
||||
actualChanges.put(LoanProductConstants.recalculationCompoundingFrequencyWeekdayParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.compoundingFrequencyWeekday = newValue;
|
||||
this.compoundingFrequencyOnDay = null;
|
||||
}
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyOnDayParamName,
|
||||
getCompoundingFrequencyOnDay())) {
|
||||
Integer newValue = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyOnDayParamName);
|
||||
actualChanges.put(LoanProductConstants.recalculationCompoundingFrequencyOnDayParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.compoundingFrequencyOnDay = newValue;
|
||||
this.compoundingFrequencyNthDay = null;
|
||||
this.compoundingFrequencyWeekday = null;
|
||||
}
|
||||
|
||||
if (compoundingFrequencyType.isWeekly()) {
|
||||
this.compoundingFrequencyNthDay = null;
|
||||
this.compoundingFrequencyOnDay = null;
|
||||
} else if (compoundingFrequencyType.isMonthly()) {
|
||||
if (command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyOnDayParamName) != null) {
|
||||
this.compoundingFrequencyNthDay = null;
|
||||
this.compoundingFrequencyWeekday = null;
|
||||
} else {
|
||||
this.compoundingFrequencyOnDay = null;
|
||||
}
|
||||
} else if (compoundingFrequencyType.isDaily()) {
|
||||
this.compoundingFrequencyNthDay = null;
|
||||
this.compoundingFrequencyWeekday = null;
|
||||
this.compoundingFrequencyOnDay = null;
|
||||
}
|
||||
}
|
||||
if (!compoundingFrequencyType.isDaily()) {
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.allowCompoundingOnEodParamName, allowCompoundingOnEod())) {
|
||||
boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.allowCompoundingOnEodParamName);
|
||||
actualChanges.put(LoanProductConstants.allowCompoundingOnEodParamName, newValue);
|
||||
this.allowCompoundingOnEod = newValue;
|
||||
}
|
||||
} else {
|
||||
this.allowCompoundingOnEod = false;
|
||||
}
|
||||
} else {
|
||||
this.compoundingFrequencyType = null;
|
||||
this.compoundingInterval = null;
|
||||
this.compoundingFrequencyNthDay = null;
|
||||
this.compoundingFrequencyWeekday = null;
|
||||
this.compoundingFrequencyOnDay = null;
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.isArrearsBasedOnOriginalScheduleParamName,
|
||||
this.isArrearsBasedOnOriginalSchedule)) {
|
||||
final boolean newValue = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.isArrearsBasedOnOriginalScheduleParamName);
|
||||
actualChanges.put(LoanProductConstants.isArrearsBasedOnOriginalScheduleParamName, newValue);
|
||||
this.isArrearsBasedOnOriginalSchedule = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.preClosureInterestCalculationStrategyParamName,
|
||||
this.preCloseInterestCalculationStrategy)) {
|
||||
Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.preClosureInterestCalculationStrategyParamName);
|
||||
if (newValue == null) {
|
||||
newValue = LoanPreCloseInterestCalculationStrategy.TILL_PRE_CLOSURE_DATE.getValue();
|
||||
}
|
||||
actualChanges.put(LoanProductConstants.preClosureInterestCalculationStrategyParamName, newValue);
|
||||
this.preCloseInterestCalculationStrategy = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.isCompoundingToBePostedAsTransactionParamName,
|
||||
this.isCompoundingToBePostedAsTransaction)) {
|
||||
final boolean newValue = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.isCompoundingToBePostedAsTransactionParamName);
|
||||
actualChanges.put(LoanProductConstants.isCompoundingToBePostedAsTransactionParamName, newValue);
|
||||
this.isCompoundingToBePostedAsTransaction = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.disallowInterestCalculationOnPastDueParamName,
|
||||
this.disallowInterestCalculationOnPastDue)) {
|
||||
final boolean newValue = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.disallowInterestCalculationOnPastDueParamName);
|
||||
actualChanges.put(LoanProductConstants.disallowInterestCalculationOnPastDueParamName, newValue);
|
||||
this.disallowInterestCalculationOnPastDue = newValue;
|
||||
}
|
||||
}
|
||||
|
||||
public RecalculationFrequencyType getRestFrequencyType() {
|
||||
return RecalculationFrequencyType.fromInt(this.restFrequencyType);
|
||||
}
|
||||
|
||||
public Integer getRestInterval() {
|
||||
return this.restInterval;
|
||||
}
|
||||
|
||||
public RecalculationFrequencyType getCompoundingFrequencyType() {
|
||||
return RecalculationFrequencyType.fromInt(this.compoundingFrequencyType);
|
||||
}
|
||||
|
||||
public Integer getCompoundingInterval() {
|
||||
return this.compoundingInterval;
|
||||
}
|
||||
|
||||
public boolean isArrearsBasedOnOriginalSchedule() {
|
||||
return this.isArrearsBasedOnOriginalSchedule;
|
||||
}
|
||||
|
||||
public LoanPreCloseInterestCalculationStrategy getPreCloseInterestCalculationStrategy() {
|
||||
return LoanPreCloseInterestCalculationStrategy.fromInt(this.preCloseInterestCalculationStrategy);
|
||||
}
|
||||
|
||||
public Integer getRestFrequencyNthDay() {
|
||||
return this.restFrequencyNthDay;
|
||||
}
|
||||
|
||||
public Integer getRestFrequencyWeekday() {
|
||||
return this.restFrequencyWeekday;
|
||||
}
|
||||
|
||||
public Integer getRestFrequencyOnDay() {
|
||||
return this.restFrequencyOnDay;
|
||||
}
|
||||
|
||||
public Integer getCompoundingFrequencyNthDay() {
|
||||
return this.compoundingFrequencyNthDay;
|
||||
}
|
||||
|
||||
public Integer getCompoundingFrequencyWeekday() {
|
||||
return this.compoundingFrequencyWeekday;
|
||||
}
|
||||
|
||||
public Integer getCompoundingFrequencyOnDay() {
|
||||
return this.compoundingFrequencyOnDay;
|
||||
}
|
||||
|
||||
public Boolean getIsCompoundingToBePostedAsTransaction() {
|
||||
return this.isCompoundingToBePostedAsTransaction;
|
||||
}
|
||||
|
||||
public Boolean allowCompoundingOnEod() {
|
||||
return this.allowCompoundingOnEod;
|
||||
}
|
||||
|
||||
public Boolean disallowInterestCalculationOnPastDue() {
|
||||
return disallowInterestCalculationOnPastDue;
|
||||
}
|
||||
}
|
||||
|
||||
-258
@@ -25,12 +25,9 @@ import jakarta.persistence.Embedded;
|
||||
import jakarta.persistence.EnumType;
|
||||
import jakarta.persistence.Enumerated;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
@@ -40,10 +37,8 @@ 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.LoanChargeOffBehaviour;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.AprCalculator;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
|
||||
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||
|
||||
/**
|
||||
* LoanRepaymentScheduleDetail encapsulates all the details of a {@link LoanProduct} that are also used and persisted by
|
||||
@@ -308,259 +303,6 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
return daysInYearCustomStrategy;
|
||||
}
|
||||
|
||||
// TODO: Move into assembler
|
||||
public Map<String, Object> update(final JsonCommand command, final AprCalculator aprCalculator) {
|
||||
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<>(20);
|
||||
|
||||
final String localeAsInput = command.locale();
|
||||
|
||||
String currencyCode = this.currency.getCode();
|
||||
Integer digitsAfterDecimal = this.currency.getDigitsAfterDecimal();
|
||||
Integer inMultiplesOf = this.currency.getCurrencyInMultiplesOf();
|
||||
|
||||
final String digitsAfterDecimalParamName = "digitsAfterDecimal";
|
||||
if (command.isChangeInIntegerParameterNamed(digitsAfterDecimalParamName, digitsAfterDecimal)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(digitsAfterDecimalParamName);
|
||||
actualChanges.put(digitsAfterDecimalParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
digitsAfterDecimal = newValue;
|
||||
this.currency = new MonetaryCurrency(currencyCode, digitsAfterDecimal, inMultiplesOf);
|
||||
}
|
||||
|
||||
final String currencyCodeParamName = "currencyCode";
|
||||
if (command.isChangeInStringParameterNamed(currencyCodeParamName, currencyCode)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(currencyCodeParamName);
|
||||
actualChanges.put(currencyCodeParamName, newValue);
|
||||
currencyCode = newValue;
|
||||
this.currency = new MonetaryCurrency(currencyCode, digitsAfterDecimal, inMultiplesOf);
|
||||
}
|
||||
|
||||
final String inMultiplesOfParamName = "inMultiplesOf";
|
||||
if (command.isChangeInStringParameterNamed(inMultiplesOfParamName, currencyCode)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(inMultiplesOfParamName);
|
||||
actualChanges.put(inMultiplesOfParamName, newValue);
|
||||
inMultiplesOf = newValue;
|
||||
this.currency = new MonetaryCurrency(currencyCode, digitsAfterDecimal, inMultiplesOf);
|
||||
}
|
||||
|
||||
final String loanScheduleTypeParamName = LoanProductConstants.LOAN_SCHEDULE_TYPE;
|
||||
if (command.isChangeInStringParameterNamed(loanScheduleTypeParamName, loanScheduleType.toString())) {
|
||||
LoanScheduleType newLoanScheduleType = LoanScheduleType.valueOf(command.stringValueOfParameterNamed(loanScheduleTypeParamName));
|
||||
actualChanges.put(loanScheduleTypeParamName, newLoanScheduleType);
|
||||
loanScheduleType = newLoanScheduleType;
|
||||
}
|
||||
|
||||
final String loanScheduleProcessingTypeParamName = LoanProductConstants.LOAN_SCHEDULE_PROCESSING_TYPE;
|
||||
if (command.isChangeInStringParameterNamed(loanScheduleProcessingTypeParamName, loanScheduleProcessingType.toString())) {
|
||||
LoanScheduleProcessingType newLoanScheduleProcessingType = LoanScheduleProcessingType
|
||||
.valueOf(command.stringValueOfParameterNamed(loanScheduleProcessingTypeParamName));
|
||||
actualChanges.put(loanScheduleProcessingTypeParamName, newLoanScheduleProcessingType);
|
||||
loanScheduleProcessingType = newLoanScheduleProcessingType;
|
||||
}
|
||||
|
||||
final String principalParamName = "principal";
|
||||
if (command.isChangeInBigDecimalParameterNamed(principalParamName, this.principal)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(principalParamName);
|
||||
actualChanges.put(principalParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.principal = newValue;
|
||||
}
|
||||
|
||||
final String repaymentEveryParamName = "repaymentEvery";
|
||||
if (command.isChangeInIntegerParameterNamed(repaymentEveryParamName, this.repayEvery)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(repaymentEveryParamName);
|
||||
actualChanges.put(repaymentEveryParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.repayEvery = newValue;
|
||||
}
|
||||
|
||||
final String repaymentFrequencyTypeParamName = "repaymentFrequencyType";
|
||||
if (command.isChangeInIntegerParameterNamed(repaymentFrequencyTypeParamName, this.repaymentPeriodFrequencyType.getValue())) {
|
||||
Integer newValue = command.integerValueOfParameterNamed(repaymentFrequencyTypeParamName);
|
||||
actualChanges.put(repaymentFrequencyTypeParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.repaymentPeriodFrequencyType = PeriodFrequencyType.fromInt(newValue);
|
||||
}
|
||||
if (this.repaymentPeriodFrequencyType == PeriodFrequencyType.MONTHS) {
|
||||
Integer newValue = null;
|
||||
final String repaymentFrequencyNthDayTypeParamName = "repaymentFrequencyNthDayType";
|
||||
newValue = command.integerValueOfParameterNamed(repaymentFrequencyNthDayTypeParamName);
|
||||
actualChanges.put(repaymentFrequencyNthDayTypeParamName, newValue);
|
||||
|
||||
final String repaymentFrequencyDayOfWeekTypeParamName = "repaymentFrequencyDayOfWeekType";
|
||||
newValue = command.integerValueOfParameterNamed(repaymentFrequencyDayOfWeekTypeParamName);
|
||||
actualChanges.put(repaymentFrequencyDayOfWeekTypeParamName, newValue);
|
||||
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
}
|
||||
|
||||
final String numberOfRepaymentsParamName = "numberOfRepayments";
|
||||
if (command.isChangeInIntegerParameterNamed(numberOfRepaymentsParamName, this.numberOfRepayments)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(numberOfRepaymentsParamName);
|
||||
actualChanges.put(numberOfRepaymentsParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.numberOfRepayments = newValue;
|
||||
}
|
||||
|
||||
final String amortizationTypeParamName = "amortizationType";
|
||||
if (command.isChangeInIntegerParameterNamed(amortizationTypeParamName, this.amortizationMethod.getValue())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(amortizationTypeParamName);
|
||||
actualChanges.put(amortizationTypeParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.amortizationMethod = AmortizationMethod.fromInt(newValue);
|
||||
}
|
||||
|
||||
final String inArrearsToleranceParamName = "inArrearsTolerance";
|
||||
if (command.isChangeInBigDecimalParameterNamed(inArrearsToleranceParamName, this.inArrearsTolerance)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(inArrearsToleranceParamName);
|
||||
actualChanges.put(inArrearsToleranceParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.inArrearsTolerance = newValue;
|
||||
}
|
||||
|
||||
final String interestRatePerPeriodParamName = "interestRatePerPeriod";
|
||||
if (command.isChangeInBigDecimalParameterNamed(interestRatePerPeriodParamName, this.nominalInterestRatePerPeriod)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(interestRatePerPeriodParamName);
|
||||
actualChanges.put(interestRatePerPeriodParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.nominalInterestRatePerPeriod = newValue;
|
||||
updateInterestRateDerivedFields(aprCalculator);
|
||||
}
|
||||
|
||||
final String interestRateFrequencyTypeParamName = "interestRateFrequencyType";
|
||||
final int interestPeriodFrequencyType = this.interestPeriodFrequencyType == null ? PeriodFrequencyType.INVALID.getValue()
|
||||
: this.interestPeriodFrequencyType.getValue();
|
||||
if (command.isChangeInIntegerParameterNamed(interestRateFrequencyTypeParamName, interestPeriodFrequencyType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(interestRateFrequencyTypeParamName);
|
||||
actualChanges.put(interestRateFrequencyTypeParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.interestPeriodFrequencyType = PeriodFrequencyType.fromInt(newValue);
|
||||
updateInterestRateDerivedFields(aprCalculator);
|
||||
}
|
||||
|
||||
final String interestTypeParamName = "interestType";
|
||||
if (command.isChangeInIntegerParameterNamed(interestTypeParamName, this.interestMethod.getValue())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(interestTypeParamName);
|
||||
actualChanges.put(interestTypeParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.interestMethod = InterestMethod.fromInt(newValue);
|
||||
}
|
||||
|
||||
final String interestCalculationPeriodTypeParamName = "interestCalculationPeriodType";
|
||||
if (command.isChangeInIntegerParameterNamed(interestCalculationPeriodTypeParamName,
|
||||
this.interestCalculationPeriodMethod.getValue())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(interestCalculationPeriodTypeParamName);
|
||||
actualChanges.put(interestCalculationPeriodTypeParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.interestCalculationPeriodMethod = InterestCalculationPeriodMethod.fromInt(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.ALLOW_PARTIAL_PERIOD_INTEREST_CALCUALTION_PARAM_NAME,
|
||||
this.allowPartialPeriodInterestCalcualtion)) {
|
||||
final boolean newValue = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ALLOW_PARTIAL_PERIOD_INTEREST_CALCUALTION_PARAM_NAME);
|
||||
actualChanges.put(LoanProductConstants.ALLOW_PARTIAL_PERIOD_INTEREST_CALCUALTION_PARAM_NAME, newValue);
|
||||
this.allowPartialPeriodInterestCalcualtion = newValue;
|
||||
}
|
||||
|
||||
if (this.interestCalculationPeriodMethod.isDaily()) {
|
||||
this.allowPartialPeriodInterestCalcualtion = false;
|
||||
}
|
||||
|
||||
final String graceOnPrincipalPaymentParamName = "graceOnPrincipalPayment";
|
||||
if (command.isChangeInIntegerParameterNamed(graceOnPrincipalPaymentParamName, this.graceOnPrincipalPayment)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(graceOnPrincipalPaymentParamName);
|
||||
actualChanges.put(graceOnPrincipalPaymentParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.graceOnPrincipalPayment = newValue;
|
||||
}
|
||||
|
||||
final String recurringMoratoriumOnPrincipalPeriodsParamName = "recurringMoratoriumOnPrincipalPeriods";
|
||||
if (command.isChangeInIntegerParameterNamed(recurringMoratoriumOnPrincipalPeriodsParamName,
|
||||
this.recurringMoratoriumOnPrincipalPeriods)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(recurringMoratoriumOnPrincipalPeriodsParamName);
|
||||
actualChanges.put(recurringMoratoriumOnPrincipalPeriodsParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.recurringMoratoriumOnPrincipalPeriods = newValue;
|
||||
}
|
||||
|
||||
final String graceOnInterestPaymentParamName = "graceOnInterestPayment";
|
||||
if (command.isChangeInIntegerParameterNamed(graceOnInterestPaymentParamName, this.graceOnInterestPayment)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(graceOnInterestPaymentParamName);
|
||||
actualChanges.put(graceOnInterestPaymentParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.graceOnInterestPayment = newValue;
|
||||
}
|
||||
|
||||
final String graceOnInterestChargedParamName = "graceOnInterestCharged";
|
||||
if (command.isChangeInIntegerParameterNamed(graceOnInterestChargedParamName, this.graceOnInterestCharged)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(graceOnInterestChargedParamName);
|
||||
actualChanges.put(graceOnInterestChargedParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.graceOnInterestCharged = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME,
|
||||
this.graceOnArrearsAgeing)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME);
|
||||
actualChanges.put(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.graceOnArrearsAgeing = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.DAYS_IN_MONTH_TYPE_PARAMETER_NAME, this.daysInMonthType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.DAYS_IN_MONTH_TYPE_PARAMETER_NAME);
|
||||
actualChanges.put(LoanProductConstants.DAYS_IN_MONTH_TYPE_PARAMETER_NAME, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.daysInMonthType = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.DAYS_IN_YEAR_TYPE_PARAMETER_NAME, this.daysInYearType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.DAYS_IN_YEAR_TYPE_PARAMETER_NAME);
|
||||
actualChanges.put(LoanProductConstants.DAYS_IN_YEAR_TYPE_PARAMETER_NAME, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.daysInYearType = newValue;
|
||||
}
|
||||
|
||||
if (command.parameterExists(LoanProductConstants.DAYS_IN_YEAR_CUSTOM_STRATEGY_TYPE_PARAMETER_NAME)) {
|
||||
final DaysInYearCustomStrategyType newValue = DaysInYearCustomStrategyType
|
||||
.valueOf(command.stringValueOfParameterNamed(LoanProductConstants.DAYS_IN_YEAR_CUSTOM_STRATEGY_TYPE_PARAMETER_NAME));
|
||||
actualChanges.put(LoanProductConstants.DAYS_IN_YEAR_CUSTOM_STRATEGY_TYPE_PARAMETER_NAME, newValue.name());
|
||||
this.daysInYearCustomStrategy = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.IS_INTEREST_RECALCULATION_ENABLED_PARAMETER_NAME,
|
||||
this.isInterestRecalculationEnabled)) {
|
||||
final boolean newValue = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.IS_INTEREST_RECALCULATION_ENABLED_PARAMETER_NAME);
|
||||
actualChanges.put(LoanProductConstants.IS_INTEREST_RECALCULATION_ENABLED_PARAMETER_NAME, newValue);
|
||||
this.isInterestRecalculationEnabled = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.IS_EQUAL_AMORTIZATION_PARAM, this.isEqualAmortization)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.IS_EQUAL_AMORTIZATION_PARAM);
|
||||
actualChanges.put(LoanProductConstants.IS_EQUAL_AMORTIZATION_PARAM, newValue);
|
||||
this.isEqualAmortization = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.INTEREST_RECOGNITION_ON_DISBURSEMENT_DATE,
|
||||
this.isInterestRecognitionOnDisbursementDate())) {
|
||||
final boolean newValue = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.INTEREST_RECOGNITION_ON_DISBURSEMENT_DATE);
|
||||
actualChanges.put(LoanProductConstants.INTEREST_RECOGNITION_ON_DISBURSEMENT_DATE, newValue);
|
||||
this.updateInterestRecognitionOnDisbursementDate(newValue);
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
public void updateInterestRateDerivedFields(final AprCalculator aprCalculator) {
|
||||
this.annualNominalInterestRate = aprCalculator.calculateFrom(this.interestPeriodFrequencyType, this.nominalInterestRatePerPeriod,
|
||||
this.numberOfRepayments, this.repayEvery, this.repaymentPeriodFrequencyType);
|
||||
|
||||
}
|
||||
|
||||
public boolean hasCurrencyCodeOf(final String currencyCode) {
|
||||
return this.currency.getCode().equalsIgnoreCase(currencyCode);
|
||||
}
|
||||
|
||||
+4
-42
@@ -21,10 +21,11 @@ package org.apache.fineract.portfolio.loanproduct.domain;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Embeddable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Map;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Embeddable
|
||||
public class LoanProductTrancheDetails {
|
||||
|
||||
@@ -48,43 +49,4 @@ public class LoanProductTrancheDetails {
|
||||
this.outstandingLoanBalance = outstandingLoanBalance;
|
||||
}
|
||||
|
||||
public void update(final JsonCommand command, final Map<String, Object> actualChanges, final String localeAsInput) {
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.MULTI_DISBURSE_LOAN_PARAMETER_NAME, this.multiDisburseLoan)) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.MULTI_DISBURSE_LOAN_PARAMETER_NAME);
|
||||
actualChanges.put(LoanProductConstants.MULTI_DISBURSE_LOAN_PARAMETER_NAME, newValue);
|
||||
this.multiDisburseLoan = newValue;
|
||||
}
|
||||
|
||||
if (this.multiDisburseLoan) {
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.MAX_TRANCHE_COUNT_PARAMETER_NAME, this.maxTrancheCount)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.MAX_TRANCHE_COUNT_PARAMETER_NAME);
|
||||
actualChanges.put(LoanProductConstants.MAX_TRANCHE_COUNT_PARAMETER_NAME, newValue);
|
||||
this.maxTrancheCount = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamed(LoanProductConstants.OUTSTANDING_LOAN_BALANCE_PARAMETER_NAME,
|
||||
this.outstandingLoanBalance)) {
|
||||
final BigDecimal newValue = command
|
||||
.bigDecimalValueOfParameterNamed(LoanProductConstants.OUTSTANDING_LOAN_BALANCE_PARAMETER_NAME);
|
||||
actualChanges.put(LoanProductConstants.OUTSTANDING_LOAN_BALANCE_PARAMETER_NAME, newValue);
|
||||
this.outstandingLoanBalance = newValue;
|
||||
}
|
||||
} else {
|
||||
this.maxTrancheCount = null;
|
||||
this.outstandingLoanBalance = null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isMultiDisburseLoan() {
|
||||
return this.multiDisburseLoan;
|
||||
}
|
||||
|
||||
public BigDecimal outstandingLoanBalance() {
|
||||
return this.outstandingLoanBalance;
|
||||
}
|
||||
|
||||
public Integer maxTrancheCount() {
|
||||
return this.maxTrancheCount;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-22
@@ -23,18 +23,15 @@ import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||
|
||||
@Entity
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table(name = "m_product_loan_variable_installment_config")
|
||||
@@ -50,22 +47,4 @@ public class LoanProductVariableInstallmentConfig extends AbstractPersistableCus
|
||||
|
||||
@Column(name = "maximum_gap")
|
||||
private Integer maximumGap;
|
||||
|
||||
public Map<? extends String, ?> update(JsonCommand command) {
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<>(3);
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.minimumGapBetweenInstallments, this.minimumGap)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.minimumGapBetweenInstallments);
|
||||
actualChanges.put(LoanProductConstants.minimumGapBetweenInstallments, newValue);
|
||||
this.minimumGap = newValue;
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.maximumGapBetweenInstallments, this.maximumGap)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.maximumGapBetweenInstallments);
|
||||
actualChanges.put(LoanProductConstants.maximumGapBetweenInstallments, newValue);
|
||||
this.maximumGap = newValue;
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user