MIFOSX-282: remove min and max fields from loan table
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
ALTER TABLE `m_loan`
|
||||
DROP COLUMN `min_principal_amount`,
|
||||
DROP COLUMN `max_principal_amount`,
|
||||
DROP COLUMN `min_nominal_interest_rate_per_period`,
|
||||
DROP COLUMN `max_nominal_interest_rate_per_period`,
|
||||
DROP COLUMN `min_number_of_repayments`,
|
||||
DROP COLUMN `max_number_of_repayments`;
|
||||
+9
-12
@@ -668,6 +668,10 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
return this.client;
|
||||
}
|
||||
|
||||
public LoanProduct loanProduct(){
|
||||
return this.loanProduct;
|
||||
}
|
||||
|
||||
public LoanProductRelatedDetail repaymentScheduleDetail() {
|
||||
return this.loanRepaymentScheduleDetail;
|
||||
}
|
||||
@@ -1318,12 +1322,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 BigDecimal minInterestRatePerPeriod = this.loanRepaymentScheduleDetail.getMinNominalInterestRatePerPeriod();
|
||||
final BigDecimal maxInterestRatePerPeriod = this.loanRepaymentScheduleDetail.getMaxNominalInterestRatePerPeriod();
|
||||
final PeriodFrequencyType interestRatePeriodFrequencyType = this.loanRepaymentScheduleDetail.getInterestPeriodFrequencyType();
|
||||
final BigDecimal defaultAnnualNominalInterestRate = this.loanRepaymentScheduleDetail.getAnnualNominalInterestRate();
|
||||
|
||||
@@ -1332,18 +1332,15 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
final Integer repaymentEvery = this.loanRepaymentScheduleDetail.getRepayEvery();
|
||||
final PeriodFrequencyType repaymentPeriodFrequencyType = this.loanRepaymentScheduleDetail.getRepaymentPeriodFrequencyType();
|
||||
final Integer numberOfRepayments = this.loanRepaymentScheduleDetail.getNumberOfRepayments();
|
||||
final Integer minNumberOfRepayments = this.loanRepaymentScheduleDetail.getMinNumberOfRepayments();
|
||||
final Integer maxNumberOfRepayments = this.loanRepaymentScheduleDetail.getMaxNumberOfRepayments();
|
||||
final AmortizationMethod amortizationMethod = this.loanRepaymentScheduleDetail.getAmortizationMethod();
|
||||
final Integer loanTermFrequency = this.termFrequency;
|
||||
final PeriodFrequencyType loanTermPeriodFrequencyType = PeriodFrequencyType.fromInt(this.termPeriodFrequencyType);
|
||||
|
||||
final LoanSchedule loanSchedule = new LoanSchedule(loanScheduleGenerator, applicationCurrency, principal, minPrincipal,
|
||||
maxPrincipal, interestRatePerPeriod, minInterestRatePerPeriod, maxInterestRatePerPeriod, interestRatePeriodFrequencyType,
|
||||
defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repaymentEvery,
|
||||
repaymentPeriodFrequencyType, numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, amortizationMethod,
|
||||
loanTermFrequency, loanTermPeriodFrequencyType, setOfLoanCharges(), this.getDisbursementDate(),
|
||||
this.getExpectedFirstRepaymentOnDate(), this.getInterestChargedFromDate(), inArrearsTolerance);
|
||||
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 LoanScheduleData generatedData = loanSchedule.generate();
|
||||
|
||||
|
||||
+7
-20
@@ -27,11 +27,7 @@ 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 BigDecimal minNominalInterestRatePerPeriod;
|
||||
private final BigDecimal maxNominalInterestRatePerPeriod;
|
||||
private final PeriodFrequencyType interestRatePeriodFrequencyType;
|
||||
private final BigDecimal nominalAnnualInterestRate;
|
||||
private final InterestMethod interestMethod;
|
||||
@@ -39,8 +35,6 @@ public final class LoanSchedule {
|
||||
private final Integer repaymentEvery;
|
||||
private final PeriodFrequencyType repaymentPeriodFrequencyType;
|
||||
private final Integer numberOfRepayments;
|
||||
private final Integer minNumberOfRepayments;
|
||||
private final Integer maxNumberOfRepayments;
|
||||
private final AmortizationMethod amortizationMethod;
|
||||
private final Integer loanTermFrequency;
|
||||
private final PeriodFrequencyType loanTermPeriodFrequencyType;
|
||||
@@ -52,22 +46,17 @@ public final class LoanSchedule {
|
||||
private final Set<LoanCharge> loanCharges;
|
||||
|
||||
public LoanSchedule(final LoanScheduleGenerator loanScheduleGenerator, final ApplicationCurrency applicationCurrency,
|
||||
final BigDecimal principal, final BigDecimal minPrincipal, final BigDecimal maxPrincipal,
|
||||
final BigDecimal nominalInterestRatePerPeriod, final BigDecimal minNominalInterestRatePerPeriod, final BigDecimal maxNominalInterestRatePerPeriod, final PeriodFrequencyType interestRatePeriodFrequencyType,
|
||||
final BigDecimal nominalAnnualInterestRate, final InterestMethod interestMethod,
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final Integer repaymentEvery,
|
||||
final PeriodFrequencyType repaymentPeriodFrequencyType, final Integer numberOfRepayments, final Integer minNumberOfRepayments, final Integer maxNumberOfRepayments,
|
||||
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 AmortizationMethod amortizationMethod, final Integer loanTermFrequency,
|
||||
final PeriodFrequencyType loanTermPeriodFrequencyType, final Set<LoanCharge> loanCharges, final LocalDate disbursementDate,
|
||||
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.minNominalInterestRatePerPeriod = minNominalInterestRatePerPeriod;
|
||||
this.maxNominalInterestRatePerPeriod = maxNominalInterestRatePerPeriod;
|
||||
this.interestRatePeriodFrequencyType = interestRatePeriodFrequencyType;
|
||||
this.nominalAnnualInterestRate = nominalAnnualInterestRate;
|
||||
this.interestMethod = interestMethod;
|
||||
@@ -75,8 +64,6 @@ public final class LoanSchedule {
|
||||
this.repaymentEvery = repaymentEvery;
|
||||
this.repaymentPeriodFrequencyType = repaymentPeriodFrequencyType;
|
||||
this.numberOfRepayments = numberOfRepayments;
|
||||
this.minNumberOfRepayments = minNumberOfRepayments;
|
||||
this.maxNumberOfRepayments = maxNumberOfRepayments;
|
||||
this.amortizationMethod = amortizationMethod;
|
||||
this.loanTermFrequency = loanTermFrequency;
|
||||
this.loanTermPeriodFrequencyType = loanTermPeriodFrequencyType;
|
||||
@@ -95,9 +82,9 @@ public final class LoanSchedule {
|
||||
public LoanProductRelatedDetail loanProductRelatedDetail() {
|
||||
final MonetaryCurrency currency = new MonetaryCurrency(applicationCurrency.getCode(), applicationCurrency.getDecimalPlaces());
|
||||
|
||||
return LoanProductRelatedDetail.createFrom(currency, principal, minPrincipal, maxPrincipal, nominalInterestRatePerPeriod, minNominalInterestRatePerPeriod, maxNominalInterestRatePerPeriod,
|
||||
interestRatePeriodFrequencyType, nominalAnnualInterestRate, interestMethod, interestCalculationPeriodMethod,
|
||||
repaymentEvery, repaymentPeriodFrequencyType, numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, amortizationMethod, this.inArrearsTolerance);
|
||||
return LoanProductRelatedDetail.createFrom(currency, principal, nominalInterestRatePerPeriod, interestRatePeriodFrequencyType,
|
||||
nominalAnnualInterestRate, interestMethod, interestCalculationPeriodMethod, repaymentEvery, repaymentPeriodFrequencyType,
|
||||
numberOfRepayments, amortizationMethod, this.inArrearsTolerance);
|
||||
}
|
||||
|
||||
public Integer getLoanTermFrequency() {
|
||||
|
||||
+5
-43
@@ -73,33 +73,7 @@ public class LoanScheduleAssembler {
|
||||
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
||||
|
||||
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 BigDecimal minInterestRatePerPeriod = loanProduct.getMinNominalInterestRatePerPeriod();// Copy
|
||||
// from
|
||||
// Loan
|
||||
// product
|
||||
// to
|
||||
// Loan
|
||||
final BigDecimal maxInterestRatePerPeriod = loanProduct.getMaxNominalInterestRatePerPeriod();// Copy
|
||||
// from
|
||||
// Loan
|
||||
// product
|
||||
// to
|
||||
// Loan
|
||||
final Integer interestRateFrequencyType = fromApiJsonHelper.extractIntegerWithLocaleNamed("interestRateFrequencyType", element);
|
||||
final Integer interestType = fromApiJsonHelper.extractIntegerWithLocaleNamed("interestType", element);
|
||||
final Integer interestCalculationPeriodType = fromApiJsonHelper.extractIntegerWithLocaleNamed("interestCalculationPeriodType",
|
||||
@@ -116,18 +90,6 @@ public class LoanScheduleAssembler {
|
||||
final Integer repaymentEvery = fromApiJsonHelper.extractIntegerWithLocaleNamed("repaymentEvery", element);
|
||||
final Integer repaymentFrequencyType = fromApiJsonHelper.extractIntegerWithLocaleNamed("repaymentFrequencyType", element);
|
||||
final Integer numberOfRepayments = fromApiJsonHelper.extractIntegerWithLocaleNamed("numberOfRepayments", element);
|
||||
final Integer minNumberOfRepayments = loanProduct.getMinNumberOfRepayments();// Copy
|
||||
// from
|
||||
// Loan
|
||||
// product
|
||||
// to
|
||||
// Loan
|
||||
final Integer maxNumberOfRepayments = loanProduct.getMaxNumberOfRepayments();// Copy
|
||||
// from
|
||||
// Loan
|
||||
// product
|
||||
// to
|
||||
// Loan
|
||||
final Integer amortizationType = fromApiJsonHelper.extractIntegerWithLocaleNamed("amortizationType", element);
|
||||
final PeriodFrequencyType repaymentPeriodFrequencyType = PeriodFrequencyType.fromInt(repaymentFrequencyType);
|
||||
final AmortizationMethod amortizationMethod = AmortizationMethod.fromInt(amortizationType);
|
||||
@@ -144,10 +106,10 @@ public class LoanScheduleAssembler {
|
||||
|
||||
final LoanScheduleGenerator loanScheduleGenerator = this.loanScheduleFactory.create(interestMethod);
|
||||
|
||||
return new LoanSchedule(loanScheduleGenerator, applicationCurrency, principal, minPrincipal, maxPrincipal, interestRatePerPeriod,
|
||||
minInterestRatePerPeriod, maxInterestRatePerPeriod, interestRatePeriodFrequencyType, defaultAnnualNominalInterestRate,
|
||||
interestMethod, interestCalculationPeriodMethod, repaymentEvery, repaymentPeriodFrequencyType, numberOfRepayments,
|
||||
minNumberOfRepayments, maxNumberOfRepayments, amortizationMethod, loanTermFrequency, loanTermPeriodFrequencyType,
|
||||
loanCharges, expectedDisbursementDate, repaymentsStartingFromDate, interestChargedFromDate, inArrearsTolerance);
|
||||
return new LoanSchedule(loanScheduleGenerator, applicationCurrency, principal, interestRatePerPeriod,
|
||||
interestRatePeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod,
|
||||
repaymentEvery, repaymentPeriodFrequencyType, numberOfRepayments, amortizationMethod, loanTermFrequency,
|
||||
loanTermPeriodFrequencyType, loanCharges, expectedDisbursementDate, repaymentsStartingFromDate, interestChargedFromDate,
|
||||
inArrearsTolerance);
|
||||
}
|
||||
}
|
||||
+11
-13
@@ -23,6 +23,7 @@ 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.mifosplatform.portfolio.loanproduct.serialization.LoanProductCommandFromApiJsonDeserializer;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -49,13 +50,16 @@ public final class LoanApplicationCommandFromApiJsonHelper {
|
||||
));
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
private final LoanProductCommandFromApiJsonDeserializer loanProductCommandFromApiJsonDeserializer;
|
||||
|
||||
@Autowired
|
||||
public LoanApplicationCommandFromApiJsonHelper(final FromJsonHelper fromApiJsonHelper) {
|
||||
public LoanApplicationCommandFromApiJsonHelper(final FromJsonHelper fromApiJsonHelper, final LoanProductCommandFromApiJsonDeserializer loanProductCommandFromApiJsonDeserializer) {
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
this.loanProductCommandFromApiJsonDeserializer = loanProductCommandFromApiJsonDeserializer;
|
||||
}
|
||||
|
||||
public void validateForCreate(final String json) {
|
||||
public void validateForCreate(final String json, final LoanProduct loanProduct) {
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
@@ -281,6 +285,8 @@ public final class LoanApplicationCommandFromApiJsonHelper {
|
||||
}
|
||||
}
|
||||
|
||||
loanProductCommandFromApiJsonDeserializer.validateMinMaxConstraints(element, baseDataValidator, loanProduct);
|
||||
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
@@ -593,19 +599,11 @@ public final class LoanApplicationCommandFromApiJsonHelper {
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
|
||||
public void validateMinMaxConstraintValues(final JsonElement element, final LoanProduct loanProduct){
|
||||
|
||||
public void validateMinMaxConstraintsForModification(final String json, final LoanProduct loanProduct) {
|
||||
final JsonElement element = fromApiJsonHelper.parse(json);
|
||||
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);
|
||||
}
|
||||
this.loanProductCommandFromApiJsonDeserializer.validateMinMaxConstraints(element, baseDataValidator, loanProduct);
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
|
||||
+9
-7
@@ -57,7 +57,6 @@ import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRepository;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanTransactionProcessingStrategy;
|
||||
import org.mifosplatform.portfolio.loanproduct.exception.LoanProductNotFoundException;
|
||||
import org.mifosplatform.portfolio.loanproduct.serialization.LoanProductCommandFromApiJsonDeserializer;
|
||||
import org.mifosplatform.portfolio.note.domain.Note;
|
||||
import org.mifosplatform.portfolio.note.domain.NoteRepository;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
@@ -93,7 +92,6 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
private final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory;
|
||||
private final CalendarRepository calendarRepository;
|
||||
private final CalendarInstanceRepository calendarInstanceRepository;
|
||||
private final LoanProductCommandFromApiJsonDeserializer loanProductCommandFromApiJsonDeserializer;
|
||||
|
||||
@Autowired
|
||||
public LoanApplicationWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final FromJsonHelper fromJsonHelper,
|
||||
@@ -105,8 +103,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
final LoanProductRepository loanProductRepository, final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory,
|
||||
final LoanSummaryWrapper loanSummaryWrapper,
|
||||
final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory,
|
||||
final CalendarRepository calendarRepository, final CalendarInstanceRepository calendarInstanceRepository,
|
||||
final LoanProductCommandFromApiJsonDeserializer loanProductCommandFromApiJsonDeserializer) {
|
||||
final CalendarRepository calendarRepository, final CalendarInstanceRepository calendarInstanceRepository) {
|
||||
this.context = context;
|
||||
this.fromJsonHelper = fromJsonHelper;
|
||||
this.loanApplicationTransitionApiJsonValidator = loanApplicationTransitionApiJsonValidator;
|
||||
@@ -125,7 +122,6 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
this.loanRepaymentScheduleTransactionProcessorFactory = loanRepaymentScheduleTransactionProcessorFactory;
|
||||
this.calendarRepository = calendarRepository;
|
||||
this.calendarInstanceRepository = calendarInstanceRepository;
|
||||
this.loanProductCommandFromApiJsonDeserializer = loanProductCommandFromApiJsonDeserializer;
|
||||
}
|
||||
|
||||
private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
|
||||
@@ -139,8 +135,12 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
|
||||
AppUser currentUser = context.authenticatedUser();
|
||||
|
||||
this.fromApiJsonDeserializer.validateForCreate(command.json());
|
||||
final Long productId = fromJsonHelper.extractLongNamed("productId", command.parsedJson());
|
||||
|
||||
final LoanProduct loanProduct = this.loanProductRepository.findOne(productId);
|
||||
if (loanProduct == null) { throw new LoanProductNotFoundException(productId); }
|
||||
|
||||
this.fromApiJsonDeserializer.validateForCreate(command.json(), loanProduct);
|
||||
|
||||
//validate dates against calendar recurring dates
|
||||
//get calendar
|
||||
@@ -203,7 +203,6 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
}
|
||||
|
||||
final Loan existingLoanApplication = retrieveLoanBy(loanId);
|
||||
this.loanProductCommandFromApiJsonDeserializer.validateMinMaxConstraints(command.parsedJson(), existingLoanApplication.repaymentScheduleDetail(), "loan");
|
||||
|
||||
if (!existingLoanApplication.isSubmittedAndPendingApproval()) { throw new LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeModified(
|
||||
loanId); }
|
||||
@@ -232,6 +231,9 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
|
||||
existingLoanApplication.updateLoanProduct(loanProduct);
|
||||
}
|
||||
|
||||
//validate min and maximum constraints
|
||||
this.fromApiJsonDeserializer.validateMinMaxConstraintsForModification(command.json(), existingLoanApplication.loanProduct());
|
||||
|
||||
final String fundIdParamName = "fundId";
|
||||
if (changes.containsKey(fundIdParamName)) {
|
||||
|
||||
+1
-8
@@ -46,7 +46,6 @@ import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRepository;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanTransactionProcessingStrategy;
|
||||
import org.mifosplatform.portfolio.loanproduct.exception.LoanProductNotFoundException;
|
||||
import org.mifosplatform.portfolio.loanproduct.serialization.LoanProductCommandFromApiJsonDeserializer;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -69,7 +68,6 @@ public class LoanAssembler {
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
private final LoanSummaryWrapper loanSummaryWrapper;
|
||||
private final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory;
|
||||
private final LoanProductCommandFromApiJsonDeserializer loanProductCommandFromApiJsonDeserializer;
|
||||
|
||||
@Autowired
|
||||
public LoanAssembler(final FromJsonHelper fromApiJsonHelper, final LoanProductRepository loanProductRepository,
|
||||
@@ -78,8 +76,7 @@ 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 LoanProductCommandFromApiJsonDeserializer loanProductCommandFromApiJsonDeserializer) {
|
||||
final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory) {
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
this.loanProductRepository = loanProductRepository;
|
||||
this.clientRepository = clientRepository;
|
||||
@@ -93,7 +90,6 @@ public class LoanAssembler {
|
||||
this.loanCollateralAssembler = loanCollateralAssembler;
|
||||
this.loanSummaryWrapper = loanSummaryWrapper;
|
||||
this.loanRepaymentScheduleTransactionProcessorFactory = loanRepaymentScheduleTransactionProcessorFactory;
|
||||
this.loanProductCommandFromApiJsonDeserializer = loanProductCommandFromApiJsonDeserializer;
|
||||
}
|
||||
|
||||
public Loan assembleFrom(final JsonCommand command, final AppUser currentUser) {
|
||||
@@ -116,9 +112,6 @@ public class LoanAssembler {
|
||||
|
||||
final LoanProduct loanProduct = this.loanProductRepository.findOne(productId);
|
||||
if (loanProduct == null) { throw new LoanProductNotFoundException(productId); }
|
||||
|
||||
//validate min and max constraint parameters
|
||||
this.loanProductCommandFromApiJsonDeserializer.validateMinMaxConstraints(element, loanProduct.loanProductRelatedDetail(), "loan");
|
||||
|
||||
final Fund fund = findFundByIdIfProvided(fundId);
|
||||
final Staff loanOfficer = findLoanOfficerByIdIfProvided(loanOfficerId);
|
||||
|
||||
+26
-11
@@ -65,6 +65,9 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
|
||||
@Embedded
|
||||
private final LoanProductRelatedDetail loanProductRelatedDetail;
|
||||
|
||||
@Embedded
|
||||
private LoanProductMinMaxConstraints loanProductMinMaxConstraints;
|
||||
|
||||
@Column(name = "accounting_type", nullable = false)
|
||||
private Integer accountingRule;
|
||||
@@ -110,6 +113,7 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
|
||||
protected LoanProduct() {
|
||||
this.loanProductRelatedDetail = null;
|
||||
this.loanProductMinMaxConstraints = null;
|
||||
}
|
||||
|
||||
public LoanProduct(final Fund fund, final LoanTransactionProcessingStrategy transactionProcessingStrategy, final String name,
|
||||
@@ -136,12 +140,14 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
this.charges = charges;
|
||||
}
|
||||
|
||||
this.loanProductRelatedDetail = new LoanProductRelatedDetail(currency, defaultPrincipal, defaultMinPrincipal, defaultMaxPrincipal,
|
||||
defaultNominalInterestRatePerPeriod, defaultMinNominalInterestRatePerPeriod, defaultMaxNominalInterestRatePerPeriod,
|
||||
this.loanProductRelatedDetail = new LoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod,
|
||||
interestPeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery,
|
||||
repaymentFrequencyType, defaultNumberOfInstallments, defaultMinNumberOfInstallments, defaultMaxNumberOfInstallments,
|
||||
amortizationMethod, inArrearsTolerance);
|
||||
repaymentFrequencyType, defaultNumberOfInstallments, amortizationMethod, inArrearsTolerance);
|
||||
|
||||
this.loanProductMinMaxConstraints = new LoanProductMinMaxConstraints(defaultMinPrincipal, defaultMaxPrincipal,
|
||||
defaultMinNominalInterestRatePerPeriod, defaultMaxNominalInterestRatePerPeriod, defaultMinNumberOfInstallments,
|
||||
defaultMaxNumberOfInstallments);
|
||||
|
||||
if (accountingRuleType != null) {
|
||||
this.accountingRule = accountingRuleType.getValue();
|
||||
}
|
||||
@@ -179,6 +185,7 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
public Map<String, Object> update(final JsonCommand command, final AprCalculator aprCalculator) {
|
||||
|
||||
final Map<String, Object> actualChanges = this.loanProductRelatedDetail.update(command, aprCalculator);
|
||||
actualChanges.putAll(this.loanProductMinMaxConstraints().update(command));
|
||||
|
||||
final String accountingTypeParamName = "accountingRule";
|
||||
if (command.isChangeInIntegerParameterNamed(accountingTypeParamName, this.accountingRule)) {
|
||||
@@ -246,11 +253,11 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
public Money getMinPrincipalAmount(){
|
||||
return this.loanProductRelatedDetail.getMinPrincipal();
|
||||
return Money.of(this.loanProductRelatedDetail.getCurrency(), this.loanProductMinMaxConstraints().getMinPrincipal());
|
||||
}
|
||||
|
||||
public Money getMaxPrincipalAmount(){
|
||||
return this.loanProductRelatedDetail.getMaxPrincipal();
|
||||
return Money.of(this.loanProductRelatedDetail.getCurrency(), this.loanProductMinMaxConstraints().getMaxPrincipal());
|
||||
}
|
||||
|
||||
public BigDecimal getNominalInterestRatePerPeriod() {
|
||||
@@ -258,26 +265,34 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
public BigDecimal getMinNominalInterestRatePerPeriod() {
|
||||
return this.loanProductRelatedDetail.getMinNominalInterestRatePerPeriod();
|
||||
return this.loanProductMinMaxConstraints().getMinNominalInterestRatePerPeriod();
|
||||
}
|
||||
|
||||
public BigDecimal getMaxNominalInterestRatePerPeriod(){
|
||||
return this.loanProductRelatedDetail.getMaxNominalInterestRatePerPeriod();
|
||||
return this.loanProductMinMaxConstraints().getMaxNominalInterestRatePerPeriod();
|
||||
}
|
||||
|
||||
public Integer getNumberOfRepayments(){
|
||||
return this.loanProductRelatedDetail.getNumberOfRepayments();
|
||||
return this.loanProductRelatedDetail().getNumberOfRepayments();
|
||||
}
|
||||
|
||||
public Integer getMinNumberOfRepayments() {
|
||||
return this.loanProductRelatedDetail.getMinNumberOfRepayments();
|
||||
return this.loanProductMinMaxConstraints().getMinNumberOfRepayments();
|
||||
}
|
||||
|
||||
public Integer getMaxNumberOfRepayments() {
|
||||
return this.loanProductRelatedDetail.getMaxNumberOfRepayments();
|
||||
return this.loanProductMinMaxConstraints().getMaxNumberOfRepayments();
|
||||
}
|
||||
|
||||
public LoanProductRelatedDetail loanProductRelatedDetail(){
|
||||
return this.loanProductRelatedDetail;
|
||||
}
|
||||
|
||||
public LoanProductMinMaxConstraints loanProductMinMaxConstraints() {
|
||||
//If all min and max fields are null then loanProductMinMaxConstraints initialising to null
|
||||
//Reset LoanProductMinMaxConstraints with null values.
|
||||
this.loanProductMinMaxConstraints = (this.loanProductMinMaxConstraints == null) ? new LoanProductMinMaxConstraints(null, null, null, null, null, null)
|
||||
: this.loanProductMinMaxConstraints;
|
||||
return loanProductMinMaxConstraints;
|
||||
}
|
||||
}
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
/**
|
||||
* 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.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embeddable;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
|
||||
/**
|
||||
* LoanProductMinMaxConstraints encapsulates all the Min and Max details of a
|
||||
* {@link LoanProduct}.
|
||||
*/
|
||||
@Embeddable
|
||||
public class LoanProductMinMaxConstraints {
|
||||
|
||||
@Column(name = "min_principal_amount", scale = 6, precision = 19, nullable = true)
|
||||
private BigDecimal minPrincipal;
|
||||
|
||||
@Column(name = "max_principal_amount", scale = 6, precision = 19, nullable = true)
|
||||
private BigDecimal maxPrincipal;
|
||||
|
||||
@Column(name = "min_nominal_interest_rate_per_period", scale = 6, precision = 19, nullable = true)
|
||||
private BigDecimal minNominalInterestRatePerPeriod;
|
||||
|
||||
@Column(name = "max_nominal_interest_rate_per_period", scale = 6, precision = 19, nullable = true)
|
||||
private BigDecimal maxNominalInterestRatePerPeriod;
|
||||
|
||||
@Column(name = "min_number_of_repayments", nullable = true)
|
||||
private Integer minNumberOfRepayments;
|
||||
|
||||
@Column(name = "max_number_of_repayments", nullable = true)
|
||||
private Integer maxNumberOfRepayments;
|
||||
|
||||
public static LoanProductMinMaxConstraints createFrom(final BigDecimal minPrincipal, final BigDecimal maxPrincipal,
|
||||
final BigDecimal minNominalInterestRatePerPeriod, final BigDecimal maxNominalInterestRatePerPeriod,
|
||||
final Integer minNumberOfRepayments, final Integer maxNumberOfRepayments) {
|
||||
|
||||
return new LoanProductMinMaxConstraints(minPrincipal, maxPrincipal, minNominalInterestRatePerPeriod,
|
||||
maxNominalInterestRatePerPeriod, minNumberOfRepayments, maxNumberOfRepayments);
|
||||
}
|
||||
|
||||
protected LoanProductMinMaxConstraints() {
|
||||
//
|
||||
}
|
||||
|
||||
public LoanProductMinMaxConstraints(final BigDecimal defaultMinPrincipal, final BigDecimal defaultMaxPrincipal,
|
||||
final BigDecimal defaultMinNominalInterestRatePerPeriod, final BigDecimal defaultMaxNominalInterestRatePerPeriod,
|
||||
final Integer defaultMinNumberOfRepayments, final Integer defaultMaxNumberOfRepayments) {
|
||||
this.minPrincipal = defaultMinPrincipal;
|
||||
this.maxPrincipal = defaultMaxPrincipal;
|
||||
this.minNominalInterestRatePerPeriod = defaultMinNominalInterestRatePerPeriod;
|
||||
this.maxNominalInterestRatePerPeriod = defaultMaxNominalInterestRatePerPeriod;
|
||||
this.minNumberOfRepayments = defaultMinNumberOfRepayments;
|
||||
this.maxNumberOfRepayments = defaultMaxNumberOfRepayments;
|
||||
}
|
||||
|
||||
public Map<String, Object> update(final JsonCommand command) {
|
||||
|
||||
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(20);
|
||||
|
||||
final String localeAsInput = command.locale();
|
||||
|
||||
final String minPrincipalParamName = "minPrincipal";
|
||||
if (command.isChangeInBigDecimalParameterNamedWithNullCheck(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.isChangeInBigDecimalParameterNamedWithNullCheck(maxPrincipalParamName, this.maxPrincipal)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(maxPrincipalParamName);
|
||||
actualChanges.put(maxPrincipalParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.maxPrincipal = newValue;
|
||||
}
|
||||
|
||||
final String minNumberOfRepaymentsParamName = "minNumberOfRepayments";
|
||||
if (command.isChangeInIntegerParameterNamed(minNumberOfRepaymentsParamName, this.minNumberOfRepayments)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(minNumberOfRepaymentsParamName);
|
||||
actualChanges.put(minNumberOfRepaymentsParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.minNumberOfRepayments = newValue;
|
||||
}
|
||||
|
||||
final String maxNumberOfRepaymentsParamName = "maxNumberOfRepayments";
|
||||
if (command.isChangeInIntegerParameterNamed(maxNumberOfRepaymentsParamName, this.maxNumberOfRepayments)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(maxNumberOfRepaymentsParamName);
|
||||
actualChanges.put(maxNumberOfRepaymentsParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.maxNumberOfRepayments = newValue;
|
||||
}
|
||||
|
||||
final String minInterestRatePerPeriodParamName = "minInterestRatePerPeriod";
|
||||
if (command
|
||||
.isChangeInBigDecimalParameterNamedWithNullCheck(minInterestRatePerPeriodParamName, this.minNominalInterestRatePerPeriod)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(minInterestRatePerPeriodParamName);
|
||||
actualChanges.put(minInterestRatePerPeriodParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.minNominalInterestRatePerPeriod = newValue;
|
||||
}
|
||||
|
||||
final String maxInterestRatePerPeriodParamName = "maxInterestRatePerPeriod";
|
||||
if (command
|
||||
.isChangeInBigDecimalParameterNamedWithNullCheck(maxInterestRatePerPeriodParamName, this.maxNominalInterestRatePerPeriod)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(maxInterestRatePerPeriodParamName);
|
||||
actualChanges.put(maxInterestRatePerPeriodParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.maxNominalInterestRatePerPeriod = newValue;
|
||||
}
|
||||
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
public BigDecimal getMinPrincipal() {
|
||||
return this.minPrincipal;
|
||||
}
|
||||
|
||||
public BigDecimal getMaxPrincipal() {
|
||||
return this.maxPrincipal;
|
||||
}
|
||||
|
||||
public BigDecimal getMinNominalInterestRatePerPeriod() {
|
||||
return this.minNominalInterestRatePerPeriod == null ? null : BigDecimal.valueOf(Double.valueOf(this.minNominalInterestRatePerPeriod
|
||||
.stripTrailingZeros().toString()));
|
||||
}
|
||||
|
||||
public BigDecimal getMaxNominalInterestRatePerPeriod() {
|
||||
return this.maxNominalInterestRatePerPeriod == null ? null : BigDecimal.valueOf(Double.valueOf(this.maxNominalInterestRatePerPeriod
|
||||
.stripTrailingZeros().toString()));
|
||||
}
|
||||
|
||||
public Integer getMinNumberOfRepayments() {
|
||||
return minNumberOfRepayments;
|
||||
}
|
||||
|
||||
public Integer getMaxNumberOfRepayments() {
|
||||
return maxNumberOfRepayments;
|
||||
}
|
||||
|
||||
}
|
||||
+8
-112
@@ -34,20 +34,8 @@ 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 = true)
|
||||
private BigDecimal minPrincipal;
|
||||
|
||||
@Column(name = "max_principal_amount", scale = 6, precision = 19, nullable = true)
|
||||
private BigDecimal maxPrincipal;
|
||||
|
||||
@Column(name = "nominal_interest_rate_per_period", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal nominalInterestRatePerPeriod;
|
||||
|
||||
@Column(name = "min_nominal_interest_rate_per_period", scale = 6, precision = 19, nullable = true)
|
||||
private BigDecimal minNominalInterestRatePerPeriod;
|
||||
|
||||
@Column(name = "max_nominal_interest_rate_per_period", scale = 6, precision = 19, nullable = true)
|
||||
private BigDecimal maxNominalInterestRatePerPeriod;
|
||||
|
||||
// FIXME - move away form JPA ordinal use for enums using just integer -
|
||||
// requires sql patch for existing users of software.
|
||||
@@ -81,12 +69,6 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
|
||||
@Column(name = "number_of_repayments", nullable = false)
|
||||
private Integer numberOfRepayments;
|
||||
|
||||
@Column(name = "min_number_of_repayments", nullable = true)
|
||||
private Integer minNumberOfRepayments;
|
||||
|
||||
@Column(name = "max_number_of_repayments", nullable = true)
|
||||
private Integer maxNumberOfRepayments;
|
||||
|
||||
// FIXME - move away form JPA ordinal use for enums using just integer -
|
||||
// requires sql patch for existing users of software.
|
||||
@@ -98,18 +80,15 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
private BigDecimal inArrearsTolerance;
|
||||
|
||||
public static LoanProductRelatedDetail createFrom(final MonetaryCurrency currency, final BigDecimal principal,
|
||||
final BigDecimal minPrincipal, final BigDecimal maxPrincipal, final BigDecimal nominalInterestRatePerPeriod,
|
||||
final BigDecimal minNominalInterestRatePerPeriod, final BigDecimal maxNominalInterestRatePerPeriod,
|
||||
final PeriodFrequencyType interestRatePeriodFrequencyType, final BigDecimal nominalAnnualInterestRate,
|
||||
final InterestMethod interestMethod, final InterestCalculationPeriodMethod interestCalculationPeriodMethod,
|
||||
final Integer repaymentEvery, final PeriodFrequencyType repaymentPeriodFrequencyType, final Integer numberOfRepayments,
|
||||
final Integer minNumberOfRepayments, final Integer maxNumberOfRepayments, final AmortizationMethod amortizationMethod,
|
||||
final BigDecimal inArrearsTolerance) {
|
||||
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, minPrincipal, maxPrincipal, nominalInterestRatePerPeriod,
|
||||
minNominalInterestRatePerPeriod, maxNominalInterestRatePerPeriod, interestRatePeriodFrequencyType,
|
||||
return new LoanProductRelatedDetail(currency, principal, nominalInterestRatePerPeriod, interestRatePeriodFrequencyType,
|
||||
nominalAnnualInterestRate, interestMethod, interestCalculationPeriodMethod, repaymentEvery, repaymentPeriodFrequencyType,
|
||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, amortizationMethod, inArrearsTolerance);
|
||||
numberOfRepayments, amortizationMethod, inArrearsTolerance);
|
||||
}
|
||||
|
||||
protected LoanProductRelatedDetail() {
|
||||
@@ -117,21 +96,14 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
}
|
||||
|
||||
public LoanProductRelatedDetail(final MonetaryCurrency currency, final BigDecimal defaultPrincipal,
|
||||
final BigDecimal defaultMinPrincipal, final BigDecimal defaultMaxPrincipal,
|
||||
final BigDecimal defaultNominalInterestRatePerPeriod, final BigDecimal defaultMinNominalInterestRatePerPeriod,
|
||||
final BigDecimal defaultMaxNominalInterestRatePerPeriod, final PeriodFrequencyType interestPeriodFrequencyType,
|
||||
final BigDecimal defaultNominalInterestRatePerPeriod,final PeriodFrequencyType interestPeriodFrequencyType,
|
||||
final BigDecimal defaultAnnualNominalInterestRate, final InterestMethod interestMethod,
|
||||
final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final Integer repayEvery,
|
||||
final PeriodFrequencyType repaymentFrequencyType, final Integer defaultNumberOfRepayments,
|
||||
final Integer defaultMinNumberOfRepayments, final Integer defaultMaxNumberOfRepayments,
|
||||
final AmortizationMethod amortizationMethod, final BigDecimal inArrearsTolerance) {
|
||||
this.currency = currency;
|
||||
this.principal = defaultPrincipal;
|
||||
this.minPrincipal = defaultMinPrincipal;
|
||||
this.maxPrincipal = defaultMaxPrincipal;
|
||||
this.nominalInterestRatePerPeriod = defaultNominalInterestRatePerPeriod;
|
||||
this.minNominalInterestRatePerPeriod = defaultMinNominalInterestRatePerPeriod;
|
||||
this.maxNominalInterestRatePerPeriod = defaultMaxNominalInterestRatePerPeriod;
|
||||
this.interestPeriodFrequencyType = interestPeriodFrequencyType;
|
||||
this.annualNominalInterestRate = defaultAnnualNominalInterestRate;
|
||||
this.interestMethod = interestMethod;
|
||||
@@ -139,8 +111,6 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
this.repayEvery = repayEvery;
|
||||
this.repaymentPeriodFrequencyType = repaymentFrequencyType;
|
||||
this.numberOfRepayments = defaultNumberOfRepayments;
|
||||
this.minNumberOfRepayments = defaultMinNumberOfRepayments;
|
||||
this.maxNumberOfRepayments = defaultMaxNumberOfRepayments;
|
||||
this.amortizationMethod = amortizationMethod;
|
||||
if (inArrearsTolerance != null && BigDecimal.ZERO.compareTo(inArrearsTolerance) == 0) {
|
||||
this.inArrearsTolerance = null;
|
||||
@@ -156,14 +126,6 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
public Money getPrincipal() {
|
||||
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);
|
||||
@@ -172,17 +134,7 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
public BigDecimal getNominalInterestRatePerPeriod() {
|
||||
return BigDecimal.valueOf(Double.valueOf(this.nominalInterestRatePerPeriod.stripTrailingZeros().toString()));
|
||||
}
|
||||
|
||||
public BigDecimal getMinNominalInterestRatePerPeriod() {
|
||||
return this.minNominalInterestRatePerPeriod == null ? null : BigDecimal.valueOf(Double.valueOf(this.minNominalInterestRatePerPeriod
|
||||
.stripTrailingZeros().toString()));
|
||||
}
|
||||
|
||||
public BigDecimal getMaxNominalInterestRatePerPeriod() {
|
||||
return this.maxNominalInterestRatePerPeriod == null ? null : BigDecimal.valueOf(Double.valueOf(this.maxNominalInterestRatePerPeriod
|
||||
.stripTrailingZeros().toString()));
|
||||
}
|
||||
|
||||
public PeriodFrequencyType getInterestPeriodFrequencyType() {
|
||||
return interestPeriodFrequencyType;
|
||||
}
|
||||
@@ -214,14 +166,6 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
return numberOfRepayments;
|
||||
}
|
||||
|
||||
public Integer getMinNumberOfRepayments() {
|
||||
return minNumberOfRepayments;
|
||||
}
|
||||
|
||||
public Integer getMaxNumberOfRepayments() {
|
||||
return maxNumberOfRepayments;
|
||||
}
|
||||
|
||||
public AmortizationMethod getAmortizationMethod() {
|
||||
return amortizationMethod;
|
||||
}
|
||||
@@ -264,22 +208,6 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
|
||||
final String localeAsInput = command.locale();
|
||||
|
||||
final String minPrincipalParamName = "minPrincipal";
|
||||
if (command.isChangeInBigDecimalParameterNamedWithNullCheck(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.isChangeInBigDecimalParameterNamedWithNullCheck(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);
|
||||
@@ -303,22 +231,6 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.repaymentPeriodFrequencyType = PeriodFrequencyType.fromInt(newValue);
|
||||
}
|
||||
|
||||
final String minNumberOfRepaymentsParamName = "minNumberOfRepayments";
|
||||
if (command.isChangeInIntegerParameterNamed(minNumberOfRepaymentsParamName, this.minNumberOfRepayments)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(minNumberOfRepaymentsParamName);
|
||||
actualChanges.put(minNumberOfRepaymentsParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.minNumberOfRepayments = newValue;
|
||||
}
|
||||
|
||||
final String maxNumberOfRepaymentsParamName = "maxNumberOfRepayments";
|
||||
if (command.isChangeInIntegerParameterNamed(maxNumberOfRepaymentsParamName, this.maxNumberOfRepayments)) {
|
||||
final Integer newValue = command.integerValueOfParameterNamed(maxNumberOfRepaymentsParamName);
|
||||
actualChanges.put(maxNumberOfRepaymentsParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.maxNumberOfRepayments = newValue;
|
||||
}
|
||||
|
||||
final String numberOfRepaymentsParamName = "numberOfRepayments";
|
||||
if (command.isChangeInIntegerParameterNamed(numberOfRepaymentsParamName, this.numberOfRepayments)) {
|
||||
@@ -343,22 +255,6 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.inArrearsTolerance = newValue;
|
||||
}
|
||||
|
||||
final String minInterestRatePerPeriodParamName = "minInterestRatePerPeriod";
|
||||
if (command.isChangeInBigDecimalParameterNamedWithNullCheck(minInterestRatePerPeriodParamName, this.minNominalInterestRatePerPeriod)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(minInterestRatePerPeriodParamName);
|
||||
actualChanges.put(minInterestRatePerPeriodParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.minNominalInterestRatePerPeriod = newValue;
|
||||
}
|
||||
|
||||
final String maxInterestRatePerPeriodParamName = "maxInterestRatePerPeriod";
|
||||
if (command.isChangeInBigDecimalParameterNamedWithNullCheck(maxInterestRatePerPeriodParamName, this.maxNominalInterestRatePerPeriod)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(maxInterestRatePerPeriodParamName);
|
||||
actualChanges.put(maxInterestRatePerPeriodParamName, newValue);
|
||||
actualChanges.put("locale", localeAsInput);
|
||||
this.maxNominalInterestRatePerPeriod = newValue;
|
||||
}
|
||||
|
||||
final String interestRatePerPeriodParamName = "interestRatePerPeriod";
|
||||
if (command.isChangeInBigDecimalParameterNamed(interestRatePerPeriodParamName, this.nominalInterestRatePerPeriod)) {
|
||||
|
||||
+20
-22
@@ -23,7 +23,7 @@ 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.AccountingRuleType;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRelatedDetail;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -261,7 +261,7 @@ public final class LoanProductCommandFromApiJsonDeserializer {
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
public void validateForUpdate(final String json) {
|
||||
public void validateForUpdate(final String json, final LoanProduct loanProduct) {
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
@@ -445,23 +445,21 @@ public final class LoanProductCommandFromApiJsonDeserializer {
|
||||
baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.PENALTIES_RECEIVABLE.getValue())
|
||||
.value(receivablePenaltyAccountId).ignoreIfNull().integerGreaterThanZero();
|
||||
|
||||
validateMinMaxConstraints(element, baseDataValidator, loanProduct);
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
public void validateMinMaxConstraints(final JsonElement element, final LoanProductRelatedDetail loanProductRelatedDetail, final String resource){
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource(resource);
|
||||
public void validateMinMaxConstraints(final JsonElement element, final DataValidatorBuilder baseDataValidator, final LoanProduct loanProduct){
|
||||
|
||||
validatePrincipalMinMaxConstraint(element, loanProductRelatedDetail, baseDataValidator);
|
||||
validatePrincipalMinMaxConstraint(element, loanProduct, baseDataValidator);
|
||||
|
||||
validateNumberOfRepaymentsMinMaxConstraint(element, loanProductRelatedDetail, baseDataValidator);
|
||||
validateNumberOfRepaymentsMinMaxConstraint(element, loanProduct, baseDataValidator);
|
||||
|
||||
validateNominalInterestRatePerPeriodMinMaxConstraint(element, loanProductRelatedDetail, baseDataValidator);
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
validateNominalInterestRatePerPeriodMinMaxConstraint(element, loanProduct, baseDataValidator);
|
||||
}
|
||||
|
||||
private void validatePrincipalMinMaxConstraint(final JsonElement element, final LoanProductRelatedDetail loanProductRelatedDetail, final DataValidatorBuilder baseDataValidator) {
|
||||
private void validatePrincipalMinMaxConstraint(final JsonElement element, final LoanProduct loanProduct, final DataValidatorBuilder baseDataValidator) {
|
||||
|
||||
boolean principalUpdated = false;
|
||||
boolean minPrincipalUpdated = false;
|
||||
@@ -472,7 +470,7 @@ public final class LoanProductCommandFromApiJsonDeserializer {
|
||||
principalAmount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(principalParameterName, element);
|
||||
principalUpdated = true;
|
||||
}else{
|
||||
principalAmount = loanProductRelatedDetail.getPrincipal().getAmount();
|
||||
principalAmount = loanProduct.getPrincipalAmount().getAmount();
|
||||
}
|
||||
|
||||
String minPrincipalParameterName = "minPrincipal";
|
||||
@@ -481,7 +479,7 @@ public final class LoanProductCommandFromApiJsonDeserializer {
|
||||
minPrincipalAmount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(minPrincipalParameterName, element);
|
||||
minPrincipalUpdated = true;
|
||||
}else{
|
||||
minPrincipalAmount = loanProductRelatedDetail.getMinPrincipal().getAmount();
|
||||
minPrincipalAmount = loanProduct.getMinPrincipalAmount().getAmount();
|
||||
}
|
||||
|
||||
String maxPrincipalParameterName = "maxPrincipal";
|
||||
@@ -490,7 +488,7 @@ public final class LoanProductCommandFromApiJsonDeserializer {
|
||||
maxPrincipalAmount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(maxPrincipalParameterName, element);
|
||||
maxPrincipalUpdated = true;
|
||||
}else{
|
||||
maxPrincipalAmount = loanProductRelatedDetail.getMaxPrincipal().getAmount();
|
||||
maxPrincipalAmount = loanProduct.getMaxPrincipalAmount().getAmount();
|
||||
}
|
||||
|
||||
if(minPrincipalUpdated){
|
||||
@@ -515,7 +513,7 @@ public final class LoanProductCommandFromApiJsonDeserializer {
|
||||
}
|
||||
}
|
||||
|
||||
private void validateNumberOfRepaymentsMinMaxConstraint(final JsonElement element, final LoanProductRelatedDetail loanProductRelatedDetail, final DataValidatorBuilder baseDataValidator) {
|
||||
private void validateNumberOfRepaymentsMinMaxConstraint(final JsonElement element, final LoanProduct loanProduct, final DataValidatorBuilder baseDataValidator) {
|
||||
boolean numberOfRepaymentsUpdated = false;
|
||||
boolean minNumberOfRepaymentsUpdated = false;
|
||||
boolean maxNumberOfRepaymentsUpdated = false;
|
||||
@@ -526,7 +524,7 @@ public final class LoanProductCommandFromApiJsonDeserializer {
|
||||
numberOfRepayments = fromApiJsonHelper.extractIntegerWithLocaleNamed(numberOfRepaymentsParameterName, element);
|
||||
numberOfRepaymentsUpdated = true;
|
||||
}else{
|
||||
numberOfRepayments = loanProductRelatedDetail.getNumberOfRepayments();
|
||||
numberOfRepayments = loanProduct.getNumberOfRepayments();
|
||||
}
|
||||
|
||||
String minNumberOfRepaymentsParameterName = "minNumberOfRepayments";
|
||||
@@ -535,7 +533,7 @@ public final class LoanProductCommandFromApiJsonDeserializer {
|
||||
minNumberOfRepayments = fromApiJsonHelper.extractIntegerWithLocaleNamed(minNumberOfRepaymentsParameterName, element);
|
||||
minNumberOfRepaymentsUpdated = true;
|
||||
}else{
|
||||
minNumberOfRepayments = loanProductRelatedDetail.getMinNumberOfRepayments();
|
||||
minNumberOfRepayments = loanProduct.getMinNumberOfRepayments();
|
||||
}
|
||||
|
||||
String maxNumberOfRepaymentsParameterName = "maxNumberOfRepayments";
|
||||
@@ -544,7 +542,7 @@ public final class LoanProductCommandFromApiJsonDeserializer {
|
||||
maxNumberOfRepayments = fromApiJsonHelper.extractIntegerWithLocaleNamed(maxNumberOfRepaymentsParameterName, element);
|
||||
maxNumberOfRepaymentsUpdated = true;
|
||||
}else{
|
||||
maxNumberOfRepayments = loanProductRelatedDetail.getMaxNumberOfRepayments();
|
||||
maxNumberOfRepayments = loanProduct.getMaxNumberOfRepayments();
|
||||
}
|
||||
|
||||
if(minNumberOfRepaymentsUpdated){
|
||||
@@ -568,7 +566,7 @@ public final class LoanProductCommandFromApiJsonDeserializer {
|
||||
}
|
||||
}
|
||||
|
||||
private void validateNominalInterestRatePerPeriodMinMaxConstraint(final JsonElement element, final LoanProductRelatedDetail loanProductRelatedDetail, final DataValidatorBuilder baseDataValidator) {
|
||||
private void validateNominalInterestRatePerPeriodMinMaxConstraint(final JsonElement element, final LoanProduct loanProduct, final DataValidatorBuilder baseDataValidator) {
|
||||
|
||||
boolean iRPUpdated = false;
|
||||
boolean minIRPUpdated = false;
|
||||
@@ -580,7 +578,7 @@ public final class LoanProductCommandFromApiJsonDeserializer {
|
||||
interestRatePerPeriod = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(interestRatePerPeriodParameterName, element);
|
||||
iRPUpdated = true;
|
||||
}else{
|
||||
interestRatePerPeriod = loanProductRelatedDetail.getNominalInterestRatePerPeriod();
|
||||
interestRatePerPeriod = loanProduct.getNominalInterestRatePerPeriod();
|
||||
}
|
||||
|
||||
String minInterestRatePerPeriodParameterName = "minInterestRatePerPeriod";
|
||||
@@ -589,7 +587,7 @@ public final class LoanProductCommandFromApiJsonDeserializer {
|
||||
minInterestRatePerPeriod = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(minInterestRatePerPeriodParameterName, element);
|
||||
minIRPUpdated = true;
|
||||
}else{
|
||||
minInterestRatePerPeriod = loanProductRelatedDetail.getMinNominalInterestRatePerPeriod();
|
||||
minInterestRatePerPeriod = loanProduct.getMinNominalInterestRatePerPeriod();
|
||||
}
|
||||
|
||||
String maxInterestRatePerPeriodParameterName = "maxInterestRatePerPeriod";
|
||||
@@ -598,7 +596,7 @@ public final class LoanProductCommandFromApiJsonDeserializer {
|
||||
maxInterestRatePerPeriod = fromApiJsonHelper.extractBigDecimalWithLocaleNamed(maxInterestRatePerPeriodParameterName, element);
|
||||
maxIRPUpdated = true;
|
||||
}else{
|
||||
maxInterestRatePerPeriod = loanProductRelatedDetail.getMaxNominalInterestRatePerPeriod();
|
||||
maxInterestRatePerPeriod = loanProduct.getMaxNominalInterestRatePerPeriod();
|
||||
}
|
||||
|
||||
if(minIRPUpdated){
|
||||
|
||||
+2
-4
@@ -132,12 +132,10 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
||||
try {
|
||||
this.context.authenticatedUser();
|
||||
|
||||
this.fromApiJsonDeserializer.validateForUpdate(command.json());
|
||||
|
||||
final LoanProduct product = this.loanProductRepository.findOne(loanProductId);
|
||||
if (product == null) { throw new LoanProductNotFoundException(loanProductId); }
|
||||
|
||||
this.fromApiJsonDeserializer.validateMinMaxConstraints(command.parsedJson(), product.loanProductRelatedDetail(), "loanproduct");
|
||||
|
||||
this.fromApiJsonDeserializer.validateForUpdate(command.json(), product);
|
||||
|
||||
final Map<String, Object> changes = product.update(command, this.aprCalculator);
|
||||
|
||||
|
||||
+20
-54
@@ -21,13 +21,9 @@ 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"));
|
||||
BigDecimal defaultMinNominalInterestRatePerPeriod = BigDecimal.valueOf(Double.valueOf("1"));
|
||||
BigDecimal defaultMaxNominalInterestRatePerPeriod = BigDecimal.valueOf(Double.valueOf("10"));
|
||||
PeriodFrequencyType interestPeriodFrequencyType = PeriodFrequencyType.MONTHS;
|
||||
BigDecimal defaultAnnualNominalInterestRate = BigDecimal.valueOf(Double.valueOf("24"));
|
||||
|
||||
@@ -37,29 +33,21 @@ public class LoanProductRelatedDetailTestHelper {
|
||||
PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType.MONTHS;
|
||||
|
||||
Integer defaultNumberOfRepayments = Integer.valueOf(4);
|
||||
Integer defaultMinNumberOfRepayments = Integer.valueOf(2);
|
||||
Integer defaultMaxNumberOfRepayments = Integer.valueOf(6);
|
||||
AmortizationMethod amortizationMethod = AmortizationMethod.EQUAL_PRINCIPAL;
|
||||
|
||||
BigDecimal inArrearsTolerance = BigDecimal.ZERO;
|
||||
|
||||
return createLoanProductRelatedDetail(currency, defaultPrincipal, defaultMinPrincipal, defaultMaxPrincipal,
|
||||
defaultNominalInterestRatePerPeriod, defaultMinNominalInterestRatePerPeriod, defaultMaxNominalInterestRatePerPeriod,
|
||||
interestPeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery,
|
||||
repaymentFrequencyType, defaultNumberOfRepayments, defaultMinNumberOfRepayments, defaultMaxNumberOfRepayments,
|
||||
amortizationMethod, inArrearsTolerance);
|
||||
return createLoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType,
|
||||
defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType,
|
||||
defaultNumberOfRepayments, amortizationMethod, inArrearsTolerance);
|
||||
}
|
||||
|
||||
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"));
|
||||
BigDecimal defaultMinNominalInterestRatePerPeriod = BigDecimal.valueOf(Double.valueOf("2"));
|
||||
BigDecimal defaultMaxNominalInterestRatePerPeriod = BigDecimal.valueOf(Double.valueOf("2"));
|
||||
PeriodFrequencyType interestPeriodFrequencyType = PeriodFrequencyType.MONTHS;
|
||||
BigDecimal defaultAnnualNominalInterestRate = BigDecimal.valueOf(Double.valueOf("24"));
|
||||
|
||||
@@ -69,30 +57,22 @@ public class LoanProductRelatedDetailTestHelper {
|
||||
PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType.MONTHS;
|
||||
|
||||
Integer defaultNumberOfRepayments = Integer.valueOf(4);
|
||||
Integer defaultMinNumberOfRepayments = Integer.valueOf(4);
|
||||
Integer defaultMaxNumberOfRepayments = Integer.valueOf(4);
|
||||
AmortizationMethod amortizationMethod = AmortizationMethod.EQUAL_INSTALLMENTS;
|
||||
|
||||
BigDecimal inArrearsTolerance = BigDecimal.ZERO;
|
||||
|
||||
return createLoanProductRelatedDetail(currency, defaultPrincipal, defaultMinPrincipal, defaultMaxPrincipal,
|
||||
defaultNominalInterestRatePerPeriod, defaultMinNominalInterestRatePerPeriod, defaultMaxNominalInterestRatePerPeriod,
|
||||
interestPeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery,
|
||||
repaymentFrequencyType, defaultNumberOfRepayments, defaultMinNumberOfRepayments, defaultMaxNumberOfRepayments,
|
||||
amortizationMethod, inArrearsTolerance);
|
||||
return createLoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType,
|
||||
defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType,
|
||||
defaultNumberOfRepayments, amortizationMethod, inArrearsTolerance);
|
||||
}
|
||||
|
||||
public static LoanProductRelatedDetail createSettingsForFlatQuarterly(final AmortizationMethod amortizationMethod) {
|
||||
|
||||
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"));
|
||||
BigDecimal defaultMinNominalInterestRatePerPeriod = BigDecimal.valueOf(Double.valueOf("2"));
|
||||
BigDecimal defaultMaxNominalInterestRatePerPeriod = BigDecimal.valueOf(Double.valueOf("2"));
|
||||
PeriodFrequencyType interestPeriodFrequencyType = PeriodFrequencyType.MONTHS;
|
||||
BigDecimal defaultAnnualNominalInterestRate = BigDecimal.valueOf(Double.valueOf("24"));
|
||||
|
||||
@@ -102,29 +82,21 @@ public class LoanProductRelatedDetailTestHelper {
|
||||
PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType.MONTHS;
|
||||
|
||||
Integer defaultNumberOfRepayments = Integer.valueOf(4);
|
||||
Integer defaultMinNumberOfRepayments = Integer.valueOf(4);
|
||||
Integer defaultMaxNumberOfRepayments = Integer.valueOf(4);
|
||||
|
||||
BigDecimal inArrearsTolerance = BigDecimal.ZERO;
|
||||
|
||||
return createLoanProductRelatedDetail(currency, defaultPrincipal, defaultMinPrincipal, defaultMaxPrincipal,
|
||||
defaultNominalInterestRatePerPeriod, defaultMinNominalInterestRatePerPeriod, defaultMaxNominalInterestRatePerPeriod,
|
||||
interestPeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery,
|
||||
repaymentFrequencyType, defaultNumberOfRepayments, defaultMinNumberOfRepayments, defaultMaxNumberOfRepayments,
|
||||
amortizationMethod, inArrearsTolerance);
|
||||
return createLoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType,
|
||||
defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType,
|
||||
defaultNumberOfRepayments, amortizationMethod, inArrearsTolerance);
|
||||
}
|
||||
|
||||
public static LoanProductRelatedDetail createSettingsForIrregularFlatEveryFourMonths() {
|
||||
|
||||
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"));
|
||||
BigDecimal defaultMinNominalInterestRatePerPeriod = BigDecimal.valueOf(Double.valueOf("2"));
|
||||
BigDecimal defaultMaxNominalInterestRatePerPeriod = BigDecimal.valueOf(Double.valueOf("4"));
|
||||
PeriodFrequencyType interestPeriodFrequencyType = PeriodFrequencyType.MONTHS;
|
||||
BigDecimal defaultAnnualNominalInterestRate = BigDecimal.valueOf(Double.valueOf("24"));
|
||||
|
||||
@@ -134,31 +106,25 @@ public class LoanProductRelatedDetailTestHelper {
|
||||
PeriodFrequencyType repaymentFrequencyType = PeriodFrequencyType.MONTHS;
|
||||
|
||||
Integer defaultNumberOfRepayments = Integer.valueOf(2);
|
||||
Integer defaultMinNumberOfRepayments = Integer.valueOf(2);
|
||||
Integer defaultMaxNumberOfRepayments = Integer.valueOf(2);
|
||||
|
||||
BigDecimal inArrearsTolerance = BigDecimal.ZERO;
|
||||
|
||||
AmortizationMethod amortizationMethod = AmortizationMethod.EQUAL_PRINCIPAL;
|
||||
|
||||
return createLoanProductRelatedDetail(currency, defaultPrincipal, defaultMinPrincipal, defaultMaxPrincipal,
|
||||
defaultNominalInterestRatePerPeriod, defaultMinNominalInterestRatePerPeriod, defaultMaxNominalInterestRatePerPeriod, interestPeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod,
|
||||
interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType, defaultNumberOfRepayments, defaultMinNumberOfRepayments, defaultMaxNumberOfRepayments, amortizationMethod,
|
||||
inArrearsTolerance);
|
||||
return createLoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType,
|
||||
defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType,
|
||||
defaultNumberOfRepayments, amortizationMethod, inArrearsTolerance);
|
||||
}
|
||||
|
||||
private static LoanProductRelatedDetail createLoanProductRelatedDetail(MonetaryCurrency currency, BigDecimal defaultPrincipal,
|
||||
BigDecimal defaultMinPrincipal, BigDecimal defaultMaxPrincipal, BigDecimal defaultNominalInterestRatePerPeriod,
|
||||
BigDecimal defaultMinNominalInterestRatePerPeriod, BigDecimal defaultMaxNominalInterestRatePerPeriod,
|
||||
PeriodFrequencyType interestPeriodFrequencyType, BigDecimal defaultAnnualNominalInterestRate, InterestMethod interestMethod,
|
||||
BigDecimal defaultNominalInterestRatePerPeriod, PeriodFrequencyType interestPeriodFrequencyType,
|
||||
BigDecimal defaultAnnualNominalInterestRate, InterestMethod interestMethod,
|
||||
InterestCalculationPeriodMethod interestCalculationPeriodMethod, Integer repayEvery,
|
||||
PeriodFrequencyType repaymentFrequencyType, Integer defaultNumberOfRepayments, Integer defaultMinNumberOfRepayments,
|
||||
Integer defaultMaxNumberOfRepayments, AmortizationMethod amortizationMethod, BigDecimal inArrearsTolerance) {
|
||||
PeriodFrequencyType repaymentFrequencyType, Integer defaultNumberOfRepayments, AmortizationMethod amortizationMethod,
|
||||
BigDecimal inArrearsTolerance) {
|
||||
|
||||
return new LoanProductRelatedDetail(currency, defaultPrincipal, defaultMinPrincipal, defaultMaxPrincipal,
|
||||
defaultNominalInterestRatePerPeriod, defaultMinNominalInterestRatePerPeriod, defaultMaxNominalInterestRatePerPeriod,
|
||||
interestPeriodFrequencyType, defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery,
|
||||
repaymentFrequencyType, defaultNumberOfRepayments, defaultMinNumberOfRepayments, defaultMaxNumberOfRepayments,
|
||||
amortizationMethod, inArrearsTolerance);
|
||||
return new LoanProductRelatedDetail(currency, defaultPrincipal, defaultNominalInterestRatePerPeriod, interestPeriodFrequencyType,
|
||||
defaultAnnualNominalInterestRate, interestMethod, interestCalculationPeriodMethod, repayEvery, repaymentFrequencyType,
|
||||
defaultNumberOfRepayments, amortizationMethod, inArrearsTolerance);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user