WIP: add min and max constraint to Principal amount
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
ALTER TABLE `m_product_loan`
|
||||
ADD COLUMN `min_principal_amount` DECIMAL(19,6) NOT NULL AFTER `principal_amount`,
|
||||
ADD COLUMN `max_principal_amount` DECIMAL(19,6) NOT NULL AFTER `min_principal_amount`;
|
||||
|
||||
ALTER TABLE `m_loan`
|
||||
ADD COLUMN `min_principal_amount` DECIMAL(19,6) NOT NULL AFTER `principal_amount`,
|
||||
ADD COLUMN `max_principal_amount` DECIMAL(19,6) NOT NULL AFTER `min_principal_amount`;
|
||||
+17
@@ -372,6 +372,23 @@ public class DataValidatorBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public DataValidatorBuilder inMinAndMaxAmountRange(final BigDecimal minimumAmount, final BigDecimal maximumAmount) {
|
||||
if (minimumAmount != null && maximumAmount != null && value != null){
|
||||
BigDecimal amount = BigDecimal.valueOf(Double.valueOf(value.toString()));
|
||||
if (amount.compareTo(minimumAmount) == -1 || amount.compareTo(maximumAmount) == 1) {
|
||||
StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(resource).append(".").append(parameter)
|
||||
.append(".amount.is.not.within.min.max.range");
|
||||
StringBuilder defaultEnglishMessage = new StringBuilder("The ").append(parameter) .append(" amount ").append(amount)
|
||||
.append(" must be between ").append(minimumAmount).append(" and ").append(maximumAmount).append(" .");
|
||||
ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
|
||||
defaultEnglishMessage.toString(), parameter, amount, minimumAmount, maximumAmount);
|
||||
dataValidationErrors.add(error);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public DataValidatorBuilder comapareMinAndMaxOfTwoBigDecmimalNos(final BigDecimal min, final BigDecimal max) {
|
||||
if (min != null && max != null)
|
||||
if (max.compareTo(min) == -1) {
|
||||
|
||||
+7
-5
@@ -1317,6 +1317,8 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
final LoanScheduleGenerator loanScheduleGenerator = new DefaultLoanScheduleGeneratorFactory().create(interestMethod);
|
||||
|
||||
final BigDecimal principal = this.loanRepaymentScheduleDetail.getPrincipal().getAmount();
|
||||
final BigDecimal minPrincipal = this.loanRepaymentScheduleDetail.getMinPrincipal().getAmount();
|
||||
final BigDecimal maxPrincipal = this.loanRepaymentScheduleDetail.getMaxPrincipal().getAmount();
|
||||
final BigDecimal inArrearsTolerance = this.loanRepaymentScheduleDetail.getInArrearsTolerance().getAmount();
|
||||
final BigDecimal interestRatePerPeriod = this.loanRepaymentScheduleDetail.getNominalInterestRatePerPeriod();
|
||||
final PeriodFrequencyType interestRatePeriodFrequencyType = this.loanRepaymentScheduleDetail.getInterestPeriodFrequencyType();
|
||||
@@ -1331,11 +1333,11 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
final Integer loanTermFrequency = this.termFrequency;
|
||||
final PeriodFrequencyType loanTermPeriodFrequencyType = PeriodFrequencyType.fromInt(this.termPeriodFrequencyType);
|
||||
|
||||
final LoanSchedule loanSchedule = new LoanSchedule(loanScheduleGenerator, applicationCurrency, principal, interestRatePerPeriod,
|
||||
interestRatePeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod,
|
||||
repaymentEvery, repaymentPeriodFrequencyType, numberOfRepayments, amortizationMethod, loanTermFrequency,
|
||||
loanTermPeriodFrequencyType, setOfLoanCharges(), this.getDisbursementDate(), this.getExpectedFirstRepaymentOnDate(),
|
||||
this.getInterestChargedFromDate(), inArrearsTolerance);
|
||||
final LoanSchedule loanSchedule = new LoanSchedule(loanScheduleGenerator, applicationCurrency, principal, minPrincipal,
|
||||
maxPrincipal, interestRatePerPeriod, interestRatePeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod,
|
||||
interestCalculationPeriodMethod, repaymentEvery, repaymentPeriodFrequencyType, numberOfRepayments, amortizationMethod,
|
||||
loanTermFrequency, loanTermPeriodFrequencyType, setOfLoanCharges(), this.getDisbursementDate(),
|
||||
this.getExpectedFirstRepaymentOnDate(), this.getInterestChargedFromDate(), inArrearsTolerance);
|
||||
|
||||
final LoanScheduleData generatedData = loanSchedule.generate();
|
||||
|
||||
|
||||
+13
-9
@@ -27,6 +27,8 @@ public final class LoanSchedule {
|
||||
private final LoanScheduleGenerator loanScheduleGenerator;
|
||||
private final ApplicationCurrency applicationCurrency;
|
||||
private final BigDecimal principal;
|
||||
private final BigDecimal minPrincipal;
|
||||
private final BigDecimal maxPrincipal;
|
||||
private final BigDecimal nominalInterestRatePerPeriod;
|
||||
private final PeriodFrequencyType interestRatePeriodFrequencyType;
|
||||
private final BigDecimal nominalAnnualInterestRate;
|
||||
@@ -46,17 +48,19 @@ public final class LoanSchedule {
|
||||
private final Set<LoanCharge> loanCharges;
|
||||
|
||||
public LoanSchedule(final LoanScheduleGenerator loanScheduleGenerator, final ApplicationCurrency applicationCurrency,
|
||||
final BigDecimal principal, final BigDecimal nominalInterestRatePerPeriod,
|
||||
final PeriodFrequencyType interestRatePeriodFrequencyType, final BigDecimal nominalAnnualInterestRate,
|
||||
final InterestMethod interestMethod, final InterestCalculationPeriodMethod interestCalculationPeriodMethod,
|
||||
final Integer repaymentEvery, final PeriodFrequencyType repaymentPeriodFrequencyType, final Integer numberOfRepayments,
|
||||
final BigDecimal principal, final BigDecimal minPrincipal, final BigDecimal maxPrincipal,
|
||||
final BigDecimal nominalInterestRatePerPeriod, final PeriodFrequencyType interestRatePeriodFrequencyType,
|
||||
final BigDecimal nominalAnnualInterestRate, final InterestMethod interestMethod,
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final Integer repaymentEvery,
|
||||
final PeriodFrequencyType repaymentPeriodFrequencyType, final Integer numberOfRepayments,
|
||||
final AmortizationMethod amortizationMethod, final Integer loanTermFrequency,
|
||||
final PeriodFrequencyType loanTermPeriodFrequencyType, final Set<LoanCharge> loanCharges, final LocalDate disbursementDate,
|
||||
final LocalDate repaymentStartFromDate, final LocalDate interestChargedFromDate,
|
||||
final BigDecimal inArrearsTolerance) {
|
||||
final LocalDate repaymentStartFromDate, final LocalDate interestChargedFromDate, final BigDecimal inArrearsTolerance) {
|
||||
this.loanScheduleGenerator = loanScheduleGenerator;
|
||||
this.applicationCurrency = applicationCurrency;
|
||||
this.principal = principal;
|
||||
this.minPrincipal = minPrincipal;
|
||||
this.maxPrincipal = maxPrincipal;
|
||||
this.nominalInterestRatePerPeriod = nominalInterestRatePerPeriod;
|
||||
this.interestRatePeriodFrequencyType = interestRatePeriodFrequencyType;
|
||||
this.nominalAnnualInterestRate = nominalAnnualInterestRate;
|
||||
@@ -83,9 +87,9 @@ public final class LoanSchedule {
|
||||
public LoanProductRelatedDetail loanProductRelatedDetail() {
|
||||
final MonetaryCurrency currency = new MonetaryCurrency(applicationCurrency.getCode(), applicationCurrency.getDecimalPlaces());
|
||||
|
||||
return LoanProductRelatedDetail.createFrom(currency, principal, nominalInterestRatePerPeriod, interestRatePeriodFrequencyType,
|
||||
nominalAnnualInterestRate, interestMethod, interestCalculationPeriodMethod, repaymentEvery, repaymentPeriodFrequencyType,
|
||||
numberOfRepayments, amortizationMethod, this.inArrearsTolerance);
|
||||
return LoanProductRelatedDetail.createFrom(currency, principal, minPrincipal, maxPrincipal, nominalInterestRatePerPeriod,
|
||||
interestRatePeriodFrequencyType, nominalAnnualInterestRate, interestMethod, interestCalculationPeriodMethod,
|
||||
repaymentEvery, repaymentPeriodFrequencyType, numberOfRepayments, amortizationMethod, this.inArrearsTolerance);
|
||||
}
|
||||
|
||||
public Integer getLoanTermFrequency() {
|
||||
|
||||
+3
-1
@@ -72,6 +72,8 @@ public class LoanScheduleAssembler {
|
||||
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneByCode(currency.getCode());
|
||||
|
||||
final BigDecimal principal = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("principal", element);
|
||||
final BigDecimal minPrincipal = loanProduct.getMinPrincipalAmount().getAmount();//Copy minPrincipal from loan product to loan
|
||||
final BigDecimal maxPrincipal = loanProduct.getMaxPrincipalAmount().getAmount();//Copy maxPrincipal from loan product to loan
|
||||
final BigDecimal interestRatePerPeriod = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("interestRatePerPeriod", element);
|
||||
final Integer interestRateFrequencyType = fromApiJsonHelper.extractIntegerWithLocaleNamed("interestRateFrequencyType", element);
|
||||
final Integer interestType = fromApiJsonHelper.extractIntegerWithLocaleNamed("interestType", element);
|
||||
@@ -105,7 +107,7 @@ public class LoanScheduleAssembler {
|
||||
|
||||
final LoanScheduleGenerator loanScheduleGenerator = this.loanScheduleFactory.create(interestMethod);
|
||||
|
||||
return new LoanSchedule(loanScheduleGenerator, applicationCurrency, principal, interestRatePerPeriod,
|
||||
return new LoanSchedule(loanScheduleGenerator, applicationCurrency, principal, minPrincipal, maxPrincipal, interestRatePerPeriod,
|
||||
interestRatePeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod,
|
||||
repaymentEvery, repaymentPeriodFrequencyType, numberOfRepayments, amortizationMethod, loanTermFrequency,
|
||||
loanTermPeriodFrequencyType, loanCharges, expectedDisbursementDate, repaymentsStartingFromDate, interestChargedFromDate, inArrearsTolerance);
|
||||
|
||||
+18
@@ -22,6 +22,7 @@ import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -591,4 +592,21 @@ public final class LoanApplicationCommandFromApiJsonHelper {
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
|
||||
public void validateMinMaxConstraintValues(final JsonElement element, final LoanProduct loanProduct){
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan");
|
||||
|
||||
final BigDecimal minPrincipal = loanProduct.getMinPrincipalAmount().getAmount();
|
||||
final BigDecimal maxPrincipal = loanProduct.getMaxPrincipalAmount().getAmount();
|
||||
final String principalParameterName = "principal";
|
||||
|
||||
if (fromApiJsonHelper.parameterExists(principalParameterName, element)) {
|
||||
final BigDecimal principal = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(principalParameterName, element);
|
||||
baseDataValidator.reset().parameter(principalParameterName).value(principal).notNull().positiveAmount().inMinAndMaxAmountRange(minPrincipal, maxPrincipal);
|
||||
}
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
}
|
||||
+8
-1
@@ -42,6 +42,7 @@ import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionProcessingS
|
||||
import org.mifosplatform.portfolio.loanaccount.exception.LoanTransactionProcessingStrategyNotFoundException;
|
||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanSchedule;
|
||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.service.LoanScheduleAssembler;
|
||||
import org.mifosplatform.portfolio.loanaccount.serialization.LoanApplicationCommandFromApiJsonHelper;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRepository;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanTransactionProcessingStrategy;
|
||||
@@ -68,6 +69,7 @@ public class LoanAssembler {
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
private final LoanSummaryWrapper loanSummaryWrapper;
|
||||
private final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory;
|
||||
private final LoanApplicationCommandFromApiJsonHelper fromApiJsonDeserializer;
|
||||
|
||||
@Autowired
|
||||
public LoanAssembler(final FromJsonHelper fromApiJsonHelper, final LoanProductRepository loanProductRepository,
|
||||
@@ -76,7 +78,8 @@ public class LoanAssembler {
|
||||
final StaffRepository staffRepository, final CodeValueRepositoryWrapper codeValueRepository,
|
||||
final LoanScheduleAssembler loanScheduleAssembler, final LoanChargeAssembler loanChargeAssembler,
|
||||
final CollateralAssembler loanCollateralAssembler, final LoanSummaryWrapper loanSummaryWrapper,
|
||||
final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory) {
|
||||
final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory,
|
||||
final LoanApplicationCommandFromApiJsonHelper fromApiJsonDeserializer) {
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
this.loanProductRepository = loanProductRepository;
|
||||
this.clientRepository = clientRepository;
|
||||
@@ -90,6 +93,7 @@ public class LoanAssembler {
|
||||
this.loanCollateralAssembler = loanCollateralAssembler;
|
||||
this.loanSummaryWrapper = loanSummaryWrapper;
|
||||
this.loanRepaymentScheduleTransactionProcessorFactory = loanRepaymentScheduleTransactionProcessorFactory;
|
||||
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
||||
}
|
||||
|
||||
public Loan assembleFrom(final JsonCommand command, final AppUser currentUser) {
|
||||
@@ -113,6 +117,9 @@ public class LoanAssembler {
|
||||
final LoanProduct loanProduct = this.loanProductRepository.findOne(productId);
|
||||
if (loanProduct == null) { throw new LoanProductNotFoundException(productId); }
|
||||
|
||||
//validate min and max constraint parameters
|
||||
this.fromApiJsonDeserializer.validateMinMaxConstraintValues(element, loanProduct);
|
||||
|
||||
final Fund fund = findFundByIdIfProvided(fundId);
|
||||
final Staff loanOfficer = findLoanOfficerByIdIfProvided(loanOfficerId);
|
||||
final LoanTransactionProcessingStrategy loanTransactionProcessingStrategy = findStrategyByIdIfProvided(transactionProcessingStrategyId);
|
||||
|
||||
+26
-5
@@ -37,6 +37,8 @@ public class LoanProductData {
|
||||
// terms
|
||||
private final CurrencyData currency;
|
||||
private final BigDecimal principal;
|
||||
private BigDecimal minPrincipal;
|
||||
private BigDecimal maxPrincipal;
|
||||
private final Integer numberOfRepayments;
|
||||
private final Integer repaymentEvery;
|
||||
private final EnumOptionData repaymentFrequencyType;
|
||||
@@ -80,6 +82,8 @@ public class LoanProductData {
|
||||
final String description = null;
|
||||
final CurrencyData currency = null;
|
||||
final BigDecimal principal = null;
|
||||
final BigDecimal minPrincipal = null;
|
||||
final BigDecimal maxPrincipal = null;
|
||||
final BigDecimal tolerance = null;
|
||||
final Integer numberOfRepayments = null;
|
||||
final Integer repaymentEvery = null;
|
||||
@@ -97,7 +101,7 @@ public class LoanProductData {
|
||||
final Collection<ChargeData> charges = null;
|
||||
final EnumOptionData accountingType = null;
|
||||
|
||||
return new LoanProductData(id, name, description, currency, principal, tolerance, numberOfRepayments, repaymentEvery,
|
||||
return new LoanProductData(id, name, description, currency, principal, minPrincipal, maxPrincipal, tolerance, numberOfRepayments, repaymentEvery,
|
||||
interestRatePerPeriod, annualInterestRate, repaymentFrequencyType, interestRateFrequencyType, amortizationType,
|
||||
interestType, interestCalculationPeriodType, fundId, fundName, transactionProcessingStrategyId,
|
||||
transactionProcessingStrategyName, charges, accountingType);
|
||||
@@ -106,6 +110,8 @@ public class LoanProductData {
|
||||
public static LoanProductData lookupWithCurrency(final Long id, final String name, final CurrencyData currency) {
|
||||
final String description = null;
|
||||
final BigDecimal principal = null;
|
||||
final BigDecimal minPrincipal = null;
|
||||
final BigDecimal maxPrincipal = null;
|
||||
final BigDecimal tolerance = null;
|
||||
final Integer numberOfRepayments = null;
|
||||
final Integer repaymentEvery = null;
|
||||
@@ -123,7 +129,7 @@ public class LoanProductData {
|
||||
final Collection<ChargeData> charges = null;
|
||||
final EnumOptionData accountingType = null;
|
||||
|
||||
return new LoanProductData(id, name, description, currency, principal, tolerance, numberOfRepayments, repaymentEvery,
|
||||
return new LoanProductData(id, name, description, currency, principal, minPrincipal, maxPrincipal, tolerance, numberOfRepayments, repaymentEvery,
|
||||
interestRatePerPeriod, annualInterestRate, repaymentFrequencyType, interestRateFrequencyType, amortizationType,
|
||||
interestType, interestCalculationPeriodType, fundId, fundName, transactionProcessingStrategyId,
|
||||
transactionProcessingStrategyName, charges, accountingType);
|
||||
@@ -135,6 +141,8 @@ public class LoanProductData {
|
||||
final String description = null;
|
||||
final CurrencyData currency = CurrencyData.blank();
|
||||
final BigDecimal principal = null;
|
||||
final BigDecimal minPrincipal = null;
|
||||
final BigDecimal maxPrincipal = null;
|
||||
final BigDecimal tolerance = null;
|
||||
final Integer numberOfRepayments = null;
|
||||
final Integer repaymentEvery = null;
|
||||
@@ -153,7 +161,7 @@ public class LoanProductData {
|
||||
final Collection<ChargeData> charges = null;
|
||||
final EnumOptionData accountingType = LoanEnumerations.accountingRuleType(AccountingRuleType.NONE);
|
||||
|
||||
return new LoanProductData(id, name, description, currency, principal, tolerance, numberOfRepayments, repaymentEvery,
|
||||
return new LoanProductData(id, name, description, currency, principal, minPrincipal, maxPrincipal, tolerance, numberOfRepayments, repaymentEvery,
|
||||
interestRatePerPeriod, annualInterestRate, repaymentFrequencyType, interestRateFrequencyType, amortizationType,
|
||||
interestType, interestCalculationPeriodType, fundId, fundName, transactionProcessingStrategyId,
|
||||
transactionProcessingStrategyName, charges, accountingType);
|
||||
@@ -169,8 +177,9 @@ public class LoanProductData {
|
||||
}
|
||||
|
||||
public LoanProductData(final Long id, final String name, final String description, final CurrencyData currency,
|
||||
final BigDecimal principal, final BigDecimal tolerance, final Integer numberOfRepayments, final Integer repaymentEvery,
|
||||
final BigDecimal interestRatePerPeriod, final BigDecimal annualInterestRate, final EnumOptionData repaymentFrequencyType,
|
||||
final BigDecimal principal, final BigDecimal minPrincipal, final BigDecimal maxPrincipal, final BigDecimal tolerance,
|
||||
final Integer numberOfRepayments, final Integer repaymentEvery, final BigDecimal interestRatePerPeriod,
|
||||
final BigDecimal annualInterestRate, final EnumOptionData repaymentFrequencyType,
|
||||
final EnumOptionData interestRateFrequencyType, final EnumOptionData amortizationType, final EnumOptionData interestType,
|
||||
final EnumOptionData interestCalculationPeriodType, final Long fundId, final String fundName,
|
||||
final Long transactionProcessingStrategyId, final String transactionProcessingStrategyName,
|
||||
@@ -180,6 +189,8 @@ public class LoanProductData {
|
||||
this.description = description;
|
||||
this.currency = currency;
|
||||
this.principal = principal;
|
||||
this.minPrincipal = minPrincipal;
|
||||
this.maxPrincipal = maxPrincipal;
|
||||
this.inArrearsTolerance = tolerance;
|
||||
this.numberOfRepayments = numberOfRepayments;
|
||||
this.repaymentEvery = repaymentEvery;
|
||||
@@ -227,6 +238,8 @@ public class LoanProductData {
|
||||
this.fundName = productData.fundName;
|
||||
|
||||
this.principal = productData.principal;
|
||||
this.minPrincipal = productData.minPrincipal;
|
||||
this.maxPrincipal = productData.maxPrincipal;
|
||||
this.inArrearsTolerance = productData.inArrearsTolerance;
|
||||
this.numberOfRepayments = productData.numberOfRepayments;
|
||||
this.repaymentEvery = productData.repaymentEvery;
|
||||
@@ -337,6 +350,14 @@ public class LoanProductData {
|
||||
return principal;
|
||||
}
|
||||
|
||||
public BigDecimal getMinPrincipal() {
|
||||
return this.minPrincipal;
|
||||
}
|
||||
|
||||
public BigDecimal getMaxPrincipal() {
|
||||
return this.maxPrincipal;
|
||||
}
|
||||
|
||||
public BigDecimal getInArrearsTolerance() {
|
||||
return inArrearsTolerance;
|
||||
}
|
||||
|
||||
+20
-6
@@ -24,6 +24,7 @@ import javax.persistence.UniqueConstraint;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
import org.mifosplatform.portfolio.charge.domain.Charge;
|
||||
import org.mifosplatform.portfolio.fund.domain.Fund;
|
||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.AprCalculator;
|
||||
@@ -78,6 +79,8 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
|
||||
final MonetaryCurrency currency = new MonetaryCurrency(currencyCode, digitsAfterDecimal);
|
||||
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
|
||||
@@ -95,9 +98,10 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
final BigDecimal inArrearsTolerance = command.bigDecimalValueOfParameterNamed("inArrearsTolerance");
|
||||
final AccountingRuleType accountingRuleType = AccountingRuleType.fromInt(command.integerValueOfParameterNamed("accountingRule"));
|
||||
|
||||
return new LoanProduct(fund, loanTransactionProcessingStrategy, name, description, currency, principal, interestRatePerPeriod,
|
||||
interestFrequencyType, annualInterestRate, interestMethod, interestCalculationPeriodMethod, repaymentEvery,
|
||||
repaymentFrequencyType, numberOfRepayments, amortizationMethod, inArrearsTolerance, productCharges, accountingRuleType);
|
||||
return new LoanProduct(fund, loanTransactionProcessingStrategy, name, description, currency, principal, minPrincipal, maxPrincipal,
|
||||
interestRatePerPeriod, interestFrequencyType, annualInterestRate, interestMethod, interestCalculationPeriodMethod,
|
||||
repaymentEvery, repaymentFrequencyType, numberOfRepayments, amortizationMethod, inArrearsTolerance, productCharges,
|
||||
accountingRuleType);
|
||||
}
|
||||
|
||||
protected LoanProduct() {
|
||||
@@ -106,6 +110,7 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
|
||||
public LoanProduct(final Fund fund, final LoanTransactionProcessingStrategy transactionProcessingStrategy, final String name,
|
||||
final String description, final MonetaryCurrency currency, final BigDecimal defaultPrincipal,
|
||||
final BigDecimal defaultMinPrincipal, final BigDecimal defaultMaxPrincipal,
|
||||
final BigDecimal defaultNominalInterestRatePerPeriod, final PeriodFrequencyType interestPeriodFrequencyType,
|
||||
final BigDecimal defaultAnnualNominalInterestRate, final InterestMethod interestMethod,
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final Integer repayEvery,
|
||||
@@ -125,9 +130,10 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
this.charges = charges;
|
||||
}
|
||||
|
||||
this.loanProductRelatedDetail = new LoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod,
|
||||
interestPeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery,
|
||||
repaymentFrequencyType, defaultNumberOfInstallments, amortizationMethod, inArrearsTolerance);
|
||||
this.loanProductRelatedDetail = new LoanProductRelatedDetail(currency, defaultPrincipal, defaultMinPrincipal, defaultMaxPrincipal,
|
||||
defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod,
|
||||
interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType, defaultNumberOfInstallments, amortizationMethod,
|
||||
inArrearsTolerance);
|
||||
|
||||
if (accountingRuleType != null) {
|
||||
this.accountingRule = accountingRuleType.getValue();
|
||||
@@ -227,4 +233,12 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
public boolean isAccrualBasedAccountingEnabled() {
|
||||
return AccountingRuleType.ACCRUAL_BASED.getValue().equals(this.accountingRule);
|
||||
}
|
||||
|
||||
public Money getMinPrincipalAmount(){
|
||||
return this.loanProductRelatedDetail.getMinPrincipal();
|
||||
}
|
||||
|
||||
public Money getMaxPrincipalAmount(){
|
||||
return this.loanProductRelatedDetail.getMaxPrincipal();
|
||||
}
|
||||
}
|
||||
+47
-5
@@ -20,6 +20,7 @@ import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
|
||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.AprCalculator;
|
||||
import org.mifosplatform.portfolio.loanproduct.exception.NotInMinMaxRangeException;
|
||||
|
||||
/**
|
||||
* LoanRepaymentScheduleDetail encapsulates all the details of a
|
||||
@@ -33,6 +34,12 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
|
||||
@Column(name = "principal_amount", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal principal;
|
||||
|
||||
@Column(name = "min_principal_amount", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal minPrincipal;
|
||||
|
||||
@Column(name = "max_principal_amount", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal maxPrincipal;
|
||||
|
||||
@Column(name = "nominal_interest_rate_per_period", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal nominalInterestRatePerPeriod;
|
||||
@@ -80,13 +87,13 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
private BigDecimal inArrearsTolerance;
|
||||
|
||||
public static LoanProductRelatedDetail createFrom(final MonetaryCurrency currency, final BigDecimal principal,
|
||||
final BigDecimal nominalInterestRatePerPeriod, final PeriodFrequencyType interestRatePeriodFrequencyType,
|
||||
final BigDecimal nominalAnnualInterestRate, final InterestMethod interestMethod,
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final Integer repaymentEvery,
|
||||
final PeriodFrequencyType repaymentPeriodFrequencyType, final Integer numberOfRepayments,
|
||||
final BigDecimal minPrincipal, final BigDecimal maxPrincipal, final BigDecimal nominalInterestRatePerPeriod,
|
||||
final PeriodFrequencyType interestRatePeriodFrequencyType, final BigDecimal nominalAnnualInterestRate,
|
||||
final InterestMethod interestMethod, final InterestCalculationPeriodMethod interestCalculationPeriodMethod,
|
||||
final Integer repaymentEvery, final PeriodFrequencyType repaymentPeriodFrequencyType, final Integer numberOfRepayments,
|
||||
final AmortizationMethod amortizationMethod, final BigDecimal inArrearsTolerance) {
|
||||
|
||||
return new LoanProductRelatedDetail(currency, principal, nominalInterestRatePerPeriod, interestRatePeriodFrequencyType,
|
||||
return new LoanProductRelatedDetail(currency, principal, minPrincipal, maxPrincipal, nominalInterestRatePerPeriod, interestRatePeriodFrequencyType,
|
||||
nominalAnnualInterestRate, interestMethod, interestCalculationPeriodMethod, repaymentEvery, repaymentPeriodFrequencyType,
|
||||
numberOfRepayments, amortizationMethod, inArrearsTolerance);
|
||||
}
|
||||
@@ -96,6 +103,7 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
}
|
||||
|
||||
public LoanProductRelatedDetail(final MonetaryCurrency currency, final BigDecimal defaultPrincipal,
|
||||
final BigDecimal defaultMinPrincipal, final BigDecimal defaultMaxPrincipal,
|
||||
final BigDecimal defaultNominalInterestRatePerPeriod, final PeriodFrequencyType interestPeriodFrequencyType,
|
||||
final BigDecimal defaultAnnualNominalInterestRate, final InterestMethod interestMethod,
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final Integer repayEvery,
|
||||
@@ -103,6 +111,8 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
final AmortizationMethod amortizationMethod, final BigDecimal inArrearsTolerance) {
|
||||
this.currency = currency;
|
||||
this.principal = defaultPrincipal;
|
||||
this.minPrincipal = defaultMinPrincipal;
|
||||
this.maxPrincipal = defaultMaxPrincipal;
|
||||
this.nominalInterestRatePerPeriod = defaultNominalInterestRatePerPeriod;
|
||||
this.interestPeriodFrequencyType = interestPeriodFrequencyType;
|
||||
this.annualNominalInterestRate = defaultAnnualNominalInterestRate;
|
||||
@@ -127,6 +137,14 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
return Money.of(this.currency, this.principal);
|
||||
}
|
||||
|
||||
public Money getMinPrincipal() {
|
||||
return Money.of(this.currency, this.minPrincipal);
|
||||
}
|
||||
|
||||
public Money getMaxPrincipal() {
|
||||
return Money.of(this.currency, this.maxPrincipal);
|
||||
}
|
||||
|
||||
public Money getInArrearsTolerance() {
|
||||
return Money.of(this.currency, this.inArrearsTolerance);
|
||||
}
|
||||
@@ -208,12 +226,29 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
|
||||
final String localeAsInput = command.locale();
|
||||
|
||||
final String minPrincipalParamName = "minPrincipal";
|
||||
if (command.isChangeInBigDecimalParameterNamed(minPrincipalParamName, this.minPrincipal)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(minPrincipalParamName);
|
||||
actualChanges.put(minPrincipalParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.minPrincipal = newValue;
|
||||
}
|
||||
|
||||
final String maxPrincipalParamName = "maxPrincipal";
|
||||
if (command.isChangeInBigDecimalParameterNamed(maxPrincipalParamName, this.maxPrincipal)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(maxPrincipalParamName);
|
||||
actualChanges.put(maxPrincipalParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.maxPrincipal = newValue;
|
||||
}
|
||||
|
||||
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;
|
||||
validatePrincipalAmount();
|
||||
}
|
||||
|
||||
final String repaymentEveryParamName = "repaymentEvery";
|
||||
@@ -294,6 +329,13 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
private void validatePrincipalAmount() {
|
||||
if(this.principal.compareTo(this.minPrincipal) == -1 || this.principal.compareTo(maxPrincipal) == 1){
|
||||
final String errorMessage = "The Principal amount " + this.principal + " is invalid. Must be an amount between " + this.minPrincipal + " and " + this.maxPrincipal + " inclusive.";
|
||||
throw new NotInMinMaxRangeException("loan", "principal.amount", errorMessage, this.principal, this.minPrincipal, this.maxPrincipal);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateInterestRateDerivedFields(final AprCalculator aprCalculator) {
|
||||
this.annualNominalInterestRate = aprCalculator.calculateFrom(this.interestPeriodFrequencyType, this.nominalInterestRatePerPeriod);
|
||||
}
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.portfolio.loanproduct.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
/**
|
||||
* {@link AbstractPlatformDomainRuleException} thrown when a value is not within minimum and maximum values.
|
||||
*
|
||||
*/
|
||||
public class NotInMinMaxRangeException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
public NotInMinMaxRangeException(final String entity, final String postFix, String defaultUserMessage, Object... defaultUserMessageArgs) {
|
||||
super("validation.msg." + entity + "." + postFix + ".is.not.within.min.max.range", defaultUserMessage, defaultUserMessageArgs);
|
||||
}
|
||||
}
|
||||
+33
-4
@@ -36,7 +36,7 @@ public final class LoanProductCommandFromApiJsonDeserializer {
|
||||
* The parameters supported for this command.
|
||||
*/
|
||||
private final Set<String> supportedParameters = new HashSet<String>(Arrays.asList("locale", "name", "description", "fundId",
|
||||
"currencyCode", "digitsAfterDecimal", "principal", "repaymentEvery", "numberOfRepayments", "repaymentFrequencyType",
|
||||
"currencyCode", "digitsAfterDecimal", "principal", "minPrincipal", "maxPrincipal", "repaymentEvery", "numberOfRepayments", "repaymentFrequencyType",
|
||||
"interestRatePerPeriod", "interestRateFrequencyType", "amortizationType", "interestType", "interestCalculationPeriodType",
|
||||
"inArrearsTolerance", "transactionProcessingStrategyId", "charges", "accountingRule",
|
||||
LOAN_PRODUCT_ACCOUNTING_PARAMS.FEES_RECEIVABLE.getValue(), LOAN_PRODUCT_ACCOUNTING_PARAMS.FUND_SOURCE.getValue(),
|
||||
@@ -81,9 +81,15 @@ public final class LoanProductCommandFromApiJsonDeserializer {
|
||||
final Integer digitsAfterDecimal = fromApiJsonHelper.extractIntegerNamed("digitsAfterDecimal", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("digitsAfterDecimal").value(digitsAfterDecimal).notNull().inMinMaxRange(0, 6);
|
||||
|
||||
final BigDecimal minPrincipal = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("minPrincipal", element);
|
||||
baseDataValidator.reset().parameter("minPrincipal").value(minPrincipal).notNull().positiveAmount();
|
||||
|
||||
final BigDecimal maxPrincipal = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maxPrincipal", element);
|
||||
baseDataValidator.reset().parameter("maxPrincipal").value(maxPrincipal).notNull().positiveAmount();
|
||||
|
||||
final BigDecimal principal = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("principal", element);
|
||||
baseDataValidator.reset().parameter("principal").value(principal).notNull().positiveAmount();
|
||||
|
||||
baseDataValidator.reset().parameter("principal").value(principal).notNull().positiveAmount().inMinAndMaxAmountRange(minPrincipal, maxPrincipal);
|
||||
|
||||
final Integer numberOfRepayments = fromApiJsonHelper.extractIntegerWithLocaleNamed("numberOfRepayments", element);
|
||||
baseDataValidator.reset().parameter("numberOfRepayments").value(numberOfRepayments).notNull().integerGreaterThanZero();
|
||||
|
||||
@@ -212,10 +218,33 @@ public final class LoanProductCommandFromApiJsonDeserializer {
|
||||
final Integer digitsAfterDecimal = fromApiJsonHelper.extractIntegerNamed("digitsAfterDecimal", element, Locale.getDefault());
|
||||
baseDataValidator.reset().parameter("digitsAfterDecimal").value(digitsAfterDecimal).notNull().inMinMaxRange(0, 6);
|
||||
}
|
||||
|
||||
String minPrincipalParameterName = "minPrincipal";
|
||||
BigDecimal minPrincipalAmount = null;
|
||||
if(fromApiJsonHelper.parameterExists(minPrincipalParameterName, element)){
|
||||
minPrincipalAmount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(minPrincipalParameterName, element);
|
||||
}
|
||||
|
||||
String maxPrincipalParameterName = "maxPrincipal";
|
||||
BigDecimal maxPrincipalAmount = null;
|
||||
if(fromApiJsonHelper.parameterExists(maxPrincipalParameterName, element)){
|
||||
maxPrincipalAmount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(maxPrincipalParameterName, element);
|
||||
}
|
||||
|
||||
//Principal amount is allowed to change only when Min and Max principal amounts are sent in JSON request
|
||||
//Validate if minPrincipal amount or principal amount is part of JSON request.
|
||||
if(fromApiJsonHelper.parameterExists(minPrincipalParameterName, element) || fromApiJsonHelper.parameterExists("principal", element)){
|
||||
baseDataValidator.reset().parameter(minPrincipalParameterName).value(minPrincipalAmount).notNull().positiveAmount();
|
||||
}
|
||||
|
||||
//Validate if maxPrincipal amount or principal amount is part of JSON request.
|
||||
if(fromApiJsonHelper.parameterExists(maxPrincipalParameterName, element) || fromApiJsonHelper.parameterExists("principal", element)){
|
||||
baseDataValidator.reset().parameter(maxPrincipalParameterName).value(maxPrincipalAmount).notNull().positiveAmount();
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists("principal", element)) {
|
||||
final BigDecimal principal = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("principal", element);
|
||||
baseDataValidator.reset().parameter("principal").value(principal).notNull().positiveAmount();
|
||||
baseDataValidator.reset().parameter("principal").value(principal).notNull().positiveAmount().inMinAndMaxAmountRange(minPrincipalAmount, maxPrincipalAmount);
|
||||
}
|
||||
|
||||
if (fromApiJsonHelper.parameterExists("inArrearsTolerance", element)) {
|
||||
|
||||
+7
-5
@@ -96,7 +96,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
||||
public String loanProductSchema() {
|
||||
return "lp.id as id, lp.fund_id as fundId, f.name as fundName, lp.loan_transaction_strategy_id as transactionStrategyId, ltps.name as transactionStrategyName, "
|
||||
+ "lp.name as name, lp.description as description, "
|
||||
+ "lp.principal_amount as principal, lp.currency_code as currencyCode, lp.currency_digits as currencyDigits, "
|
||||
+ "lp.principal_amount as principal, lp.min_principal_amount as minPrincipal, lp.max_principal_amount as maxPrincipal, lp.currency_code as currencyCode, lp.currency_digits as currencyDigits, "
|
||||
+ "lp.nominal_interest_rate_per_period as interestRatePerPeriod, lp.interest_period_frequency_enum as interestRatePerPeriodFreq, "
|
||||
+ "lp.annual_nominal_interest_rate as annualInterestRate, lp.interest_method_enum as interestMethod, lp.interest_calculated_in_period_enum as interestCalculationInPeriodMethod,"
|
||||
+ "lp.repay_every as repaidEvery, lp.repayment_period_frequency_enum as repaymentPeriodFrequency, lp.number_of_repayments as numberOfRepayments, "
|
||||
@@ -130,6 +130,8 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
||||
currencyNameCode);
|
||||
|
||||
final BigDecimal principal = rs.getBigDecimal("principal");
|
||||
final BigDecimal minPrincipal = rs.getBigDecimal("minPrincipal");
|
||||
final BigDecimal maxPrincipal = rs.getBigDecimal("maxPrincipal");
|
||||
final BigDecimal tolerance = rs.getBigDecimal("tolerance");
|
||||
|
||||
final Integer numberOfRepayments = JdbcSupport.getInteger(rs, "numberOfRepayments");
|
||||
@@ -157,10 +159,10 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
||||
final EnumOptionData interestCalculationPeriodType = LoanEnumerations
|
||||
.interestCalculationPeriodType(interestCalculationPeriodTypeId);
|
||||
|
||||
return new LoanProductData(id, name, description, currency, principal, tolerance, numberOfRepayments, repaymentEvery,
|
||||
interestRatePerPeriod, annualInterestRate, repaymentFrequencyType, interestRateFrequencyType, amortizationType,
|
||||
interestType, interestCalculationPeriodType, fundId, fundName, transactionStrategyId, transactionStrategyName,
|
||||
this.charges, accountingRuleType);
|
||||
return new LoanProductData(id, name, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||
numberOfRepayments, repaymentEvery, interestRatePerPeriod, annualInterestRate, repaymentFrequencyType,
|
||||
interestRateFrequencyType, amortizationType, interestType, interestCalculationPeriodType, fundId, fundName,
|
||||
transactionStrategyId, transactionStrategyName, this.charges, accountingRuleType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+18
-9
@@ -21,6 +21,8 @@ public class LoanProductRelatedDetailTestHelper {
|
||||
|
||||
MonetaryCurrency currency = new MonetaryCurrencyBuilder().withCode("USD").withDigitsAfterDecimal(2).build();
|
||||
BigDecimal defaultPrincipal = BigDecimal.valueOf(Double.valueOf("200000"));
|
||||
BigDecimal defaultMinPrincipal = BigDecimal.valueOf(Double.valueOf("100000"));
|
||||
BigDecimal defaultMaxPrincipal = BigDecimal.valueOf(Double.valueOf("250000"));
|
||||
|
||||
// 2% per month, 24% per year
|
||||
BigDecimal defaultNominalInterestRatePerPeriod = BigDecimal.valueOf(Double.valueOf("2"));
|
||||
@@ -37,7 +39,7 @@ public class LoanProductRelatedDetailTestHelper {
|
||||
|
||||
BigDecimal inArrearsTolerance = BigDecimal.ZERO;
|
||||
|
||||
return createLoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType,
|
||||
return createLoanProductRelatedDetail(currency, defaultPrincipal, defaultMinPrincipal, defaultMaxPrincipal, defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType,
|
||||
defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType,
|
||||
defaultNumberOfRepayments, amortizationMethod, inArrearsTolerance);
|
||||
}
|
||||
@@ -45,6 +47,8 @@ public class LoanProductRelatedDetailTestHelper {
|
||||
public static LoanProductRelatedDetail createSettingsForEqualInstallmentAmortizationQuarterly() {
|
||||
MonetaryCurrency currency = new MonetaryCurrencyBuilder().withCode("USD").withDigitsAfterDecimal(2).build();
|
||||
BigDecimal defaultPrincipal = BigDecimal.valueOf(Double.valueOf("200000"));
|
||||
BigDecimal defaultMinPrincipal = BigDecimal.valueOf(Double.valueOf("100000"));
|
||||
BigDecimal defaultMaxPrincipal = BigDecimal.valueOf(Double.valueOf("250000"));
|
||||
|
||||
// 2% per month, 24% per year
|
||||
BigDecimal defaultNominalInterestRatePerPeriod = BigDecimal.valueOf(Double.valueOf("2"));
|
||||
@@ -61,7 +65,7 @@ public class LoanProductRelatedDetailTestHelper {
|
||||
|
||||
BigDecimal inArrearsTolerance = BigDecimal.ZERO;
|
||||
|
||||
return createLoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType,
|
||||
return createLoanProductRelatedDetail(currency, defaultPrincipal, defaultMinPrincipal, defaultMaxPrincipal, defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType,
|
||||
defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType,
|
||||
defaultNumberOfRepayments, amortizationMethod, inArrearsTolerance);
|
||||
}
|
||||
@@ -70,6 +74,8 @@ public class LoanProductRelatedDetailTestHelper {
|
||||
|
||||
MonetaryCurrency currency = new MonetaryCurrencyBuilder().withCode("USD").withDigitsAfterDecimal(2).build();
|
||||
BigDecimal defaultPrincipal = BigDecimal.valueOf(Double.valueOf("200000"));
|
||||
BigDecimal defaultMinPrincipal = BigDecimal.valueOf(Double.valueOf("200000"));
|
||||
BigDecimal defaultMaxPrincipal = BigDecimal.valueOf(Double.valueOf("200000"));
|
||||
|
||||
// 2% per month, 24% per year
|
||||
BigDecimal defaultNominalInterestRatePerPeriod = BigDecimal.valueOf(Double.valueOf("2"));
|
||||
@@ -85,7 +91,7 @@ public class LoanProductRelatedDetailTestHelper {
|
||||
|
||||
BigDecimal inArrearsTolerance = BigDecimal.ZERO;
|
||||
|
||||
return createLoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType,
|
||||
return createLoanProductRelatedDetail(currency, defaultPrincipal, defaultMinPrincipal, defaultMaxPrincipal, defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType,
|
||||
defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType,
|
||||
defaultNumberOfRepayments, amortizationMethod, inArrearsTolerance);
|
||||
}
|
||||
@@ -94,6 +100,8 @@ public class LoanProductRelatedDetailTestHelper {
|
||||
|
||||
MonetaryCurrency currency = new MonetaryCurrencyBuilder().withCode("KSH").withDigitsAfterDecimal(0).build();
|
||||
BigDecimal defaultPrincipal = BigDecimal.valueOf(Double.valueOf("15000"));
|
||||
BigDecimal defaultMinPrincipal = BigDecimal.valueOf(Double.valueOf("15000"));
|
||||
BigDecimal defaultMaxPrincipal = BigDecimal.valueOf(Double.valueOf("15000"));
|
||||
|
||||
// 2% per month, 24% per year
|
||||
BigDecimal defaultNominalInterestRatePerPeriod = BigDecimal.valueOf(Double.valueOf("2"));
|
||||
@@ -111,19 +119,20 @@ public class LoanProductRelatedDetailTestHelper {
|
||||
|
||||
AmortizationMethod amortizationMethod = AmortizationMethod.EQUAL_PRINCIPAL;
|
||||
|
||||
return createLoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType,
|
||||
defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType,
|
||||
defaultNumberOfRepayments, amortizationMethod, inArrearsTolerance);
|
||||
return createLoanProductRelatedDetail(currency, defaultPrincipal, defaultMinPrincipal, defaultMaxPrincipal,
|
||||
defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod,
|
||||
interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType, defaultNumberOfRepayments, amortizationMethod,
|
||||
inArrearsTolerance);
|
||||
}
|
||||
|
||||
private static LoanProductRelatedDetail createLoanProductRelatedDetail(MonetaryCurrency currency, BigDecimal defaultPrincipal,
|
||||
BigDecimal defaultNominalInterestRatePerPeriod, PeriodFrequencyType interestPeriodFrequencyType,
|
||||
BigDecimal defaultAnnualNominalInterestRate, InterestMethod interestMethod,
|
||||
BigDecimal defaultMinPrincipal, BigDecimal defaultMaxPrincipal, BigDecimal defaultNominalInterestRatePerPeriod,
|
||||
PeriodFrequencyType interestPeriodFrequencyType, BigDecimal defaultAnnualNominalInterestRate, InterestMethod interestMethod,
|
||||
InterestCalculationPeriodMethod interestCalculationPeriodMethod, Integer repayEvery,
|
||||
PeriodFrequencyType repaymentFrequencyType, Integer defaultNumberOfRepayments, AmortizationMethod amortizationMethod,
|
||||
BigDecimal inArrearsTolerance) {
|
||||
|
||||
return new LoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType,
|
||||
return new LoanProductRelatedDetail(currency, defaultPrincipal, defaultMinPrincipal, defaultMaxPrincipal, defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType,
|
||||
defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType,
|
||||
defaultNumberOfRepayments, amortizationMethod, inArrearsTolerance);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user