FINERACT-2081: Adding additional E2E tests to improve test coverage - pt1: stepdef files
This commit is contained in:
+2
-1
@@ -36,7 +36,8 @@ public class CacheConfiguration {
|
||||
simpleCacheManager.setCaches(List.of(new ConcurrentMapCache("paymentTypesByName"), //
|
||||
new ConcurrentMapCache("jobsByShortName"), //
|
||||
new ConcurrentMapCache("loanProductsByName"), //
|
||||
new ConcurrentMapCache("accountTypesByName")));//
|
||||
new ConcurrentMapCache("accountTypesByName"), //
|
||||
new ConcurrentMapCache("codeValuesByName")));//
|
||||
return simpleCacheManager;
|
||||
}
|
||||
}
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* 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.test.data;
|
||||
|
||||
public enum ChargeOffBehaviour {
|
||||
|
||||
ZERO_INTEREST("ZERO_INTEREST"), REGULAR("REGULAR");
|
||||
|
||||
public final String value;
|
||||
|
||||
ChargeOffBehaviour(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* 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.test.data.codevalue;
|
||||
|
||||
public interface CodeValue {
|
||||
|
||||
String getName();
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* 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.test.data.codevalue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fineract.client.models.GetCodeValuesDataResponse;
|
||||
import org.apache.fineract.client.services.CodeValuesApi;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Component;
|
||||
import retrofit2.Response;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class CodeValueResolver {
|
||||
|
||||
private final CodeValuesApi codeValuesApi;
|
||||
|
||||
@Cacheable(key = "#codeValue.getName()", value = "codeValuesByName")
|
||||
public long resolve(Long codeId, CodeValue codeValue) {
|
||||
try {
|
||||
String codeValueName = codeValue.getName();
|
||||
|
||||
log.debug("Resolving code value by code id and name [{}]", codeValue);
|
||||
Response<List<GetCodeValuesDataResponse>> response = codeValuesApi.retrieveAllCodeValues(codeId).execute();
|
||||
if (!response.isSuccessful()) {
|
||||
throw new IllegalStateException("Unable to get payment types. Status code was HTTP " + response.code());
|
||||
}
|
||||
|
||||
List<GetCodeValuesDataResponse> codeValuesResponses = response.body();
|
||||
GetCodeValuesDataResponse foundPtr = codeValuesResponses.stream().filter(ptr -> codeValueName.equals(ptr.getName())).findAny()
|
||||
.orElseThrow(() -> new IllegalArgumentException("Payment type [%s] not found".formatted(codeValueName)));
|
||||
|
||||
return foundPtr.getId();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* 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.test.data.codevalue;
|
||||
|
||||
public enum DefaultCodeValue implements CodeValue {
|
||||
|
||||
// Charge-off reason
|
||||
FRAUD("Fraud"), DELINQUENT("Delinquent"), OTHER("Other");
|
||||
|
||||
private final String customName;
|
||||
|
||||
DefaultCodeValue(String customName) {
|
||||
this.customName = customName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
if (customName != null) {
|
||||
return customName;
|
||||
}
|
||||
return name();
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -25,7 +25,9 @@ public enum DefaultJob implements Job {
|
||||
INCREASE_BUSINESS_DAY("Increase Business Date by 1 day", "BDT_INC1"), //
|
||||
LOAN_DELINQUENCY_CLASSIFICATION("Loan Delinquency Classification", "LA_DECL"), //
|
||||
LOAN_COB("Loan COB", "LA_ECOB"), //
|
||||
ACCRUAL_ACTIVITY_POSTING("Accrual Activity Posting", "ACC_ACPO");
|
||||
ACCRUAL_ACTIVITY_POSTING("Accrual Activity Posting", "ACC_ACPO"), ADD_ACCRUAL_TRANSACTIONS_FOR_LOANS_WITH_INCOME_POSTED_AS_TRANSACTIONS(
|
||||
"Add Accrual Transactions For Loans With Income Posted As Transactions",
|
||||
"LA_AATR"), RECALCULATE_INTEREST_FOR_LOANS("Recalculate Interest For Loans", "LA_RINT");
|
||||
|
||||
private final String customName;
|
||||
private final String shortName;
|
||||
|
||||
+13
@@ -53,10 +53,13 @@ public enum DefaultLoanProduct implements LoanProduct {
|
||||
LP2_DOWNPAYMENT_AUTO_ADVANCED_PAYMENT_ALLOCATION_REPAYMENT_START_SUBMITTED, //
|
||||
LP2_DOWNPAYMENT_INTEREST_FLAT_ADV_PMT_ALLOC, //
|
||||
LP2_ADV_PYMNT_INTEREST_RECALCULATION_DAILY_EMI_360_30_MULTIDISBURSE_DOWNPAYMENT, //
|
||||
LP2_ADV_PYMNT_INTEREST_RECALCULATION_DAILY_EMI_360_30_MULTIDISBURSE_AUTO_DOWNPAYMENT, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_ACTUAL_ACTUAL, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_ACCRUAL_ACTIVITY, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_AUTO_DOWNPAYMENT_EMI_ACTUAL_ACTUAL_ACCRUAL_ACTIVITY, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY_TILL_PRECLOSE, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALC_DAILY_NO_CALC_ON_PAST_DUE_TILL_PRECLOSE, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY_TILL_PRECLOSE_PMT_ALLOC_1, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_SARP_TILL_PRECLOSE, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY_TILL_REST_FREQUENCY_DATE, //
|
||||
@@ -64,9 +67,11 @@ public enum DefaultLoanProduct implements LoanProduct {
|
||||
LP2_ADV_CUSTOM_PAYMENT_ALLOC_INTEREST_RECALCULATION_DAILY_EMI_360_30_MULTIDISBURSE, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_REFUND_FULL, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_MULTIDISBURSE, //
|
||||
LP2_ADV_PAYMENT_ALLOC_INTEREST_RECALCULATION_DAILY_NO_CALC_ON_PAST_DUE_EMI_360_30_MULTIDISBURSE, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_MULTIDISBURSE_DOWNPAYMENT, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_DOWNPAYMENT, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_365_ACTUAL, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_ACTUAL, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_REFUND, //
|
||||
LP1_ADV_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL, //
|
||||
LP2_ADV_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL, //
|
||||
@@ -74,8 +79,16 @@ public enum DefaultLoanProduct implements LoanProduct {
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_IR_DAILY_TILL_PRECLOSE_LAST_INSTALLMENT_STRATEGY, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_REFUND_INTEREST_RECALCULATION, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ZERO_INTEREST_CHARGE_OFF, //
|
||||
LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR, //
|
||||
LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ACCELERATE_MATURITY_CHARGE_OFF_BEHAVIOUR, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY_ALLOW_PARTIAL_PERIOD, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY_ACCRUAL_ACTIVITY_POSTING, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_CHARGEBACK_INTEREST_FEE_PRINCIPAL, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_CHARGEBACK_PRINCIPAL_INTEREST_FEE, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_CHARGEBACK_INTEREST_PENALTY_FEE_PRINCIPAL, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_RECALCULATION_DAILY, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_ACCRUAL_ACTIVITY, //
|
||||
LP2_ADV_PYMNT_ACCELERATE_MATURITY_CHARGE_OFF_BEHAVIOUR, //
|
||||
LP2_NO_INTEREST_RECALCULATION_CHARGEBACK_ALLOCATION_INTEREST_FIRST, //
|
||||
|
||||
+141
@@ -29,10 +29,12 @@ import org.apache.fineract.client.models.ChargeData;
|
||||
import org.apache.fineract.client.models.ChargeToGLAccountMapper;
|
||||
import org.apache.fineract.client.models.GetLoanFeeToIncomeAccountMappings;
|
||||
import org.apache.fineract.client.models.GetLoanPaymentChannelToFundSourceMappings;
|
||||
import org.apache.fineract.client.models.PostChargeOffReasonToExpenseAccountMappings;
|
||||
import org.apache.fineract.client.models.PostLoanProductsRequest;
|
||||
import org.apache.fineract.test.data.AccountingRule;
|
||||
import org.apache.fineract.test.data.AdvancePaymentsAdjustmentType;
|
||||
import org.apache.fineract.test.data.AmortizationType;
|
||||
import org.apache.fineract.test.data.ChargeOffBehaviour;
|
||||
import org.apache.fineract.test.data.DaysInMonthType;
|
||||
import org.apache.fineract.test.data.DaysInYearType;
|
||||
import org.apache.fineract.test.data.DelinquencyBucket;
|
||||
@@ -48,9 +50,13 @@ import org.apache.fineract.test.data.RepaymentFrequencyType;
|
||||
import org.apache.fineract.test.data.TransactionProcessingStrategyCode;
|
||||
import org.apache.fineract.test.data.accounttype.AccountTypeResolver;
|
||||
import org.apache.fineract.test.data.accounttype.DefaultAccountType;
|
||||
import org.apache.fineract.test.data.codevalue.CodeValueResolver;
|
||||
import org.apache.fineract.test.data.codevalue.DefaultCodeValue;
|
||||
import org.apache.fineract.test.data.paymenttype.DefaultPaymentType;
|
||||
import org.apache.fineract.test.data.paymenttype.PaymentTypeResolver;
|
||||
import org.apache.fineract.test.helper.CodeHelper;
|
||||
import org.apache.fineract.test.helper.Utils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@@ -59,6 +65,10 @@ public class LoanProductsRequestFactory {
|
||||
|
||||
private final PaymentTypeResolver paymentTypeResolver;
|
||||
private final AccountTypeResolver accountTypeResolver;
|
||||
private final CodeValueResolver codeValueResolver;
|
||||
|
||||
@Autowired
|
||||
private CodeHelper codeHelper;
|
||||
|
||||
public static final String NAME_PREFIX = "LP1-";
|
||||
public static final String NAME_PREFIX_LP2 = "LP2-";
|
||||
@@ -112,6 +122,7 @@ public class LoanProductsRequestFactory {
|
||||
public static final Integer FREQUENCY_FOR_COMPOUNDING_MONTHLY = RecalculationCompoundingFrequencyType.MONTHLY.value;
|
||||
public static final Integer FREQUENCY_FOR_RECALCULATE_OUTSTANDING_PRINCIPAL_SAME_AS_REPAYMENT = RecalculationRestFrequencyType.SAME_AS_REPAYMENT.value;
|
||||
public static final Integer FREQUENCY_FOR_RECALCULATE_OUTSTANDING_DAILY = RecalculationRestFrequencyType.DAILY.value;
|
||||
public static final String CHARGE_OFF_REASONS = "ChargeOffReasons";
|
||||
|
||||
public PostLoanProductsRequest defaultLoanProductsRequestLP1() {
|
||||
String name = Utils.randomNameGenerator(NAME_PREFIX, 4);
|
||||
@@ -1110,4 +1121,134 @@ public class LoanProductsRequestFactory {
|
||||
.chargeOffFraudExpenseAccountId(accountTypeResolver.resolve(DefaultAccountType.CREDIT_LOSS_BAD_DEBT_FRAUD))//
|
||||
.incomeFromChargeOffPenaltyAccountId(accountTypeResolver.resolve(DefaultAccountType.FEE_CHARGE_OFF));//
|
||||
}
|
||||
|
||||
public PostLoanProductsRequest defaultLoanProductsRequestLP2EmiWithChargeOff() {
|
||||
String name = Utils.randomNameGenerator(NAME_PREFIX_LP2_EMI, 4);
|
||||
String shortName = Utils.randomNameGenerator(SHORT_NAME_PREFIX_EMI, 3);
|
||||
|
||||
List<Integer> principalVariationsForBorrowerCycle = new ArrayList<>();
|
||||
List<Integer> numberOfRepaymentVariationsForBorrowerCycle = new ArrayList<>();
|
||||
List<Integer> interestRateVariationsForBorrowerCycle = new ArrayList<>();
|
||||
List<ChargeData> charges = new ArrayList<>();
|
||||
List<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings = new ArrayList<>();
|
||||
List<GetLoanFeeToIncomeAccountMappings> feeToIncomeAccountMappings = new ArrayList<>();
|
||||
|
||||
List<GetLoanPaymentChannelToFundSourceMappings> paymentChannelToFundSourceMappings = new ArrayList<>();
|
||||
GetLoanPaymentChannelToFundSourceMappings loanPaymentChannelToFundSourceMappings = new GetLoanPaymentChannelToFundSourceMappings();
|
||||
loanPaymentChannelToFundSourceMappings.fundSourceAccountId(accountTypeResolver.resolve(DefaultAccountType.FUND_RECEIVABLES));
|
||||
loanPaymentChannelToFundSourceMappings.paymentTypeId(paymentTypeResolver.resolve(DefaultPaymentType.MONEY_TRANSFER));
|
||||
paymentChannelToFundSourceMappings.add(loanPaymentChannelToFundSourceMappings);
|
||||
|
||||
Long chargeOffReasonId = codeHelper.retrieveCodeByName(CHARGE_OFF_REASONS).getId();
|
||||
|
||||
List<PostChargeOffReasonToExpenseAccountMappings> chargeOffReasonToExpenseAccountMappings = new ArrayList<>();
|
||||
PostChargeOffReasonToExpenseAccountMappings chargeOffFraudReason = new PostChargeOffReasonToExpenseAccountMappings();
|
||||
PostChargeOffReasonToExpenseAccountMappings chargeOffDelinquentReason = new PostChargeOffReasonToExpenseAccountMappings();
|
||||
PostChargeOffReasonToExpenseAccountMappings chargeOffOtherReason = new PostChargeOffReasonToExpenseAccountMappings();
|
||||
chargeOffFraudReason.chargeOffReasonCodeValueId(codeValueResolver.resolve(chargeOffReasonId, DefaultCodeValue.FRAUD));
|
||||
chargeOffFraudReason.expenseAccountId(accountTypeResolver.resolve(DefaultAccountType.CREDIT_LOSS_BAD_DEBT_FRAUD));
|
||||
chargeOffDelinquentReason.chargeOffReasonCodeValueId(codeValueResolver.resolve(chargeOffReasonId, DefaultCodeValue.DELINQUENT));
|
||||
chargeOffDelinquentReason.expenseAccountId(accountTypeResolver.resolve(DefaultAccountType.CREDIT_LOSS_BAD_DEBT));
|
||||
chargeOffOtherReason.chargeOffReasonCodeValueId(codeValueResolver.resolve(chargeOffReasonId, DefaultCodeValue.OTHER));
|
||||
chargeOffOtherReason.expenseAccountId(accountTypeResolver.resolve(DefaultAccountType.CREDIT_LOSS_BAD_DEBT));
|
||||
chargeOffReasonToExpenseAccountMappings.add(chargeOffFraudReason);
|
||||
chargeOffReasonToExpenseAccountMappings.add(chargeOffDelinquentReason);
|
||||
chargeOffReasonToExpenseAccountMappings.add(chargeOffOtherReason);
|
||||
|
||||
return new PostLoanProductsRequest()//
|
||||
.name(name)//
|
||||
.shortName(shortName)//
|
||||
.description(DESCRIPTION_LP2_EMI)//
|
||||
.loanScheduleType("PROGRESSIVE") //
|
||||
.interestCalculationPeriodType(InterestCalculationPeriodTime.DAILY.value)//
|
||||
.transactionProcessingStrategyCode(ADVANCED_PAYMENT_ALLOCATION.getValue())//
|
||||
.fundId(FUND_ID)//
|
||||
.startDate(null)//
|
||||
.closeDate(null)//
|
||||
.includeInBorrowerCycle(false)//
|
||||
.currencyCode(CURRENCY_CODE)//
|
||||
.digitsAfterDecimal(2)//
|
||||
.inMultiplesOf(0)//
|
||||
.useBorrowerCycle(false)//
|
||||
.minPrincipal(10.0)//
|
||||
.principal(1000.0)//
|
||||
.maxPrincipal(10000.0)//
|
||||
.minNumberOfRepayments(1)//
|
||||
.numberOfRepayments(4)//
|
||||
.maxNumberOfRepayments(30)//
|
||||
.isLinkedToFloatingInterestRates(false)//
|
||||
.minInterestRatePerPeriod((double) 0)//
|
||||
.interestRatePerPeriod((double) 12)//
|
||||
.maxInterestRatePerPeriod((double) 60)//
|
||||
.interestRateFrequencyType(INTEREST_RATE_FREQUENCY_TYPE_YEAR)//
|
||||
.repaymentEvery(15)//
|
||||
.repaymentStartDateType(1)//
|
||||
.repaymentFrequencyType(REPAYMENT_FREQUENCY_TYPE_DAYS)//
|
||||
.principalVariationsForBorrowerCycle(principalVariationsForBorrowerCycle)//
|
||||
.numberOfRepaymentVariationsForBorrowerCycle(numberOfRepaymentVariationsForBorrowerCycle)//
|
||||
.interestRateVariationsForBorrowerCycle(interestRateVariationsForBorrowerCycle)//
|
||||
.amortizationType(AMORTIZATION_TYPE)//
|
||||
.interestType(INTEREST_TYPE_DECLINING_BALANCE)//
|
||||
.isEqualAmortization(false)//
|
||||
.interestCalculationPeriodType(INTEREST_CALCULATION_PERIOD_TYPE_DAILY)//
|
||||
.transactionProcessingStrategyCode(TRANSACTION_PROCESSING_STRATEGY_CODE_ADVANCED)//
|
||||
.daysInYearType(DAYS_IN_YEAR_TYPE)//
|
||||
.daysInMonthType(DAYS_IN_MONTH_TYPE)//
|
||||
.canDefineInstallmentAmount(true)//
|
||||
.graceOnArrearsAgeing(3)//
|
||||
.overdueDaysForNPA(179)//
|
||||
.accountMovesOutOfNPAOnlyOnArrearsCompletion(false)//
|
||||
.principalThresholdForLastInstallment(50)//
|
||||
.allowVariableInstallments(false)//
|
||||
.canUseForTopup(false)//
|
||||
|
||||
.chargeOffBehaviour(ChargeOffBehaviour.ZERO_INTEREST.value)
|
||||
.chargeOffReasonToExpenseAccountMappings(chargeOffReasonToExpenseAccountMappings)
|
||||
|
||||
.isInterestRecalculationEnabled(false)//
|
||||
.holdGuaranteeFunds(false)//
|
||||
.multiDisburseLoan(false)//
|
||||
.allowAttributeOverrides(new AllowAttributeOverrides()//
|
||||
.amortizationType(true)//
|
||||
.interestType(true)//
|
||||
.transactionProcessingStrategyCode(true)//
|
||||
.interestCalculationPeriodType(true)//
|
||||
.inArrearsTolerance(true)//
|
||||
.repaymentEvery(true)//
|
||||
.graceOnPrincipalAndInterestPayment(true)//
|
||||
.graceOnArrearsAgeing(true))//
|
||||
.allowPartialPeriodInterestCalcualtion(false)//
|
||||
.maxTrancheCount(10)//
|
||||
.outstandingLoanBalance(10000.0)//
|
||||
.charges(charges)//
|
||||
.accountingRule(LOAN_ACCOUNTING_RULE)//
|
||||
.fundSourceAccountId(accountTypeResolver.resolve(DefaultAccountType.SUSPENSE_CLEARING_ACCOUNT))//
|
||||
.loanPortfolioAccountId(accountTypeResolver.resolve(DefaultAccountType.LOANS_RECEIVABLE))//
|
||||
.transfersInSuspenseAccountId(accountTypeResolver.resolve(DefaultAccountType.TRANSFER_IN_SUSPENSE_ACCOUNT))//
|
||||
.interestOnLoanAccountId(accountTypeResolver.resolve(DefaultAccountType.INTEREST_INCOME))//
|
||||
.incomeFromFeeAccountId(accountTypeResolver.resolve(DefaultAccountType.FEE_INCOME))//
|
||||
.incomeFromPenaltyAccountId(accountTypeResolver.resolve(DefaultAccountType.FEE_INCOME))//
|
||||
.incomeFromRecoveryAccountId(accountTypeResolver.resolve(DefaultAccountType.RECOVERIES))//
|
||||
.writeOffAccountId(accountTypeResolver.resolve(DefaultAccountType.WRITTEN_OFF))//
|
||||
.overpaymentLiabilityAccountId(accountTypeResolver.resolve(DefaultAccountType.OVERPAYMENT_ACCOUNT))//
|
||||
.receivableInterestAccountId(accountTypeResolver.resolve(DefaultAccountType.INTEREST_FEE_RECEIVABLE))//
|
||||
.receivableFeeAccountId(accountTypeResolver.resolve(DefaultAccountType.INTEREST_FEE_RECEIVABLE))//
|
||||
.receivablePenaltyAccountId(accountTypeResolver.resolve(DefaultAccountType.INTEREST_FEE_RECEIVABLE))//
|
||||
.dateFormat(DATE_FORMAT)//
|
||||
.locale(LOCALE_EN)//
|
||||
.disallowExpectedDisbursements(false)//
|
||||
.delinquencyBucketId(DELINQUENCY_BUCKET_ID.longValue())//
|
||||
.goodwillCreditAccountId(accountTypeResolver.resolve(DefaultAccountType.GOODWILL_EXPENSE_ACCOUNT))//
|
||||
.incomeFromGoodwillCreditInterestAccountId(accountTypeResolver.resolve(DefaultAccountType.INTEREST_INCOME_CHARGE_OFF))//
|
||||
.incomeFromGoodwillCreditFeesAccountId(accountTypeResolver.resolve(DefaultAccountType.FEE_CHARGE_OFF))//
|
||||
.incomeFromGoodwillCreditPenaltyAccountId(accountTypeResolver.resolve(DefaultAccountType.FEE_CHARGE_OFF))//
|
||||
.paymentChannelToFundSourceMappings(paymentChannelToFundSourceMappings)//
|
||||
.penaltyToIncomeAccountMappings(penaltyToIncomeAccountMappings)//
|
||||
.feeToIncomeAccountMappings(feeToIncomeAccountMappings)//
|
||||
.incomeFromChargeOffInterestAccountId(accountTypeResolver.resolve(DefaultAccountType.INTEREST_INCOME_CHARGE_OFF))//
|
||||
.incomeFromChargeOffFeesAccountId(accountTypeResolver.resolve(DefaultAccountType.FEE_CHARGE_OFF))//
|
||||
.chargeOffExpenseAccountId(accountTypeResolver.resolve(DefaultAccountType.CREDIT_LOSS_BAD_DEBT))//
|
||||
.chargeOffFraudExpenseAccountId(accountTypeResolver.resolve(DefaultAccountType.CREDIT_LOSS_BAD_DEBT_FRAUD))//
|
||||
.incomeFromChargeOffPenaltyAccountId(accountTypeResolver.resolve(DefaultAccountType.FEE_CHARGE_OFF));//
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -22,6 +22,7 @@ import java.math.BigDecimal;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.client.models.InterestPauseRequestDto;
|
||||
import org.apache.fineract.client.models.PostCreateRescheduleLoansRequest;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdChargesChargeIdRequest;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdRequest;
|
||||
@@ -279,4 +280,9 @@ public class LoanRequestFactory {
|
||||
return new PostLoansLoanIdTransactionsRequest().transactionDate(DEFAULT_TRANSACTION_DATE).dateFormat(DATE_FORMAT)
|
||||
.locale(DEFAULT_LOCALE).note("Write Off");
|
||||
}
|
||||
|
||||
public static InterestPauseRequestDto defaultInterestPauseRequest() {
|
||||
return new InterestPauseRequestDto().dateFormat(DATE_FORMAT).locale(DEFAULT_LOCALE).startDate(DEFAULT_TRANSACTION_DATE)
|
||||
.endDate(DEFAULT_TRANSACTION_DATE);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -20,6 +20,7 @@ package org.apache.fineract.test.helper;
|
||||
|
||||
import java.io.IOException;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.fineract.client.models.GetCodesResponse;
|
||||
import org.apache.fineract.client.models.PostCodeValueDataResponse;
|
||||
import org.apache.fineract.client.models.PostCodeValuesDataRequest;
|
||||
@@ -54,7 +55,8 @@ public class CodeHelper {
|
||||
return codeValuesApi.createCodeValue(codeId, new PostCodeValuesDataRequest().name(stateName)).execute();
|
||||
}
|
||||
|
||||
public GetCodesResponse retrieveCodeByName(String name) throws IOException {
|
||||
@SneakyThrows
|
||||
public GetCodesResponse retrieveCodeByName(String name) {
|
||||
return codesApi.retrieveCodes().execute().body().stream().filter(r -> name.equals(r.getName())).findAny()
|
||||
.orElseThrow(() -> new IllegalArgumentException("Code with name " + name + " has not been found"));
|
||||
}
|
||||
|
||||
+12
@@ -71,6 +71,10 @@ public final class ErrorMessageHelper {
|
||||
return "Loan disbursal amount can't be greater than maximum applied loan amount calculation. Total disbursed amount: [0-9]* Maximum disbursal amount: [0-9]*";
|
||||
}
|
||||
|
||||
public static String disburseChargedOffLoanFailure() {
|
||||
return "Loan: [0-9]* disbursement is not allowed on charged-off loan.";
|
||||
}
|
||||
|
||||
public static String loanSubmitDateInFutureFailureMsg() {
|
||||
return "The date on which a loan is submitted cannot be in the future.";
|
||||
}
|
||||
@@ -273,6 +277,10 @@ public final class ErrorMessageHelper {
|
||||
expectedToStr);
|
||||
}
|
||||
|
||||
public static String transactionHasNullResourceValue(String transactionType, String resourceName) {
|
||||
return String.format("The transaction %s should has non-null value for %s, but it is null.", transactionType, resourceName);
|
||||
}
|
||||
|
||||
public static String wrongDataInChargesName(String actual, String expected) {
|
||||
return String.format("Wrong data in Charges / Name. Actual value is: %s - But expected value is: %s", actual, expected);
|
||||
}
|
||||
@@ -449,6 +457,10 @@ public final class ErrorMessageHelper {
|
||||
return String.format("Idempotency key is not matching: Actual value is: %s - But expected value is: %s", actual, expected);
|
||||
}
|
||||
|
||||
public static String wrongNumberOfLinesInRepaymentSchedule(int actual, int expected) {
|
||||
return wrongNumberOfLinesInRepaymentSchedule(null, actual, expected);
|
||||
}
|
||||
|
||||
public static String wrongNumberOfLinesInRepaymentSchedule(String resourceId, int actual, int expected) {
|
||||
return String.format("Number of lines in Repayment schedule of resource %s is not correct. " //
|
||||
+ "Actual value is: %s - But expected value is: %s", resourceId, actual, expected);
|
||||
|
||||
+6
@@ -53,6 +53,9 @@ public class CodeGlobalInitializerStep implements FineractGlobalInitializerStep
|
||||
public static final Long CODE_VALUE_FINANCIAL_INSTRUMENT_ID = 39L;
|
||||
public static final String CODE_VALUE_FINANCIAL_INSTRUMENT_DEBIT = "debit_card";
|
||||
public static final String CODE_VALUE_FINANCIAL_INSTRUMENT_CREDIT = "credit_card";
|
||||
public static final String CODE_VALUE_FINANCIAL_INSTRUMENT_FRAUD = "Fraud";
|
||||
public static final String CODE_VALUE_FINANCIAL_INSTRUMENT_DELINQUENT = "Delinquent";
|
||||
public static final String CODE_VALUE_FINANCIAL_INSTRUMENT_OTHER = "Other";
|
||||
public static final Long CODE_VALUE_TRANSACTION_TYPE_ID = 40L;
|
||||
public static final String CODE_VALUE_TRANSACTION_TYPE_SCHEDULED_PAYMENT = "scheduled_payment";
|
||||
public static final Long CODE_VALUE_BANKRUPTCY_TAG_ID = 41L;
|
||||
@@ -138,6 +141,9 @@ public class CodeGlobalInitializerStep implements FineractGlobalInitializerStep
|
||||
List<String> financialInstrumentNames = new ArrayList<>();
|
||||
financialInstrumentNames.add(CODE_VALUE_FINANCIAL_INSTRUMENT_DEBIT);
|
||||
financialInstrumentNames.add(CODE_VALUE_FINANCIAL_INSTRUMENT_CREDIT);
|
||||
financialInstrumentNames.add(CODE_VALUE_FINANCIAL_INSTRUMENT_FRAUD);
|
||||
financialInstrumentNames.add(CODE_VALUE_FINANCIAL_INSTRUMENT_DELINQUENT);
|
||||
financialInstrumentNames.add(CODE_VALUE_FINANCIAL_INSTRUMENT_OTHER);
|
||||
createCodeValues(CODE_VALUE_FINANCIAL_INSTRUMENT_ID, financialInstrumentNames);
|
||||
|
||||
// transaction type
|
||||
|
||||
+387
-25
@@ -19,7 +19,10 @@
|
||||
package org.apache.fineract.test.initializer.global;
|
||||
|
||||
import static org.apache.fineract.test.data.TransactionProcessingStrategyCode.ADVANCED_PAYMENT_ALLOCATION;
|
||||
import static org.apache.fineract.test.factory.LoanProductsRequestFactory.INTEREST_CALCULATION_PERIOD_TYPE_SAME_AS_REPAYMENT;
|
||||
import static org.apache.fineract.test.factory.LoanProductsRequestFactory.INTEREST_RATE_FREQUENCY_TYPE_MONTH;
|
||||
import static org.apache.fineract.test.factory.LoanProductsRequestFactory.INTEREST_RATE_FREQUENCY_TYPE_WHOLE_TERM;
|
||||
import static org.apache.fineract.test.factory.LoanProductsRequestFactory.REPAYMENT_FREQUENCY_TYPE_MONTHS;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
@@ -1089,14 +1092,112 @@ public class LoanProductGlobalInitializerStep implements FineractGlobalInitializ
|
||||
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADVANCED_CUSTOM_PAYMENT_ALLOCATION_INTEREST_RECALCULATION_DAILY_EMI_360_30_MULTIDISBURSE,
|
||||
responseLoanProductsRequestLP2AdvCustomPaymentAllocationInterestRecalculationDaily36030MultiDisburse);
|
||||
|
||||
// LP2 with progressive loan schedule + horizontal + interest EMI + 360/30
|
||||
// + interest recalculation, no interest on past due principal balances,
|
||||
// preClosureInterestCalculationStrategy= till preclose,
|
||||
// interestRecalculationCompoundingMethod = none
|
||||
// Frequency for recalculate Outstanding Principal: Daily, Frequency Interval for recalculation: 1
|
||||
// (LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY_NO_CALC_ON_PAST_DUE_TILL_PRECLOSE)
|
||||
String name51 = DefaultLoanProduct.LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALC_DAILY_NO_CALC_ON_PAST_DUE_TILL_PRECLOSE
|
||||
.getName();
|
||||
PostLoanProductsRequest loanProductsRequestLP2AdvancedPaymentInterestEmi36030InterestRecalcDailyNoCalcOnPastDueTillPreclose = loanProductsRequestFactory
|
||||
.defaultLoanProductsRequestLP2Emi()//
|
||||
.name(name51)//
|
||||
.daysInYearType(DaysInYearType.DAYS360.value)//
|
||||
.daysInMonthType(DaysInMonthType.DAYS30.value)//
|
||||
.isInterestRecalculationEnabled(true)//
|
||||
.preClosureInterestCalculationStrategy(1)//
|
||||
.rescheduleStrategyMethod(4)//
|
||||
.interestRecalculationCompoundingMethod(0)//
|
||||
.recalculationRestFrequencyType(2)//
|
||||
.recalculationRestFrequencyInterval(1)//
|
||||
.disallowInterestCalculationOnPastDue(true)//
|
||||
.paymentAllocation(List.of(//
|
||||
createPaymentAllocation("DEFAULT", "NEXT_INSTALLMENT"), //
|
||||
createPaymentAllocation("GOODWILL_CREDIT", "LAST_INSTALLMENT"), //
|
||||
createPaymentAllocation("MERCHANT_ISSUED_REFUND", "REAMORTIZATION"), //
|
||||
createPaymentAllocation("PAYOUT_REFUND", "NEXT_INSTALLMENT")));//
|
||||
Response<PostLoanProductsResponse> responseLoanProductsRequestLP2AdvancedpaymentInterest36030InterestRecalcNoCalcOnPastDueDailyTillPreClose = loanProductsApi
|
||||
.createLoanProduct(loanProductsRequestLP2AdvancedPaymentInterestEmi36030InterestRecalcDailyNoCalcOnPastDueTillPreclose)
|
||||
.execute();
|
||||
TestContext.INSTANCE.set(TestContextKey.temp,
|
||||
responseLoanProductsRequestLP2AdvancedpaymentInterest36030InterestRecalcNoCalcOnPastDueDailyTillPreClose);
|
||||
|
||||
// LP2 with progressive loan schedule + horizontal + interest recalculation daily EMI + 360/30
|
||||
// + multi disbursement + no interest on past due principal balances,
|
||||
// (LP2_ADV_PAYMENT_ALLOC_INTEREST_RECALCULATION_DAILY_NO_CALC_ON_PAST_DUE_EMI_360_30_MULTIDISBURSE)
|
||||
String name52 = DefaultLoanProduct.LP2_ADV_PAYMENT_ALLOC_INTEREST_RECALCULATION_DAILY_NO_CALC_ON_PAST_DUE_EMI_360_30_MULTIDISBURSE
|
||||
.getName();
|
||||
PostLoanProductsRequest loanProductsRequestLP2AdvPaymentAllocationInterestRecalculationDailyNoCalcOnPastDueEmi36030MultiDisburse = loanProductsRequestFactory
|
||||
.defaultLoanProductsRequestLP2Emi()//
|
||||
.name(name52)//
|
||||
.daysInYearType(DaysInYearType.DAYS360.value)//
|
||||
.daysInMonthType(DaysInMonthType.DAYS30.value)//
|
||||
.isInterestRecalculationEnabled(true)//
|
||||
.preClosureInterestCalculationStrategy(1)//
|
||||
.rescheduleStrategyMethod(4)//
|
||||
.interestRecalculationCompoundingMethod(0)//
|
||||
.recalculationRestFrequencyType(2)//
|
||||
.recalculationRestFrequencyInterval(1)//
|
||||
.disallowInterestCalculationOnPastDue(true)//
|
||||
.paymentAllocation(List.of(//
|
||||
createPaymentAllocation("DEFAULT", "NEXT_INSTALLMENT"), //
|
||||
createPaymentAllocation("GOODWILL_CREDIT", "LAST_INSTALLMENT"), //
|
||||
createPaymentAllocation("MERCHANT_ISSUED_REFUND", "REAMORTIZATION"), //
|
||||
createPaymentAllocation("PAYOUT_REFUND", "NEXT_INSTALLMENT")))
|
||||
.multiDisburseLoan(true)//
|
||||
.disallowExpectedDisbursements(true)//
|
||||
.maxTrancheCount(10)//
|
||||
.outstandingLoanBalance(10000.0);//
|
||||
Response<PostLoanProductsResponse> responseLoanProductsRequestLP2AdvPaymentAllocationInterestRecalculationDailyNoCalcOnPastDue36030MultiDisburse = loanProductsApi
|
||||
.createLoanProduct(loanProductsRequestLP2AdvPaymentAllocationInterestRecalculationDailyNoCalcOnPastDueEmi36030MultiDisburse)
|
||||
.execute();
|
||||
TestContext.INSTANCE.set(
|
||||
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADVANCED_PAYMENT_ALLOCATION_INTEREST_RECALCULATION_DAILY_NO_CALC_ON_PAST_DUE_EMI_360_30_MULTIDISBURSE,
|
||||
responseLoanProductsRequestLP2AdvPaymentAllocationInterestRecalculationDailyNoCalcOnPastDue36030MultiDisburse);
|
||||
|
||||
// LP2 with progressive loan schedule + horizontal + interest EMI + 360/30 + multidisbursement + downpayment +
|
||||
// interest recalculation
|
||||
// 25%, auto enabled
|
||||
// (LP2_ADV_PYMNT_INTEREST_RECALCULATION_DAILY_EMI_360_30_MULTIDISBURSE_AUTO_DOWNPAYMENT)
|
||||
String name53 = DefaultLoanProduct.LP2_ADV_PYMNT_INTEREST_RECALCULATION_DAILY_EMI_360_30_MULTIDISBURSE_AUTO_DOWNPAYMENT.getName();
|
||||
PostLoanProductsRequest loanProductsRequestLP2AdvancedpaymentInterestRecalculationEmi36030MultiDisburseAutoDownPayment = loanProductsRequestFactory
|
||||
.defaultLoanProductsRequestLP2Emi()//
|
||||
.name(name53)//
|
||||
.enableDownPayment(true)//
|
||||
.disbursedAmountPercentageForDownPayment(new BigDecimal(25))//
|
||||
.daysInYearType(DaysInYearType.DAYS360.value)//
|
||||
.daysInMonthType(DaysInMonthType.DAYS30.value)//
|
||||
.isInterestRecalculationEnabled(true)//
|
||||
.preClosureInterestCalculationStrategy(1)//
|
||||
.rescheduleStrategyMethod(4)//
|
||||
.interestRecalculationCompoundingMethod(0)//
|
||||
.recalculationRestFrequencyType(2)//
|
||||
.recalculationRestFrequencyInterval(1)//
|
||||
.enableAutoRepaymentForDownPayment(true).paymentAllocation(List.of(//
|
||||
createPaymentAllocation("DEFAULT", "NEXT_INSTALLMENT"), //
|
||||
createPaymentAllocation("GOODWILL_CREDIT", "LAST_INSTALLMENT"), //
|
||||
createPaymentAllocation("MERCHANT_ISSUED_REFUND", "REAMORTIZATION"), //
|
||||
createPaymentAllocation("PAYOUT_REFUND", "NEXT_INSTALLMENT")))//
|
||||
.multiDisburseLoan(true)//
|
||||
.disallowExpectedDisbursements(true)//
|
||||
.maxTrancheCount(10)//
|
||||
.outstandingLoanBalance(10000.0);//
|
||||
Response<PostLoanProductsResponse> responseLoanProductsRequestLP2AdvancedpaymentInterestRecalculation36030MultiDisburseAutoDownPayment = loanProductsApi
|
||||
.createLoanProduct(loanProductsRequestLP2AdvancedpaymentInterestRecalculationEmi36030MultiDisburseAutoDownPayment)
|
||||
.execute();
|
||||
TestContext.INSTANCE.set(
|
||||
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_RECALCULATION_DAILY_EMI_360_30_MULTIDISBURSE_AUTO_DOWNPAYMENT,
|
||||
responseLoanProductsRequestLP2AdvancedpaymentInterestRecalculation36030MultiDisburseAutoDownPayment);
|
||||
|
||||
// LP2 + interest recalculation + zero-interest chargeOff behaviour + progressive loan schedule + horizontal
|
||||
// (LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR)
|
||||
final String name51 = DefaultLoanProduct.LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR
|
||||
final String name54 = DefaultLoanProduct.LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR
|
||||
.getName();
|
||||
|
||||
final PostLoanProductsRequest loanProductsRequestAdvInterestRecalculationZeroInterestChargeOffBehaviourProgressiveLoanSchedule = loanProductsRequestFactory
|
||||
.defaultLoanProductsRequestLP2InterestDailyRecalculation()//
|
||||
.name(name51)//
|
||||
.name(name54)//
|
||||
.paymentAllocation(List.of(//
|
||||
createPaymentAllocation("DEFAULT", "NEXT_INSTALLMENT")))
|
||||
.chargeOffBehaviour("ZERO_INTEREST");//
|
||||
@@ -1109,11 +1210,11 @@ public class LoanProductGlobalInitializerStep implements FineractGlobalInitializ
|
||||
|
||||
// LP2 + zero-interest chargeOff behaviour + progressive loan schedule + horizontal
|
||||
// (LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR)
|
||||
final String name52 = DefaultLoanProduct.LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR.getName();
|
||||
final String name55 = DefaultLoanProduct.LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR.getName();
|
||||
|
||||
final PostLoanProductsRequest loanProductsRequestAdvZeroInterestChargeOffBehaviourProgressiveLoanSchedule = loanProductsRequestFactory
|
||||
.defaultLoanProductsRequestLP2()//
|
||||
.name(name52)//
|
||||
.name(name55)//
|
||||
.enableDownPayment(false)//
|
||||
.enableAutoRepaymentForDownPayment(null)//
|
||||
.disbursedAmountPercentageForDownPayment(null)//
|
||||
@@ -1133,7 +1234,7 @@ public class LoanProductGlobalInitializerStep implements FineractGlobalInitializ
|
||||
LoanProductPaymentAllocationRule.AllocationTypesEnum.DUE_PRINCIPAL, //
|
||||
LoanProductPaymentAllocationRule.AllocationTypesEnum.DUE_INTEREST, //
|
||||
LoanProductPaymentAllocationRule.AllocationTypesEnum.IN_ADVANCE_PENALTY, //
|
||||
LoanProductPaymentAllocationRule.AllocationTypesEnum.IN_ADVANCE_FEE, //
|
||||
LoanProductPaymentAllocationRule.AllocationTypesEnum.IN_ADVANCE_FEE,
|
||||
LoanProductPaymentAllocationRule.AllocationTypesEnum.IN_ADVANCE_INTEREST, //
|
||||
LoanProductPaymentAllocationRule.AllocationTypesEnum.IN_ADVANCE_PRINCIPAL), //
|
||||
createPaymentAllocation("GOODWILL_CREDIT", "LAST_INSTALLMENT"), //
|
||||
@@ -1148,12 +1249,12 @@ public class LoanProductGlobalInitializerStep implements FineractGlobalInitializ
|
||||
// LP2 with progressive loan schedule + horizontal + interest EMI + 360/30 + multidisbursement +
|
||||
// accelerate-maturity chargeOff behaviour
|
||||
// (LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ACCELERATE_MATURITY_CHARGE_OFF_BEHAVIOUR)
|
||||
final String name53 = DefaultLoanProduct.LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ACCELERATE_MATURITY_CHARGE_OFF_BEHAVIOUR
|
||||
final String name56 = DefaultLoanProduct.LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ACCELERATE_MATURITY_CHARGE_OFF_BEHAVIOUR
|
||||
.getName();
|
||||
|
||||
final PostLoanProductsRequest loanProductsRequestAdvCustomInterestRecalculationAccelerateMaturityChargeOffBehaviourProgressiveLoanSchedule = loanProductsRequestFactory
|
||||
final PostLoanProductsRequest loanProductsRequestAdvCustomAccelerateMaturityChargeOffBehaviourProgressiveLoanSchedule = loanProductsRequestFactory
|
||||
.defaultLoanProductsRequestLP2InterestDailyRecalculation()//
|
||||
.name(name53)//
|
||||
.name(name56)//
|
||||
.paymentAllocation(List.of(//
|
||||
createPaymentAllocation("DEFAULT", "NEXT_INSTALLMENT",
|
||||
LoanProductPaymentAllocationRule.AllocationTypesEnum.PAST_DUE_PENALTY, //
|
||||
@@ -1172,19 +1273,280 @@ public class LoanProductGlobalInitializerStep implements FineractGlobalInitializ
|
||||
createPaymentAllocation("MERCHANT_ISSUED_REFUND", "REAMORTIZATION"), //
|
||||
createPaymentAllocation("PAYOUT_REFUND", "NEXT_INSTALLMENT"))) //
|
||||
.chargeOffBehaviour("ACCELERATE_MATURITY");//
|
||||
final Response<PostLoanProductsResponse> responseLoanProductsRequestAdvCustomInterestRecalculationAccelerateMaturityChargeOffBehaviourProgressiveLoanSchedule = loanProductsApi
|
||||
.createLoanProduct(
|
||||
loanProductsRequestAdvCustomInterestRecalculationAccelerateMaturityChargeOffBehaviourProgressiveLoanSchedule)
|
||||
.execute();
|
||||
final Response<PostLoanProductsResponse> responseLoanProductsRequestAdvCustomAccelerateMaturityChargeOffBehaviourProgressiveLoanSchedule = loanProductsApi
|
||||
.createLoanProduct(loanProductsRequestAdvCustomAccelerateMaturityChargeOffBehaviourProgressiveLoanSchedule).execute();
|
||||
TestContext.INSTANCE.set(
|
||||
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ACCELERATE_MATURITY_CHARGE_OFF_BEHAVIOUR,
|
||||
responseLoanProductsRequestAdvCustomInterestRecalculationAccelerateMaturityChargeOffBehaviourProgressiveLoanSchedule);
|
||||
responseLoanProductsRequestAdvCustomAccelerateMaturityChargeOffBehaviourProgressiveLoanSchedule);
|
||||
|
||||
// + interest recalculation, allowPartialPeriodInterestCalculation = true
|
||||
// interestRecalculationCompoundingMethod = none
|
||||
// Frequency for recalculate Outstanding Principal: Daily, Frequency Interval for recalculation: 2
|
||||
// Frequency for Interest rate - Whole Year
|
||||
// (LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY_ALLOW_PARTIAL_PERIOD)
|
||||
String name57 = DefaultLoanProduct.LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY_ALLOW_PARTIAL_PERIOD
|
||||
.getName();
|
||||
PostLoanProductsRequest loanProductsRequestLP2AdvancedPaymentInterestEmi36030InterestRecalculationDailyAllowPartialPeriod = loanProductsRequestFactory//
|
||||
.defaultLoanProductsRequestLP2Emi()//
|
||||
.name(name57)//
|
||||
.loanScheduleProcessingType("HORIZONTAL")//
|
||||
.daysInYearType(DaysInYearType.DAYS360.value)//
|
||||
.daysInMonthType(DaysInMonthType.DAYS30.value)//
|
||||
.isInterestRecalculationEnabled(true)//
|
||||
.interestCalculationPeriodType(INTEREST_CALCULATION_PERIOD_TYPE_SAME_AS_REPAYMENT).preClosureInterestCalculationStrategy(1)//
|
||||
.rescheduleStrategyMethod(4)//
|
||||
.interestRecalculationCompoundingMethod(0)//
|
||||
.recalculationRestFrequencyType(1)//
|
||||
.recalculationRestFrequencyInterval(1)//
|
||||
.repaymentEvery(1)//
|
||||
.interestRatePerPeriod((double) 7.0)//
|
||||
.interestRateFrequencyType(INTEREST_RATE_FREQUENCY_TYPE_MONTH)//
|
||||
.enableDownPayment(false)//
|
||||
.interestRecalculationCompoundingMethod(0)//
|
||||
.repaymentFrequencyType(REPAYMENT_FREQUENCY_TYPE_MONTHS)//
|
||||
.allowPartialPeriodInterestCalcualtion(true)//
|
||||
.paymentAllocation(List.of(//
|
||||
createPaymentAllocation("DEFAULT", "NEXT_INSTALLMENT")));//
|
||||
Response<PostLoanProductsResponse> responseLP2AdvancedPaymentInterestEmi36030InterestRecalculationDailyAllowPartialPeriod = loanProductsApi
|
||||
.createLoanProduct(loanProductsRequestLP2AdvancedPaymentInterestEmi36030InterestRecalculationDailyAllowPartialPeriod)
|
||||
.execute();
|
||||
TestContext.INSTANCE.set(
|
||||
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY_ALLOW_PARTIAL_PERIOD,
|
||||
responseLP2AdvancedPaymentInterestEmi36030InterestRecalculationDailyAllowPartialPeriod);
|
||||
|
||||
// LP2 + interest recalculation + zero-interest chargeOff behaviour + progressive loan schedule + horizontal
|
||||
// interest EMI + 360/30, preClosureInterestCalculationStrategy= till preclose,
|
||||
// Frequency for recalculate Outstanding Principal: Daily, Frequency Interval for recalculation: 1
|
||||
// (LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ZERO_INTEREST_CHARGE_OFF)
|
||||
final String name58 = DefaultLoanProduct.LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ZERO_INTEREST_CHARGE_OFF.getName();
|
||||
final PostLoanProductsRequest loanProductsRequestLP2AdvancedPaymentInterestEmi36030InterestRecalculationDailyChargeOff = loanProductsRequestFactory
|
||||
.defaultLoanProductsRequestLP2EmiWithChargeOff()//
|
||||
.name(name58)//
|
||||
.daysInYearType(DaysInYearType.DAYS360.value)//
|
||||
.daysInMonthType(DaysInMonthType.DAYS30.value)//
|
||||
.isInterestRecalculationEnabled(true)//
|
||||
.preClosureInterestCalculationStrategy(1)//
|
||||
.rescheduleStrategyMethod(4)//
|
||||
.interestRecalculationCompoundingMethod(0)//
|
||||
.recalculationRestFrequencyType(2)//
|
||||
.recalculationRestFrequencyInterval(1)//
|
||||
.paymentAllocation(List.of(//
|
||||
createPaymentAllocation("DEFAULT", "NEXT_INSTALLMENT"), //
|
||||
createPaymentAllocation("GOODWILL_CREDIT", "LAST_INSTALLMENT"), //
|
||||
createPaymentAllocation("MERCHANT_ISSUED_REFUND", "REAMORTIZATION"), //
|
||||
createPaymentAllocation("PAYOUT_REFUND", "NEXT_INSTALLMENT")))//
|
||||
.chargeOffBehaviour("ZERO_INTEREST");//
|
||||
final Response<PostLoanProductsResponse> responseLoanProductsRequestLP2AdvancedPaymentInterestEmi36030InterestRecalculationDailyChargeOff = loanProductsApi
|
||||
.createLoanProduct(loanProductsRequestLP2AdvancedPaymentInterestEmi36030InterestRecalculationDailyChargeOff).execute();
|
||||
TestContext.INSTANCE.set(
|
||||
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ZERO_INTEREST_CHARGE_OFF,
|
||||
responseLoanProductsRequestLP2AdvancedPaymentInterestEmi36030InterestRecalculationDailyChargeOff);
|
||||
|
||||
// LP2 + NO interest recalculation + zero-interest chargeOff behaviour + progressive loan schedule + horizontal
|
||||
// (LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF)
|
||||
final String name59 = DefaultLoanProduct.LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF.getName();
|
||||
final PostLoanProductsRequest loanProductsRequestLP2AdvancedPaymentNoInterestInterestRecalculationChargeOff = loanProductsRequestFactory
|
||||
.defaultLoanProductsRequestLP2EmiWithChargeOff()//
|
||||
.name(name59)//
|
||||
.daysInYearType(DaysInYearType.DAYS360.value)//
|
||||
.daysInMonthType(DaysInMonthType.DAYS30.value)//
|
||||
.paymentAllocation(List.of(//
|
||||
createPaymentAllocation("DEFAULT", "NEXT_INSTALLMENT"))) //
|
||||
.chargeOffBehaviour("ZERO_INTEREST");//
|
||||
final Response<PostLoanProductsResponse> responseLoanProductsRequestLP2AdvancedPaymentNoInterestInterestRecalculationChargeOff = loanProductsApi
|
||||
.createLoanProduct(loanProductsRequestLP2AdvancedPaymentNoInterestInterestRecalculationChargeOff).execute();
|
||||
TestContext.INSTANCE.set(TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF,
|
||||
responseLoanProductsRequestLP2AdvancedPaymentNoInterestInterestRecalculationChargeOff);
|
||||
|
||||
// LP2 with progressive loan schedule + horizontal + interest EMI + actual/actual + accrual activity posting +
|
||||
// down payment
|
||||
// enableAccrualActivityPosting
|
||||
// (LP2_ADV_PYMNT_INTEREST_DAILY_AUTO_DOWNPAYMENT_EMI_ACTUAL_ACTUAL_ACCRUAL_ACTIVITY)
|
||||
String name60 = DefaultLoanProduct.LP2_ADV_PYMNT_INTEREST_DAILY_AUTO_DOWNPAYMENT_EMI_ACTUAL_ACTUAL_ACCRUAL_ACTIVITY.getName();
|
||||
PostLoanProductsRequest loanProductsRequestLP2AdvancedpaymentInterestAutoDownpaymentEmiActualActualAccrualActivity = loanProductsRequestFactory
|
||||
.defaultLoanProductsRequestLP2Emi()//
|
||||
.name(name60)//
|
||||
.enableDownPayment(true)//
|
||||
.disbursedAmountPercentageForDownPayment(new BigDecimal(25))//
|
||||
.enableAutoRepaymentForDownPayment(true)//
|
||||
.enableAccrualActivityPosting(true)//
|
||||
.paymentAllocation(List.of(//
|
||||
createPaymentAllocation("DEFAULT", "NEXT_INSTALLMENT"), //
|
||||
createPaymentAllocation("GOODWILL_CREDIT", "LAST_INSTALLMENT"), //
|
||||
createPaymentAllocation("MERCHANT_ISSUED_REFUND", "REAMORTIZATION"), //
|
||||
createPaymentAllocation("PAYOUT_REFUND", "NEXT_INSTALLMENT")));//
|
||||
Response<PostLoanProductsResponse> responseLoanProductsRequestLP2AdvancedpaymentInterestAutoDownpaymentEmiActualActualAccrualActivity = loanProductsApi
|
||||
.createLoanProduct(loanProductsRequestLP2AdvancedpaymentInterestAutoDownpaymentEmiActualActualAccrualActivity).execute();
|
||||
TestContext.INSTANCE.set(TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_ACTUAL_ACTUAL,
|
||||
responseLoanProductsRequestLP2AdvancedpaymentInterestAutoDownpaymentEmiActualActualAccrualActivity);
|
||||
|
||||
// LP2 with progressive loan schedule + horizontal + interest EMI + 360/30
|
||||
// + interest recalculation, preClosureInterestCalculationStrategy= till preclose,
|
||||
// interestRecalculationCompoundingMethod = none
|
||||
// Frequency for recalculate Outstanding Principal: Daily, Frequency Interval for recalculation: 1
|
||||
// AccrualActivityPostingEnabled = true
|
||||
// (LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY_ACCRUAL_ACTIVITY_POSTING)
|
||||
String name61 = DefaultLoanProduct.LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY_ACCRUAL_ACTIVITY_POSTING
|
||||
.getName();
|
||||
PostLoanProductsRequest loanProductsRequestLP2AdvancedpaymentInterestEmi36030InterestRecalcDailyAccrualActivityPosting = loanProductsRequestFactory
|
||||
.defaultLoanProductsRequestLP2Emi()//
|
||||
.name(name61)//
|
||||
.daysInYearType(DaysInYearType.DAYS360.value)//
|
||||
.daysInMonthType(DaysInMonthType.DAYS30.value)//
|
||||
.isInterestRecalculationEnabled(true)//
|
||||
.preClosureInterestCalculationStrategy(1)//
|
||||
.rescheduleStrategyMethod(4)//
|
||||
.interestRecalculationCompoundingMethod(0)//
|
||||
.recalculationRestFrequencyType(2)//
|
||||
.recalculationRestFrequencyInterval(1)//
|
||||
.enableAccrualActivityPosting(true).paymentAllocation(List.of(//
|
||||
createPaymentAllocation("DEFAULT", "NEXT_INSTALLMENT"), //
|
||||
createPaymentAllocation("GOODWILL_CREDIT", "LAST_INSTALLMENT"), //
|
||||
createPaymentAllocation("MERCHANT_ISSUED_REFUND", "REAMORTIZATION"), //
|
||||
createPaymentAllocation("PAYOUT_REFUND", "NEXT_INSTALLMENT")));//
|
||||
Response<PostLoanProductsResponse> responseloanProductsRequestLP2AdvancedpaymentInterestEmi36030InterestRecalcDailyAccrualActivityPosting = loanProductsApi
|
||||
.createLoanProduct(loanProductsRequestLP2AdvancedpaymentInterestEmi36030InterestRecalcDailyAccrualActivityPosting)
|
||||
.execute();
|
||||
TestContext.INSTANCE.set(
|
||||
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY_ACCRUAL_ACTIVITY_POSTING,
|
||||
responseloanProductsRequestLP2AdvancedpaymentInterestEmi36030InterestRecalcDailyAccrualActivityPosting);
|
||||
|
||||
// LP2 with progressive loan schedule + horizontal + interest EMI + 360/Actual
|
||||
// (LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_ACTUAL)
|
||||
String name62 = DefaultLoanProduct.LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_ACTUAL.getName();
|
||||
PostLoanProductsRequest loanProductsRequestLP2AdvancedpaymentInterest360Actual = loanProductsRequestFactory
|
||||
.defaultLoanProductsRequestLP2Emi()//
|
||||
.name(name62)//
|
||||
.daysInYearType(DaysInYearType.DAYS360.value)//
|
||||
.daysInMonthType(DaysInMonthType.ACTUAL.value)//
|
||||
.paymentAllocation(List.of(//
|
||||
createPaymentAllocation("DEFAULT", "NEXT_INSTALLMENT"), //
|
||||
createPaymentAllocation("GOODWILL_CREDIT", "LAST_INSTALLMENT"), //
|
||||
createPaymentAllocation("MERCHANT_ISSUED_REFUND", "REAMORTIZATION"), //
|
||||
createPaymentAllocation("PAYOUT_REFUND", "NEXT_INSTALLMENT")));//
|
||||
Response<PostLoanProductsResponse> responseLoanProductsRequestLP2AdvancedpaymentInterestEmi360Actual = loanProductsApi
|
||||
.createLoanProduct(loanProductsRequestLP2AdvancedpaymentInterest360Actual).execute();
|
||||
TestContext.INSTANCE.set(TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_ACTUAL,
|
||||
responseLoanProductsRequestLP2AdvancedpaymentInterestEmi360Actual);
|
||||
|
||||
// LP2 with progressive loan schedule + horizontal + interest EMI + 360/30
|
||||
// Chargeback: Interest, Fee, Principal
|
||||
// + interest recalculation DISABLED
|
||||
// Frequency for recalculate Outstanding Principal: Daily, Frequency Interval for recalculation: 1
|
||||
// (LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_CHARGEBACK_INTEREST_FEE_PRINCIPAL)
|
||||
String name63 = DefaultLoanProduct.LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_CHARGEBACK_INTEREST_FEE_PRINCIPAL.getName();
|
||||
PostLoanProductsRequest loanProductsRequestLP2AdvancedpaymentInterestDailyEmi36030ChargebackInterestFeePrincipal = loanProductsRequestFactory
|
||||
.defaultLoanProductsRequestLP2Emi()//
|
||||
.name(name63)//
|
||||
.daysInYearType(DaysInYearType.DAYS360.value)//
|
||||
.daysInMonthType(DaysInMonthType.DAYS30.value)//
|
||||
.creditAllocation(List.of(//
|
||||
createCreditAllocation("CHARGEBACK", List.of("INTEREST", "FEE", "PRINCIPAL", "PENALTY"))//
|
||||
))//
|
||||
.paymentAllocation(List.of(//
|
||||
createPaymentAllocation("DEFAULT", "NEXT_INSTALLMENT"), //
|
||||
createPaymentAllocation("GOODWILL_CREDIT", "LAST_INSTALLMENT"), //
|
||||
createPaymentAllocation("MERCHANT_ISSUED_REFUND", "REAMORTIZATION"), //
|
||||
createPaymentAllocation("PAYOUT_REFUND", "NEXT_INSTALLMENT")));//
|
||||
Response<PostLoanProductsResponse> responseLoanProductsRequestLP2AdvancedpaymentInterestDailyEmi36030ChargebackInterestFeePrincipal = loanProductsApi
|
||||
.createLoanProduct(loanProductsRequestLP2AdvancedpaymentInterestDailyEmi36030ChargebackInterestFeePrincipal).execute();
|
||||
TestContext.INSTANCE.set(
|
||||
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_CHARGEBACK_INTEREST_FEE_PRINCIPAL,
|
||||
responseLoanProductsRequestLP2AdvancedpaymentInterestDailyEmi36030ChargebackInterestFeePrincipal);
|
||||
|
||||
// LP2 with progressive loan schedule + horizontal + interest EMI + 360/30
|
||||
// Chargeback: Principal, Interest, Fee
|
||||
// + interest recalculation DISABLED
|
||||
// Frequency for recalculate Outstanding Principal: Daily, Frequency Interval for recalculation: 1
|
||||
// (LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_CHARGEBACK_PRINCIPAL_INTEREST_FEE)
|
||||
String name64 = DefaultLoanProduct.LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_CHARGEBACK_PRINCIPAL_INTEREST_FEE.getName();
|
||||
PostLoanProductsRequest loanProductsRequestLP2AdvancedpaymentInterestDailyEmi36030ChargebackPrincipalInterestFee = loanProductsRequestFactory
|
||||
.defaultLoanProductsRequestLP2Emi()//
|
||||
.name(name64)//
|
||||
.daysInYearType(DaysInYearType.DAYS360.value)//
|
||||
.daysInMonthType(DaysInMonthType.DAYS30.value)//
|
||||
.creditAllocation(List.of(//
|
||||
createCreditAllocation("CHARGEBACK", List.of("PRINCIPAL", "INTEREST", "FEE", "PENALTY"))//
|
||||
))//
|
||||
.paymentAllocation(List.of(//
|
||||
createPaymentAllocation("DEFAULT", "NEXT_INSTALLMENT"), //
|
||||
createPaymentAllocation("GOODWILL_CREDIT", "LAST_INSTALLMENT"), //
|
||||
createPaymentAllocation("MERCHANT_ISSUED_REFUND", "REAMORTIZATION"), //
|
||||
createPaymentAllocation("PAYOUT_REFUND", "NEXT_INSTALLMENT")));//
|
||||
Response<PostLoanProductsResponse> responseLoanProductsRequestLP2AdvancedpaymentInterestDailyEmi36030ChargebackPrincipalInterestFee = loanProductsApi
|
||||
.createLoanProduct(loanProductsRequestLP2AdvancedpaymentInterestDailyEmi36030ChargebackPrincipalInterestFee).execute();
|
||||
TestContext.INSTANCE.set(
|
||||
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_CHARGEBACK_PRINCIPAL_INTEREST_FEE,
|
||||
responseLoanProductsRequestLP2AdvancedpaymentInterestDailyEmi36030ChargebackPrincipalInterestFee); // LP2
|
||||
// with
|
||||
// progressive
|
||||
// loan
|
||||
// schedule
|
||||
// +
|
||||
// horizontal
|
||||
// +
|
||||
// interest
|
||||
// EMI
|
||||
// +
|
||||
// 360/30
|
||||
|
||||
// LP2 with progressive loan schedule + horizontal + interest EMI + 360/30
|
||||
// Chargeback: Interest, Penalty, Fee, Principal
|
||||
// + interest recalculation DISABLED
|
||||
// Frequency for recalculate Outstanding Principal: Daily, Frequency Interval for recalculation: 1
|
||||
// (LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_CHARGEBACK_INTEREST_PENALTY_FEE_PRINCIPAL)
|
||||
String name65 = DefaultLoanProduct.LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_CHARGEBACK_INTEREST_PENALTY_FEE_PRINCIPAL.getName();
|
||||
PostLoanProductsRequest loanProductsRequestLP2AdvancedpaymentInterestDailyEmi36030ChargebackInterestPenaltyFeePrincipal = loanProductsRequestFactory
|
||||
.defaultLoanProductsRequestLP2Emi()//
|
||||
.name(name65)//
|
||||
.daysInYearType(DaysInYearType.DAYS360.value)//
|
||||
.daysInMonthType(DaysInMonthType.DAYS30.value)//
|
||||
.creditAllocation(List.of(//
|
||||
createCreditAllocation("CHARGEBACK", List.of("INTEREST", "PENALTY", "FEE", "PRINCIPAL"))//
|
||||
))//
|
||||
.paymentAllocation(List.of(//
|
||||
createPaymentAllocation("DEFAULT", "NEXT_INSTALLMENT"), //
|
||||
createPaymentAllocation("GOODWILL_CREDIT", "LAST_INSTALLMENT"), //
|
||||
createPaymentAllocation("MERCHANT_ISSUED_REFUND", "REAMORTIZATION"), //
|
||||
createPaymentAllocation("PAYOUT_REFUND", "NEXT_INSTALLMENT")));//
|
||||
Response<PostLoanProductsResponse> responseLoanProductsRequestLP2AdvancedpaymentInterestDailyEmi36030ChargebackInterestPenaltyFeePrincipal = loanProductsApi
|
||||
.createLoanProduct(loanProductsRequestLP2AdvancedpaymentInterestDailyEmi36030ChargebackInterestPenaltyFeePrincipal)
|
||||
.execute();
|
||||
TestContext.INSTANCE.set(
|
||||
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_CHARGEBACK_INTEREST_PENALTY_FEE_PRINCIPAL,
|
||||
responseLoanProductsRequestLP2AdvancedpaymentInterestDailyEmi36030ChargebackInterestPenaltyFeePrincipal);
|
||||
|
||||
// LP2 with progressive loan schedule + horizontal + interest EMI + actual/actual
|
||||
// + interest recalculation, preClosureInterestCalculationStrategy= till preclose,
|
||||
// Frequency for recalculate Outstanding Principal: Daily, Frequency Interval for recalculation: 1
|
||||
// (LP2_ADV_PYMNT_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_RECALCULATION_DAILY)
|
||||
String name66 = DefaultLoanProduct.LP2_ADV_PYMNT_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_RECALCULATION_DAILY.getName();
|
||||
PostLoanProductsRequest loanProductsRequestLP2AdvancedpaymentInterestEmiActualActualInterestRecalculationDaily = loanProductsRequestFactory
|
||||
.defaultLoanProductsRequestLP2Emi()//
|
||||
.name(name66)//
|
||||
.maxPrincipal(1000000.0)//
|
||||
.isInterestRecalculationEnabled(true)//
|
||||
.preClosureInterestCalculationStrategy(1)//
|
||||
.rescheduleStrategyMethod(4)//
|
||||
.interestRecalculationCompoundingMethod(0)//
|
||||
.recalculationRestFrequencyType(2)//
|
||||
.recalculationRestFrequencyInterval(1)//
|
||||
.paymentAllocation(List.of(//
|
||||
createPaymentAllocation("DEFAULT", "NEXT_INSTALLMENT"), //
|
||||
createPaymentAllocation("GOODWILL_CREDIT", "LAST_INSTALLMENT"), //
|
||||
createPaymentAllocation("MERCHANT_ISSUED_REFUND", "REAMORTIZATION"), //
|
||||
createPaymentAllocation("PAYOUT_REFUND", "NEXT_INSTALLMENT")));//
|
||||
Response<PostLoanProductsResponse> responseLoanProductsRequestLP2AdvancedpaymentInterestEmiActualActualInterestRecalculationDaily = loanProductsApi
|
||||
.createLoanProduct(loanProductsRequestLP2AdvancedpaymentInterestEmiActualActualInterestRecalculationDaily).execute();
|
||||
TestContext.INSTANCE.set(
|
||||
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_RECALCULATION_DAILY,
|
||||
responseLoanProductsRequestLP2AdvancedpaymentInterestEmiActualActualInterestRecalculationDaily);
|
||||
|
||||
// LP2 with progressive loan schedule + horizontal + interest EMI + 360/30 + accrual activity
|
||||
String name54 = DefaultLoanProduct.LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_ACCRUAL_ACTIVITY.getName();
|
||||
String name67 = DefaultLoanProduct.LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_ACCRUAL_ACTIVITY.getName();
|
||||
PostLoanProductsRequest loanProductsRequestLP2AdvancedPaymentInterestEmi36030AccrualActivity = loanProductsRequestFactory
|
||||
.defaultLoanProductsRequestLP2Emi()//
|
||||
.name(name54)//
|
||||
.name(name67)//
|
||||
.enableAccrualActivityPosting(true)//
|
||||
.daysInYearType(DaysInYearType.DAYS360.value)//
|
||||
.daysInMonthType(DaysInMonthType.DAYS30.value)//
|
||||
@@ -1207,11 +1569,11 @@ public class LoanProductGlobalInitializerStep implements FineractGlobalInitializ
|
||||
|
||||
// LP2 with progressive loan schedule + horizontal + accelerate-maturity chargeOff behaviour
|
||||
// (LP2_ADV_PYMNT_ACCELERATE_MATURITY_CHARGE_OFF_BEHAVIOUR)
|
||||
final String name55 = DefaultLoanProduct.LP2_ADV_PYMNT_ACCELERATE_MATURITY_CHARGE_OFF_BEHAVIOUR.getName();
|
||||
final String name68 = DefaultLoanProduct.LP2_ADV_PYMNT_ACCELERATE_MATURITY_CHARGE_OFF_BEHAVIOUR.getName();
|
||||
|
||||
final PostLoanProductsRequest loanProductsRequestAdvCustomAccelerateMaturityChargeOffBehaviourProgressiveLoanSchedule = loanProductsRequestFactory
|
||||
final PostLoanProductsRequest loanProductsRequestAdvCustomAccelerateMaturityChargeOffBehaviourProgressiveLoanSchedule2 = loanProductsRequestFactory
|
||||
.defaultLoanProductsRequestLP2()//
|
||||
.name(name55)//
|
||||
.name(name68)//
|
||||
.enableDownPayment(false)//
|
||||
.enableAutoRepaymentForDownPayment(null)//
|
||||
.disbursedAmountPercentageForDownPayment(null)//
|
||||
@@ -1238,16 +1600,16 @@ public class LoanProductGlobalInitializerStep implements FineractGlobalInitializ
|
||||
createPaymentAllocation("MERCHANT_ISSUED_REFUND", "REAMORTIZATION"), //
|
||||
createPaymentAllocation("PAYOUT_REFUND", "NEXT_INSTALLMENT")))//
|
||||
.chargeOffBehaviour("ACCELERATE_MATURITY");//
|
||||
final Response<PostLoanProductsResponse> responseLoanProductsRequestAdvCustomAccelerateMaturityChargeOffBehaviourProgressiveLoanSchedule = loanProductsApi
|
||||
.createLoanProduct(loanProductsRequestAdvCustomAccelerateMaturityChargeOffBehaviourProgressiveLoanSchedule).execute();
|
||||
final Response<PostLoanProductsResponse> responseLoanProductsRequestAdvCustomAccelerateMaturityChargeOffBehaviourProgressiveLoanSchedule2 = loanProductsApi
|
||||
.createLoanProduct(loanProductsRequestAdvCustomAccelerateMaturityChargeOffBehaviourProgressiveLoanSchedule2).execute();
|
||||
TestContext.INSTANCE.set(TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_ACCELERATE_MATURITY_CHARGE_OFF_BEHAVIOUR,
|
||||
responseLoanProductsRequestAdvCustomAccelerateMaturityChargeOffBehaviourProgressiveLoanSchedule);
|
||||
responseLoanProductsRequestAdvCustomAccelerateMaturityChargeOffBehaviourProgressiveLoanSchedule2);
|
||||
|
||||
// LP2 with disabled interest recalculation + chargeback allocation(INTEREST, PENALTY, FEE, PRINCIPAL)
|
||||
// (LP2_NO_INTEREST_RECALCULATION_CHARGEBACK_ALLOCATION_INTEREST_FIRST)
|
||||
String name56 = DefaultLoanProduct.LP2_NO_INTEREST_RECALCULATION_CHARGEBACK_ALLOCATION_INTEREST_FIRST.getName();
|
||||
String name69 = DefaultLoanProduct.LP2_NO_INTEREST_RECALCULATION_CHARGEBACK_ALLOCATION_INTEREST_FIRST.getName();
|
||||
PostLoanProductsRequest loanProductsRequestChargebackAllocation = loanProductsRequestFactory.defaultLoanProductsRequestLP2Emi()//
|
||||
.name(name56)//
|
||||
.name(name69)//
|
||||
.daysInYearType(DaysInYearType.DAYS360.value)//
|
||||
.daysInMonthType(DaysInMonthType.DAYS30.value)//
|
||||
.creditAllocation(List.of(//
|
||||
@@ -1265,10 +1627,10 @@ public class LoanProductGlobalInitializerStep implements FineractGlobalInitializ
|
||||
|
||||
// LP2 with disabled interest recalculation + chargeback allocation(PRINCIPAL, INTEREST, PENALTY, FEE)
|
||||
// (LP2_NO_INTEREST_RECALCULATION_CHARGEBACK_ALLOCATION_PRINCIPAL_FIRST)
|
||||
String name57 = DefaultLoanProduct.LP2_NO_INTEREST_RECALCULATION_CHARGEBACK_ALLOCATION_PRINCIPAL_FIRST.getName();
|
||||
String name70 = DefaultLoanProduct.LP2_NO_INTEREST_RECALCULATION_CHARGEBACK_ALLOCATION_PRINCIPAL_FIRST.getName();
|
||||
PostLoanProductsRequest loanProductsRequestChargebackAllocationPrincipalFirst = loanProductsRequestFactory
|
||||
.defaultLoanProductsRequestLP2Emi()//
|
||||
.name(name57)//
|
||||
.name(name70)//
|
||||
.daysInYearType(DaysInYearType.DAYS360.value)//
|
||||
.daysInMonthType(DaysInMonthType.DAYS30.value)//
|
||||
.creditAllocation(List.of(//
|
||||
|
||||
+8
@@ -251,6 +251,14 @@ public class EventCheckHelper {
|
||||
return targetTransaction;
|
||||
}
|
||||
|
||||
public GetLoansLoanIdTransactions findNthTransaction(String nthItemStr, String transactionType, String transactionDate, long loanId)
|
||||
throws IOException {
|
||||
List<GetLoansLoanIdTransactions> transactions = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute().body()
|
||||
.getTransactions();
|
||||
GetLoansLoanIdTransactions targetTransaction = getNthTransactionType(nthItemStr, transactionType, transactionDate, transactions);
|
||||
return targetTransaction;
|
||||
}
|
||||
|
||||
public void checkTransactionWithLoanTransactionAdjustmentBizEvent(GetLoansLoanIdTransactions transaction) {
|
||||
EventAssertion.EventAssertionBuilder<LoanTransactionAdjustmentDataV1> eventAssertionBuilder = eventAssertion
|
||||
.assertEvent(LoanAdjustTransactionBusinessEvent.class, transaction.getId());
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* 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.test.messaging.event.loan.transaction;
|
||||
|
||||
public class LoanChargeAdjustmentPostBusinessEvent extends AbstractLoanTransactionEvent {
|
||||
|
||||
@Override
|
||||
public String getEventName() {
|
||||
return "LoanChargeAdjustmentPostBusinessEvent";
|
||||
}
|
||||
}
|
||||
+10
@@ -52,6 +52,16 @@ public class SchedulerStepDef extends AbstractStepDef {
|
||||
jobService.executeAndWait(DefaultJob.LOAN_DELINQUENCY_CLASSIFICATION);
|
||||
}
|
||||
|
||||
@When("Admin runs the Add Accrual Transactions For Loans With Income Posted As Transactions job")
|
||||
public void runAddAccrualTransactionsForLoansWithIncomePostedAsTransactions() {
|
||||
jobService.executeAndWait(DefaultJob.ADD_ACCRUAL_TRANSACTIONS_FOR_LOANS_WITH_INCOME_POSTED_AS_TRANSACTIONS);
|
||||
}
|
||||
|
||||
@When("Admin runs the Recalculate Interest for Loans job")
|
||||
public void runRecalculateInterestForLoans() {
|
||||
jobService.executeAndWait(DefaultJob.RECALCULATE_INTEREST_FOR_LOANS);
|
||||
}
|
||||
|
||||
@When("Admin runs COB job")
|
||||
public void runCOB() {
|
||||
jobService.executeAndWait(DefaultJob.LOAN_COB);
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ public class LoanInterestPauseStepDef extends AbstractStepDef {
|
||||
@Autowired
|
||||
private LoanInterestPauseApi loanInterestPauseApi;
|
||||
|
||||
@And("Create interest pause period with start date {string} and end date {string}")
|
||||
@And("Create an interest pause period with start date {string} and end date {string}")
|
||||
public void createInterestPause(final String startDate, final String endDate) throws IOException {
|
||||
final Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
assert loanResponse.body() != null;
|
||||
|
||||
+38
@@ -21,6 +21,7 @@ package org.apache.fineract.test.stepdef.loan;
|
||||
import static org.apache.fineract.test.data.paymenttype.DefaultPaymentType.AUTOPAY;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import io.cucumber.java.en.And;
|
||||
import io.cucumber.java.en.Then;
|
||||
import io.cucumber.java.en.When;
|
||||
@@ -51,6 +52,7 @@ import org.apache.fineract.client.models.PostUsersResponse;
|
||||
import org.apache.fineract.client.services.LoanTransactionsApi;
|
||||
import org.apache.fineract.client.services.LoansApi;
|
||||
import org.apache.fineract.client.services.UsersApi;
|
||||
import org.apache.fineract.client.util.JSON;
|
||||
import org.apache.fineract.test.data.TransactionType;
|
||||
import org.apache.fineract.test.data.paymenttype.DefaultPaymentType;
|
||||
import org.apache.fineract.test.data.paymenttype.PaymentTypeResolver;
|
||||
@@ -79,6 +81,8 @@ public class LoanRepaymentStepDef extends AbstractStepDef {
|
||||
public static final String DEFAULT_REPAYMENT_TYPE = "AUTOPAY";
|
||||
private static final String PWD_USER_WITH_ROLE = "1234567890Aa!";
|
||||
|
||||
private static final Gson GSON = new JSON().getGson();
|
||||
|
||||
@Autowired
|
||||
private LoanTransactionsApi loanTransactionsApi;
|
||||
|
||||
@@ -446,6 +450,40 @@ public class LoanRepaymentStepDef extends AbstractStepDef {
|
||||
eventCheckHelper.loanBalanceChangedEventCheck(loanId);
|
||||
}
|
||||
|
||||
@Then("Customer is forbidden to undo {string}th {string} transaction made on {string}")
|
||||
public void makeTransactionUndoForbidden(String nthItemStr, String transactionType, String transactionDate) throws IOException {
|
||||
eventStore.reset();
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
GetLoansLoanIdTransactions targetTransaction = eventCheckHelper.findNthTransaction(nthItemStr, transactionType, transactionDate,
|
||||
loanId);
|
||||
|
||||
PostLoansLoanIdTransactionsTransactionIdRequest transactionUndoRequest = LoanRequestFactory.defaultTransactionUndoRequest()
|
||||
.transactionDate(transactionDate);
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> transactionUndoResponse = loanTransactionsApi
|
||||
.adjustLoanTransaction(loanId, targetTransaction.getId(), transactionUndoRequest, "").execute();
|
||||
|
||||
String string = transactionUndoResponse.errorBody().string();
|
||||
ErrorResponse errorResponse = GSON.fromJson(string, ErrorResponse.class);
|
||||
Integer httpStatusCodeActual = errorResponse.getHttpStatusCode();
|
||||
String developerMessageActual = errorResponse.getErrors().get(0).getDeveloperMessage();
|
||||
|
||||
Integer httpStatusCodeExpected = 403;
|
||||
String developerMessageExpected = String.format("Interest refund transaction: %s cannot be reversed or adjusted directly",
|
||||
targetTransaction.getId());
|
||||
|
||||
assertThat(httpStatusCodeActual)
|
||||
.as(ErrorMessageHelper.wrongErrorCodeInFailedChargeAdjustment(httpStatusCodeActual, httpStatusCodeExpected))
|
||||
.isEqualTo(httpStatusCodeExpected);
|
||||
assertThat(developerMessageActual)
|
||||
.as(ErrorMessageHelper.wrongErrorMessageInFailedChargeAdjustment(developerMessageActual, developerMessageExpected))
|
||||
.isEqualTo(developerMessageExpected);
|
||||
|
||||
log.debug("Error code: {}", httpStatusCodeActual);
|
||||
log.debug("Error message: {}", developerMessageActual);
|
||||
}
|
||||
|
||||
@When("Customer undo {string}th {string} transaction made on {string} with linked {string} transaction")
|
||||
public void checkNthTransactionType(String nthItemStr, String transactionType, String transactionDate, String linkedTransactionType)
|
||||
throws IOException {
|
||||
|
||||
+216
-3
@@ -22,6 +22,7 @@ import static org.apache.fineract.test.data.TransactionProcessingStrategyCode.AD
|
||||
import static org.apache.fineract.test.data.loanproduct.DefaultLoanProduct.LP2_ADV_PYMNT_ACCELERATE_MATURITY_CHARGE_OFF_BEHAVIOUR;
|
||||
import static org.apache.fineract.test.data.loanproduct.DefaultLoanProduct.LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR;
|
||||
import static org.apache.fineract.test.data.loanproduct.DefaultLoanProduct.LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR;
|
||||
import static org.apache.fineract.test.factory.LoanProductsRequestFactory.CHARGE_OFF_REASONS;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.awaitility.Awaitility.await;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
@@ -55,6 +56,7 @@ import org.apache.fineract.avro.loan.v1.LoanChargePaidByDataV1;
|
||||
import org.apache.fineract.avro.loan.v1.LoanStatusEnumDataV1;
|
||||
import org.apache.fineract.avro.loan.v1.LoanTransactionDataV1;
|
||||
import org.apache.fineract.client.models.AdvancedPaymentData;
|
||||
import org.apache.fineract.client.models.CommandProcessingResult;
|
||||
import org.apache.fineract.client.models.DeleteLoansLoanIdResponse;
|
||||
import org.apache.fineract.client.models.GetLoanProductsChargeOffReasonOptions;
|
||||
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
|
||||
@@ -70,6 +72,7 @@ import org.apache.fineract.client.models.GetLoansLoanIdResponse;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdTimeline;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdTransactions;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdTransactionsTransactionIdResponse;
|
||||
import org.apache.fineract.client.models.InterestPauseRequestDto;
|
||||
import org.apache.fineract.client.models.IsCatchUpRunningResponse;
|
||||
import org.apache.fineract.client.models.PaymentAllocationOrder;
|
||||
import org.apache.fineract.client.models.PostClientsResponse;
|
||||
@@ -85,6 +88,7 @@ import org.apache.fineract.client.models.PutLoanProductsProductIdResponse;
|
||||
import org.apache.fineract.client.models.PutLoansLoanIdRequest;
|
||||
import org.apache.fineract.client.models.PutLoansLoanIdResponse;
|
||||
import org.apache.fineract.client.services.LoanCobCatchUpApi;
|
||||
import org.apache.fineract.client.services.LoanInterestPauseApi;
|
||||
import org.apache.fineract.client.services.LoanProductsApi;
|
||||
import org.apache.fineract.client.services.LoanTransactionsApi;
|
||||
import org.apache.fineract.client.services.LoansApi;
|
||||
@@ -98,11 +102,15 @@ import org.apache.fineract.test.data.LoanTermFrequencyType;
|
||||
import org.apache.fineract.test.data.RepaymentFrequencyType;
|
||||
import org.apache.fineract.test.data.TransactionProcessingStrategyCode;
|
||||
import org.apache.fineract.test.data.TransactionType;
|
||||
import org.apache.fineract.test.data.codevalue.CodeValue;
|
||||
import org.apache.fineract.test.data.codevalue.CodeValueResolver;
|
||||
import org.apache.fineract.test.data.codevalue.DefaultCodeValue;
|
||||
import org.apache.fineract.test.data.loanproduct.DefaultLoanProduct;
|
||||
import org.apache.fineract.test.data.loanproduct.LoanProductResolver;
|
||||
import org.apache.fineract.test.data.paymenttype.DefaultPaymentType;
|
||||
import org.apache.fineract.test.data.paymenttype.PaymentTypeResolver;
|
||||
import org.apache.fineract.test.factory.LoanRequestFactory;
|
||||
import org.apache.fineract.test.helper.CodeHelper;
|
||||
import org.apache.fineract.test.helper.ErrorHelper;
|
||||
import org.apache.fineract.test.helper.ErrorMessageHelper;
|
||||
import org.apache.fineract.test.helper.ErrorResponse;
|
||||
@@ -113,6 +121,7 @@ import org.apache.fineract.test.messaging.event.EventCheckHelper;
|
||||
import org.apache.fineract.test.messaging.event.loan.LoanRescheduledDueAdjustScheduleEvent;
|
||||
import org.apache.fineract.test.messaging.event.loan.LoanStatusChangedEvent;
|
||||
import org.apache.fineract.test.messaging.event.loan.transaction.LoanAccrualTransactionCreatedBusinessEvent;
|
||||
import org.apache.fineract.test.messaging.event.loan.transaction.LoanChargeAdjustmentPostBusinessEvent;
|
||||
import org.apache.fineract.test.messaging.event.loan.transaction.LoanChargeOffEvent;
|
||||
import org.apache.fineract.test.messaging.event.loan.transaction.LoanChargeOffUndoEvent;
|
||||
import org.apache.fineract.test.messaging.event.loan.transaction.LoanTransactionAccrualActivityPostEvent;
|
||||
@@ -170,6 +179,15 @@ public class LoanStepDef extends AbstractStepDef {
|
||||
@Autowired
|
||||
private EventStore eventStore;
|
||||
|
||||
@Autowired
|
||||
private CodeValueResolver codeValueResolver;
|
||||
|
||||
@Autowired
|
||||
private CodeHelper codeHelper;
|
||||
|
||||
@Autowired
|
||||
private LoanInterestPauseApi loanInterestPauseApi;
|
||||
|
||||
@When("Admin creates a new Loan")
|
||||
public void createLoan() throws IOException {
|
||||
Response<PostClientsResponse> clientResponse = testContext().get(TestContextKey.CLIENT_CREATE_RESPONSE);
|
||||
@@ -1405,6 +1423,60 @@ public class LoanStepDef extends AbstractStepDef {
|
||||
.isEqualTo(loanId).extractingData(LoanTransactionDataV1::getId).isEqualTo(chargeOffResponse.body().getResourceId());
|
||||
}
|
||||
|
||||
@Then("Backdated charge-off on a date {string} is forbidden")
|
||||
public void chargeOffBackdatedForbidden(String transactionDate) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
PostLoansLoanIdTransactionsRequest chargeOffRequest = LoanRequestFactory.defaultChargeOffRequest().transactionDate(transactionDate)
|
||||
.dateFormat(DATE_FORMAT).locale(DEFAULT_LOCALE);
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> chargeOffResponse = loanTransactionsApi
|
||||
.executeLoanTransaction(loanId, chargeOffRequest, "charge-off").execute();
|
||||
testContext().set(TestContextKey.LOAN_CHARGE_OFF_RESPONSE, chargeOffResponse);
|
||||
|
||||
assertThat(chargeOffResponse.isSuccessful()).isFalse();
|
||||
|
||||
String string = chargeOffResponse.errorBody().string();
|
||||
ErrorResponse errorResponse = GSON.fromJson(string, ErrorResponse.class);
|
||||
|
||||
Integer httpStatusCodeActual = errorResponse.getHttpStatusCode();
|
||||
String developerMessageActual = errorResponse.getErrors().get(0).getDeveloperMessage();
|
||||
|
||||
Integer httpStatusCodeExpected = 403;
|
||||
String developerMessageExpected = String.format(
|
||||
"Loan: %s charge-off cannot be executed. Loan has monetary activity after the charge-off transaction date!", loanId);
|
||||
|
||||
assertThat(httpStatusCodeActual)
|
||||
.as(ErrorMessageHelper.wrongErrorCodeInFailedChargeAdjustment(httpStatusCodeActual, httpStatusCodeExpected))
|
||||
.isEqualTo(httpStatusCodeExpected);
|
||||
assertThat(developerMessageActual)
|
||||
.as(ErrorMessageHelper.wrongErrorMessageInFailedChargeAdjustment(developerMessageActual, developerMessageExpected))
|
||||
.isEqualTo(developerMessageExpected);
|
||||
}
|
||||
|
||||
@And("Admin does charge-off the loan with reason {string} on {string}")
|
||||
public void chargeOffLoan(String chargeOffReason, String transactionDate) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
final CodeValue chargeOffReasonCodeValue = DefaultCodeValue.valueOf(chargeOffReason);
|
||||
Long chargeOffReasonCodeId = codeHelper.retrieveCodeByName(CHARGE_OFF_REASONS).getId();
|
||||
long chargeOffReasonId = codeValueResolver.resolve(chargeOffReasonCodeId, chargeOffReasonCodeValue);
|
||||
|
||||
PostLoansLoanIdTransactionsRequest chargeOffRequest = LoanRequestFactory.defaultChargeOffRequest()
|
||||
.chargeOffReasonId(chargeOffReasonId).transactionDate(transactionDate).dateFormat(DATE_FORMAT).locale(DEFAULT_LOCALE);
|
||||
|
||||
Response<PostLoansLoanIdTransactionsResponse> chargeOffResponse = loanTransactionsApi
|
||||
.executeLoanTransaction(loanId, chargeOffRequest, "charge-off").execute();
|
||||
testContext().set(TestContextKey.LOAN_CHARGE_OFF_RESPONSE, chargeOffResponse);
|
||||
ErrorHelper.checkSuccessfulApiCall(chargeOffResponse);
|
||||
|
||||
Long transactionId = chargeOffResponse.body().getResourceId();
|
||||
eventAssertion.assertEvent(LoanChargeOffEvent.class, transactionId).extractingData(LoanTransactionDataV1::getLoanId)
|
||||
.isEqualTo(loanId).extractingData(LoanTransactionDataV1::getId).isEqualTo(chargeOffResponse.body().getResourceId());
|
||||
}
|
||||
|
||||
@And("Admin tries to charge-off the loan on {string} but fails due to monetary activity after the charge-off date")
|
||||
public void chargeOffLoanWithError(final String transactionDate) throws IOException {
|
||||
final Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
@@ -1573,6 +1645,23 @@ public class LoanStepDef extends AbstractStepDef {
|
||||
log.debug("Error message: {}", developerMessage);
|
||||
}
|
||||
|
||||
@Then("Admin fails to disburse the loan on {string} with {string} EUR transaction amount because of charge-off that was performed for the loan")
|
||||
public void disburseChargedOffLoanFailure(String actualDisbursementDate, String transactionAmount) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
PostLoansLoanIdRequest disburseRequest = LoanRequestFactory.defaultLoanDisburseRequest()
|
||||
.actualDisbursementDate(actualDisbursementDate).transactionAmount(new BigDecimal(transactionAmount));
|
||||
|
||||
Response<PostLoansLoanIdResponse> loanDisburseResponse = loansApi.stateTransitions(loanId, disburseRequest, "disburse").execute();
|
||||
testContext().set(TestContextKey.LOAN_DISBURSE_RESPONSE, loanDisburseResponse);
|
||||
ErrorResponse errorDetails = ErrorResponse.from(loanDisburseResponse);
|
||||
String developerMessage = errorDetails.getSingleError().getDeveloperMessage();
|
||||
|
||||
assertThat(errorDetails.getHttpStatusCode()).as(ErrorMessageHelper.dateFailureErrorCodeMsg()).isEqualTo(403);
|
||||
assertThat(developerMessage).matches(ErrorMessageHelper.disburseChargedOffLoanFailure());
|
||||
log.debug("Error message: {}", developerMessage);
|
||||
}
|
||||
|
||||
@Then("Loan has {double} outstanding amount")
|
||||
public void loanOutstanding(double totalOutstandingExpected) throws IOException {
|
||||
Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
@@ -1795,6 +1884,57 @@ public class LoanStepDef extends AbstractStepDef {
|
||||
assertThat(isReverted).as(ErrorMessageHelper.transactionIsNotReversedError(isReverted, false)).isEqualTo(false);
|
||||
}
|
||||
|
||||
@Then("In Loan Transactions the {string}th Transaction with type={string} and date {string} has non-null external-id")
|
||||
public void loanTransactionsNthTransactionHasNonNullExternalId(String nthTransactionStr, String transactionType, String transactionDate)
|
||||
throws IOException {
|
||||
Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanCreateResponse.body().getLoanId();
|
||||
|
||||
Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse);
|
||||
|
||||
List<GetLoansLoanIdTransactions> transactions = loanDetailsResponse.body().getTransactions();
|
||||
int nthItem = Integer.parseInt(nthTransactionStr) - 1;
|
||||
GetLoansLoanIdTransactions targetTransaction = transactions//
|
||||
.stream()//
|
||||
.filter(t -> transactionDate.equals(FORMATTER.format(t.getDate())) && transactionType.equals(t.getType().getValue()))//
|
||||
.toList().get(nthItem);//
|
||||
|
||||
assertThat(targetTransaction.getExternalId()).as(ErrorMessageHelper.transactionHasNullResourceValue(transactionType, "external-id"))
|
||||
.isNotNull();
|
||||
testContext().set(TestContextKey.LOAN_TRANSACTION_RESPONSE, targetTransaction);
|
||||
}
|
||||
|
||||
@Then("In Loan Transactions all transactions have non-null external-id")
|
||||
public void loanTransactionsHaveNonNullExternalId() throws IOException {
|
||||
Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanCreateResponse.body().getLoanId();
|
||||
|
||||
Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse);
|
||||
|
||||
List<GetLoansLoanIdTransactions> transactions = loanDetailsResponse.body().getTransactions();
|
||||
|
||||
assertThat(transactions.stream().allMatch(transaction -> transaction.getExternalId() != null))
|
||||
.as(ErrorMessageHelper.transactionHasNullResourceValue("", "external-id")).isTrue();
|
||||
}
|
||||
|
||||
@Then("Check required transaction for non-null eternal-id")
|
||||
public void loanTransactionHasNonNullExternalId() throws IOException {
|
||||
Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanCreateResponse.body().getLoanId();
|
||||
|
||||
GetLoansLoanIdTransactions targetTransaction = testContext().get(TestContextKey.LOAN_TRANSACTION_RESPONSE);
|
||||
Long targetTransactionId = targetTransaction.getId();
|
||||
|
||||
Response<GetLoansLoanIdTransactionsTransactionIdResponse> transactionResponse = loanTransactionsApi
|
||||
.retrieveTransaction(loanId, targetTransactionId, "").execute();
|
||||
|
||||
GetLoansLoanIdTransactionsTransactionIdResponse transaction = transactionResponse.body();
|
||||
assertThat(transaction.getExternalId())
|
||||
.as(ErrorMessageHelper.transactionHasNullResourceValue(transaction.getType().getCode(), "external-id")).isNotNull();
|
||||
}
|
||||
|
||||
@Then("Loan Charges tab has a given charge with the following data:")
|
||||
public void loanChargesGivenChargeDataCheck(DataTable table) throws IOException {
|
||||
Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
@@ -2186,6 +2326,37 @@ public class LoanStepDef extends AbstractStepDef {
|
||||
eventAssertion.assertEventRaised(LoanAccrualTransactionCreatedBusinessEvent.class, accrualTransactionId);
|
||||
}
|
||||
|
||||
@Then("LoanChargeAdjustmentPostBusinessEvent is raised on {string}")
|
||||
public void checkLoanChargeAdjustmentPostBusinessEvent(String date) throws IOException {
|
||||
Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanCreateResponse.body().getLoanId();
|
||||
|
||||
Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse);
|
||||
|
||||
List<GetLoansLoanIdTransactions> transactions = loanDetailsResponse.body().getTransactions();
|
||||
|
||||
GetLoansLoanIdTransactions loadTransaction = transactions.stream()
|
||||
.filter(t -> date.equals(FORMATTER.format(t.getDate())) && "Charge Adjustment".equals(t.getType().getValue())).findFirst()
|
||||
.orElseThrow(() -> new IllegalStateException(String.format("No Charge Adjustment transaction found on %s", date)));
|
||||
|
||||
eventAssertion.assertEventRaised(LoanChargeAdjustmentPostBusinessEvent.class, loadTransaction.getId());
|
||||
}
|
||||
|
||||
@Then("LoanAccrualTransactionCreatedBusinessEvent is not raised on {string}")
|
||||
public void checkLoanAccrualTransactionNotCreatedBusinessEvent(String date) throws IOException {
|
||||
Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanCreateResponse.body().getLoanId();
|
||||
|
||||
Response<GetLoansLoanIdResponse> loanDetailsResponse = loansApi.retrieveLoan(loanId, false, "transactions", "", "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(loanDetailsResponse);
|
||||
|
||||
List<GetLoansLoanIdTransactions> transactions = loanDetailsResponse.body().getTransactions();
|
||||
|
||||
assertThat(transactions).as("Unexpected Accrual activity transaction found on %s", date)
|
||||
.noneMatch(t -> date.equals(FORMATTER.format(t.getDate())) && "Accrual Activity".equals(t.getType().getValue()));
|
||||
}
|
||||
|
||||
@Then("LoanTransactionAccrualActivityPostBusinessEvent is raised on {string}")
|
||||
public void checkLoanTransactionAccrualActivityPostBusinessEvent(String date) throws IOException {
|
||||
Response<PostLoansResponse> loanCreateResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
@@ -2475,6 +2646,18 @@ public class LoanStepDef extends AbstractStepDef {
|
||||
.isEqualTo(expectedAmountParsed);
|
||||
}
|
||||
|
||||
@Then("Create interest pause period with start date {string} and end date {string}")
|
||||
public void interestPauseCreate(final String startDate, final String endDate) throws IOException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
final InterestPauseRequestDto interestPauseRequest = LoanRequestFactory.defaultInterestPauseRequest().startDate(startDate)
|
||||
.endDate(endDate);
|
||||
final Response<CommandProcessingResult> interestPauseResponse = loanInterestPauseApi
|
||||
.createInterestPause(loanId, interestPauseRequest).execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(interestPauseResponse);
|
||||
}
|
||||
|
||||
@Then("LoanDetails has fixedLength field with int value: {int}")
|
||||
public void checkLoanDetailsFieldAndValueInt(int fieldValue) throws IOException, NoSuchMethodException {
|
||||
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
@@ -2790,13 +2973,43 @@ public class LoanStepDef extends AbstractStepDef {
|
||||
|
||||
@When("Admin creates a new zero charge-off Loan with interest recalculation and date: {string}")
|
||||
public void createLoanWithInterestRecalculationAndZeroChargeOffBehaviour(final String date) throws IOException {
|
||||
createLoanWithLoanBehaviour(date, true, DefaultLoanProduct
|
||||
.valueOf(LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR.getName()));
|
||||
createLoanWithZeroChargeOffBehaviour(date, true);
|
||||
}
|
||||
|
||||
@When("Admin creates a new zero charge-off Loan without interest recalculation and with date: {string}")
|
||||
public void createLoanWithoutInterestRecalculationAndZeroChargeOffBehaviour(final String date) throws IOException {
|
||||
createLoanWithLoanBehaviour(date, false, DefaultLoanProduct.valueOf(LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR.getName()));
|
||||
createLoanWithZeroChargeOffBehaviour(date, false);
|
||||
}
|
||||
|
||||
private void createLoanWithZeroChargeOffBehaviour(final String date, final boolean isInterestRecalculation) throws IOException {
|
||||
final Response<PostClientsResponse> clientResponse = testContext().get(TestContextKey.CLIENT_CREATE_RESPONSE);
|
||||
final Long clientId = clientResponse.body().getClientId();
|
||||
|
||||
final DefaultLoanProduct product = isInterestRecalculation
|
||||
? DefaultLoanProduct
|
||||
.valueOf(LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR.getName())
|
||||
: DefaultLoanProduct.valueOf(LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR.getName());
|
||||
|
||||
final Long loanProductId = loanProductResolver.resolve(product);
|
||||
|
||||
final PostLoansRequest loansRequest = loanRequestFactory.defaultLoansRequest(clientId).productId(loanProductId)
|
||||
.principal(new BigDecimal(100)).numberOfRepayments(6).submittedOnDate(date).expectedDisbursementDate(date)
|
||||
.loanTermFrequency(6)//
|
||||
.loanTermFrequencyType(LoanTermFrequencyType.MONTHS.value)//
|
||||
.repaymentEvery(1)//
|
||||
.repaymentFrequencyType(RepaymentFrequencyType.MONTHS.value)//
|
||||
.interestRateFrequencyType(3)//
|
||||
.interestRatePerPeriod(new BigDecimal(7))//
|
||||
.interestType(InterestType.DECLINING_BALANCE.value)//
|
||||
.interestCalculationPeriodType(isInterestRecalculation ? InterestCalculationPeriodTime.DAILY.value
|
||||
: InterestCalculationPeriodTime.SAME_AS_REPAYMENT_PERIOD.value)//
|
||||
.transactionProcessingStrategyCode(ADVANCED_PAYMENT_ALLOCATION.value);
|
||||
|
||||
final Response<PostLoansResponse> response = loansApi.calculateLoanScheduleOrSubmitLoanApplication(loansRequest, "").execute();
|
||||
testContext().set(TestContextKey.LOAN_CREATE_RESPONSE, response);
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
|
||||
eventCheckHelper.createLoanEventCheck(response);
|
||||
}
|
||||
|
||||
@When("Admin creates a new accelerate maturity charge-off Loan without interest recalculation and with date: {string}")
|
||||
|
||||
+16
-3
@@ -85,11 +85,12 @@ public abstract class TestContextKey {
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_DOWNPAYMENT_ADV_PMT_ALLOC_FIXED_LENGTH = "loanProductCreateResponseLP2DownPaymentProgressiveLoanScheduleFixedLength";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_DOWNPAYMENT_INTEREST_FLAT_ADV_PMT_ALLOC = "loanProductCreateResponseLP2DownPaymentInterestFlatAdvancedPaymentAllocation";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_RECALCULATION_DAILY_EMI_360_30_MULTIDISBURSE_DOWNPAYMENT = "loanProductCreateResponseLP2AdvancedPaymentInterestRecalculationDailyEmi36030MultiDisburseDownPayment";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_RECALCULATION_DAILY_EMI_360_30_MULTIDISBURSE_AUTO_DOWNPAYMENT = "loanProductCreateResponseLP2AdvancedPaymentInterestRecalculationDailyEmi36030MultiDisburseEnabledDownPayment";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_ACTUAL_ACTUAL = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmiActualActual";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_ACCRUAL_ACTIVITY = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmiActualActualAccrualActivity";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_ACCRUAL_ACTIVITY = "loanProductCreateResponseLP2AdvancedPaymentInterestEmi36030AccrualActivity";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30 = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY_TILL_PRECLOSE = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030InterestRecalculationDailyTillPreClose";
|
||||
public static final String temp = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030InterestRecalculationDailyNoCalcOnPastDueTillPreClose";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY_TILL_PRECLOSE_LAST_INSTALLMENT = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030InterestRecalculationDailyTillPreCloseLastInstallment";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY_TILL_PRECLOSE_PMT_ALLOC_1 = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030InterestRecalculationDailyTillPreClosePmtAlloc1";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_SAME_AS_REP_TILL_PRECLOSE = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030InterestRecalculationSameAsRepTillPreClose";
|
||||
@@ -97,18 +98,31 @@ public abstract class TestContextKey {
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_SAME_AS_REP_TILL_REST_FREQUENCY_DATE = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030InterestRecalculationSameAsRepTillRestFrequencyDate";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_REFUND_FULL = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmiActualActualInterestRefundFull";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_MULTIDISBURSE = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030MultiDisburse";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADVANCED_PAYMENT_ALLOCATION_INTEREST_RECALCULATION_DAILY_NO_CALC_ON_PAST_DUE_EMI_360_30_MULTIDISBURSE = "loanProductCreateResponseLP2AdvancedPaymentAllocationInterestRecalculationDailyNoCalcOnPastDueEmi36030MultiDisburse";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADVANCED_CUSTOM_PAYMENT_ALLOCATION_INTEREST_RECALCULATION_DAILY_EMI_360_30_MULTIDISBURSE = "loanProductCreateResponseLP2AdvancedCustomPaymentInterestRecalculationDailyEmi36030MultiDisburse";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_MULTIDISBURSE_DOWNPAYMENT = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030MultiDisburseDownPayment";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_365_ACTUAL = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi365Actual";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_ACTUAL = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi360Actual";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_DOWNPAYMENT = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030DownPayment";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_REFUND = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmiActualActualInterestRefund";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP1_ADVANCED_PAYMENT_ALLOCATION_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL = "loanProductCreateResponseLP1ProgressiveLoanScheduleHorizontal";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY_TILL_PRECLOSE_WHOLE_TERM = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030InterestRecalculationSameAsRepTillPreCloseWholeTerm";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_REFUND_INTEREST_RECALCULATION = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmiActualActualInterestRefundFInterestRecalculation";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyInterestRecalculationZeroInterestChargeOffBehaviour";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ZERO_INTEREST_CHARGE_OFF = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyInterestRecalculationZeroInterestChargeOff";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR = "loanProductCreateResponseLP2AdvancedPaymentZeroInterestChargeOffBehaviour";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF = "loanProductCreateResponseLP2AdvancedPaymentZeroInterestChargeOff";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY_ALLOW_PARTIAL_PERIOD = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030InterestRecalculationDailyAllowPartialPeriod";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY_ACCRUAL_ACTIVITY_POSTING = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030InterestRecalculationDailyAccrualActivityPosting";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_CHARGEBACK_INTEREST_FEE_PRINCIPAL = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030ChargebackInterestFeePrincipal";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_CHARGEBACK_PRINCIPAL_INTEREST_FEE = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030ChargebackPrincipalInterestFee";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_CHARGEBACK_INTEREST_PENALTY_FEE_PRINCIPAL = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030ChargebackInterestPenaltyFeePrincipal";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_ACTUAL_ACTUAL_INTEREST_RECALCULATION_DAILY = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmiActualActualInterestRecalculationDaily";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ACCELERATE_MATURITY_CHARGE_OFF_BEHAVIOUR = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyInterestRecalculationAccelerateMaturityChargeOffBehaviour";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_ACCRUAL_ACTIVITY = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030AccrualActivity";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_ACCELERATE_MATURITY_CHARGE_OFF_BEHAVIOUR = "loanProductCreateResponseLP2AdvancedPaymentAccelerateMaturityChargeOffBehaviour";
|
||||
public static final String LP2_NO_INTEREST_RECALCULATION_CHARGEBACK_ALLOCATION_INTEREST_FIRST_RESPONSE = "loanProductCreateResponseLP2NoInterestRecalculationChargebackAllocationInterestFirst";
|
||||
public static final String LP2_NO_INTEREST_RECALCULATION_CHARGEBACK_ALLOCATION_PRINCIPAL_FIRST_RESPONSE = "loanProductCreateResponseLP2NoInterestRecalculationChargebackAllocationPrincipalFirst";
|
||||
public static final String CHARGE_FOR_LOAN_PERCENT_LATE_CREATE_RESPONSE = "ChargeForLoanPercentLateCreateResponse";
|
||||
public static final String CHARGE_FOR_LOAN_PERCENT_LATE_AMOUNT_PLUS_INTEREST_CREATE_RESPONSE = "ChargeForLoanPercentLateAmountPlusInterestCreateResponse";
|
||||
public static final String CHARGE_FOR_LOAN_PERCENT_PROCESSING_CREATE_RESPONSE = "ChargeForLoanPercentProcessingCreateResponse";
|
||||
@@ -159,6 +173,5 @@ public abstract class TestContextKey {
|
||||
public static final String TRANSACTION_EVENT = "transactionEvent";
|
||||
public static final String LOAN_WRITE_OFF_RESPONSE = "loanWriteOffResponse";
|
||||
public static final String LOAN_DELINQUENCY_ACTION_RESPONSE = "loanDelinquencyActionResponse";
|
||||
public static final String LP2_NO_INTEREST_RECALCULATION_CHARGEBACK_ALLOCATION_INTEREST_FIRST_RESPONSE = "loanProductCreateResponseLP2NoInterestRecalculationChargebackAllocationInterestFirst";
|
||||
public static final String LP2_NO_INTEREST_RECALCULATION_CHARGEBACK_ALLOCATION_PRINCIPAL_FIRST_RESPONSE = "loanProductCreateResponseLP2NoInterestRecalculationChargebackAllocationPrincipalFirst";
|
||||
public static final String LOAN_TRANSACTION_RESPONSE = "loanTransactionResponse";
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ Feature: Loan interest pause on repayment schedule
|
||||
And Admin successfully disburse the loan on "1 January 2024" with "100" EUR transaction amount
|
||||
When Admin sets the business date to "1 February 2024"
|
||||
And Customer makes "AUTOPAY" repayment on "01 February 2024" with 17.01 EUR transaction amount
|
||||
And Create interest pause period with start date "05 February 2024" and end date "10 February 2024"
|
||||
And Create an interest pause period with start date "05 February 2024" and end date "10 February 2024"
|
||||
Then Loan Repayment schedule has 6 periods, with the following data for periods:
|
||||
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||
| | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||
@@ -59,7 +59,7 @@ Feature: Loan interest pause on repayment schedule
|
||||
And Admin successfully disburse the loan on "1 January 2024" with "100" EUR transaction amount
|
||||
When Admin sets the business date to "1 February 2024"
|
||||
And Customer makes "AUTOPAY" repayment on "01 February 2024" with 17.01 EUR transaction amount
|
||||
And Create interest pause period with start date "10 February 2024" and end date "10 March 2024"
|
||||
And Create an interest pause period with start date "10 February 2024" and end date "10 March 2024"
|
||||
Then Loan Repayment schedule has 6 periods, with the following data for periods:
|
||||
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||
| | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||
@@ -113,7 +113,7 @@ Feature: Loan interest pause on repayment schedule
|
||||
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
|
||||
| 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | false |
|
||||
| 01 March 2024 | Repayment | 17.01 | 16.52 | 0.49 | 0.0 | 0.0 | 67.05 | false | false |
|
||||
And Create interest pause period with start date "05 February 2024" and end date "10 February 2024"
|
||||
And Create an interest pause period with start date "05 February 2024" and end date "10 February 2024"
|
||||
Then Loan Repayment schedule has 6 periods, with the following data for periods:
|
||||
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||
| | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||
@@ -172,7 +172,7 @@ Feature: Loan interest pause on repayment schedule
|
||||
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
|
||||
| 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | false |
|
||||
| 01 March 2024 | Repayment | 17.01 | 16.52 | 0.49 | 0.0 | 0.0 | 67.05 | false | false |
|
||||
And Create interest pause period with start date "05 February 2024" and end date "10 February 2024"
|
||||
And Create an interest pause period with start date "05 February 2024" and end date "10 February 2024"
|
||||
Then Loan Repayment schedule has 6 periods, with the following data for periods:
|
||||
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||
| | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||
@@ -190,7 +190,7 @@ Feature: Loan interest pause on repayment schedule
|
||||
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
|
||||
| 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | false |
|
||||
| 01 March 2024 | Repayment | 17.01 | 16.62 | 0.39 | 0.0 | 0.0 | 66.95 | false | true |
|
||||
And Create interest pause period with start date "10 March 2024" and end date "20 March 2024"
|
||||
And Create an interest pause period with start date "10 March 2024" and end date "20 March 2024"
|
||||
Then Loan Repayment schedule has 6 periods, with the following data for periods:
|
||||
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||
| | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||
@@ -230,7 +230,7 @@ Feature: Loan interest pause on repayment schedule
|
||||
And Admin successfully approves the loan on "1 January 2024" with "100" amount and expected disbursement date on "1 January 2024"
|
||||
And Admin successfully disburse the loan on "1 January 2024" with "100" EUR transaction amount
|
||||
When Admin runs inline COB job for Loan
|
||||
And Create interest pause period with start date "10 February 2024" and end date "10 March 2024"
|
||||
And Create an interest pause period with start date "10 February 2024" and end date "10 March 2024"
|
||||
Then Loan term variations has 1 variation, with the following data:
|
||||
| Term Type Id | Term Type Code | Term Type Value | Applicable From | Decimal Value | Date Value | Is Specific To Installment | Is Processed |
|
||||
| 11 | loanTermType.interestPause | interestPause | 10 February 2024 | 0.0 | 10 March 2024 | false | |
|
||||
@@ -356,7 +356,7 @@ Feature: Loan interest pause on repayment schedule
|
||||
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
||||
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
|
||||
| 14 January 2024 | Repayment | 17.01 | 16.77 | 0.24 | 0.0 | 0.0 | 83.23 | false | false |
|
||||
And Create interest pause period with start date "15 January 2024" and end date "25 January 2024"
|
||||
And Create an interest pause period with start date "15 January 2024" and end date "25 January 2024"
|
||||
Then Loan Repayment schedule has 6 periods, with the following data for periods:
|
||||
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||
| | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||
|
||||
@@ -186,16 +186,22 @@ Feature: LoanProduct
|
||||
When Admin sets the business date to "12 December 2021"
|
||||
When Admin creates a client with random data
|
||||
And Admin successfully creates a new customised Loan submitted on date: "12 December 2021", with Principal: "1000", a loanTermFrequency: 1 months, and numberOfRepayments: 1
|
||||
Then Loan Product Charge-Off reasons options from loan product template have 2 options, with the following data:
|
||||
Then Loan Product Charge-Off reasons options from loan product template have 5 options, with the following data:
|
||||
| Charge-Off Reason Name | Description | Position | Is Active | Is Mandatory |
|
||||
| debit_card | | 0 | true | false |
|
||||
| credit_card | | 1 | true | false |
|
||||
| Fraud | | 2 | true | false |
|
||||
| Delinquent | | 3 | true | false |
|
||||
| Other | | 4 | true | false |
|
||||
|
||||
Scenario: As a user I would like to verify Charge-Off reasons options in specific loan product response
|
||||
When Admin sets the business date to "12 December 2021"
|
||||
When Admin creates a client with random data
|
||||
And Admin successfully creates a new customised Loan submitted on date: "12 December 2021", with Principal: "1000", a loanTermFrequency: 1 months, and numberOfRepayments: 1
|
||||
Then Loan Product "LP1" Charge-Off reasons options from specific loan product have 2 options, with the following data:
|
||||
Then Loan Product "LP1" Charge-Off reasons options from specific loan product have 5 options, with the following data:
|
||||
| Charge-Off Reason Name | Description | Position | Is Active | Is Mandatory |
|
||||
| debit_card | | 0 | true | false |
|
||||
| credit_card | | 1 | true | false |
|
||||
| credit_card | | 1 | true | false |
|
||||
| Fraud | | 2 | true | false |
|
||||
| Delinquent | | 3 | true | false |
|
||||
| Other | | 4 | true | false |
|
||||
|
||||
Reference in New Issue
Block a user