blob: 3b4c767682307669141514c27fd486b8f19c3609 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.integrationtests.common.loans;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.fineract.integrationtests.common.Utils;
import org.apache.fineract.integrationtests.common.accounting.Account;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
public class LoanProductTestBuilder {
private static final String LOCALE = "en_GB";
private static final String USD = "USD";
private static final String DAYS = "0";
private static final String WEEK = "1";
private static final String MONTHS = "2";
private static final String YEARS = "3";
private static final String CALCULATION_PERIOD_SAME_AS_REPAYMENT_PERIOD = "1";
private static final String EQUAL_PRINCIPAL_PAYMENTS = "0";
private static final String EQUAL_INSTALLMENTS = "1";
private static final String DECLINING_BALANCE = "0";
private static final String FLAT_BALANCE = "1";
public static final String DEFAULT_STRATEGY = "1";
// private static final String HEAVENS_FAMILY_STRATEGY ="2";
// private static final String CREO_CORE_STRATEGY ="3";
public static final String RBI_INDIA_STRATEGY = "4";
public static final String RECALCULATION_FREQUENCY_TYPE_SAME_AS_REPAYMENT_PERIOD = "1";
public static final String RECALCULATION_FREQUENCY_TYPE_DAILY = "2";
public static final String RECALCULATION_FREQUENCY_TYPE_WEEKLY = "3";
public static final String RECALCULATION_FREQUENCY_TYPE_MONTHLY = "4";
public static final String RECALCULATION_STRATEGY_RESCHEDULE_NEXT_REPAYMENTS = "1";
public static final String RECALCULATION_STRATEGY_REDUCE_NUMBER_OF_INSTALLMENTS = "2";
public static final String RECALCULATION_STRATEGY_REDUCE_EMI_AMOUN = "3";
public static final String RECALCULATION_COMPOUNDING_METHOD_NONE = "0";
public static final String RECALCULATION_COMPOUNDING_METHOD_INTEREST = "1";
public static final String RECALCULATION_COMPOUNDING_METHOD_FEE = "2";
public static final String RECALCULATION_COMPOUNDING_METHOD_INTEREST_AND_FEE = "3";
private static final String NONE = "1";
private static final String CASH_BASED = "2";
private static final String ACCRUAL_PERIODIC = "3";
private static final String ACCRUAL_UPFRONT = "4";
public static final String INTEREST_APPLICABLE_STRATEGY_REST_DATE = "2";
public static final String INTEREST_APPLICABLE_STRATEGY_ON_PRE_CLOSE_DATE = "1";
private String digitsAfterDecimal = "2";
private String inMultiplesOf = "0";
private String nameOfLoanProduct = Utils.randomNameGenerator("LOAN_PRODUCT_", 6);
private final String shortName = Utils.randomNameGenerator("", 4);
private String principal = "10000.00";
private String numberOfRepayments = "5";
private String repaymentFrequency = MONTHS;
private String repaymentPeriod = "1";
private String interestRatePerPeriod = "2";
private String interestRateFrequencyType = MONTHS;
private String interestType = FLAT_BALANCE;
private String overdueDaysForNPA = "5";
private String interestCalculationPeriodType = CALCULATION_PERIOD_SAME_AS_REPAYMENT_PERIOD;
private String inArrearsTolerance = "0";
private String transactionProcessingStrategy = DEFAULT_STRATEGY;
private String accountingRule = NONE;
private final String currencyCode = USD;
private String amortizationType = EQUAL_INSTALLMENTS;
private String minPrincipal = "1000.00";
private String maxPrincipal = "10000000.00";
private Account[] accountList = null;
private Boolean multiDisburseLoan = false;
private final String outstandingLoanBalance = "35000";
private final String maxTrancheCount = "3";
private Boolean isInterestRecalculationEnabled = false;
private String daysInYearType = "1";
private String daysInMonthType = "1";
private String interestRecalculationCompoundingMethod = "0";
private String preCloseInterestCalculationStrategy = INTEREST_APPLICABLE_STRATEGY_ON_PRE_CLOSE_DATE;
private String rescheduleStrategyMethod = "1";
private String recalculationRestFrequencyType = "1";
private String recalculationRestFrequencyInterval = "0";
private String recalculationRestFrequencyDate = null;
private String recalculationCompoundingFrequencyType = null;
private String recalculationCompoundingFrequencyInterval = null;
private String recalculationCompoundingFrequencyDate = null;
private String minimumDaysBetweenDisbursalAndFirstRepayment = null;
private Boolean holdGuaranteeFunds = null;
private String mandatoryGuarantee = null;
private String minimumGuaranteeFromOwnFunds = null;
private String minimumGuaranteeFromGuarantor = null;
private String isArrearsBasedOnOriginalSchedule = null;
private String graceOnPrincipalPayment = "1";
private String graceOnInterestPayment = "1";
private JsonObject allowAttributeOverrides = null;
private Boolean allowPartialPeriodInterestCalcualtion = false;
private Boolean allowVariableInstallments = Boolean.FALSE;
private Integer minimumGap;
private Integer maximumGap;
public String build(final String chargeId) {
final HashMap<String, Object> map = new HashMap<>();
if (chargeId != null) {
List<HashMap<String, String>> charges = new ArrayList<>();
HashMap<String, String> chargeMap = new HashMap<>();
chargeMap.put("id", chargeId);
charges.add(chargeMap);
map.put("charges", charges);
}
map.put("name", this.nameOfLoanProduct);
map.put("shortName", this.shortName);
map.put("currencyCode", this.currencyCode);
map.put("locale", LOCALE);
map.put("dateFormat", "dd MMMM yyyy");
map.put("digitsAfterDecimal", digitsAfterDecimal);
map.put("inMultiplesOf", inMultiplesOf);
map.put("principal", this.principal);
map.put("numberOfRepayments", this.numberOfRepayments);
map.put("repaymentEvery", this.repaymentPeriod);
map.put("repaymentFrequencyType", this.repaymentFrequency);
map.put("interestRatePerPeriod", this.interestRatePerPeriod);
map.put("interestRateFrequencyType", this.interestRateFrequencyType);
map.put("amortizationType", this.amortizationType);
map.put("interestType", this.interestType);
map.put("interestCalculationPeriodType", this.interestCalculationPeriodType);
map.put("inArrearsTolerance", this.inArrearsTolerance);
map.put("transactionProcessingStrategyId", this.transactionProcessingStrategy);
map.put("accountingRule", this.accountingRule);
map.put("minPrincipal", this.minPrincipal);
map.put("maxPrincipal", this.maxPrincipal);
map.put("overdueDaysForNPA", this.overdueDaysForNPA);
if (this.minimumDaysBetweenDisbursalAndFirstRepayment != null) {
map.put("minimumDaysBetweenDisbursalAndFirstRepayment", this.minimumDaysBetweenDisbursalAndFirstRepayment);
}
if (multiDisburseLoan) {
map.put("multiDisburseLoan", this.multiDisburseLoan);
map.put("maxTrancheCount", this.maxTrancheCount);
map.put("outstandingLoanBalance", this.outstandingLoanBalance);
}
if (this.accountingRule.equals(ACCRUAL_UPFRONT) || this.accountingRule.equals(ACCRUAL_PERIODIC)) {
map.putAll(getAccountMappingForAccrualBased());
} else if (this.accountingRule.equals(CASH_BASED)) {
map.putAll(getAccountMappingForCashBased());
}
map.put("daysInMonthType", this.daysInMonthType);
map.put("daysInYearType", this.daysInYearType);
map.put("isInterestRecalculationEnabled", this.isInterestRecalculationEnabled);
if (this.isInterestRecalculationEnabled) {
map.put("interestRecalculationCompoundingMethod", this.interestRecalculationCompoundingMethod);
map.put("rescheduleStrategyMethod", this.rescheduleStrategyMethod);
map.put("recalculationRestFrequencyType", recalculationRestFrequencyType);
map.put("recalculationRestFrequencyInterval", recalculationRestFrequencyInterval);
map.put("recalculationRestFrequencyDate", recalculationRestFrequencyDate);
if (!RECALCULATION_COMPOUNDING_METHOD_NONE.equals(this.interestRecalculationCompoundingMethod)) {
map.put("recalculationCompoundingFrequencyType", recalculationCompoundingFrequencyType);
map.put("recalculationCompoundingFrequencyInterval", recalculationCompoundingFrequencyInterval);
map.put("recalculationCompoundingFrequencyDate", recalculationCompoundingFrequencyDate);
}
map.put("preClosureInterestCalculationStrategy", preCloseInterestCalculationStrategy);
if (isArrearsBasedOnOriginalSchedule != null) {
map.put("isArrearsBasedOnOriginalSchedule", isArrearsBasedOnOriginalSchedule);
}
}
if (holdGuaranteeFunds != null) {
map.put("holdGuaranteeFunds", this.holdGuaranteeFunds);
if (this.holdGuaranteeFunds) {
map.put("mandatoryGuarantee", this.mandatoryGuarantee);
map.put("minimumGuaranteeFromGuarantor", this.minimumGuaranteeFromGuarantor);
map.put("minimumGuaranteeFromOwnFunds", this.minimumGuaranteeFromOwnFunds);
}
}
map.put("graceOnPrincipalPayment", graceOnPrincipalPayment);
map.put("graceOnInterestPayment", graceOnInterestPayment);
if (allowAttributeOverrides != null) {
map.put("allowAttributeOverrides", this.allowAttributeOverrides);
}
map.put("allowPartialPeriodInterestCalcualtion", this.allowPartialPeriodInterestCalcualtion);
map.put("allowVariableInstallments", allowVariableInstallments) ;
if(allowVariableInstallments) {
map.put("minimumGap", minimumGap) ;
map.put("maximumGap", maximumGap) ;
}
return new Gson().toJson(map);
}
public LoanProductTestBuilder withMinPrincipal(final String minPrincipal) {
this.minPrincipal = minPrincipal;
return this;
}
public LoanProductTestBuilder withMaxPrincipal(final String maxPrincipal) {
this.maxPrincipal = maxPrincipal;
return this;
}
public LoanProductTestBuilder withLoanName(final String loanName) {
this.nameOfLoanProduct = loanName;
return this;
}
public LoanProductTestBuilder withPrincipal(final String principal) {
this.principal = principal;
return this;
}
public LoanProductTestBuilder withNumberOfRepayments(final String numberOfRepayment) {
this.numberOfRepayments = numberOfRepayment;
return this;
}
public LoanProductTestBuilder withRepaymentTypeAsMonth() {
this.repaymentFrequency = MONTHS;
return this;
}
public LoanProductTestBuilder withRepaymentTypeAsWeek() {
this.repaymentFrequency = WEEK;
return this;
}
public LoanProductTestBuilder withRepaymentTypeAsDays() {
this.repaymentFrequency = DAYS;
return this;
}
public LoanProductTestBuilder withRepaymentAfterEvery(final String repaymentAfterEvery) {
this.repaymentPeriod = repaymentAfterEvery;
return this;
}
public LoanProductTestBuilder withInterestRateFrequencyTypeAsMonths() {
this.interestRateFrequencyType = MONTHS;
return this;
}
public LoanProductTestBuilder withInterestRateFrequencyTypeAsYear() {
this.interestRateFrequencyType = YEARS;
return this;
}
public LoanProductTestBuilder withinterestRatePerPeriod(final String interestRatePerPeriod) {
this.interestRatePerPeriod = interestRatePerPeriod;
return this;
}
public LoanProductTestBuilder withAmortizationTypeAsEqualPrincipalPayment() {
this.amortizationType = EQUAL_PRINCIPAL_PAYMENTS;
return this;
}
public LoanProductTestBuilder withAmortizationTypeAsEqualInstallments() {
this.amortizationType = EQUAL_INSTALLMENTS;
return this;
}
public LoanProductTestBuilder withInterestTypeAsFlat() {
this.interestType = FLAT_BALANCE;
return this;
}
public LoanProductTestBuilder withInterestTypeAsDecliningBalance() {
this.interestType = DECLINING_BALANCE;
return this;
}
public LoanProductTestBuilder withOverdueDaysForNPA(String days) {
this.overdueDaysForNPA = days;
return this;
}
public LoanProductTestBuilder withInterestCalculationPeriodTypeAsDays() {
this.interestCalculationPeriodType = DAYS;
return this;
}
public LoanProductTestBuilder withInterestCalculationPeriodTypeAsRepaymentPeriod(final Boolean allowPartialPeriodInterestCalcualtion) {
this.interestCalculationPeriodType = CALCULATION_PERIOD_SAME_AS_REPAYMENT_PERIOD;
this.allowPartialPeriodInterestCalcualtion = allowPartialPeriodInterestCalcualtion;
return this;
}
public LoanProductTestBuilder withInArrearsTolerance(final String amountCanBeWaved) {
this.inArrearsTolerance = amountCanBeWaved;
return this;
}
public LoanProductTestBuilder withAccountingRuleAsNone() {
this.accountingRule = NONE;
return this;
}
public LoanProductTestBuilder withAccountingRuleAsCashBased(final Account[] account_list) {
this.accountingRule = CASH_BASED;
this.accountList = account_list;
return this;
}
public LoanProductTestBuilder withAccountingRuleUpfrontAccrual(final Account[] account_list) {
this.accountingRule = ACCRUAL_UPFRONT;
this.accountList = account_list;
return this;
}
public LoanProductTestBuilder withAccountingRulePeriodicAccrual(final Account[] account_list) {
this.accountingRule = ACCRUAL_PERIODIC;
this.accountList = account_list;
return this;
}
public LoanProductTestBuilder withTranches(boolean multiDisburseLoan) {
this.multiDisburseLoan = multiDisburseLoan;
return this;
}
private Map<String, String> getAccountMappingForCashBased() {
final Map<String, String> map = new HashMap<>();
for (int i = 0; i < this.accountList.length; i++) {
if (this.accountList[i].getAccountType().equals(Account.AccountType.ASSET)) {
final String ID = this.accountList[i].getAccountID().toString();
map.put("fundSourceAccountId", ID);
map.put("loanPortfolioAccountId", ID);
map.put("transfersInSuspenseAccountId", ID);
}
if (this.accountList[i].getAccountType().equals(Account.AccountType.INCOME)) {
final String ID = this.accountList[i].getAccountID().toString();
map.put("interestOnLoanAccountId", ID);
map.put("incomeFromFeeAccountId", ID);
map.put("incomeFromPenaltyAccountId", ID);
map.put("incomeFromRecoveryAccountId", ID);
}
if (this.accountList[i].getAccountType().equals(Account.AccountType.EXPENSE)) {
final String ID = this.accountList[i].getAccountID().toString();
map.put("writeOffAccountId", ID);
}
if (this.accountList[i].getAccountType().equals(Account.AccountType.LIABILITY)) {
final String ID = this.accountList[i].getAccountID().toString();
map.put("overpaymentLiabilityAccountId", ID);
}
}
return map;
}
private Map<String, String> getAccountMappingForAccrualBased() {
final Map<String, String> map = new HashMap<>();
for (int i = 0; i < this.accountList.length; i++) {
if (this.accountList[i].getAccountType().equals(Account.AccountType.ASSET)) {
final String ID = this.accountList[i].getAccountID().toString();
map.put("fundSourceAccountId", ID);
map.put("loanPortfolioAccountId", ID);
map.put("transfersInSuspenseAccountId", ID);
map.put("receivableInterestAccountId", ID);
map.put("receivableFeeAccountId", ID);
map.put("receivablePenaltyAccountId", ID);
}
if (this.accountList[i].getAccountType().equals(Account.AccountType.INCOME)) {
final String ID = this.accountList[i].getAccountID().toString();
map.put("interestOnLoanAccountId", ID);
map.put("incomeFromFeeAccountId", ID);
map.put("incomeFromPenaltyAccountId", ID);
map.put("incomeFromRecoveryAccountId", ID);
}
if (this.accountList[i].getAccountType().equals(Account.AccountType.EXPENSE)) {
final String ID = this.accountList[i].getAccountID().toString();
map.put("writeOffAccountId", ID);
}
if (this.accountList[i].getAccountType().equals(Account.AccountType.LIABILITY)) {
final String ID = this.accountList[i].getAccountID().toString();
map.put("overpaymentLiabilityAccountId", ID);
}
}
return map;
}
public LoanProductTestBuilder withAccounting(final String accountingRule, final Account[] account_list) {
this.accountingRule = accountingRule;
this.accountList = account_list;
return this;
}
public LoanProductTestBuilder currencyDetails(final String digitsAfterDecimal, final String inMultiplesOf) {
this.digitsAfterDecimal = digitsAfterDecimal;
this.inMultiplesOf = inMultiplesOf;
return this;
}
public LoanProductTestBuilder withRepaymentStrategy(final String transactionProcessingStrategy) {
this.transactionProcessingStrategy = transactionProcessingStrategy;
return this;
}
public LoanProductTestBuilder withDaysInMonth(final String daysInMonthType) {
this.daysInMonthType = daysInMonthType;
return this;
}
public LoanProductTestBuilder withDaysInYear(final String daysInYearType) {
this.daysInYearType = daysInYearType;
return this;
}
public LoanProductTestBuilder withInterestRecalculationDetails(final String interestRecalculationCompoundingMethod,
final String rescheduleStrategyMethod, String preCloseInterestCalculationStrategy) {
this.isInterestRecalculationEnabled = true;
this.interestRecalculationCompoundingMethod = interestRecalculationCompoundingMethod;
this.rescheduleStrategyMethod = rescheduleStrategyMethod;
this.preCloseInterestCalculationStrategy = preCloseInterestCalculationStrategy;
return this;
}
public LoanProductTestBuilder withInterestRecalculationRestFrequencyDetails(final String recalculationRestFrequencyType,
final String recalculationRestFrequencyInterval, final String recalculationRestFrequencyDate) {
this.isInterestRecalculationEnabled = true;
this.recalculationRestFrequencyType = recalculationRestFrequencyType;
this.recalculationRestFrequencyInterval = recalculationRestFrequencyInterval;
this.recalculationRestFrequencyDate = recalculationRestFrequencyDate;
return this;
}
public LoanProductTestBuilder withInterestRecalculationCompoundingFrequencyDetails(final String recalculationCompoundingFrequencyType,
final String recalculationCompoundingFrequencyInterval, final String recalculationCompoundingFrequencyDate) {
this.isInterestRecalculationEnabled = true;
this.recalculationCompoundingFrequencyType = recalculationCompoundingFrequencyType;
this.recalculationCompoundingFrequencyInterval = recalculationCompoundingFrequencyInterval;
this.recalculationCompoundingFrequencyDate = recalculationCompoundingFrequencyDate;
return this;
}
public LoanProductTestBuilder withMinimumDaysBetweenDisbursalAndFirstRepayment(final String minimumDaysBetweenDisbursalAndFirstRepayment) {
this.minimumDaysBetweenDisbursalAndFirstRepayment = minimumDaysBetweenDisbursalAndFirstRepayment;
return this;
}
public LoanProductTestBuilder withArrearsConfiguration() {
this.isArrearsBasedOnOriginalSchedule = "true";
return this;
}
public LoanProductTestBuilder withOnHoldFundDetails(final String mandatoryGuarantee, final String minimumGuaranteeFromGuarantor,
final String minimumGuaranteeFromOwnFunds) {
this.holdGuaranteeFunds = true;
this.mandatoryGuarantee = mandatoryGuarantee;
this.minimumGuaranteeFromGuarantor = minimumGuaranteeFromGuarantor;
this.minimumGuaranteeFromOwnFunds = minimumGuaranteeFromOwnFunds;
return this;
}
public LoanProductTestBuilder withMoratorium(String principal, String interest) {
this.graceOnPrincipalPayment = principal;
this.graceOnInterestPayment = interest;
return this;
}
public LoanProductTestBuilder withLoanProductConfiguration(JsonObject loanProductConfigurableAttributes) {
this.allowAttributeOverrides = loanProductConfigurableAttributes;
return this;
}
public LoanProductTestBuilder withVariableInstallmentsConfig(Boolean allowVariableInstallments, Integer minimumGap, Integer maximumGap) {
this.allowVariableInstallments = allowVariableInstallments ;
this.minimumGap = minimumGap;
this.maximumGap = maximumGap;
return this ;
}
}