in fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/serialization/LoanProductDataValidator.java [1242:1939]
public void validateForUpdate(final JsonCommand command, final LoanProduct loanProduct) {
String json = command.json();
if (StringUtils.isBlank(json)) {
throw new InvalidJsonException();
}
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, SUPPORTED_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource(LOANPRODUCT);
final JsonElement element = this.fromApiJsonHelper.parse(json);
if (this.fromApiJsonHelper.parameterExists(NAME, element)) {
final String name = this.fromApiJsonHelper.extractStringNamed(NAME, element);
baseDataValidator.reset().parameter(NAME).value(name).notBlank().notExceedingLengthOf(100);
}
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.SHORT_NAME, element)) {
final String shortName = this.fromApiJsonHelper.extractStringNamed(LoanProductConstants.SHORT_NAME, element);
baseDataValidator.reset().parameter(LoanProductConstants.SHORT_NAME).value(shortName).notBlank().notExceedingLengthOf(4);
}
if (this.fromApiJsonHelper.parameterExists(DESCRIPTION, element)) {
final String description = this.fromApiJsonHelper.extractStringNamed(DESCRIPTION, element);
baseDataValidator.reset().parameter(DESCRIPTION).value(description).notExceedingLengthOf(500);
}
if (this.fromApiJsonHelper.parameterExists(FUND_ID, element)) {
final Long fundId = this.fromApiJsonHelper.extractLongNamed(FUND_ID, element);
baseDataValidator.reset().parameter(FUND_ID).value(fundId).ignoreIfNull().integerGreaterThanZero();
}
if (this.fromApiJsonHelper.parameterExists(INCLUDE_IN_BORROWER_CYCLE, element)) {
final Boolean includeInBorrowerCycle = this.fromApiJsonHelper.extractBooleanNamed(INCLUDE_IN_BORROWER_CYCLE, element);
baseDataValidator.reset().parameter(INCLUDE_IN_BORROWER_CYCLE).value(includeInBorrowerCycle).ignoreIfNull()
.validateForBooleanValue();
}
if (this.fromApiJsonHelper.parameterExists(CURRENCY_CODE, element)) {
final String currencyCode = this.fromApiJsonHelper.extractStringNamed(CURRENCY_CODE, element);
baseDataValidator.reset().parameter(CURRENCY_CODE).value(currencyCode).notBlank().notExceedingLengthOf(3);
}
if (this.fromApiJsonHelper.parameterExists(DIGITS_AFTER_DECIMAL, element)) {
final Integer digitsAfterDecimal = this.fromApiJsonHelper.extractIntegerNamed(DIGITS_AFTER_DECIMAL, element,
Locale.getDefault());
baseDataValidator.reset().parameter(DIGITS_AFTER_DECIMAL).value(digitsAfterDecimal).notNull().inMinMaxRange(0, 6);
}
if (this.fromApiJsonHelper.parameterExists(IN_MULTIPLES_OF, element)) {
final Integer inMultiplesOf = this.fromApiJsonHelper.extractIntegerNamed(IN_MULTIPLES_OF, element, Locale.getDefault());
baseDataValidator.reset().parameter(IN_MULTIPLES_OF).value(inMultiplesOf).ignoreIfNull().integerZeroOrGreater();
}
final String minPrincipalParameterName = MIN_PRINCIPAL;
BigDecimal minPrincipalAmount;
if (this.fromApiJsonHelper.parameterExists(minPrincipalParameterName, element)) {
minPrincipalAmount = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(minPrincipalParameterName, element);
baseDataValidator.reset().parameter(minPrincipalParameterName).value(minPrincipalAmount).ignoreIfNull().positiveAmount();
}
final String maxPrincipalParameterName = MAX_PRINCIPAL;
BigDecimal maxPrincipalAmount;
if (this.fromApiJsonHelper.parameterExists(maxPrincipalParameterName, element)) {
maxPrincipalAmount = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(maxPrincipalParameterName, element);
baseDataValidator.reset().parameter(maxPrincipalParameterName).value(maxPrincipalAmount).ignoreIfNull().positiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(PRINCIPAL, element)) {
final BigDecimal principal = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(PRINCIPAL, element);
baseDataValidator.reset().parameter(PRINCIPAL).value(principal).positiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(IN_ARREARS_TOLERANCE, element)) {
final BigDecimal inArrearsTolerance = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(IN_ARREARS_TOLERANCE, element);
baseDataValidator.reset().parameter(IN_ARREARS_TOLERANCE).value(inArrearsTolerance).ignoreIfNull().zeroOrPositiveAmount();
}
final String minNumberOfRepaymentsParameterName = MIN_NUMBER_OF_REPAYMENTS;
Integer minNumberOfRepayments;
if (this.fromApiJsonHelper.parameterExists(minNumberOfRepaymentsParameterName, element)) {
minNumberOfRepayments = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(minNumberOfRepaymentsParameterName, element);
baseDataValidator.reset().parameter(minNumberOfRepaymentsParameterName).value(minNumberOfRepayments).ignoreIfNull()
.integerGreaterThanZero();
}
final String maxNumberOfRepaymentsParameterName = MAX_NUMBER_OF_REPAYMENTS;
Integer maxNumberOfRepayments;
if (this.fromApiJsonHelper.parameterExists(maxNumberOfRepaymentsParameterName, element)) {
maxNumberOfRepayments = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(maxNumberOfRepaymentsParameterName, element);
baseDataValidator.reset().parameter(maxNumberOfRepaymentsParameterName).value(maxNumberOfRepayments).ignoreIfNull()
.integerGreaterThanZero();
}
Integer numberOfRepayments = null;
if (this.fromApiJsonHelper.parameterExists(NUMBER_OF_REPAYMENTS, element)) {
numberOfRepayments = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(NUMBER_OF_REPAYMENTS, element);
baseDataValidator.reset().parameter(NUMBER_OF_REPAYMENTS).value(numberOfRepayments).notNull().integerGreaterThanZero();
}
if (numberOfRepayments == null) {
numberOfRepayments = loanProduct.getNumberOfRepayments();
}
Integer repaymentEvery = loanProduct.getLoanProductRelatedDetail().getRepayEvery();
if (this.fromApiJsonHelper.parameterExists(REPAYMENT_EVERY, element)) {
repaymentEvery = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(REPAYMENT_EVERY, element);
baseDataValidator.reset().parameter(REPAYMENT_EVERY).value(repaymentEvery).notNull().integerGreaterThanZero();
}
if (this.fromApiJsonHelper.parameterExists(REPAYMENT_FREQUENCY_TYPE, element)) {
final Integer repaymentFrequencyType = this.fromApiJsonHelper.extractIntegerNamed(REPAYMENT_FREQUENCY_TYPE, element,
Locale.getDefault());
baseDataValidator.reset().parameter(REPAYMENT_FREQUENCY_TYPE).value(repaymentFrequencyType).notNull().inMinMaxRange(0, 3);
}
String transactionProcessingStrategyCode = loanProduct.getTransactionProcessingStrategyCode();
if (this.fromApiJsonHelper.parameterExists(TRANSACTION_PROCESSING_STRATEGY_CODE, element)) {
transactionProcessingStrategyCode = this.fromApiJsonHelper.extractStringNamed(TRANSACTION_PROCESSING_STRATEGY_CODE, element);
baseDataValidator.reset().parameter(TRANSACTION_PROCESSING_STRATEGY_CODE).value(transactionProcessingStrategyCode).notBlank();
// Validating whether the processor is existing
loanRepaymentScheduleTransactionProcessorFactory.determineProcessor(transactionProcessingStrategyCode);
}
// grace validation
Integer graceOnPrincipalPayment = loanProduct.getLoanProductRelatedDetail().getGraceOnPrincipalPayment();
if (this.fromApiJsonHelper.parameterExists(GRACE_ON_PRINCIPAL_PAYMENT, element)) {
graceOnPrincipalPayment = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(GRACE_ON_PRINCIPAL_PAYMENT, element);
baseDataValidator.reset().parameter(GRACE_ON_PRINCIPAL_PAYMENT).value(graceOnPrincipalPayment).zeroOrPositiveAmount();
}
Integer graceOnInterestPayment = loanProduct.getLoanProductRelatedDetail().getGraceOnInterestPayment();
if (this.fromApiJsonHelper.parameterExists(GRACE_ON_INTEREST_PAYMENT, element)) {
graceOnInterestPayment = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(GRACE_ON_INTEREST_PAYMENT, element);
baseDataValidator.reset().parameter(GRACE_ON_INTEREST_PAYMENT).value(graceOnInterestPayment).zeroOrPositiveAmount();
}
Integer graceOnInterestCharged = loanProduct.getLoanProductRelatedDetail().getGraceOnInterestCharged();
if (this.fromApiJsonHelper.parameterExists(GRACE_ON_INTEREST_CHARGED, element)) {
graceOnInterestCharged = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(GRACE_ON_INTEREST_CHARGED, element);
baseDataValidator.reset().parameter(GRACE_ON_INTEREST_CHARGED).value(graceOnInterestCharged).zeroOrPositiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME, element)) {
final Integer graceOnArrearsAgeing = this.fromApiJsonHelper
.extractIntegerWithLocaleNamed(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME, element);
baseDataValidator.reset().parameter(LoanProductConstants.GRACE_ON_ARREARS_AGEING_PARAMETER_NAME).value(graceOnArrearsAgeing)
.integerZeroOrGreater();
}
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.OVERDUE_DAYS_FOR_NPA_PARAMETER_NAME, element)) {
final Integer overdueDaysForNPA = this.fromApiJsonHelper
.extractIntegerWithLocaleNamed(LoanProductConstants.OVERDUE_DAYS_FOR_NPA_PARAMETER_NAME, element);
baseDataValidator.reset().parameter(LoanProductConstants.OVERDUE_DAYS_FOR_NPA_PARAMETER_NAME).value(overdueDaysForNPA)
.integerZeroOrGreater();
}
Long delinquencyBucketId = null;
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.DELINQUENCY_BUCKET_PARAM_NAME, element)) {
delinquencyBucketId = this.fromApiJsonHelper.extractLongNamed(LoanProductConstants.DELINQUENCY_BUCKET_PARAM_NAME, element);
baseDataValidator.reset().parameter(LoanProductConstants.DELINQUENCY_BUCKET_PARAM_NAME).value(delinquencyBucketId)
.ignoreIfNull().integerGreaterThanZero();
}
Integer amortizationType = null;
if (this.fromApiJsonHelper.parameterExists(AMORTIZATION_TYPE, element)) {
amortizationType = this.fromApiJsonHelper.extractIntegerNamed(AMORTIZATION_TYPE, element, Locale.getDefault());
baseDataValidator.reset().parameter(AMORTIZATION_TYPE).value(amortizationType).notNull().inMinMaxRange(0, 1);
}
if (this.fromApiJsonHelper.parameterExists(INTEREST_TYPE, element)) {
final Integer interestType = this.fromApiJsonHelper.extractIntegerNamed(INTEREST_TYPE, element, Locale.getDefault());
baseDataValidator.reset().parameter(INTEREST_TYPE).value(interestType).notNull().inMinMaxRange(0, 1);
}
Integer interestCalculationPeriodType = loanProduct.getLoanProductRelatedDetail().getInterestCalculationPeriodMethod().getValue();
if (this.fromApiJsonHelper.parameterExists(INTEREST_CALCULATION_PERIOD_TYPE, element)) {
interestCalculationPeriodType = this.fromApiJsonHelper.extractIntegerNamed(INTEREST_CALCULATION_PERIOD_TYPE, element,
Locale.getDefault());
baseDataValidator.reset().parameter(INTEREST_CALCULATION_PERIOD_TYPE).value(interestCalculationPeriodType).notNull()
.inMinMaxRange(0, 1);
}
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.DAYS_IN_YEAR_TYPE_PARAMETER_NAME, element)) {
final Integer daysInYearType = this.fromApiJsonHelper.extractIntegerNamed(LoanProductConstants.DAYS_IN_YEAR_TYPE_PARAMETER_NAME,
element, Locale.getDefault());
baseDataValidator.reset().parameter(LoanProductConstants.DAYS_IN_YEAR_TYPE_PARAMETER_NAME).value(daysInYearType).notNull()
.isOneOfTheseValues(1, 360, 364, 365);
}
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.DAYS_IN_YEAR_TYPE_PARAMETER_NAME, element)) {
final Integer daysInMonthType = this.fromApiJsonHelper
.extractIntegerNamed(LoanProductConstants.DAYS_IN_MONTH_TYPE_PARAMETER_NAME, element, Locale.getDefault());
baseDataValidator.reset().parameter(LoanProductConstants.DAYS_IN_MONTH_TYPE_PARAMETER_NAME).value(daysInMonthType).notNull()
.isOneOfTheseValues(1, 30);
}
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.ACCOUNT_MOVES_OUT_OF_NPA_ONLY_ON_ARREARS_COMPLETION_PARAM_NAME,
element)) {
Boolean npaChangeConfig = this.fromApiJsonHelper
.extractBooleanNamed(LoanProductConstants.ACCOUNT_MOVES_OUT_OF_NPA_ONLY_ON_ARREARS_COMPLETION_PARAM_NAME, element);
baseDataValidator.reset().parameter(LoanProductConstants.ACCOUNT_MOVES_OUT_OF_NPA_ONLY_ON_ARREARS_COMPLETION_PARAM_NAME)
.value(npaChangeConfig).notNull().isOneOfTheseValues(true, false);
}
boolean isEqualAmortization = loanProduct.isEqualAmortization();
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.IS_EQUAL_AMORTIZATION_PARAM, element)) {
isEqualAmortization = this.fromApiJsonHelper.extractBooleanNamed(LoanProductConstants.IS_EQUAL_AMORTIZATION_PARAM, element);
baseDataValidator.reset().parameter(LoanProductConstants.IS_EQUAL_AMORTIZATION_PARAM).value(isEqualAmortization).ignoreIfNull()
.validateForBooleanValue();
}
// Interest recalculation settings
Boolean isInterestRecalculationEnabled = loanProduct.isInterestRecalculationEnabled();
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.IS_INTEREST_RECALCULATION_ENABLED_PARAMETER_NAME, element)) {
isInterestRecalculationEnabled = this.fromApiJsonHelper
.extractBooleanNamed(LoanProductConstants.IS_INTEREST_RECALCULATION_ENABLED_PARAMETER_NAME, element);
baseDataValidator.reset().parameter(LoanProductConstants.IS_INTEREST_RECALCULATION_ENABLED_PARAMETER_NAME)
.value(isInterestRecalculationEnabled).notNull().isOneOfTheseValues(true, false);
}
if (isInterestRecalculationEnabled != null && isInterestRecalculationEnabled) {
if (isEqualAmortization) {
throw new EqualAmortizationUnsupportedFeatureException("interest.recalculation", "interest recalculation");
}
validateInterestRecalculationParams(element, baseDataValidator, loanProduct);
}
// interest rates
boolean isLinkedToFloatingInterestRates = loanProduct.isLinkedToFloatingInterestRate();
if (this.fromApiJsonHelper.parameterExists(IS_LINKED_TO_FLOATING_INTEREST_RATES, element)) {
isLinkedToFloatingInterestRates = this.fromApiJsonHelper.extractBooleanNamed(IS_LINKED_TO_FLOATING_INTEREST_RATES, element);
}
boolean isInterestBearing = false;
if (isLinkedToFloatingInterestRates) {
if (isEqualAmortization) {
throw new EqualAmortizationUnsupportedFeatureException("floating.interest.rate", "floating interest rate");
}
if (this.fromApiJsonHelper.parameterExists(INTEREST_RATE_PER_PERIOD, element)) {
baseDataValidator.reset().parameter(INTEREST_RATE_PER_PERIOD).failWithCode(
"not.supported.when.isLinkedToFloatingInterestRates.is.true",
"interestRatePerPeriod param is not supported when isLinkedToFloatingInterestRates is true");
}
if (this.fromApiJsonHelper.parameterExists(MIN_INTEREST_RATE_PER_PERIOD, element)) {
baseDataValidator.reset().parameter(MIN_INTEREST_RATE_PER_PERIOD).failWithCode(
"not.supported.when.isLinkedToFloatingInterestRates.is.true",
"minInterestRatePerPeriod param is not supported when isLinkedToFloatingInterestRates is true");
}
if (this.fromApiJsonHelper.parameterExists(MAX_INTEREST_RATE_PER_PERIOD, element)) {
baseDataValidator.reset().parameter(MAX_INTEREST_RATE_PER_PERIOD).failWithCode(
"not.supported.when.isLinkedToFloatingInterestRates.is.true",
"maxInterestRatePerPeriod param is not supported when isLinkedToFloatingInterestRates is true");
}
if (this.fromApiJsonHelper.parameterExists(INTEREST_RATE_FREQUENCY_TYPE, element)) {
baseDataValidator.reset().parameter(INTEREST_RATE_FREQUENCY_TYPE).failWithCode(
"not.supported.when.isLinkedToFloatingInterestRates.is.true",
"interestRateFrequencyType param is not supported when isLinkedToFloatingInterestRates is true");
}
Integer interestType = this.fromApiJsonHelper.parameterExists(INTEREST_TYPE, element)
? this.fromApiJsonHelper.extractIntegerNamed(INTEREST_TYPE, element, Locale.getDefault())
: loanProduct.getLoanProductRelatedDetail().getInterestMethod().getValue();
if ((interestType == null || !interestType.equals(InterestMethod.DECLINING_BALANCE.getValue()))
|| (isInterestRecalculationEnabled == null || !isInterestRecalculationEnabled)) {
baseDataValidator.reset().parameter(IS_LINKED_TO_FLOATING_INTEREST_RATES).failWithCode(
"supported.only.for.declining.balance.interest.recalculation.enabled",
"Floating interest rates are supported only for declining balance and interest recalculation enabled loan products");
}
Long floatingRatesId = loanProduct.getFloatingRates() == null ? null : loanProduct.getFloatingRates().getFloatingRate().getId();
if (this.fromApiJsonHelper.parameterExists(FLOATING_RATES_ID, element)) {
floatingRatesId = this.fromApiJsonHelper.extractLongNamed(FLOATING_RATES_ID, element);
}
baseDataValidator.reset().parameter(FLOATING_RATES_ID).value(floatingRatesId).notNull();
BigDecimal interestRateDifferential = loanProduct.getFloatingRates() == null ? null
: loanProduct.getFloatingRates().getInterestRateDifferential();
if (this.fromApiJsonHelper.parameterExists(INTEREST_RATE_DIFFERENTIAL, element)) {
interestRateDifferential = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(INTEREST_RATE_DIFFERENTIAL, element);
}
baseDataValidator.reset().parameter(INTEREST_RATE_DIFFERENTIAL).value(interestRateDifferential).notNull()
.zeroOrPositiveAmount();
final String minDifferentialLendingRateParameterName = MIN_DIFFERENTIAL_LENDING_RATE;
BigDecimal minDifferentialLendingRate = loanProduct.getFloatingRates() == null ? null
: loanProduct.getFloatingRates().getMinDifferentialLendingRate();
if (this.fromApiJsonHelper.parameterExists(minDifferentialLendingRateParameterName, element)) {
minDifferentialLendingRate = this.fromApiJsonHelper
.extractBigDecimalWithLocaleNamed(minDifferentialLendingRateParameterName, element);
}
baseDataValidator.reset().parameter(minDifferentialLendingRateParameterName).value(minDifferentialLendingRate).notNull()
.zeroOrPositiveAmount();
final String defaultDifferentialLendingRateParameterName = DEFAULT_DIFFERENTIAL_LENDING_RATE;
BigDecimal defaultDifferentialLendingRate = loanProduct.getFloatingRates() == null ? null
: loanProduct.getFloatingRates().getDefaultDifferentialLendingRate();
if (this.fromApiJsonHelper.parameterExists(defaultDifferentialLendingRateParameterName, element)) {
defaultDifferentialLendingRate = this.fromApiJsonHelper
.extractBigDecimalWithLocaleNamed(defaultDifferentialLendingRateParameterName, element);
}
baseDataValidator.reset().parameter(defaultDifferentialLendingRateParameterName).value(defaultDifferentialLendingRate).notNull()
.zeroOrPositiveAmount();
final String maxDifferentialLendingRateParameterName = MAX_DIFFERENTIAL_LENDING_RATE;
BigDecimal maxDifferentialLendingRate = loanProduct.getFloatingRates() == null ? null
: loanProduct.getFloatingRates().getMaxDifferentialLendingRate();
if (this.fromApiJsonHelper.parameterExists(maxDifferentialLendingRateParameterName, element)) {
maxDifferentialLendingRate = this.fromApiJsonHelper
.extractBigDecimalWithLocaleNamed(maxDifferentialLendingRateParameterName, element);
}
baseDataValidator.reset().parameter(maxDifferentialLendingRateParameterName).value(maxDifferentialLendingRate).notNull()
.zeroOrPositiveAmount();
if (defaultDifferentialLendingRate != null && defaultDifferentialLendingRate.compareTo(BigDecimal.ZERO) >= 0
&& minDifferentialLendingRate != null && minDifferentialLendingRate.compareTo(BigDecimal.ZERO) >= 0) {
baseDataValidator.reset().parameter(DEFAULT_DIFFERENTIAL_LENDING_RATE).value(defaultDifferentialLendingRate)
.notLessThanMin(minDifferentialLendingRate);
}
if (maxDifferentialLendingRate != null && maxDifferentialLendingRate.compareTo(BigDecimal.ZERO) >= 0
&& minDifferentialLendingRate != null && minDifferentialLendingRate.compareTo(BigDecimal.ZERO) >= 0) {
baseDataValidator.reset().parameter(MAX_DIFFERENTIAL_LENDING_RATE).value(maxDifferentialLendingRate)
.notLessThanMin(minDifferentialLendingRate);
}
if (maxDifferentialLendingRate != null && maxDifferentialLendingRate.compareTo(BigDecimal.ZERO) >= 0
&& defaultDifferentialLendingRate != null && defaultDifferentialLendingRate.compareTo(BigDecimal.ZERO) >= 0) {
baseDataValidator.reset().parameter(MAX_DIFFERENTIAL_LENDING_RATE).value(maxDifferentialLendingRate)
.notLessThanMin(defaultDifferentialLendingRate);
}
Boolean isFloatingInterestRateCalculationAllowed = loanProduct.getFloatingRates() == null ? null
: loanProduct.getFloatingRates().isFloatingInterestRateCalculationAllowed();
if (this.fromApiJsonHelper.parameterExists(IS_FLOATING_INTEREST_RATE_CALCULATION_ALLOWED, element)) {
isFloatingInterestRateCalculationAllowed = this.fromApiJsonHelper
.extractBooleanNamed(IS_FLOATING_INTEREST_RATE_CALCULATION_ALLOWED, element);
}
baseDataValidator.reset().parameter(IS_FLOATING_INTEREST_RATE_CALCULATION_ALLOWED)
.value(isFloatingInterestRateCalculationAllowed).notNull().isOneOfTheseValues(true, false);
isInterestBearing = true;
} else {
if (this.fromApiJsonHelper.parameterExists(FLOATING_RATES_ID, element)) {
baseDataValidator.reset().parameter(FLOATING_RATES_ID).failWithCode(
"not.supported.when.isLinkedToFloatingInterestRates.is.false",
"floatingRatesId param is not supported when isLinkedToFloatingInterestRates is not supplied or false");
}
if (this.fromApiJsonHelper.parameterExists(INTEREST_RATE_DIFFERENTIAL, element)) {
baseDataValidator.reset().parameter(INTEREST_RATE_DIFFERENTIAL).failWithCode(
"not.supported.when.isLinkedToFloatingInterestRates.is.false",
"interestRateDifferential param is not supported when isLinkedToFloatingInterestRates is not supplied or false");
}
if (this.fromApiJsonHelper.parameterExists(MIN_DIFFERENTIAL_LENDING_RATE, element)) {
baseDataValidator.reset().parameter(MIN_DIFFERENTIAL_LENDING_RATE).failWithCode(
"not.supported.when.isLinkedToFloatingInterestRates.is.false",
"minDifferentialLendingRate param is not supported when isLinkedToFloatingInterestRates is not supplied or false");
}
if (this.fromApiJsonHelper.parameterExists(DEFAULT_DIFFERENTIAL_LENDING_RATE, element)) {
baseDataValidator.reset().parameter(DEFAULT_DIFFERENTIAL_LENDING_RATE).failWithCode(
"not.supported.when.isLinkedToFloatingInterestRates.is.false",
"defaultDifferentialLendingRate param is not supported when isLinkedToFloatingInterestRates is not supplied or false");
}
if (this.fromApiJsonHelper.parameterExists(MAX_DIFFERENTIAL_LENDING_RATE, element)) {
baseDataValidator.reset().parameter(MAX_DIFFERENTIAL_LENDING_RATE).failWithCode(
"not.supported.when.isLinkedToFloatingInterestRates.is.false",
"maxDifferentialLendingRate param is not supported when isLinkedToFloatingInterestRates is not supplied or false");
}
if (this.fromApiJsonHelper.parameterExists(IS_FLOATING_INTEREST_RATE_CALCULATION_ALLOWED, element)) {
baseDataValidator.reset().parameter(IS_FLOATING_INTEREST_RATE_CALCULATION_ALLOWED).failWithCode(
"not.supported.when.isLinkedToFloatingInterestRates.is.false",
"isFloatingInterestRateCalculationAllowed param is not supported when isLinkedToFloatingInterestRates is not supplied or false");
}
final String minInterestRatePerPeriodParameterName = MIN_INTEREST_RATE_PER_PERIOD;
BigDecimal minInterestRatePerPeriod = loanProduct.getMinNominalInterestRatePerPeriod();
if (this.fromApiJsonHelper.parameterExists(minInterestRatePerPeriodParameterName, element)) {
minInterestRatePerPeriod = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(minInterestRatePerPeriodParameterName,
element);
}
baseDataValidator.reset().parameter(minInterestRatePerPeriodParameterName).value(minInterestRatePerPeriod).ignoreIfNull()
.zeroOrPositiveAmount();
final String maxInterestRatePerPeriodParameterName = MAX_INTEREST_RATE_PER_PERIOD;
BigDecimal maxInterestRatePerPeriod = loanProduct.getMaxNominalInterestRatePerPeriod();
if (this.fromApiJsonHelper.parameterExists(maxInterestRatePerPeriodParameterName, element)) {
maxInterestRatePerPeriod = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(maxInterestRatePerPeriodParameterName,
element);
}
baseDataValidator.reset().parameter(maxInterestRatePerPeriodParameterName).value(maxInterestRatePerPeriod).ignoreIfNull()
.zeroOrPositiveAmount();
BigDecimal interestRatePerPeriod = loanProduct.getLoanProductRelatedDetail().getNominalInterestRatePerPeriod();
if (this.fromApiJsonHelper.parameterExists(INTEREST_RATE_PER_PERIOD, element)) {
interestRatePerPeriod = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(INTEREST_RATE_PER_PERIOD, element);
}
baseDataValidator.reset().parameter(INTEREST_RATE_PER_PERIOD).value(interestRatePerPeriod).notNull().zeroOrPositiveAmount();
Integer interestRateFrequencyType = loanProduct.getLoanProductRelatedDetail().getInterestPeriodFrequencyType().getValue();
if (this.fromApiJsonHelper.parameterExists(INTEREST_RATE_FREQUENCY_TYPE, element)) {
interestRateFrequencyType = this.fromApiJsonHelper.extractIntegerNamed(INTEREST_RATE_FREQUENCY_TYPE, element,
Locale.getDefault());
}
baseDataValidator.reset().parameter(INTEREST_RATE_FREQUENCY_TYPE).value(interestRateFrequencyType).notNull().inMinMaxRange(0,
4);
isInterestBearing = MathUtil.isGreaterThanZero(interestRatePerPeriod);
}
// Fixed Length validation
fixedLengthValidations(transactionProcessingStrategyCode, isInterestBearing, numberOfRepayments, repaymentEvery, element,
baseDataValidator);
// Guarantee Funds
Boolean holdGuaranteeFunds = loanProduct.isHoldGuaranteeFunds();
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.holdGuaranteeFundsParamName, element)) {
holdGuaranteeFunds = this.fromApiJsonHelper.extractBooleanNamed(LoanProductConstants.holdGuaranteeFundsParamName, element);
baseDataValidator.reset().parameter(LoanProductConstants.holdGuaranteeFundsParamName).value(holdGuaranteeFunds).notNull()
.isOneOfTheseValues(true, false);
}
if (holdGuaranteeFunds != null && holdGuaranteeFunds) {
validateGuaranteeParams(element, baseDataValidator, null);
}
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.principalThresholdForLastInstallmentParamName, element)) {
BigDecimal principalThresholdForLastInstallment = this.fromApiJsonHelper
.extractBigDecimalWithLocaleNamed(LoanProductConstants.principalThresholdForLastInstallmentParamName, element);
baseDataValidator.reset().parameter(LoanProductConstants.principalThresholdForLastInstallmentParamName)
.value(principalThresholdForLastInstallment).notNull().notLessThanMin(BigDecimal.ZERO)
.notGreaterThanMax(BigDecimal.valueOf(100));
}
BigDecimal fixedPrincipalPercentagePerInstallment = this.fromApiJsonHelper
.extractBigDecimalWithLocaleNamed(LoanProductConstants.fixedPrincipalPercentagePerInstallmentParamName, element);
baseDataValidator.reset().parameter(LoanProductConstants.fixedPrincipalPercentagePerInstallmentParamName)
.value(fixedPrincipalPercentagePerInstallment).notLessThanMin(BigDecimal.ONE).notGreaterThanMax(BigDecimal.valueOf(100));
if (!AmortizationMethod.EQUAL_PRINCIPAL.getValue().equals(amortizationType) && fixedPrincipalPercentagePerInstallment != null) {
baseDataValidator.reset().parameter(LoanApiConstants.fixedPrincipalPercentagePerInstallmentParamName).failWithCode(
"not.supported.principal.fixing.not.allowed.with.equal.installments",
"Principal fixing cannot be done with equal installment amortization");
}
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.canDefineEmiAmountParamName, element)) {
final Boolean canDefineInstallmentAmount = this.fromApiJsonHelper
.extractBooleanNamed(LoanProductConstants.canDefineEmiAmountParamName, element);
baseDataValidator.reset().parameter(LoanProductConstants.canDefineEmiAmountParamName).value(canDefineInstallmentAmount)
.isOneOfTheseValues(true, false);
}
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.installmentAmountInMultiplesOfParamName, element)) {
final Integer installmentAmountInMultiplesOf = this.fromApiJsonHelper
.extractIntegerWithLocaleNamed(LoanProductConstants.installmentAmountInMultiplesOfParamName, element);
baseDataValidator.reset().parameter(LoanProductConstants.installmentAmountInMultiplesOfParamName)
.value(installmentAmountInMultiplesOf).ignoreIfNull().integerGreaterThanZero();
}
final Integer accountingRuleType = this.fromApiJsonHelper.extractIntegerNamed(ACCOUNTING_RULE, element, Locale.getDefault());
baseDataValidator.reset().parameter(ACCOUNTING_RULE).value(accountingRuleType).ignoreIfNull().inMinMaxRange(1, 4);
boolean actualValue = loanProduct.getLoanProductRelatedDetail().isEnableAccrualActivityPosting();
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.ENABLE_ACCRUAL_ACTIVITY_POSTING, element)) {
final Boolean enableAccrualActivityPosting = this.fromApiJsonHelper
.extractBooleanNamed(LoanProductConstants.ENABLE_ACCRUAL_ACTIVITY_POSTING, element);
baseDataValidator.reset().parameter(LoanProductConstants.ENABLE_ACCRUAL_ACTIVITY_POSTING).value(enableAccrualActivityPosting)
.ignoreIfNull().validateForBooleanValue();
actualValue = enableAccrualActivityPosting;
}
if (actualValue) {
Integer ruleType = accountingRuleType;
if (ruleType == null && loanProduct.getAccountingRule() != null) {
ruleType = loanProduct.getAccountingRule().getValue();
}
if (!AccountingValidations.isAccrualBasedAccounting(ruleType)) {
baseDataValidator.reset().parameter(LoanProductConstants.ENABLE_ACCRUAL_ACTIVITY_POSTING)
.failWithCode("should be false for non accrual accounting");
}
}
final Long fundAccountId = this.fromApiJsonHelper.extractLongNamed(LoanProductAccountingParams.FUND_SOURCE.getValue(), element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.FUND_SOURCE.getValue()).value(fundAccountId).ignoreIfNull()
.integerGreaterThanZero();
final Long loanPortfolioAccountId = this.fromApiJsonHelper.extractLongNamed(LoanProductAccountingParams.LOAN_PORTFOLIO.getValue(),
element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.LOAN_PORTFOLIO.getValue()).value(loanPortfolioAccountId)
.ignoreIfNull().integerGreaterThanZero();
final Long transfersInSuspenseAccountId = this.fromApiJsonHelper
.extractLongNamed(LoanProductAccountingParams.TRANSFERS_SUSPENSE.getValue(), element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.TRANSFERS_SUSPENSE.getValue()).value(transfersInSuspenseAccountId)
.ignoreIfNull().integerGreaterThanZero();
final Long incomeFromInterestId = this.fromApiJsonHelper.extractLongNamed(LoanProductAccountingParams.INTEREST_ON_LOANS.getValue(),
element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.INTEREST_ON_LOANS.getValue()).value(incomeFromInterestId)
.ignoreIfNull().integerGreaterThanZero();
final Long incomeFromFeeId = this.fromApiJsonHelper.extractLongNamed(LoanProductAccountingParams.INCOME_FROM_FEES.getValue(),
element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.INCOME_FROM_FEES.getValue()).value(incomeFromFeeId).ignoreIfNull()
.integerGreaterThanZero();
final Long incomeFromPenaltyId = this.fromApiJsonHelper
.extractLongNamed(LoanProductAccountingParams.INCOME_FROM_PENALTIES.getValue(), element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.INCOME_FROM_PENALTIES.getValue()).value(incomeFromPenaltyId)
.ignoreIfNull().integerGreaterThanZero();
final Long incomeFromRecoveryAccountId = this.fromApiJsonHelper
.extractLongNamed(LoanProductAccountingParams.INCOME_FROM_RECOVERY.getValue(), element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.INCOME_FROM_RECOVERY.getValue()).value(incomeFromRecoveryAccountId)
.ignoreIfNull().integerGreaterThanZero();
final Long writeOffAccountId = this.fromApiJsonHelper.extractLongNamed(LoanProductAccountingParams.LOSSES_WRITTEN_OFF.getValue(),
element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.LOSSES_WRITTEN_OFF.getValue()).value(writeOffAccountId)
.ignoreIfNull().integerGreaterThanZero();
final Long goodwillCreditAccountId = this.fromApiJsonHelper
.extractLongNamed(LoanProductAccountingParams.LOSSES_WRITTEN_OFF.getValue(), element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.GOODWILL_CREDIT.getValue()).value(goodwillCreditAccountId)
.ignoreIfNull().integerGreaterThanZero();
final Long overpaymentAccountId = this.fromApiJsonHelper.extractLongNamed(LoanProductAccountingParams.OVERPAYMENT.getValue(),
element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.OVERPAYMENT.getValue()).value(overpaymentAccountId).ignoreIfNull()
.integerGreaterThanZero();
final Long receivableInterestAccountId = this.fromApiJsonHelper
.extractLongNamed(LoanProductAccountingParams.INTEREST_RECEIVABLE.getValue(), element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.INTEREST_RECEIVABLE.getValue()).value(receivableInterestAccountId)
.ignoreIfNull().integerGreaterThanZero();
final Long receivableFeeAccountId = this.fromApiJsonHelper.extractLongNamed(LoanProductAccountingParams.FEES_RECEIVABLE.getValue(),
element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.FEES_RECEIVABLE.getValue()).value(receivableFeeAccountId)
.ignoreIfNull().integerGreaterThanZero();
final Long receivablePenaltyAccountId = this.fromApiJsonHelper
.extractLongNamed(LoanProductAccountingParams.PENALTIES_RECEIVABLE.getValue(), element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.PENALTIES_RECEIVABLE.getValue()).value(receivablePenaltyAccountId)
.ignoreIfNull().integerGreaterThanZero();
final Long incomeFromChargeOffInterestAccountId = this.fromApiJsonHelper
.extractLongNamed(LoanProductAccountingParams.INCOME_FROM_CHARGE_OFF_INTEREST.getValue(), element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.INCOME_FROM_CHARGE_OFF_INTEREST.getValue())
.value(incomeFromChargeOffInterestAccountId).ignoreIfNull().integerGreaterThanZero();
final Long incomeFromChargeOffFeesAccountId = this.fromApiJsonHelper
.extractLongNamed(LoanProductAccountingParams.INCOME_FROM_CHARGE_OFF_FEES.getValue(), element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.INCOME_FROM_CHARGE_OFF_FEES.getValue())
.value(incomeFromChargeOffFeesAccountId).ignoreIfNull().integerGreaterThanZero();
final Long incomeFromChargeOffPenaltyAccountId = this.fromApiJsonHelper
.extractLongNamed(LoanProductAccountingParams.INCOME_FROM_CHARGE_OFF_PENALTY.getValue(), element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.INCOME_FROM_CHARGE_OFF_PENALTY.getValue())
.value(incomeFromChargeOffPenaltyAccountId).ignoreIfNull().integerGreaterThanZero();
final Long incomeFromGoodwillCreditInterestAccountId = this.fromApiJsonHelper
.extractLongNamed(LoanProductAccountingParams.INCOME_FROM_GOODWILL_CREDIT_INTEREST.getValue(), element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.INCOME_FROM_GOODWILL_CREDIT_INTEREST.getValue())
.value(incomeFromGoodwillCreditInterestAccountId).ignoreIfNull().integerGreaterThanZero();
final Long incomeFromGoodwillCreditFeesAccountId = this.fromApiJsonHelper
.extractLongNamed(LoanProductAccountingParams.INCOME_FROM_GOODWILL_CREDIT_FEES.getValue(), element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.INCOME_FROM_GOODWILL_CREDIT_FEES.getValue())
.value(incomeFromGoodwillCreditFeesAccountId).ignoreIfNull().integerGreaterThanZero();
final Long incomeFromGoodwillCreditPenaltyAccountId = this.fromApiJsonHelper
.extractLongNamed(LoanProductAccountingParams.INCOME_FROM_GOODWILL_CREDIT_PENALTY.getValue(), element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.INCOME_FROM_GOODWILL_CREDIT_PENALTY.getValue())
.value(incomeFromGoodwillCreditPenaltyAccountId).ignoreIfNull().integerGreaterThanZero();
final Long chargeOffExpenseAccountId = this.fromApiJsonHelper
.extractLongNamed(LoanProductAccountingParams.CHARGE_OFF_EXPENSE.getValue(), element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.CHARGE_OFF_EXPENSE.getValue()).value(chargeOffExpenseAccountId)
.ignoreIfNull().integerGreaterThanZero();
final Long chargeOffFraudExpenseAccountId = this.fromApiJsonHelper
.extractLongNamed(LoanProductAccountingParams.CHARGE_OFF_FRAUD_EXPENSE.getValue(), element);
baseDataValidator.reset().parameter(LoanProductAccountingParams.CHARGE_OFF_FRAUD_EXPENSE.getValue())
.value(chargeOffFraudExpenseAccountId).ignoreIfNull().integerGreaterThanZero();
validatePaymentChannelFundSourceMappings(baseDataValidator, element);
validateChargeToIncomeAccountMappings(baseDataValidator, element);
validateChargeOffToExpenseMappings(baseDataValidator, element);
validateMinMaxConstraints(element, baseDataValidator, loanProduct);
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.USE_BORROWER_CYCLE_PARAMETER_NAME, element)) {
final Boolean useBorrowerCycle = this.fromApiJsonHelper
.extractBooleanNamed(LoanProductConstants.USE_BORROWER_CYCLE_PARAMETER_NAME, element);
baseDataValidator.reset().parameter(LoanProductConstants.USE_BORROWER_CYCLE_PARAMETER_NAME).value(useBorrowerCycle)
.ignoreIfNull().validateForBooleanValue();
if (useBorrowerCycle) {
validateBorrowerCycleVariations(element, baseDataValidator);
}
}
validateMultiDisburseLoanData(baseDataValidator, element);
// validateLoanConfigurableAttributes(baseDataValidator,element);
validateVariableInstallmentSettings(baseDataValidator, element);
validatePartialPeriodSupport(interestCalculationPeriodType, baseDataValidator, element, loanProduct);
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.CAN_USE_FOR_TOPUP, element)) {
final Boolean canUseForTopup = this.fromApiJsonHelper.extractBooleanNamed(LoanProductConstants.CAN_USE_FOR_TOPUP, element);
baseDataValidator.reset().parameter(LoanProductConstants.CAN_USE_FOR_TOPUP).value(canUseForTopup).validateForBooleanValue();
}
final Integer dueDaysForRepaymentEvent = this.fromApiJsonHelper
.extractIntegerWithLocaleNamed(LoanProductConstants.DUE_DAYS_FOR_REPAYMENT_EVENT, element);
baseDataValidator.reset().parameter(LoanProductConstants.DUE_DAYS_FOR_REPAYMENT_EVENT).value(dueDaysForRepaymentEvent)
.integerZeroOrGreater();
final Integer overDueDaysForRepaymentEvent = this.fromApiJsonHelper
.extractIntegerWithLocaleNamed(LoanProductConstants.OVER_DUE_DAYS_FOR_REPAYMENT_EVENT, element);
baseDataValidator.reset().parameter(LoanProductConstants.OVER_DUE_DAYS_FOR_REPAYMENT_EVENT).value(overDueDaysForRepaymentEvent)
.integerZeroOrGreater();
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.ENABLE_DOWN_PAYMENT, element)) {
final Boolean enableDownPayment = this.fromApiJsonHelper.extractBooleanNamed(LoanProductConstants.ENABLE_DOWN_PAYMENT, element);
baseDataValidator.reset().parameter(LoanProductConstants.ENABLE_DOWN_PAYMENT).value(enableDownPayment).ignoreIfNull()
.validateForBooleanValue();
validateDownPaymentPercentage(enableDownPayment, baseDataValidator, element);
validateAutoRepaymentForDownPayment(enableDownPayment, baseDataValidator, element);
}
Integer repaymentStartDateType = loanProduct.getRepaymentStartDateType().getValue();
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.REPAYMENT_START_DATE_TYPE, element)) {
repaymentStartDateType = this.fromApiJsonHelper.extractIntegerNamed(LoanProductConstants.REPAYMENT_START_DATE_TYPE, element,
Locale.getDefault());
}
baseDataValidator.reset().parameter(LoanProductConstants.REPAYMENT_START_DATE_TYPE).value(repaymentStartDateType).notNull()
.isOneOfTheseValues(1, 2);
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY, element)) {
final Boolean enableInstallmentLevelDelinquency = this.fromApiJsonHelper
.extractBooleanNamed(LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY, element);
baseDataValidator.reset().parameter(LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY)
.value(enableInstallmentLevelDelinquency).ignoreIfNull().validateForBooleanValue();
if (delinquencyBucketId == null) {
if (enableInstallmentLevelDelinquency) {
baseDataValidator.reset().parameter(LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY).failWithCode(
"can.be.enabled.for.loan.product.having.valid.delinquency.bucket",
"Installment level delinquency cannot be enabled if Delinquency bucket is not configured for loan product");
}
}
}
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.LOAN_SCHEDULE_TYPE, element)) {
validateLoanScheduleType(transactionProcessingStrategyCode, baseDataValidator, element);
}
String loanScheduleProcessingType = loanProduct.getLoanProductRelatedDetail().getLoanScheduleProcessingType().name();
if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.LOAN_SCHEDULE_PROCESSING_TYPE, element)) {
loanScheduleProcessingType = this.fromApiJsonHelper.extractStringNamed(LoanProductConstants.LOAN_SCHEDULE_PROCESSING_TYPE,
element);
baseDataValidator.reset().parameter(LoanProductConstants.LOAN_SCHEDULE_PROCESSING_TYPE).value(loanScheduleProcessingType)
.isOneOfEnumValues(LoanScheduleProcessingType.class);
}
List<LoanProductPaymentAllocationRule> allocationRules = loanProduct.getPaymentAllocationRules();
if (this.fromApiJsonHelper.parameterExists(ADVANCED_PAYMENT_ALLOCATIONS, element)
&& LoanScheduleProcessingType.HORIZONTAL.name().equals(loanScheduleProcessingType)) {
allocationRules = advancedPaymentAllocationsJsonParser.assembleLoanProductPaymentAllocationRules(command,
transactionProcessingStrategyCode);
}
if (LoanScheduleProcessingType.HORIZONTAL.name().equals(loanScheduleProcessingType)
&& AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY
.equals(transactionProcessingStrategyCode)) {
advancedPaymentAllocationsValidator.checkGroupingOfAllocationRules(allocationRules);
}
if (LoanScheduleProcessingType.VERTICAL.equals(LoanScheduleProcessingType.valueOf(loanScheduleProcessingType))
&& !AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY
.equals(transactionProcessingStrategyCode)) {
baseDataValidator.reset().parameter(LoanProductConstants.LOAN_SCHEDULE_PROCESSING_TYPE).failWithCode(
"supported.only.for.progressive.loan.schedule.handling",
"Vertical repayment schedule processing is only available with `Advanced payment allocation` strategy");
}
final Integer recurringMoratoriumOnPrincipalPeriods = this.fromApiJsonHelper
.extractIntegerWithLocaleNamed("recurringMoratoriumOnPrincipalPeriods", element);
validateRepaymentPeriodWithGraceSettings(numberOfRepayments, graceOnPrincipalPayment, graceOnInterestPayment,
graceOnInterestCharged, recurringMoratoriumOnPrincipalPeriods, baseDataValidator);
validateIncomeCapitalization(transactionProcessingStrategyCode, element, baseDataValidator, accountingRuleType);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}