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;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-3
@@ -118,6 +118,7 @@ import org.apache.fineract.portfolio.loanaccount.service.LoanChargeAssembler;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanChargeService;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanDisbursementDetailsAssembler;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanDisbursementService;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanProductRelatedDetailUpdateUtil;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanScheduleService;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanUtilService;
|
||||
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||
@@ -164,6 +165,7 @@ public class LoanScheduleAssembler {
|
||||
private final LoanDisbursementService loanDisbursementService;
|
||||
private final LoanChargeService loanChargeService;
|
||||
private final LoanScheduleService loanScheduleService;
|
||||
private final LoanProductRelatedDetailUpdateUtil relatedDetailUpdateUtil;
|
||||
|
||||
public LoanApplicationTerms assembleLoanTerms(final JsonElement element) {
|
||||
final Long loanProductId = this.fromApiJsonHelper.extractLongNamed("productId", element);
|
||||
@@ -421,7 +423,7 @@ public class LoanScheduleAssembler {
|
||||
loanProductInterestRecalculationDetails.getCompoundingInterval(), recalculationCompoundingFrequencyNthDay,
|
||||
compoundingRepeatsOnDay);
|
||||
}
|
||||
allowCompoundingOnEod = loanProductInterestRecalculationDetails.allowCompoundingOnEod();
|
||||
allowCompoundingOnEod = loanProductInterestRecalculationDetails.getAllowCompoundingOnEod();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1303,7 +1305,7 @@ public class LoanScheduleAssembler {
|
||||
changes.put(interestRatePerPeriodParamName, newValue);
|
||||
changes.put("locale", localeAsInput);
|
||||
loanProductRelatedDetail.setNominalInterestRatePerPeriod(newValue);
|
||||
loanProductRelatedDetail.updateInterestRateDerivedFields(aprCalculator);
|
||||
relatedDetailUpdateUtil.updateInterestRateDerivedFields(loanProductRelatedDetail, aprCalculator);
|
||||
}
|
||||
|
||||
final String interestRateFrequencyTypeParamName = "interestRateFrequencyType";
|
||||
@@ -1315,7 +1317,7 @@ public class LoanScheduleAssembler {
|
||||
changes.put(interestRateFrequencyTypeParamName, newValue);
|
||||
changes.put("locale", localeAsInput);
|
||||
loanProductRelatedDetail.setInterestPeriodFrequencyType(PeriodFrequencyType.fromInt(newValue));
|
||||
loanProductRelatedDetail.updateInterestRateDerivedFields(aprCalculator);
|
||||
relatedDetailUpdateUtil.updateInterestRateDerivedFields(loanProductRelatedDetail, aprCalculator);
|
||||
}
|
||||
|
||||
final String interestTypeParamName = "interestType";
|
||||
|
||||
+406
@@ -0,0 +1,406 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.service;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
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.ExternalId;
|
||||
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.portfolio.charge.domain.Charge;
|
||||
import org.apache.fineract.portfolio.common.domain.DaysInMonthType;
|
||||
import org.apache.fineract.portfolio.common.domain.DaysInYearCustomStrategyType;
|
||||
import org.apache.fineract.portfolio.common.domain.DaysInYearType;
|
||||
import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
|
||||
import org.apache.fineract.portfolio.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;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.AmortizationMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.InterestMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductBorrowerCycleVariations;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductConfigurableAttributes;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductCreditAllocationRule;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductGuaranteeDetails;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductInterestRecalculationDetails;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductParamType;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductPaymentAllocationRule;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanSupportedInterestRefundTypes;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.RepaymentStartDateType;
|
||||
import org.apache.fineract.portfolio.rate.domain.Rate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class LoanProductAssembler {
|
||||
|
||||
private final LoanProductInterestRecalculationDetailsAssembler interestRecalculationDetailsAssembler;
|
||||
private final LoanProductGuaranteeDetailsAssembler guaranteeDetailsAssembler;
|
||||
|
||||
public 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 = interestRecalculationDetailsAssembler.createFrom(command);
|
||||
}
|
||||
|
||||
final boolean holdGuarantorFunds = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.holdGuaranteeFundsParamName);
|
||||
LoanProductGuaranteeDetails loanProductGuaranteeDetails = null;
|
||||
if (holdGuarantorFunds) {
|
||||
loanProductGuaranteeDetails = guaranteeDetailsAssembler.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);
|
||||
|
||||
}
|
||||
|
||||
private void populateBorrowerCycleVariations(final JsonCommand command,
|
||||
final Set<LoanProductBorrowerCycleVariations> loanProductBorrowerCycleVariations) {
|
||||
assemblePrincipalVariations(command, loanProductBorrowerCycleVariations);
|
||||
|
||||
assembleRepaymentVariations(command, loanProductBorrowerCycleVariations);
|
||||
|
||||
assembleInterestRateVariations(command, loanProductBorrowerCycleVariations);
|
||||
}
|
||||
|
||||
private 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 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 void assemblePrincipalVariations(final JsonCommand command,
|
||||
final Set<LoanProductBorrowerCycleVariations> loanProductBorrowerCycleVariations) {
|
||||
assembleVariations(command, loanProductBorrowerCycleVariations, LoanProductParamType.PRINCIPAL.getValue(),
|
||||
LoanProductConstants.PRINCIPAL_VARIATIONS_FOR_BORROWER_CYCLE_PARAMETER_NAME);
|
||||
}
|
||||
|
||||
private 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.portfolio.floatingrates.domain.FloatingRate;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductFloatingRates;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class LoanProductFloatingRatesUpdateUtil {
|
||||
|
||||
public Map<? extends String, ?> update(LoanProductFloatingRates loanProductFloatingRates, JsonCommand command,
|
||||
FloatingRate floatingRate) {
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<>(20);
|
||||
if (floatingRate != null) {
|
||||
final String floatingRatesId = "floatingRatesId";
|
||||
if (loanProductFloatingRates.getFloatingRate() == null
|
||||
|| command.isChangeInLongParameterNamed(floatingRatesId, loanProductFloatingRates.getFloatingRate().getId())) {
|
||||
final long newValue = command.longValueOfParameterNamed(floatingRatesId);
|
||||
actualChanges.put(floatingRatesId, newValue);
|
||||
loanProductFloatingRates.setFloatingRate(floatingRate);
|
||||
}
|
||||
}
|
||||
|
||||
final String interestRateDifferential = "interestRateDifferential";
|
||||
if (command.isChangeInBigDecimalParameterNamed(interestRateDifferential, loanProductFloatingRates.getInterestRateDifferential())) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(interestRateDifferential);
|
||||
actualChanges.put(interestRateDifferential, newValue);
|
||||
loanProductFloatingRates.setInterestRateDifferential(newValue);
|
||||
}
|
||||
final String minDifferentialLendingRate = "minDifferentialLendingRate";
|
||||
if (command.isChangeInBigDecimalParameterNamed(minDifferentialLendingRate,
|
||||
loanProductFloatingRates.getMinDifferentialLendingRate())) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(minDifferentialLendingRate);
|
||||
actualChanges.put(minDifferentialLendingRate, newValue);
|
||||
loanProductFloatingRates.setMinDifferentialLendingRate(newValue);
|
||||
}
|
||||
final String defaultDifferentialLendingRate = "defaultDifferentialLendingRate";
|
||||
if (command.isChangeInBigDecimalParameterNamed(defaultDifferentialLendingRate,
|
||||
loanProductFloatingRates.getDefaultDifferentialLendingRate())) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(defaultDifferentialLendingRate);
|
||||
actualChanges.put(defaultDifferentialLendingRate, newValue);
|
||||
loanProductFloatingRates.setDefaultDifferentialLendingRate(newValue);
|
||||
}
|
||||
final String maxDifferentialLendingRate = "maxDifferentialLendingRate";
|
||||
if (command.isChangeInBigDecimalParameterNamed(maxDifferentialLendingRate,
|
||||
loanProductFloatingRates.getMaxDifferentialLendingRate())) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(maxDifferentialLendingRate);
|
||||
actualChanges.put(maxDifferentialLendingRate, newValue);
|
||||
loanProductFloatingRates.setMaxDifferentialLendingRate(newValue);
|
||||
}
|
||||
final String isFloatingInterestRateCalculationAllowed = "isFloatingInterestRateCalculationAllowed";
|
||||
if (command.isChangeInBooleanParameterNamed(isFloatingInterestRateCalculationAllowed,
|
||||
loanProductFloatingRates.isFloatingInterestRateCalculationAllowed())) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(isFloatingInterestRateCalculationAllowed);
|
||||
actualChanges.put(isFloatingInterestRateCalculationAllowed, newValue);
|
||||
loanProductFloatingRates.setFloatingInterestRateCalculationAllowed(newValue);
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductGuaranteeDetails;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class LoanProductGuaranteeDetailsAssembler {
|
||||
|
||||
public 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);
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Map;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductGuaranteeDetails;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class LoanProductGuaranteeDetailsUpdateUtil {
|
||||
|
||||
public void update(final LoanProductGuaranteeDetails loanProductGuaranteeDetails, final JsonCommand command,
|
||||
final Map<String, Object> actualChanges) {
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamed(LoanProductConstants.mandatoryGuaranteeParamName,
|
||||
loanProductGuaranteeDetails.getMandatoryGuarantee())) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(LoanProductConstants.mandatoryGuaranteeParamName);
|
||||
actualChanges.put(LoanProductConstants.mandatoryGuaranteeParamName, newValue);
|
||||
loanProductGuaranteeDetails.setMandatoryGuarantee(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamed(LoanProductConstants.minimumGuaranteeFromGuarantorParamName,
|
||||
loanProductGuaranteeDetails.getMinimumGuaranteeFromGuarantor())) {
|
||||
final BigDecimal newValue = command
|
||||
.bigDecimalValueOfParameterNamed(LoanProductConstants.minimumGuaranteeFromGuarantorParamName);
|
||||
actualChanges.put(LoanProductConstants.minimumGuaranteeFromGuarantorParamName, newValue);
|
||||
loanProductGuaranteeDetails.setMinimumGuaranteeFromGuarantor(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamed(LoanProductConstants.minimumGuaranteeFromOwnFundsParamName,
|
||||
loanProductGuaranteeDetails.getMinimumGuaranteeFromOwnFunds())) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(LoanProductConstants.minimumGuaranteeFromOwnFundsParamName);
|
||||
actualChanges.put(LoanProductConstants.minimumGuaranteeFromOwnFundsParamName, newValue);
|
||||
loanProductGuaranteeDetails.setMinimumGuaranteeFromOwnFunds(newValue);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.service;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.InterestRecalculationCompoundingMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanPreCloseInterestCalculationStrategy;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductInterestRecalculationDetails;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanRescheduleStrategyMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.RecalculationFrequencyType;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class LoanProductInterestRecalculationDetailsAssembler {
|
||||
|
||||
public 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);
|
||||
}
|
||||
}
|
||||
+247
@@ -0,0 +1,247 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.service;
|
||||
|
||||
import java.util.Map;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.InterestRecalculationCompoundingMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanPreCloseInterestCalculationStrategy;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductInterestRecalculationDetails;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanRescheduleStrategyMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.RecalculationFrequencyType;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class LoanProductInterestRecalculationDetailsUpdateUtil {
|
||||
|
||||
public void update(final LoanProductInterestRecalculationDetails loanProductInterestRecalculationDetails, final JsonCommand command,
|
||||
final Map<String, Object> actualChanges, final String localeAsInput) {
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.interestRecalculationCompoundingMethodParameterName,
|
||||
loanProductInterestRecalculationDetails.getInterestRecalculationCompoundingMethod())) {
|
||||
final Integer newValue = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.interestRecalculationCompoundingMethodParameterName);
|
||||
actualChanges.put(LoanProductConstants.interestRecalculationCompoundingMethodParameterName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanProductInterestRecalculationDetails
|
||||
.setInterestRecalculationCompoundingMethod(InterestRecalculationCompoundingMethod.fromInt(newValue).getValue());
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.rescheduleStrategyMethodParameterName,
|
||||
loanProductInterestRecalculationDetails.getRescheduleStrategyMethod())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.rescheduleStrategyMethodParameterName);
|
||||
actualChanges.put(LoanProductConstants.rescheduleStrategyMethodParameterName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanProductInterestRecalculationDetails.setRescheduleStrategyMethod(LoanRescheduleStrategyMethod.fromInt(newValue).getValue());
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationRestFrequencyTypeParameterName,
|
||||
loanProductInterestRecalculationDetails.getRestFrequencyType().getValue())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyTypeParameterName);
|
||||
actualChanges.put(LoanProductConstants.recalculationRestFrequencyTypeParameterName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanProductInterestRecalculationDetails.setRestFrequencyType(RecalculationFrequencyType.fromInt(newValue).getValue());
|
||||
}
|
||||
RecalculationFrequencyType frequencyType = loanProductInterestRecalculationDetails.getRestFrequencyType();
|
||||
if (frequencyType.isSameAsRepayment()) {
|
||||
loanProductInterestRecalculationDetails.setRestInterval(0);
|
||||
loanProductInterestRecalculationDetails.setRestFrequencyNthDay(null);
|
||||
loanProductInterestRecalculationDetails.setRestFrequencyWeekday(null);
|
||||
loanProductInterestRecalculationDetails.setRestFrequencyOnDay(null);
|
||||
} else {
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationRestFrequencyIntervalParameterName,
|
||||
loanProductInterestRecalculationDetails.getRestInterval())) {
|
||||
Integer newValue = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyIntervalParameterName);
|
||||
actualChanges.put(LoanProductConstants.recalculationRestFrequencyIntervalParameterName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanProductInterestRecalculationDetails.setRestInterval(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationRestFrequencyNthDayParamName,
|
||||
loanProductInterestRecalculationDetails.getRestFrequencyNthDay())) {
|
||||
Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyNthDayParamName);
|
||||
actualChanges.put(LoanProductConstants.recalculationRestFrequencyNthDayParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanProductInterestRecalculationDetails.setRestFrequencyNthDay(newValue);
|
||||
loanProductInterestRecalculationDetails.setRestFrequencyOnDay(null);
|
||||
}
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationRestFrequencyWeekdayParamName,
|
||||
loanProductInterestRecalculationDetails.getRestFrequencyWeekday())) {
|
||||
Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyWeekdayParamName);
|
||||
actualChanges.put(LoanProductConstants.recalculationRestFrequencyWeekdayParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanProductInterestRecalculationDetails.setRestFrequencyWeekday(newValue);
|
||||
loanProductInterestRecalculationDetails.setRestFrequencyOnDay(null);
|
||||
}
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationRestFrequencyOnDayParamName,
|
||||
loanProductInterestRecalculationDetails.getRestFrequencyOnDay())) {
|
||||
Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyOnDayParamName);
|
||||
actualChanges.put(LoanProductConstants.recalculationRestFrequencyOnDayParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanProductInterestRecalculationDetails.setRestFrequencyOnDay(newValue);
|
||||
loanProductInterestRecalculationDetails.setRestFrequencyNthDay(null);
|
||||
loanProductInterestRecalculationDetails.setRestFrequencyWeekday(null);
|
||||
}
|
||||
|
||||
if (frequencyType.isWeekly()) {
|
||||
loanProductInterestRecalculationDetails.setRestFrequencyNthDay(null);
|
||||
loanProductInterestRecalculationDetails.setRestFrequencyOnDay(null);
|
||||
} else if (frequencyType.isMonthly()) {
|
||||
if (command.integerValueOfParameterNamed(LoanProductConstants.recalculationRestFrequencyOnDayParamName) != null) {
|
||||
loanProductInterestRecalculationDetails.setRestFrequencyNthDay(null);
|
||||
loanProductInterestRecalculationDetails.setRestFrequencyWeekday(null);
|
||||
} else {
|
||||
loanProductInterestRecalculationDetails.setRestFrequencyOnDay(null);
|
||||
}
|
||||
} else if (frequencyType.isDaily()) {
|
||||
loanProductInterestRecalculationDetails.setRestFrequencyNthDay(null);
|
||||
loanProductInterestRecalculationDetails.setRestFrequencyWeekday(null);
|
||||
loanProductInterestRecalculationDetails.setRestFrequencyOnDay(null);
|
||||
}
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyTypeParameterName,
|
||||
loanProductInterestRecalculationDetails.getCompoundingFrequencyType().getValue())) {
|
||||
final Integer newValue = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyTypeParameterName);
|
||||
actualChanges.put(LoanProductConstants.recalculationCompoundingFrequencyTypeParameterName, newValue);
|
||||
loanProductInterestRecalculationDetails.setCompoundingFrequencyType(RecalculationFrequencyType.fromInt(newValue).getValue());
|
||||
}
|
||||
|
||||
InterestRecalculationCompoundingMethod compoundingMethod = InterestRecalculationCompoundingMethod
|
||||
.fromInt(loanProductInterestRecalculationDetails.getInterestRecalculationCompoundingMethod());
|
||||
if (compoundingMethod.isCompoundingEnabled()) {
|
||||
RecalculationFrequencyType compoundingFrequencyType = loanProductInterestRecalculationDetails.getCompoundingFrequencyType();
|
||||
if (compoundingFrequencyType.isSameAsRepayment()) {
|
||||
loanProductInterestRecalculationDetails.setCompoundingInterval(null);
|
||||
loanProductInterestRecalculationDetails.setCompoundingFrequencyNthDay(null);
|
||||
loanProductInterestRecalculationDetails.setCompoundingFrequencyWeekday(null);
|
||||
loanProductInterestRecalculationDetails.setCompoundingFrequencyOnDay(null);
|
||||
} else {
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyIntervalParameterName,
|
||||
loanProductInterestRecalculationDetails.getCompoundingInterval())) {
|
||||
Integer newValue = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyIntervalParameterName);
|
||||
actualChanges.put(LoanProductConstants.recalculationCompoundingFrequencyIntervalParameterName, newValue);
|
||||
loanProductInterestRecalculationDetails.setCompoundingInterval(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyNthDayParamName,
|
||||
loanProductInterestRecalculationDetails.getCompoundingFrequencyNthDay())) {
|
||||
Integer newValue = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyNthDayParamName);
|
||||
actualChanges.put(LoanProductConstants.recalculationCompoundingFrequencyNthDayParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanProductInterestRecalculationDetails.setCompoundingFrequencyNthDay(newValue);
|
||||
loanProductInterestRecalculationDetails.setCompoundingFrequencyOnDay(null);
|
||||
}
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyWeekdayParamName,
|
||||
loanProductInterestRecalculationDetails.getCompoundingFrequencyWeekday())) {
|
||||
Integer newValue = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyWeekdayParamName);
|
||||
actualChanges.put(LoanProductConstants.recalculationCompoundingFrequencyWeekdayParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanProductInterestRecalculationDetails.setCompoundingFrequencyWeekday(newValue);
|
||||
loanProductInterestRecalculationDetails.setCompoundingFrequencyOnDay(null);
|
||||
}
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyOnDayParamName,
|
||||
loanProductInterestRecalculationDetails.getCompoundingFrequencyOnDay())) {
|
||||
Integer newValue = command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyOnDayParamName);
|
||||
actualChanges.put(LoanProductConstants.recalculationCompoundingFrequencyOnDayParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanProductInterestRecalculationDetails.setCompoundingFrequencyOnDay(newValue);
|
||||
loanProductInterestRecalculationDetails.setCompoundingFrequencyNthDay(null);
|
||||
loanProductInterestRecalculationDetails.setCompoundingFrequencyWeekday(null);
|
||||
}
|
||||
|
||||
if (compoundingFrequencyType.isWeekly()) {
|
||||
loanProductInterestRecalculationDetails.setCompoundingFrequencyNthDay(null);
|
||||
loanProductInterestRecalculationDetails.setCompoundingFrequencyOnDay(null);
|
||||
} else if (compoundingFrequencyType.isMonthly()) {
|
||||
if (command
|
||||
.integerValueOfParameterNamed(LoanProductConstants.recalculationCompoundingFrequencyOnDayParamName) != null) {
|
||||
loanProductInterestRecalculationDetails.setCompoundingFrequencyNthDay(null);
|
||||
loanProductInterestRecalculationDetails.setCompoundingFrequencyWeekday(null);
|
||||
} else {
|
||||
loanProductInterestRecalculationDetails.setCompoundingFrequencyOnDay(null);
|
||||
}
|
||||
} else if (compoundingFrequencyType.isDaily()) {
|
||||
loanProductInterestRecalculationDetails.setCompoundingFrequencyNthDay(null);
|
||||
loanProductInterestRecalculationDetails.setCompoundingFrequencyWeekday(null);
|
||||
loanProductInterestRecalculationDetails.setCompoundingFrequencyOnDay(null);
|
||||
}
|
||||
}
|
||||
if (!compoundingFrequencyType.isDaily()) {
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.allowCompoundingOnEodParamName,
|
||||
loanProductInterestRecalculationDetails.getAllowCompoundingOnEod())) {
|
||||
boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.allowCompoundingOnEodParamName);
|
||||
actualChanges.put(LoanProductConstants.allowCompoundingOnEodParamName, newValue);
|
||||
loanProductInterestRecalculationDetails.setAllowCompoundingOnEod(newValue);
|
||||
}
|
||||
} else {
|
||||
loanProductInterestRecalculationDetails.setAllowCompoundingOnEod(false);
|
||||
}
|
||||
} else {
|
||||
loanProductInterestRecalculationDetails.setCompoundingFrequencyType(null);
|
||||
loanProductInterestRecalculationDetails.setCompoundingInterval(null);
|
||||
loanProductInterestRecalculationDetails.setCompoundingFrequencyNthDay(null);
|
||||
loanProductInterestRecalculationDetails.setCompoundingFrequencyWeekday(null);
|
||||
loanProductInterestRecalculationDetails.setCompoundingFrequencyOnDay(null);
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.isArrearsBasedOnOriginalScheduleParamName,
|
||||
loanProductInterestRecalculationDetails.isArrearsBasedOnOriginalSchedule())) {
|
||||
final boolean newValue = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.isArrearsBasedOnOriginalScheduleParamName);
|
||||
actualChanges.put(LoanProductConstants.isArrearsBasedOnOriginalScheduleParamName, newValue);
|
||||
loanProductInterestRecalculationDetails.setArrearsBasedOnOriginalSchedule(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.preClosureInterestCalculationStrategyParamName,
|
||||
loanProductInterestRecalculationDetails.getPreCloseInterestCalculationStrategy().getValue())) {
|
||||
Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.preClosureInterestCalculationStrategyParamName);
|
||||
if (newValue == null) {
|
||||
newValue = LoanPreCloseInterestCalculationStrategy.TILL_PRE_CLOSURE_DATE.getValue();
|
||||
}
|
||||
actualChanges.put(LoanProductConstants.preClosureInterestCalculationStrategyParamName, newValue);
|
||||
loanProductInterestRecalculationDetails.setPreCloseInterestCalculationStrategy(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.isCompoundingToBePostedAsTransactionParamName,
|
||||
loanProductInterestRecalculationDetails.getIsCompoundingToBePostedAsTransaction())) {
|
||||
final boolean newValue = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.isCompoundingToBePostedAsTransactionParamName);
|
||||
actualChanges.put(LoanProductConstants.isCompoundingToBePostedAsTransactionParamName, newValue);
|
||||
loanProductInterestRecalculationDetails.setIsCompoundingToBePostedAsTransaction(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.disallowInterestCalculationOnPastDueParamName,
|
||||
loanProductInterestRecalculationDetails.getDisallowInterestCalculationOnPastDue())) {
|
||||
final boolean newValue = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.disallowInterestCalculationOnPastDueParamName);
|
||||
actualChanges.put(LoanProductConstants.disallowInterestCalculationOnPastDueParamName, newValue);
|
||||
loanProductInterestRecalculationDetails.setDisallowInterestCalculationOnPastDue(newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductMinMaxConstraints;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class LoanProductMinMaxConstraintsUpdateUtil {
|
||||
|
||||
public Map<String, Object> update(final LoanProductMinMaxConstraints loanProductMinMaxConstraints, final JsonCommand command) {
|
||||
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<>(20);
|
||||
|
||||
final String localeAsInput = command.locale();
|
||||
|
||||
final String minPrincipalParamName = "minPrincipal";
|
||||
if (command.isChangeInBigDecimalParameterNamedWithNullCheck(minPrincipalParamName,
|
||||
loanProductMinMaxConstraints.getMinPrincipal())) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(minPrincipalParamName);
|
||||
actualChanges.put(minPrincipalParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanProductMinMaxConstraints.setMinPrincipal(newValue);
|
||||
}
|
||||
|
||||
final String maxPrincipalParamName = "maxPrincipal";
|
||||
if (command.isChangeInBigDecimalParameterNamedWithNullCheck(maxPrincipalParamName,
|
||||
loanProductMinMaxConstraints.getMaxPrincipal())) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(maxPrincipalParamName);
|
||||
actualChanges.put(maxPrincipalParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanProductMinMaxConstraints.setMaxPrincipal(newValue);
|
||||
}
|
||||
|
||||
final String minNumberOfRepaymentsParamName = "minNumberOfRepayments";
|
||||
if (command.isChangeInIntegerParameterNamed(minNumberOfRepaymentsParamName,
|
||||
loanProductMinMaxConstraints.getMinNumberOfRepayments())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(minNumberOfRepaymentsParamName);
|
||||
actualChanges.put(minNumberOfRepaymentsParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanProductMinMaxConstraints.setMinNumberOfRepayments(newValue);
|
||||
}
|
||||
|
||||
final String maxNumberOfRepaymentsParamName = "maxNumberOfRepayments";
|
||||
if (command.isChangeInIntegerParameterNamed(maxNumberOfRepaymentsParamName,
|
||||
loanProductMinMaxConstraints.getMaxNumberOfRepayments())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(maxNumberOfRepaymentsParamName);
|
||||
actualChanges.put(maxNumberOfRepaymentsParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanProductMinMaxConstraints.setMaxNumberOfRepayments(newValue);
|
||||
}
|
||||
|
||||
final String minInterestRatePerPeriodParamName = "minInterestRatePerPeriod";
|
||||
if (command.isChangeInBigDecimalParameterNamedWithNullCheck(minInterestRatePerPeriodParamName,
|
||||
loanProductMinMaxConstraints.getMinNominalInterestRatePerPeriod())) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(minInterestRatePerPeriodParamName);
|
||||
actualChanges.put(minInterestRatePerPeriodParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanProductMinMaxConstraints.setMinNominalInterestRatePerPeriod(newValue);
|
||||
}
|
||||
|
||||
final String maxInterestRatePerPeriodParamName = "maxInterestRatePerPeriod";
|
||||
if (command.isChangeInBigDecimalParameterNamedWithNullCheck(maxInterestRatePerPeriodParamName,
|
||||
loanProductMinMaxConstraints.getMaxNominalInterestRatePerPeriod())) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(maxInterestRatePerPeriodParamName);
|
||||
actualChanges.put(maxInterestRatePerPeriodParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanProductMinMaxConstraints.setMaxNominalInterestRatePerPeriod(newValue);
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
}
|
||||
+309
@@ -0,0 +1,309 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.apache.fineract.portfolio.common.domain.DaysInYearCustomStrategyType;
|
||||
import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
|
||||
import org.apache.fineract.portfolio.loanaccount.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;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.AmortizationMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.InterestMethod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRelatedDetail;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class LoanProductRelatedDetailUpdateUtil {
|
||||
|
||||
public Map<String, Object> updateLoanRepaymentSchedule(final LoanProductRelatedDetail loanRepaymentScheduleDetail,
|
||||
final JsonCommand command, final AprCalculator aprCalculator) {
|
||||
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<>(20);
|
||||
|
||||
final String localeAsInput = command.locale();
|
||||
|
||||
String currencyCode = loanRepaymentScheduleDetail.getCurrency().getCode();
|
||||
Integer digitsAfterDecimal = loanRepaymentScheduleDetail.getCurrency().getDigitsAfterDecimal();
|
||||
Integer inMultiplesOf = loanRepaymentScheduleDetail.getCurrency().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;
|
||||
loanRepaymentScheduleDetail.setCurrency(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;
|
||||
loanRepaymentScheduleDetail.setCurrency(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;
|
||||
loanRepaymentScheduleDetail.setCurrency(new MonetaryCurrency(currencyCode, digitsAfterDecimal, inMultiplesOf));
|
||||
}
|
||||
|
||||
final String loanScheduleTypeParamName = LoanProductConstants.LOAN_SCHEDULE_TYPE;
|
||||
if (command.isChangeInStringParameterNamed(loanScheduleTypeParamName,
|
||||
loanRepaymentScheduleDetail.getLoanScheduleType().toString())) {
|
||||
LoanScheduleType newLoanScheduleType = LoanScheduleType.valueOf(command.stringValueOfParameterNamed(loanScheduleTypeParamName));
|
||||
actualChanges.put(loanScheduleTypeParamName, newLoanScheduleType);
|
||||
loanRepaymentScheduleDetail.setLoanScheduleType(newLoanScheduleType);
|
||||
}
|
||||
|
||||
final String loanScheduleProcessingTypeParamName = LoanProductConstants.LOAN_SCHEDULE_PROCESSING_TYPE;
|
||||
if (command.isChangeInStringParameterNamed(loanScheduleProcessingTypeParamName,
|
||||
loanRepaymentScheduleDetail.getLoanScheduleProcessingType().toString())) {
|
||||
LoanScheduleProcessingType newLoanScheduleProcessingType = LoanScheduleProcessingType
|
||||
.valueOf(command.stringValueOfParameterNamed(loanScheduleProcessingTypeParamName));
|
||||
actualChanges.put(loanScheduleProcessingTypeParamName, newLoanScheduleProcessingType);
|
||||
loanRepaymentScheduleDetail.setLoanScheduleProcessingType(newLoanScheduleProcessingType);
|
||||
}
|
||||
|
||||
final String principalParamName = "principal";
|
||||
if (command.isChangeInBigDecimalParameterNamed(principalParamName, loanRepaymentScheduleDetail.getPrincipal().getAmount())) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(principalParamName);
|
||||
actualChanges.put(principalParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanRepaymentScheduleDetail.setPrincipal(newValue);
|
||||
}
|
||||
|
||||
final String repaymentEveryParamName = "repaymentEvery";
|
||||
if (command.isChangeInIntegerParameterNamed(repaymentEveryParamName, loanRepaymentScheduleDetail.getRepayEvery())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(repaymentEveryParamName);
|
||||
actualChanges.put(repaymentEveryParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanRepaymentScheduleDetail.setRepayEvery(newValue);
|
||||
}
|
||||
|
||||
final String repaymentFrequencyTypeParamName = "repaymentFrequencyType";
|
||||
if (command.isChangeInIntegerParameterNamed(repaymentFrequencyTypeParamName,
|
||||
loanRepaymentScheduleDetail.getRepaymentPeriodFrequencyType().getValue())) {
|
||||
Integer newValue = command.integerValueOfParameterNamed(repaymentFrequencyTypeParamName);
|
||||
actualChanges.put(repaymentFrequencyTypeParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanRepaymentScheduleDetail.setRepaymentPeriodFrequencyType(PeriodFrequencyType.fromInt(newValue));
|
||||
}
|
||||
if (loanRepaymentScheduleDetail.getRepaymentPeriodFrequencyType() == PeriodFrequencyType.MONTHS) {
|
||||
final String repaymentFrequencyNthDayTypeParamName = "repaymentFrequencyNthDayType";
|
||||
Integer 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, loanRepaymentScheduleDetail.getNumberOfRepayments())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(numberOfRepaymentsParamName);
|
||||
actualChanges.put(numberOfRepaymentsParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanRepaymentScheduleDetail.setNumberOfRepayments(newValue);
|
||||
}
|
||||
|
||||
final String amortizationTypeParamName = "amortizationType";
|
||||
if (command.isChangeInIntegerParameterNamed(amortizationTypeParamName,
|
||||
loanRepaymentScheduleDetail.getAmortizationMethod().getValue())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(amortizationTypeParamName);
|
||||
actualChanges.put(amortizationTypeParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanRepaymentScheduleDetail.setAmortizationMethod(AmortizationMethod.fromInt(newValue));
|
||||
}
|
||||
|
||||
final String inArrearsToleranceParamName = "inArrearsTolerance";
|
||||
if (command.isChangeInBigDecimalParameterNamed(inArrearsToleranceParamName,
|
||||
loanRepaymentScheduleDetail.getInArrearsTolerance().getAmount())) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(inArrearsToleranceParamName);
|
||||
actualChanges.put(inArrearsToleranceParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanRepaymentScheduleDetail.setInArrearsTolerance(newValue);
|
||||
}
|
||||
|
||||
final String interestRatePerPeriodParamName = "interestRatePerPeriod";
|
||||
if (command.isChangeInBigDecimalParameterNamed(interestRatePerPeriodParamName,
|
||||
loanRepaymentScheduleDetail.getNominalInterestRatePerPeriod())) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(interestRatePerPeriodParamName);
|
||||
actualChanges.put(interestRatePerPeriodParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanRepaymentScheduleDetail.setNominalInterestRatePerPeriod(newValue);
|
||||
updateInterestRateDerivedFields(loanRepaymentScheduleDetail, aprCalculator);
|
||||
}
|
||||
|
||||
final String interestRateFrequencyTypeParamName = "interestRateFrequencyType";
|
||||
final int interestPeriodFrequencyType = loanRepaymentScheduleDetail.getInterestPeriodFrequencyType() == null
|
||||
? PeriodFrequencyType.INVALID.getValue()
|
||||
: loanRepaymentScheduleDetail.getInterestPeriodFrequencyType().getValue();
|
||||
if (command.isChangeInIntegerParameterNamed(interestRateFrequencyTypeParamName, interestPeriodFrequencyType)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(interestRateFrequencyTypeParamName);
|
||||
actualChanges.put(interestRateFrequencyTypeParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanRepaymentScheduleDetail.setInterestPeriodFrequencyType(PeriodFrequencyType.fromInt(newValue));
|
||||
updateInterestRateDerivedFields(loanRepaymentScheduleDetail, aprCalculator);
|
||||
}
|
||||
|
||||
final String interestTypeParamName = "interestType";
|
||||
if (command.isChangeInIntegerParameterNamed(interestTypeParamName, loanRepaymentScheduleDetail.getInterestMethod().getValue())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(interestTypeParamName);
|
||||
actualChanges.put(interestTypeParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanRepaymentScheduleDetail.setInterestMethod(InterestMethod.fromInt(newValue));
|
||||
}
|
||||
|
||||
final String interestCalculationPeriodTypeParamName = "interestCalculationPeriodType";
|
||||
if (command.isChangeInIntegerParameterNamed(interestCalculationPeriodTypeParamName,
|
||||
loanRepaymentScheduleDetail.getInterestCalculationPeriodMethod().getValue())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(interestCalculationPeriodTypeParamName);
|
||||
actualChanges.put(interestCalculationPeriodTypeParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanRepaymentScheduleDetail.setInterestCalculationPeriodMethod(InterestCalculationPeriodMethod.fromInt(newValue));
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.ALLOW_PARTIAL_PERIOD_INTEREST_CALCUALTION_PARAM_NAME,
|
||||
loanRepaymentScheduleDetail.isAllowPartialPeriodInterestCalcualtion())) {
|
||||
final boolean newValue = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ALLOW_PARTIAL_PERIOD_INTEREST_CALCUALTION_PARAM_NAME);
|
||||
actualChanges.put(LoanProductConstants.ALLOW_PARTIAL_PERIOD_INTEREST_CALCUALTION_PARAM_NAME, newValue);
|
||||
loanRepaymentScheduleDetail.setAllowPartialPeriodInterestCalcualtion(newValue);
|
||||
}
|
||||
|
||||
if (loanRepaymentScheduleDetail.getInterestCalculationPeriodMethod().isDaily()) {
|
||||
loanRepaymentScheduleDetail.setAllowPartialPeriodInterestCalcualtion(false);
|
||||
}
|
||||
|
||||
final String graceOnPrincipalPaymentParamName = "graceOnPrincipalPayment";
|
||||
if (command.isChangeInIntegerParameterNamed(graceOnPrincipalPaymentParamName,
|
||||
loanRepaymentScheduleDetail.getGraceOnPrincipalPayment())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(graceOnPrincipalPaymentParamName);
|
||||
actualChanges.put(graceOnPrincipalPaymentParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanRepaymentScheduleDetail.setGraceOnPrincipalPayment(newValue);
|
||||
}
|
||||
|
||||
final String recurringMoratoriumOnPrincipalPeriodsParamName = "recurringMoratoriumOnPrincipalPeriods";
|
||||
if (command.isChangeInIntegerParameterNamed(recurringMoratoriumOnPrincipalPeriodsParamName,
|
||||
loanRepaymentScheduleDetail.getRecurringMoratoriumOnPrincipalPeriods())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(recurringMoratoriumOnPrincipalPeriodsParamName);
|
||||
actualChanges.put(recurringMoratoriumOnPrincipalPeriodsParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanRepaymentScheduleDetail.setRecurringMoratoriumOnPrincipalPeriods(newValue);
|
||||
}
|
||||
|
||||
final String graceOnInterestPaymentParamName = "graceOnInterestPayment";
|
||||
if (command.isChangeInIntegerParameterNamed(graceOnInterestPaymentParamName,
|
||||
loanRepaymentScheduleDetail.getGraceOnInterestPayment())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(graceOnInterestPaymentParamName);
|
||||
actualChanges.put(graceOnInterestPaymentParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanRepaymentScheduleDetail.setGraceOnInterestPayment(newValue);
|
||||
}
|
||||
|
||||
final String graceOnInterestChargedParamName = "graceOnInterestCharged";
|
||||
if (command.isChangeInIntegerParameterNamed(graceOnInterestChargedParamName,
|
||||
loanRepaymentScheduleDetail.getGraceOnInterestCharged())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(graceOnInterestChargedParamName);
|
||||
actualChanges.put(graceOnInterestChargedParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanRepaymentScheduleDetail.setGraceOnInterestCharged(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME,
|
||||
loanRepaymentScheduleDetail.getGraceOnArrearsAgeing())) {
|
||||
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);
|
||||
loanRepaymentScheduleDetail.setGraceOnArrearsAgeing(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.DAYS_IN_MONTH_TYPE_PARAMETER_NAME,
|
||||
loanRepaymentScheduleDetail.getDaysInMonthType())) {
|
||||
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);
|
||||
loanRepaymentScheduleDetail.setDaysInMonthType(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.DAYS_IN_YEAR_TYPE_PARAMETER_NAME,
|
||||
loanRepaymentScheduleDetail.getDaysInYearType())) {
|
||||
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);
|
||||
loanRepaymentScheduleDetail.setDaysInYearType(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());
|
||||
loanRepaymentScheduleDetail.setDaysInYearCustomStrategy(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.IS_INTEREST_RECALCULATION_ENABLED_PARAMETER_NAME,
|
||||
loanRepaymentScheduleDetail.isInterestRecalculationEnabled())) {
|
||||
final boolean newValue = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.IS_INTEREST_RECALCULATION_ENABLED_PARAMETER_NAME);
|
||||
actualChanges.put(LoanProductConstants.IS_INTEREST_RECALCULATION_ENABLED_PARAMETER_NAME, newValue);
|
||||
loanRepaymentScheduleDetail.setInterestRecalculationEnabled(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.IS_EQUAL_AMORTIZATION_PARAM,
|
||||
loanRepaymentScheduleDetail.isEqualAmortization())) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.IS_EQUAL_AMORTIZATION_PARAM);
|
||||
actualChanges.put(LoanProductConstants.IS_EQUAL_AMORTIZATION_PARAM, newValue);
|
||||
loanRepaymentScheduleDetail.setEqualAmortization(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.INTEREST_RECOGNITION_ON_DISBURSEMENT_DATE,
|
||||
loanRepaymentScheduleDetail.isInterestRecognitionOnDisbursementDate())) {
|
||||
final boolean newValue = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.INTEREST_RECOGNITION_ON_DISBURSEMENT_DATE);
|
||||
actualChanges.put(LoanProductConstants.INTEREST_RECOGNITION_ON_DISBURSEMENT_DATE, newValue);
|
||||
loanRepaymentScheduleDetail.updateInterestRecognitionOnDisbursementDate(newValue);
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
public void updateInterestRateDerivedFields(final LoanProductRelatedDetail loanRepaymentScheduleDetail,
|
||||
final AprCalculator aprCalculator) {
|
||||
BigDecimal annualNominalInterestRate = aprCalculator.calculateFrom(loanRepaymentScheduleDetail.getInterestPeriodFrequencyType(),
|
||||
loanRepaymentScheduleDetail.getNominalInterestRatePerPeriod(), loanRepaymentScheduleDetail.getNumberOfRepayments(),
|
||||
loanRepaymentScheduleDetail.getRepayEvery(), loanRepaymentScheduleDetail.getRepaymentPeriodFrequencyType());
|
||||
loanRepaymentScheduleDetail.setAnnualNominalInterestRate(annualNominalInterestRate);
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Map;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductTrancheDetails;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class LoanProductTrancheDetailsUpdateUtil {
|
||||
|
||||
public void update(final LoanProductTrancheDetails loanProductTrancheDetails, final JsonCommand command,
|
||||
final Map<String, Object> actualChanges) {
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.MULTI_DISBURSE_LOAN_PARAMETER_NAME,
|
||||
loanProductTrancheDetails.isMultiDisburseLoan())) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.MULTI_DISBURSE_LOAN_PARAMETER_NAME);
|
||||
actualChanges.put(LoanProductConstants.MULTI_DISBURSE_LOAN_PARAMETER_NAME, newValue);
|
||||
loanProductTrancheDetails.setMultiDisburseLoan(newValue);
|
||||
}
|
||||
|
||||
if (loanProductTrancheDetails.isMultiDisburseLoan()) {
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.MAX_TRANCHE_COUNT_PARAMETER_NAME,
|
||||
loanProductTrancheDetails.getMaxTrancheCount())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.MAX_TRANCHE_COUNT_PARAMETER_NAME);
|
||||
actualChanges.put(LoanProductConstants.MAX_TRANCHE_COUNT_PARAMETER_NAME, newValue);
|
||||
loanProductTrancheDetails.setMaxTrancheCount(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamed(LoanProductConstants.OUTSTANDING_LOAN_BALANCE_PARAMETER_NAME,
|
||||
loanProductTrancheDetails.getOutstandingLoanBalance())) {
|
||||
final BigDecimal newValue = command
|
||||
.bigDecimalValueOfParameterNamed(LoanProductConstants.OUTSTANDING_LOAN_BALANCE_PARAMETER_NAME);
|
||||
actualChanges.put(LoanProductConstants.OUTSTANDING_LOAN_BALANCE_PARAMETER_NAME, newValue);
|
||||
loanProductTrancheDetails.setOutstandingLoanBalance(newValue);
|
||||
}
|
||||
} else {
|
||||
loanProductTrancheDetails.setMaxTrancheCount(null);
|
||||
loanProductTrancheDetails.setOutstandingLoanBalance(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
+632
@@ -0,0 +1,632 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.service;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
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.ExternalId;
|
||||
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
|
||||
import org.apache.fineract.portfolio.floatingrates.domain.FloatingRate;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.AprCalculator;
|
||||
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductBorrowerCycleVariations;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductConfigurableAttributes;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductParamType;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.RepaymentStartDateType;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class LoanProductUpdateUtil {
|
||||
|
||||
private final LoanProductRelatedDetailUpdateUtil detailUpdateUtil;
|
||||
|
||||
private final LoanProductMinMaxConstraintsUpdateUtil minMaxConstraintsUpdateUtil;
|
||||
|
||||
private final LoanProductFloatingRatesUpdateUtil floatingRatesUpdateUtil;
|
||||
|
||||
private final LoanProductVariableInstallmentConfigUpdateUtil variableInstallmentConfigUpdateUtil;
|
||||
|
||||
private final LoanProductTrancheDetailsUpdateUtil trancheDetailsUpdateUtil;
|
||||
|
||||
private final LoanProductInterestRecalculationDetailsAssembler interestRecalculationDetailsAssembler;
|
||||
|
||||
private final LoanProductInterestRecalculationDetailsUpdateUtil interestRecalculationDetailsUpdateUtil;
|
||||
|
||||
private final LoanProductGuaranteeDetailsAssembler guaranteeDetailsAssembler;
|
||||
|
||||
private final LoanProductGuaranteeDetailsUpdateUtil guaranteeDetailsUpdateUtil;
|
||||
|
||||
public Map<String, Object> update(final LoanProduct loanProduct, final JsonCommand command, final AprCalculator aprCalculator,
|
||||
FloatingRate floatingRate) {
|
||||
final Map<String, Object> actualChanges = detailUpdateUtil.updateLoanRepaymentSchedule(loanProduct.getLoanProductRelatedDetail(),
|
||||
command, aprCalculator);
|
||||
actualChanges.putAll(minMaxConstraintsUpdateUtil.update(loanProduct.loanProductMinMaxConstraints(), command));
|
||||
|
||||
final String isLinkedToFloatingInterestRates = "isLinkedToFloatingInterestRates";
|
||||
if (command.isChangeInBooleanParameterNamed(isLinkedToFloatingInterestRates, loanProduct.isLinkedToFloatingInterestRate())) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(isLinkedToFloatingInterestRates);
|
||||
actualChanges.put(isLinkedToFloatingInterestRates, newValue);
|
||||
loanProduct.setLinkedToFloatingInterestRate(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.ENABLE_ACCRUAL_ACTIVITY_POSTING,
|
||||
loanProduct.getLoanProductRelatedDetail().isEnableAccrualActivityPosting())) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ENABLE_ACCRUAL_ACTIVITY_POSTING);
|
||||
actualChanges.put(LoanProductConstants.ENABLE_ACCRUAL_ACTIVITY_POSTING, newValue);
|
||||
loanProduct.getLoanProductRelatedDetail().setEnableAccrualActivityPosting(newValue);
|
||||
}
|
||||
|
||||
if (loanProduct.isLinkedToFloatingInterestRate()) {
|
||||
actualChanges.putAll(floatingRatesUpdateUtil.update(loanProduct.loanProductFloatingRates(), command, floatingRate));
|
||||
loanProduct.getLoanProductRelatedDetail().updateForFloatingInterestRates();
|
||||
loanProduct.getLoanProductMinMaxConstraints().updateForFloatingInterestRates();
|
||||
} else {
|
||||
loanProduct.setFloatingRates(null);
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.allowVariableInstallmentsParamName,
|
||||
loanProduct.isAllowVariabeInstallments())) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.allowVariableInstallmentsParamName);
|
||||
actualChanges.put(LoanProductConstants.allowVariableInstallmentsParamName, newValue);
|
||||
loanProduct.setAllowVariabeInstallments(newValue);
|
||||
}
|
||||
|
||||
if (loanProduct.isAllowVariabeInstallments()) {
|
||||
actualChanges.putAll(variableInstallmentConfigUpdateUtil.update(loanProduct.loanProductVariableInstallmentConfig(), command));
|
||||
} else {
|
||||
loanProduct.setVariableInstallmentConfig(null);
|
||||
}
|
||||
|
||||
final String accountingTypeParamName = "accountingRule";
|
||||
Integer currentValue = loanProduct.getAccountingRule() == null ? null : loanProduct.getAccountingRule().getValue();
|
||||
if (command.isChangeInIntegerParameterNamed(accountingTypeParamName, currentValue)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(accountingTypeParamName);
|
||||
actualChanges.put(accountingTypeParamName, newValue);
|
||||
loanProduct.setAccountingRule(AccountingRuleType.fromInt(newValue));
|
||||
}
|
||||
|
||||
final String nameParamName = "name";
|
||||
if (command.isChangeInStringParameterNamed(nameParamName, loanProduct.getName())) {
|
||||
final String newValue = command.stringValueOfParameterNamed(nameParamName);
|
||||
actualChanges.put(nameParamName, newValue);
|
||||
loanProduct.setName(newValue);
|
||||
}
|
||||
|
||||
final String shortNameParamName = LoanProductConstants.SHORT_NAME;
|
||||
if (command.isChangeInStringParameterNamed(shortNameParamName, loanProduct.getShortName())) {
|
||||
final String newValue = command.stringValueOfParameterNamed(shortNameParamName);
|
||||
actualChanges.put(shortNameParamName, newValue);
|
||||
loanProduct.setShortName(newValue);
|
||||
}
|
||||
|
||||
final String descriptionParamName = "description";
|
||||
if (command.isChangeInStringParameterNamed(descriptionParamName, loanProduct.getDescription())) {
|
||||
final String newValue = command.stringValueOfParameterNamed(descriptionParamName);
|
||||
actualChanges.put(descriptionParamName, newValue);
|
||||
loanProduct.setDescription(newValue);
|
||||
}
|
||||
|
||||
Long existingFundId = null;
|
||||
if (loanProduct.getFund() != null) {
|
||||
existingFundId = loanProduct.getFund().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,
|
||||
loanProduct.getTransactionProcessingStrategyCode())) {
|
||||
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, loanProduct.isIncludeInBorrowerCycle())) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(includeInBorrowerCycleParamName);
|
||||
actualChanges.put(includeInBorrowerCycleParamName, newValue);
|
||||
loanProduct.setIncludeInBorrowerCycle(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.USE_BORROWER_CYCLE_PARAMETER_NAME,
|
||||
loanProduct.isUseBorrowerCycle())) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.USE_BORROWER_CYCLE_PARAMETER_NAME);
|
||||
actualChanges.put(LoanProductConstants.USE_BORROWER_CYCLE_PARAMETER_NAME, newValue);
|
||||
loanProduct.setUseBorrowerCycle(newValue);
|
||||
}
|
||||
|
||||
if (loanProduct.isUseBorrowerCycle()) {
|
||||
actualChanges.putAll(updateBorrowerCycleVariations(loanProduct, command));
|
||||
} else {
|
||||
clearVariations(loanProduct);
|
||||
}
|
||||
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, loanProduct.getStartDate())) {
|
||||
final String valueAsInput = command.stringValueOfParameterNamed(startDateParamName);
|
||||
actualChanges.put(startDateParamName, valueAsInput);
|
||||
actualChanges.put(dateFormatParamName, dateFormatAsInput);
|
||||
actualChanges.put(localeParamName, localeAsInput);
|
||||
|
||||
loanProduct.setStartDate(command.localDateValueOfParameterNamed(startDateParamName));
|
||||
}
|
||||
|
||||
final String closeDateParamName = "closeDate";
|
||||
if (command.isChangeInLocalDateParameterNamed(closeDateParamName, loanProduct.getCloseDate())) {
|
||||
final String valueAsInput = command.stringValueOfParameterNamed(closeDateParamName);
|
||||
actualChanges.put(closeDateParamName, valueAsInput);
|
||||
actualChanges.put(dateFormatParamName, dateFormatAsInput);
|
||||
actualChanges.put(localeParamName, localeAsInput);
|
||||
|
||||
loanProduct.setCloseDate(command.localDateValueOfParameterNamed(closeDateParamName));
|
||||
}
|
||||
|
||||
final String externalIdTypeParamName = "externalId";
|
||||
if (command.isChangeInExternalIdParameterNamed(externalIdTypeParamName, loanProduct.getExternalId())) {
|
||||
final ExternalId newValue = ExternalIdFactory.produce(command.stringValueOfParameterNamed(externalIdTypeParamName));
|
||||
actualChanges.put(accountingTypeParamName, newValue);
|
||||
loanProduct.setExternalId(newValue);
|
||||
}
|
||||
trancheDetailsUpdateUtil.update(loanProduct.getLoanProductTrancheDetails(), command, actualChanges);
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.OVERDUE_DAYS_FOR_NPA_PARAMETER_NAME,
|
||||
loanProduct.getOverdueDaysForNPA())) {
|
||||
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);
|
||||
loanProduct.setOverdueDaysForNPA(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.MINIMUM_DAYS_BETWEEN_DISBURSAL_AND_FIRST_REPAYMENT,
|
||||
loanProduct.getMinimumDaysBetweenDisbursalAndFirstRepayment())) {
|
||||
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);
|
||||
loanProduct.setMinimumDaysBetweenDisbursalAndFirstRepayment(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed("syncExpectedWithDisbursementDate", loanProduct.isSyncExpectedWithDisbursementDate())) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed("syncExpectedWithDisbursementDate");
|
||||
actualChanges.put("syncExpectedWithDisbursementDate", newValue);
|
||||
loanProduct.setSyncExpectedWithDisbursementDate(newValue);
|
||||
}
|
||||
|
||||
Long delinquencyBucketId = null;
|
||||
if (loanProduct.getDelinquencyBucket() != null) {
|
||||
delinquencyBucketId = loanProduct.getDelinquencyBucket().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 (loanProduct.isInterestRecalculationEnabled()) {
|
||||
loanProduct.setProductInterestRecalculationDetails(interestRecalculationDetailsAssembler.createFrom(command));
|
||||
loanProduct.getProductInterestRecalculationDetails().updateProduct(loanProduct);
|
||||
actualChanges.put(LoanProductConstants.interestRecalculationCompoundingMethodParameterName,
|
||||
command.integerValueOfParameterNamed(LoanProductConstants.interestRecalculationCompoundingMethodParameterName));
|
||||
actualChanges.put(LoanProductConstants.rescheduleStrategyMethodParameterName,
|
||||
command.integerValueOfParameterNamed(LoanProductConstants.rescheduleStrategyMethodParameterName));
|
||||
} else {
|
||||
loanProduct.setProductInterestRecalculationDetails(null);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isInterestRecalculationEnabledChanged && loanProduct.isInterestRecalculationEnabled()) {
|
||||
interestRecalculationDetailsUpdateUtil.update(loanProduct.getProductInterestRecalculationDetails(), command, actualChanges,
|
||||
localeAsInput);
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.holdGuaranteeFundsParamName, loanProduct.isHoldGuaranteeFunds())) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.holdGuaranteeFundsParamName);
|
||||
actualChanges.put(LoanProductConstants.holdGuaranteeFundsParamName, newValue);
|
||||
loanProduct.setHoldGuaranteeFunds(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() != loanProduct.getLoanConfigurableAttributes().getAmortizationBoolean()) {
|
||||
loanProduct.getLoanConfigurableAttributes()
|
||||
.setAmortizationType(command.parsedJson().getAsJsonObject()
|
||||
.getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.amortizationTypeParamName).getAsBoolean());
|
||||
}
|
||||
|
||||
if (command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.interestTypeParamName)
|
||||
.getAsBoolean() != loanProduct.getLoanConfigurableAttributes().getInterestMethodBoolean()) {
|
||||
loanProduct.getLoanConfigurableAttributes()
|
||||
.setInterestType(command.parsedJson().getAsJsonObject()
|
||||
.getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.interestTypeParamName).getAsBoolean());
|
||||
}
|
||||
|
||||
if (command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.transactionProcessingStrategyCodeParamName)
|
||||
.getAsBoolean() != loanProduct.getLoanConfigurableAttributes().getTransactionProcessingStrategyBoolean()) {
|
||||
loanProduct.getLoanConfigurableAttributes()
|
||||
.setTransactionProcessingStrategyCode(command.parsedJson().getAsJsonObject()
|
||||
.getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.transactionProcessingStrategyCodeParamName).getAsBoolean());
|
||||
}
|
||||
|
||||
if (command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.interestCalculationPeriodTypeParamName)
|
||||
.getAsBoolean() != loanProduct.getLoanConfigurableAttributes().getInterestCalcPeriodBoolean()) {
|
||||
loanProduct.getLoanConfigurableAttributes()
|
||||
.setInterestCalculationPeriodType(command.parsedJson().getAsJsonObject()
|
||||
.getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.interestCalculationPeriodTypeParamName).getAsBoolean());
|
||||
}
|
||||
|
||||
if (command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.inArrearsToleranceParamName)
|
||||
.getAsBoolean() != loanProduct.getLoanConfigurableAttributes().getArrearsToleranceBoolean()) {
|
||||
loanProduct.getLoanConfigurableAttributes()
|
||||
.setInArrearsTolerance(command.parsedJson().getAsJsonObject()
|
||||
.getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.inArrearsToleranceParamName).getAsBoolean());
|
||||
}
|
||||
|
||||
if (command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.repaymentEveryParamName)
|
||||
.getAsBoolean() != loanProduct.getLoanConfigurableAttributes().getRepaymentEveryBoolean()) {
|
||||
loanProduct.getLoanConfigurableAttributes()
|
||||
.setRepaymentEvery(command.parsedJson().getAsJsonObject()
|
||||
.getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.repaymentEveryParamName).getAsBoolean());
|
||||
}
|
||||
|
||||
if (command.parsedJson().getAsJsonObject().getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.graceOnPrincipalAndInterestPaymentParamName)
|
||||
.getAsBoolean() != loanProduct.getLoanConfigurableAttributes().getGraceOnPrincipalAndInterestPaymentBoolean()) {
|
||||
loanProduct.getLoanConfigurableAttributes()
|
||||
.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() != loanProduct.getLoanConfigurableAttributes().getGraceOnArrearsAgingBoolean()) {
|
||||
loanProduct.getLoanConfigurableAttributes()
|
||||
.setGraceOnArrearsAgeing(command.parsedJson().getAsJsonObject()
|
||||
.getAsJsonObject(LoanProductConstants.allowAttributeOverridesParamName)
|
||||
.getAsJsonPrimitive(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME).getAsBoolean());
|
||||
}
|
||||
} else {
|
||||
loanProduct.setLoanConfigurableAttributes(LoanProductConfigurableAttributes.populateDefaultsForConfigurableAttributes());
|
||||
loanProduct.getLoanConfigurableAttributes().updateLoanProduct(loanProduct);
|
||||
}
|
||||
}
|
||||
|
||||
if (actualChanges.containsKey(LoanProductConstants.holdGuaranteeFundsParamName)) {
|
||||
if (loanProduct.isHoldGuaranteeFunds()) {
|
||||
loanProduct.setLoanProductGuaranteeDetails(guaranteeDetailsAssembler.createFrom(command));
|
||||
loanProduct.getLoanProductGuaranteeDetails().updateProduct(loanProduct);
|
||||
actualChanges.put(LoanProductConstants.mandatoryGuaranteeParamName,
|
||||
loanProduct.getLoanProductGuaranteeDetails().getMandatoryGuarantee());
|
||||
actualChanges.put(LoanProductConstants.minimumGuaranteeFromGuarantorParamName,
|
||||
loanProduct.getLoanProductGuaranteeDetails().getMinimumGuaranteeFromGuarantor());
|
||||
actualChanges.put(LoanProductConstants.minimumGuaranteeFromOwnFundsParamName,
|
||||
loanProduct.getLoanProductGuaranteeDetails().getMinimumGuaranteeFromOwnFunds());
|
||||
} else {
|
||||
loanProduct.setLoanProductRelatedDetail(null);
|
||||
}
|
||||
|
||||
} else if (loanProduct.isHoldGuaranteeFunds()) {
|
||||
guaranteeDetailsUpdateUtil.update(loanProduct.getLoanProductGuaranteeDetails(), command, actualChanges);
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamed(LoanProductConstants.principalThresholdForLastInstallmentParamName,
|
||||
loanProduct.getPrincipalThresholdForLastInstallment())) {
|
||||
BigDecimal newValue = command
|
||||
.bigDecimalValueOfParameterNamed(LoanProductConstants.principalThresholdForLastInstallmentParamName);
|
||||
actualChanges.put(LoanProductConstants.principalThresholdForLastInstallmentParamName, newValue);
|
||||
loanProduct.setPrincipalThresholdForLastInstallment(newValue);
|
||||
}
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.ACCOUNT_MOVES_OUT_OF_NPA_ONLY_ON_ARREARS_COMPLETION_PARAM_NAME,
|
||||
loanProduct.isAccountMovesOutOfNPAOnlyOnArrearsCompletion())) {
|
||||
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);
|
||||
loanProduct.setAccountMovesOutOfNPAOnlyOnArrearsCompletion(newValue);
|
||||
}
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.canDefineEmiAmountParamName,
|
||||
loanProduct.isCanDefineInstallmentAmount())) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.canDefineEmiAmountParamName);
|
||||
actualChanges.put(LoanProductConstants.canDefineEmiAmountParamName, newValue);
|
||||
loanProduct.setCanDefineInstallmentAmount(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamedWithNullCheck(LoanProductConstants.installmentAmountInMultiplesOfParamName,
|
||||
loanProduct.getInstallmentAmountInMultiplesOf())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.installmentAmountInMultiplesOfParamName);
|
||||
actualChanges.put(LoanProductConstants.installmentAmountInMultiplesOfParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanProduct.setInstallmentAmountInMultiplesOf(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.CAN_USE_FOR_TOPUP, loanProduct.isCanUseForTopup())) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.CAN_USE_FOR_TOPUP);
|
||||
actualChanges.put(LoanProductConstants.CAN_USE_FOR_TOPUP, newValue);
|
||||
loanProduct.setCanUseForTopup(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,
|
||||
loanProduct.getFixedPrincipalPercentagePerInstallment())) {
|
||||
BigDecimal newValue = command
|
||||
.bigDecimalValueOfParameterNamed(LoanProductConstants.fixedPrincipalPercentagePerInstallmentParamName);
|
||||
actualChanges.put(LoanProductConstants.fixedPrincipalPercentagePerInstallmentParamName, newValue);
|
||||
loanProduct.setFixedPrincipalPercentagePerInstallment(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.DISALLOW_EXPECTED_DISBURSEMENTS,
|
||||
loanProduct.isDisallowExpectedDisbursements())) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.DISALLOW_EXPECTED_DISBURSEMENTS);
|
||||
actualChanges.put(LoanProductConstants.DISALLOW_EXPECTED_DISBURSEMENTS, newValue);
|
||||
loanProduct.setDisallowExpectedDisbursements(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.ALLOW_APPROVED_DISBURSED_AMOUNTS_OVER_APPLIED,
|
||||
loanProduct.isAllowApprovedDisbursedAmountsOverApplied())) {
|
||||
final boolean newValue = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ALLOW_APPROVED_DISBURSED_AMOUNTS_OVER_APPLIED);
|
||||
actualChanges.put(LoanProductConstants.ALLOW_APPROVED_DISBURSED_AMOUNTS_OVER_APPLIED, newValue);
|
||||
loanProduct.setAllowApprovedDisbursedAmountsOverApplied(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInStringParameterNamed(LoanProductConstants.OVER_APPLIED_CALCULATION_TYPE,
|
||||
loanProduct.getOverAppliedCalculationType())) {
|
||||
final String newValue = command.stringValueOfParameterNamed(LoanProductConstants.OVER_APPLIED_CALCULATION_TYPE);
|
||||
actualChanges.put(LoanProductConstants.OVER_APPLIED_CALCULATION_TYPE, newValue);
|
||||
loanProduct.setOverAppliedCalculationType(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.OVER_APPLIED_NUMBER, loanProduct.getOverAppliedNumber())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.OVER_APPLIED_NUMBER);
|
||||
actualChanges.put(LoanProductConstants.OVER_APPLIED_NUMBER, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanProduct.setOverAppliedNumber(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.DUE_DAYS_FOR_REPAYMENT_EVENT,
|
||||
loanProduct.getDueDaysForRepaymentEvent())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.DUE_DAYS_FOR_REPAYMENT_EVENT);
|
||||
actualChanges.put(LoanProductConstants.DUE_DAYS_FOR_REPAYMENT_EVENT, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
loanProduct.setDueDaysForRepaymentEvent(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.OVER_DUE_DAYS_FOR_REPAYMENT_EVENT,
|
||||
loanProduct.getOverDueDaysForRepaymentEvent())) {
|
||||
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);
|
||||
loanProduct.setOverDueDaysForRepaymentEvent(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.ENABLE_DOWN_PAYMENT,
|
||||
loanProduct.getLoanProductRelatedDetail().isEnableDownPayment())) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ENABLE_DOWN_PAYMENT);
|
||||
actualChanges.put(LoanProductConstants.ENABLE_DOWN_PAYMENT, newValue);
|
||||
loanProduct.getLoanProductRelatedDetail().setEnableDownPayment(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamed(LoanProductConstants.DISBURSED_AMOUNT_PERCENTAGE_DOWN_PAYMENT,
|
||||
loanProduct.getLoanProductRelatedDetail().getDisbursedAmountPercentageForDownPayment())) {
|
||||
BigDecimal newValue = command.bigDecimalValueOfParameterNamed(LoanProductConstants.DISBURSED_AMOUNT_PERCENTAGE_DOWN_PAYMENT);
|
||||
actualChanges.put(LoanProductConstants.DISBURSED_AMOUNT_PERCENTAGE_DOWN_PAYMENT, newValue);
|
||||
loanProduct.getLoanProductRelatedDetail().setDisbursedAmountPercentageForDownPayment(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.ENABLE_AUTO_REPAYMENT_DOWN_PAYMENT,
|
||||
loanProduct.getLoanProductRelatedDetail().isEnableAutoRepaymentForDownPayment())) {
|
||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ENABLE_AUTO_REPAYMENT_DOWN_PAYMENT);
|
||||
actualChanges.put(LoanProductConstants.ENABLE_AUTO_REPAYMENT_DOWN_PAYMENT, newValue);
|
||||
loanProduct.getLoanProductRelatedDetail().setEnableAutoRepaymentForDownPayment(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.REPAYMENT_START_DATE_TYPE,
|
||||
loanProduct.getRepaymentStartDateType().getValue())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.REPAYMENT_START_DATE_TYPE);
|
||||
actualChanges.put(LoanProductConstants.REPAYMENT_START_DATE_TYPE, newValue);
|
||||
loanProduct.setRepaymentStartDateType(RepaymentStartDateType.fromInt(newValue));
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY,
|
||||
loanProduct.isEnableInstallmentLevelDelinquency())) {
|
||||
final boolean newValue = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY);
|
||||
actualChanges.put(LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY, newValue);
|
||||
loanProduct.updateEnableInstallmentLevelDelinquency(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.FIXED_LENGTH,
|
||||
loanProduct.getLoanProductRelatedDetail().getFixedLength())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.FIXED_LENGTH);
|
||||
actualChanges.put(LoanProductConstants.FIXED_LENGTH, newValue);
|
||||
loanProduct.getLoanProductRelatedDetail().setFixedLength(newValue);
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
private Map<String, Object> updateBorrowerCycleVariations(final LoanProduct loanProduct, final JsonCommand command) {
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<>(20);
|
||||
List<Long> variationIds = fetchAllVariationIds(loanProduct);
|
||||
updateBorrowerCycleVariations(loanProduct, command, LoanProductParamType.PRINCIPAL.getValue(),
|
||||
LoanProductConstants.PRINCIPAL_VARIATIONS_FOR_BORROWER_CYCLE_PARAMETER_NAME, actualChanges, variationIds);
|
||||
updateBorrowerCycleVariations(loanProduct, command, LoanProductParamType.INTERESTRATE.getValue(),
|
||||
LoanProductConstants.INTEREST_RATE_VARIATIONS_FOR_BORROWER_CYCLE_PARAMETER_NAME, actualChanges, variationIds);
|
||||
updateBorrowerCycleVariations(loanProduct, command, LoanProductParamType.REPAYMENT.getValue(),
|
||||
LoanProductConstants.NUMBER_OF_REPAYMENT_VARIATIONS_FOR_BORROWER_CYCLE_PARAMETER_NAME, actualChanges, variationIds);
|
||||
for (Long id : variationIds) {
|
||||
loanProduct.getBorrowerCycleVariations().remove(fetchLoanProductBorrowerCycleVariationById(loanProduct, id));
|
||||
}
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
public LoanProductBorrowerCycleVariations fetchLoanProductBorrowerCycleVariationById(LoanProduct loanProduct, Long id) {
|
||||
LoanProductBorrowerCycleVariations borrowerCycleVariation = null;
|
||||
for (LoanProductBorrowerCycleVariations cycleVariation : loanProduct.getBorrowerCycleVariations()) {
|
||||
if (id.equals(cycleVariation.getId())) {
|
||||
borrowerCycleVariation = cycleVariation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return borrowerCycleVariation;
|
||||
}
|
||||
|
||||
private List<Long> fetchAllVariationIds(LoanProduct loanProduct) {
|
||||
List<Long> list = new ArrayList<>();
|
||||
for (LoanProductBorrowerCycleVariations cycleVariation : loanProduct.getBorrowerCycleVariations()) {
|
||||
list.add(cycleVariation.getId());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private void updateBorrowerCycleVariations(final LoanProduct loanProduct, 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(loanProduct);
|
||||
loanProduct.getBorrowerCycleVariations().add(borrowerCycleVariations);
|
||||
actualChanges.put("borrowerCycleParamType", paramType);
|
||||
} else {
|
||||
variationIds.remove(id);
|
||||
LoanProductBorrowerCycleVariations existingCycleVariation = fetchLoanProductBorrowerCycleVariationById(loanProduct,
|
||||
id);
|
||||
if (!existingCycleVariation.equals(borrowerCycleVariations)) {
|
||||
existingCycleVariation.copy(borrowerCycleVariations);
|
||||
actualChanges.put("borrowerCycleId", id);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
} while (i < variationArray.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void clearVariations(LoanProduct loanProduct) {
|
||||
loanProduct.getBorrowerCycleVariations().clear();
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.service;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductVariableInstallmentConfig;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class LoanProductVariableInstallmentConfigUpdateUtil {
|
||||
|
||||
public Map<? extends String, ?> update(LoanProductVariableInstallmentConfig loanProductVariableInstallmentConfig, JsonCommand command) {
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<>(3);
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.minimumGapBetweenInstallments,
|
||||
loanProductVariableInstallmentConfig.getMinimumGap())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.minimumGapBetweenInstallments);
|
||||
actualChanges.put(LoanProductConstants.minimumGapBetweenInstallments, newValue);
|
||||
loanProductVariableInstallmentConfig.setMinimumGap(newValue);
|
||||
}
|
||||
|
||||
if (command.isChangeInIntegerParameterNamed(LoanProductConstants.maximumGapBetweenInstallments,
|
||||
loanProductVariableInstallmentConfig.getMaximumGap())) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(LoanProductConstants.maximumGapBetweenInstallments);
|
||||
actualChanges.put(LoanProductConstants.maximumGapBetweenInstallments, newValue);
|
||||
loanProductVariableInstallmentConfig.setMaximumGap(newValue);
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
}
|
||||
+7
-3
@@ -55,6 +55,8 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanChargeOffBehaviour;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.AprCalculator;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanProductAssembler;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanProductUpdateUtil;
|
||||
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.AdvancedPaymentAllocationsJsonParser;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.CreditAllocationsJsonParser;
|
||||
@@ -93,6 +95,8 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
||||
private final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory;
|
||||
private final AdvancedPaymentAllocationsJsonParser advancedPaymentJsonParser;
|
||||
private final CreditAllocationsJsonParser creditAllocationsJsonParser;
|
||||
private final LoanProductAssembler loanProductAssembler;
|
||||
private final LoanProductUpdateUtil loanProductUpdateUtil;
|
||||
private final LoanProductPaymentAllocationRuleMerger loanProductPaymentAllocationRuleMerger = new LoanProductPaymentAllocationRuleMerger();
|
||||
private final LoanProductCreditAllocationRuleMerger loanProductCreditAllocationRuleMerger = new LoanProductCreditAllocationRuleMerger();
|
||||
|
||||
@@ -123,8 +127,8 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
||||
floatingRate = this.floatingRateRepository
|
||||
.findOneWithNotFoundDetection(command.longValueOfParameterNamed("floatingRatesId"));
|
||||
}
|
||||
final LoanProduct loanProduct = LoanProduct.assembleFromJson(fund, loanTransactionProcessingStrategyCode, charges, command,
|
||||
this.aprCalculator, floatingRate, rates, loanProductPaymentAllocationRules, loanProductCreditAllocationRules);
|
||||
final LoanProduct loanProduct = loanProductAssembler.assembleFromJson(fund, loanTransactionProcessingStrategyCode, charges,
|
||||
command, this.aprCalculator, floatingRate, rates, loanProductPaymentAllocationRules, loanProductCreditAllocationRules);
|
||||
|
||||
loanProduct.updateLoanProductInRelatedClasses();
|
||||
loanProduct.setTransactionProcessingStrategyName(
|
||||
@@ -204,7 +208,7 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
||||
.findOneWithNotFoundDetection(command.longValueOfParameterNamed("floatingRatesId"));
|
||||
}
|
||||
|
||||
final Map<String, Object> changes = product.update(command, this.aprCalculator, floatingRate);
|
||||
final Map<String, Object> changes = loanProductUpdateUtil.update(product, command, this.aprCalculator, floatingRate);
|
||||
|
||||
if (changes.containsKey("fundId")) {
|
||||
final Long fundId = (Long) changes.get("fundId");
|
||||
|
||||
+6
-2
@@ -32,6 +32,8 @@ import org.apache.fineract.portfolio.fund.domain.FundRepository;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
|
||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.AprCalculator;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanProductAssembler;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanProductUpdateUtil;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.AdvancedPaymentAllocationsJsonParser;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.CreditAllocationsJsonParser;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRepository;
|
||||
@@ -79,10 +81,12 @@ public class LoanProductConfiguration {
|
||||
LoanRepositoryWrapper loanRepositoryWrapper, BusinessEventNotifierService businessEventNotifierService,
|
||||
DelinquencyBucketRepository delinquencyBucketRepository,
|
||||
LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory,
|
||||
AdvancedPaymentAllocationsJsonParser advancedPaymentJsonParser, CreditAllocationsJsonParser creditAllocationsJsonParser) {
|
||||
AdvancedPaymentAllocationsJsonParser advancedPaymentJsonParser, CreditAllocationsJsonParser creditAllocationsJsonParser,
|
||||
LoanProductAssembler loanProductAssembler, LoanProductUpdateUtil loanProductUpdateUtil) {
|
||||
return new LoanProductWritePlatformServiceJpaRepositoryImpl(context, fromApiJsonDeserializer, loanProductRepository, aprCalculator,
|
||||
fundRepository, chargeRepository, rateRepository, accountMappingWritePlatformService, fineractEntityAccessUtil,
|
||||
floatingRateRepository, loanRepositoryWrapper, businessEventNotifierService, delinquencyBucketRepository,
|
||||
loanRepaymentScheduleTransactionProcessorFactory, advancedPaymentJsonParser, creditAllocationsJsonParser);
|
||||
loanRepaymentScheduleTransactionProcessorFactory, advancedPaymentJsonParser, creditAllocationsJsonParser,
|
||||
loanProductAssembler, loanProductUpdateUtil);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user