FINERACT-1981: Progressive Loan schedule handling - Installment charges

This commit is contained in:
mariiaKraievska
2025-07-08 23:22:50 +02:00
committed by Adam Saghy
parent f76a65ed99
commit d165a3feda
22 changed files with 2484 additions and 89 deletions
@@ -28,12 +28,15 @@ public enum ChargeProductType {
LOAN_NSF_FEE(6L), //
LOAN_DISBURSEMENT_PERCENTAGE_FEE(7L), //
LOAN_TRANCHE_DISBURSEMENT_PERCENTAGE_FEE(8L), //
LOAN_INSTALLMENT_PERCENTAGE_FEE(9L), //
LOAN_INSTALLMENT_FEE_PERCENTAGE_AMOUNT_PLUS_INTEREST(9L), //
LOAN_PERCENTAGE_LATE_FEE_AMOUNT_PLUS_INTEREST(10L), //
CLIENT_TEST_CHARGE_FEE(11L), //
LOAN_DISBURSEMENT_CHARGE(12L), //
CHARGE_LOAN_TRANCHE_DISBURSEMENT_CHARGE_AMOUNT(13L), //
CHARGE_LOAN_TRANCHE_DISBURSEMENT_CHARGE_PERCENT(14L); //
CHARGE_LOAN_TRANCHE_DISBURSEMENT_CHARGE_PERCENT(14L), //
LOAN_INSTALLMENT_FEE_FLAT(15L), //
LOAN_INSTALLMENT_FEE_PERCENTAGE_AMOUNT(16L), //
LOAN_INSTALLMENT_FEE_PERCENTAGE_INTEREST(17L); //
public final Long value;
@@ -138,6 +138,12 @@ public enum DefaultLoanProduct implements LoanProduct {
LP2_ADV_PYMNT_INTEREST_DAILY_RECALC_EMI_360_30_APPROVED_OVER_APPLIED_FLAT_CAPITALIZED_INCOME, //
LP2_ADV_PYMNT_INTEREST_DAILY_RECALC_EMI_360_30_MULTIDISB_CAPITALIZED_INCOME_ADJ_CUSTOM_ALLOC, //
LP2_ADV_PYMNT_360_30_INTEREST_RECALC_AUTO_DOWNPAYMENT_ZERO_INTEREST_CHARGE_OFF_ACCRUAL_ACTIVITY, //
LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALC_DAILY_INSTALLMENT_FEE_FLAT_CHARGES, //
LP2_ADV_PYMNT_INTEREST_DAILY_INSTALLMENT_FEE_PERCENT_AMOUNT_CHARGES, //
LP2_ADV_PYMNT_INTEREST_DAILY_INSTALLMENT_FEE_PERCENT_INTEREST_CHARGES, //
LP2_ADV_PYMNT_INTEREST_DAILY_INSTALLMENT_FEE_PERCENT_AMOUNT_INTEREST_CHARGES, //
LP2_ADV_PYMNT_INTEREST_DAILY_INSTALLMENT_FEE_ALL_CHARGES, //
LP2_ADV_PYMNT_INTEREST_DAILY_INSTALLMENT_FEE_FLAT_INTEREST_CHARGES_TRANCHE, //
;
@Override
@@ -60,6 +60,8 @@ public class LoanRequestFactory {
public static final String DATE_FORMAT = "dd MMMM yyyy";
public static final String DEFAULT_LOCALE = "en";
public static final DefaultLoanProduct DEFAULT_LOAN_PRODUCT = DefaultLoanProduct.valueOf("LP1");
public static final DefaultLoanProduct DEFAULT_PROGRESSIVE_LOAN_PRODUCT = DefaultLoanProduct
.valueOf("LP2_ADV_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL");
public static final Double DEFAULT_PAYMENT_TRANSACTION_AMOUNT = 200.00;
public static final Double DEFAULT_UNDO_TRANSACTION_AMOUNT = 0.0;
public static final Double DEFAULT_REPAYMENT_TRANSACTION_AMOUNT = 200.00;
@@ -78,13 +80,16 @@ public class LoanRequestFactory {
public static final String DEFAULT_REAGING_FREQUENCY_TYPE = "MONTHS";
public static final BigDecimal DEFAULT_INTEREST_RATE_PER_PERIOD = new BigDecimal(0);
public static final Integer DEFAULT_INTEREST_TYPE = InterestType.FLAT.value;
public static final Integer DEFAULT_PROGRESSIVE_INTEREST_TYPE = InterestType.DECLINING_BALANCE.value;
public static final Integer DEFAULT_INTEREST_CALCULATION_PERIOD_TYPE_SAME_AS_REPAYMENT_PERIOD = InterestCalculationPeriodTime.SAME_AS_REPAYMENT_PERIOD.value;
public static final Integer DEFAULT_PROGRESSIVE_INTEREST_CALCULATION_PERIOD_TYPE_SAME_AS_REPAYMENT_PERIOD = InterestCalculationPeriodTime.DAILY.value;
public static final Integer DEFAULT_AMORTIZATION_TYPE = 1;
public static final String DEFAULT_LOAN_TYPE = "individual";
public static final Integer DEFAULT_NUMBER_OF_REPAYMENTS = 1;
public static final Integer DEFAULT_NUMBER_OF_INSTALLMENTS = 5;
public static final Integer DEFAULT_REPAYMENT_FREQUENCY = 30;
public static final String DEFAULT_TRANSACTION_PROCESSING_STRATEGY_CODE = TransactionProcessingStrategyCode.PENALTIES_FEES_INTEREST_PRINCIPAL_ORDER.value;
public static final String DEFAULT_PROGRESSIVE_TRANSACTION_PROCESSING_STRATEGY_CODE = TransactionProcessingStrategyCode.ADVANCED_PAYMENT_ALLOCATION.value;
public static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern(DATE_FORMAT);
public static final String DATE_SUBMIT_STRING = FORMATTER.format(Utils.now().minusMonths(1L));
@@ -118,6 +123,30 @@ public class LoanRequestFactory {
.maxOutstandingLoanBalance(new BigDecimal(10000));
}
public PostLoansRequest defaultProgressiveLoansRequest(final Long clientId) {
return new PostLoansRequest()//
.clientId(clientId)//
.productId(loanProductResolver.resolve(DEFAULT_PROGRESSIVE_LOAN_PRODUCT))//
.submittedOnDate(DATE_SUBMIT_STRING)//
.expectedDisbursementDate(DATE_SUBMIT_STRING)//
.principal(DEFAULT_PRINCIPAL)//
.locale(DEFAULT_LOCALE)//
.loanTermFrequency(DEFAULT_LOAN_TERM_FREQUENCY)//
.loanTermFrequencyType(DEFAULT_LOAN_TERM_FREQUENCY_TYPE)//
.loanType(DEFAULT_LOAN_TYPE)//
.numberOfRepayments(DEFAULT_NUMBER_OF_REPAYMENTS)//
.repaymentEvery(DEFAULT_REPAYMENT_FREQUENCY)//
.repaymentFrequencyType(DEFAULT_REPAYMENT_FREQUENCY_TYPE)//
.interestRatePerPeriod(DEFAULT_INTEREST_RATE_PER_PERIOD)//
.interestType(DEFAULT_PROGRESSIVE_INTEREST_TYPE)//
.interestCalculationPeriodType(DEFAULT_PROGRESSIVE_INTEREST_CALCULATION_PERIOD_TYPE_SAME_AS_REPAYMENT_PERIOD)//
.amortizationType(DEFAULT_AMORTIZATION_TYPE)//
.transactionProcessingStrategyCode(DEFAULT_PROGRESSIVE_TRANSACTION_PROCESSING_STRATEGY_CODE)//
.dateFormat(DATE_FORMAT)//
.graceOnArrearsAgeing(3)//
.maxOutstandingLoanBalance(new BigDecimal(10000));
}
public PutLoansLoanIdRequest modifySubmittedOnDateOnLoan(Long clientId, String newSubmittedOnDate) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_FORMAT);
String dateDisburseStr = formatter.format(Utils.now());
@@ -972,4 +972,12 @@ public final class ErrorMessageHelper {
public static String addInterestPauseForNotInactiveLoanFailure() {
return "Operations on interest pauses are restricted to active loans.";
}
public static String addInstallmentFeeInterestPercentageChargeFailure() {
return "Failed data validation due to: installment.loancharge.with.calculation.type.interest.not.allowed.";
}
public static String addInstallmentFeePrincipalPercentageChargeFailure() {
return "Failed data validation due to: installment.loancharge.with.calculation.type.principal.not.allowed.";
}
}
@@ -52,12 +52,17 @@ public class ChargeGlobalInitializerStep implements FineractGlobalInitializerSte
public static final String CHARGE_LOAN_NSF_FEE = "NSF fee";
public static final String CHARGE_LOAN_DISBURSEMENT_PERCENT_FEE = "Disbursement percentage fee";
public static final String CHARGE_LOAN_TRANCHE_DISBURSEMENT_PERCENT_FEE = "Tranche Disbursement percentage fee";
public static final String CHARGE_LOAN_INSTALLMENT_PERCENT_FEE = "Installment percentage fee";
public static final String CHARGE_LOAN_INSTALLMENT_FEE_FLAT = "Installment flat fee";
public static final String CHARGE_LOAN_INSTALLMENT_FEE_PERCENT_AMOUNT = "Installment percentage amount fee";
public static final String CHARGE_LOAN_INSTALLMENT_FEE_PERCENT_INTEREST = "Installment percentage interest fee";
public static final String CHARGE_LOAN_INSTALLMENT_FEE_PERCENT_AMOUNT_PLUS_INTEREST = "Installment percentage amount + interest fee";
public static final String CHARGE_CLIENT_FIXED_FEE = "Fixed fee for Client";
public static final String CHARGE_DISBURSEMENT_CHARGE = "Disbursement Charge";
public static final String CHARGE_LOAN_TRANCHE_DISBURSEMENT_CHARGE_AMOUNT = "Tranche Disbursement Charge Amount";
public static final String CHARGE_LOAN_TRANCHE_DISBURSEMENT_CHARGE_PERCENT = "Tranche Disbursement Charge Percent";
public static final Double CHARGE_AMOUNT_FLAT = 25D;
public static final Double CHARGE_INSTALLMENT_FEE_AMOUNT_FLAT = 10D;
public static final Double CHARGE_INSTALLMENT_FEE_AMOUNT_PERCENTAGE = 1D;
public static final Double CHARGE_AMOUNT_PERCENTAGE = 5D;
public static final Double CHARGE_AMOUNT_DISBURSEMENT_PERCENTAGE = 1.5D;
public static final Double CHARGE_AMOUNT_INSTALLMENT_PERCENTAGE = 1.5D;
@@ -69,6 +74,7 @@ public class ChargeGlobalInitializerStep implements FineractGlobalInitializerSte
public static final Integer CHARGE_TIME_TYPE_INSTALLMENT = ChargeTimeType.INSTALLMENT_FEE.value;
public static final Integer CHARGE_CALCULATION_TYPE_FLAT = ChargeCalculationType.FLAT.value;
public static final Integer CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT = ChargeCalculationType.PERCENTAGE_AMOUNT.value;
public static final Integer CHARGE_CALCULATION_TYPE_PERCENTAGE_INTEREST = ChargeCalculationType.PERCENTAGE_INTEREST.value;
public static final Integer CHARGE_CALCULATION_TYPE_PERCENTAGE_DISBURSEMENT_AMOUNT = ChargeCalculationType.PERCENTAGE_DISBURSEMENT_AMOUNT.value;
public static final Integer CHARGE_CALCULATION_TYPE_PERCENTAGE_LOAN_AMOUNT_PLUS_INTEREST = ChargeCalculationType.PERCENTAGE_LOAN_AMOUNT_PLUS_INTEREST.value;
@@ -130,12 +136,14 @@ public class ChargeGlobalInitializerStep implements FineractGlobalInitializerSte
TestContext.INSTANCE.set(TestContextKey.CHARGE_FOR_LOAN_TRANCHE_DISBURSEMENT_PERCENT_CREATE_RESPONSE,
responseLoanTrancheDisbursePercent);
// Loan - Installment % fee
ChargeRequest requestLoanInstallmentPercent = defaultChargesRequest(CHARGE_APPLIES_TO_LOAN, CHARGE_LOAN_INSTALLMENT_PERCENT_FEE,
CHARGE_TIME_TYPE_INSTALLMENT, CHARGE_CALCULATION_TYPE_PERCENTAGE_LOAN_AMOUNT_PLUS_INTEREST,
CHARGE_AMOUNT_INSTALLMENT_PERCENTAGE, true, false);
Response<PostChargesResponse> responseLoanInstallmentPercent = chargesApi.createCharge(requestLoanInstallmentPercent).execute();
TestContext.INSTANCE.set(TestContextKey.CHARGE_FOR_LOAN_INSTALLMENT_FEE_CREATE_RESPONSE, responseLoanInstallmentPercent);
// Loan - Installment % fee Amount + Interest
final ChargeRequest requestLoanInstallmentPercentAmountPlusInterest = defaultChargesRequest(CHARGE_APPLIES_TO_LOAN,
CHARGE_LOAN_INSTALLMENT_FEE_PERCENT_AMOUNT_PLUS_INTEREST, CHARGE_TIME_TYPE_INSTALLMENT,
CHARGE_CALCULATION_TYPE_PERCENTAGE_LOAN_AMOUNT_PLUS_INTEREST, CHARGE_INSTALLMENT_FEE_AMOUNT_PERCENTAGE, true, false);
final Response<PostChargesResponse> responseLoanInstallmentPercentAmountPlusInterest = chargesApi
.createCharge(requestLoanInstallmentPercentAmountPlusInterest).execute();
TestContext.INSTANCE.set(TestContextKey.CHARGE_FOR_LOAN_INSTALLMENT_FEE_PERCENTAGE_AMOUNT_PLUS_INTEREST_CREATE_RESPONSE,
responseLoanInstallmentPercentAmountPlusInterest);
// Loan - % late (overdue) fee amount+interest
ChargeRequest requestLoanPercentAmountPlusInterestLate = defaultChargesRequest(CHARGE_APPLIES_TO_LOAN,
@@ -175,6 +183,30 @@ public class ChargeGlobalInitializerStep implements FineractGlobalInitializerSte
.createCharge(requestTrancheDisbursementChargePercent).execute();
TestContext.INSTANCE.set(TestContextKey.CHARGE_FOR_LOAN_TRANCHE_DISBURSEMENT_CHARGE_PERCENT_CREATE_RESPONSE,
responseTrancheDisbursementChargePercent);
// Loan - Installment flat fee
final ChargeRequest requestLoanInstallmentFlat = defaultChargesRequest(CHARGE_APPLIES_TO_LOAN, CHARGE_LOAN_INSTALLMENT_FEE_FLAT,
CHARGE_TIME_TYPE_INSTALLMENT, CHARGE_CALCULATION_TYPE_FLAT, CHARGE_INSTALLMENT_FEE_AMOUNT_FLAT, true, false);
final Response<PostChargesResponse> responseLoanInstallmentFlat = chargesApi.createCharge(requestLoanInstallmentFlat).execute();
TestContext.INSTANCE.set(TestContextKey.CHARGE_FOR_LOAN_INSTALLMENT_FEE_FLAT_CREATE_RESPONSE, responseLoanInstallmentFlat);
// Loan - Installment % fee Amount
final ChargeRequest requestLoanInstallmentPercentAmount = defaultChargesRequest(CHARGE_APPLIES_TO_LOAN,
CHARGE_LOAN_INSTALLMENT_FEE_PERCENT_AMOUNT, CHARGE_TIME_TYPE_INSTALLMENT, CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT,
CHARGE_INSTALLMENT_FEE_AMOUNT_PERCENTAGE, true, false);
final Response<PostChargesResponse> responseLoanInstallmentPercentAmount = chargesApi
.createCharge(requestLoanInstallmentPercentAmount).execute();
TestContext.INSTANCE.set(TestContextKey.CHARGE_FOR_LOAN_INSTALLMENT_FEE_PERCENTAGE_AMOUNT_CREATE_RESPONSE,
responseLoanInstallmentPercentAmount);
// Loan - Installment % fee Interest
final ChargeRequest requestLoanInstallmentPercentInterest = defaultChargesRequest(CHARGE_APPLIES_TO_LOAN,
CHARGE_LOAN_INSTALLMENT_FEE_PERCENT_INTEREST, CHARGE_TIME_TYPE_INSTALLMENT, CHARGE_CALCULATION_TYPE_PERCENTAGE_INTEREST,
CHARGE_AMOUNT_PERCENTAGE, true, false);
final Response<PostChargesResponse> responseLoanInstallmentPercentInterest = chargesApi
.createCharge(requestLoanInstallmentPercentInterest).execute();
TestContext.INSTANCE.set(TestContextKey.CHARGE_FOR_LOAN_INSTALLMENT_FEE_PERCENTAGE_INTEREST_CREATE_RESPONSE,
responseLoanInstallmentPercentInterest);
}
public static ChargeRequest defaultChargesRequest(Enum<ChargeProductAppliesTo> appliesTo, String name, Integer chargeTimeType,
@@ -2982,6 +2982,171 @@ public class LoanProductGlobalInitializerStep implements FineractGlobalInitializ
TestContext.INSTANCE.set(
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_360_30_INTEREST_RECALC_AUTO_DOWNPAYMENT_ZERO_INTEREST_CHARGE_OFF_ACCRUAL_ACTIVITY,
responseLoanProductsRequestAdvInterestRecalculationAutoDownpaymentZeroInterestChargeOffBehaviourAccrualActivity);
// LP2 with progressive loan schedule + horizontal + interest recalculation
// charges - Installment Fee Flat
// (LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALC_DAILY_INSTALLMENT_FEE_FLAT_CHARGES)
final String name116 = DefaultLoanProduct.LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALC_DAILY_INSTALLMENT_FEE_FLAT_CHARGES.getName();
final List<LoanProductChargeData> chargesInstallmentFeeFlat = new ArrayList<>();
chargesInstallmentFeeFlat.add(new LoanProductChargeData().id(ChargeProductType.LOAN_INSTALLMENT_FEE_FLAT.value));
final PostLoanProductsRequest loanProductsRequestLP2AdvPaymentInterestRecalcDailyInstallmentFeeFlatCharges = loanProductsRequestFactory
.defaultLoanProductsRequestLP2InterestDailyRecalculation()//
.name(name116)//
.charges(chargesInstallmentFeeFlat)//
.paymentAllocation(List.of(//
createPaymentAllocation("DEFAULT", "NEXT_INSTALLMENT"), //
createPaymentAllocation("GOODWILL_CREDIT", "LAST_INSTALLMENT"), //
createPaymentAllocation("MERCHANT_ISSUED_REFUND", "REAMORTIZATION"), //
createPaymentAllocation("PAYOUT_REFUND", "NEXT_INSTALLMENT")));//
final Response<PostLoanProductsResponse> responseLoanProductsRequestLP2AdvPaymentInterestRecalcDailyInstallmentFeeFlatCharges = loanProductsApi
.createLoanProduct(loanProductsRequestLP2AdvPaymentInterestRecalcDailyInstallmentFeeFlatCharges).execute();
TestContext.INSTANCE.set(
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALC_DAILY_INSTALLMENT_FEE_FLAT_CHARGES,
responseLoanProductsRequestLP2AdvPaymentInterestRecalcDailyInstallmentFeeFlatCharges);
// LP2 with progressive loan schedule + horizontal
// charges - Installment Fee Percentage Amount
// (LP2_ADV_PYMNT_INTEREST_DAILY_INSTALLMENT_FEE_PERCENT_AMOUNT_CHARGES)
final String name117 = DefaultLoanProduct.LP2_ADV_PYMNT_INTEREST_DAILY_INSTALLMENT_FEE_PERCENT_AMOUNT_CHARGES.getName();
final List<LoanProductChargeData> chargesInstallmentFeePercentAmount = new ArrayList<>();
chargesInstallmentFeePercentAmount
.add(new LoanProductChargeData().id(ChargeProductType.LOAN_INSTALLMENT_FEE_PERCENTAGE_AMOUNT.value));
final PostLoanProductsRequest loanProductsRequestLP2AdvPaymentInstallmentFeePercentAmountCharges = loanProductsRequestFactory
.defaultLoanProductsRequestLP2()//
.name(name117)//
.charges(chargesInstallmentFeePercentAmount)//
.enableDownPayment(false)//
.enableAutoRepaymentForDownPayment(null)//
.disbursedAmountPercentageForDownPayment(null)//
.transactionProcessingStrategyCode(ADVANCED_PAYMENT_ALLOCATION.getValue())//
.loanScheduleType("PROGRESSIVE") //
.loanScheduleProcessingType("HORIZONTAL")//
.interestRateFrequencyType(3)//
.maxInterestRatePerPeriod(10.0)//
.paymentAllocation(List.of(//
createPaymentAllocation("DEFAULT", "NEXT_INSTALLMENT"), //
createPaymentAllocation("GOODWILL_CREDIT", "LAST_INSTALLMENT"), //
createPaymentAllocation("MERCHANT_ISSUED_REFUND", "REAMORTIZATION"), //
createPaymentAllocation("PAYOUT_REFUND", "NEXT_INSTALLMENT")));//
final Response<PostLoanProductsResponse> responseLoanProductsRequestLP2AdvPaymentInstallmentFeePercentAmountCharges = loanProductsApi
.createLoanProduct(loanProductsRequestLP2AdvPaymentInstallmentFeePercentAmountCharges).execute();
TestContext.INSTANCE.set(
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_INSTALLMENT_FEE_PERCENT_AMOUNT_CHARGES,
responseLoanProductsRequestLP2AdvPaymentInstallmentFeePercentAmountCharges);
// LP2 with progressive loan schedule + horizontal
// charges - Installment Fee Percentage Interest
// (LP2_ADV_PYMNT_INTEREST_DAILY_INSTALLMENT_FEE_PERCENT_INTEREST_CHARGES)
final String name118 = DefaultLoanProduct.LP2_ADV_PYMNT_INTEREST_DAILY_INSTALLMENT_FEE_PERCENT_INTEREST_CHARGES.getName();
final List<LoanProductChargeData> chargesInstallmentFeePercentInterest = new ArrayList<>();
chargesInstallmentFeePercentInterest
.add(new LoanProductChargeData().id(ChargeProductType.LOAN_INSTALLMENT_FEE_PERCENTAGE_INTEREST.value));
final PostLoanProductsRequest loanProductsRequestLP2AdvPaymentInstallmentFeePercentInterestCharges = loanProductsRequestFactory
.defaultLoanProductsRequestLP2()//
.name(name118)//
.charges(chargesInstallmentFeePercentInterest)//
.enableDownPayment(false)//
.enableAutoRepaymentForDownPayment(null)//
.disbursedAmountPercentageForDownPayment(null)//
.transactionProcessingStrategyCode(ADVANCED_PAYMENT_ALLOCATION.getValue())//
.loanScheduleType("PROGRESSIVE") //
.loanScheduleProcessingType("HORIZONTAL")//
.interestRateFrequencyType(3)//
.maxInterestRatePerPeriod(10.0)//
.paymentAllocation(List.of(//
createPaymentAllocation("DEFAULT", "NEXT_INSTALLMENT"), //
createPaymentAllocation("GOODWILL_CREDIT", "LAST_INSTALLMENT"), //
createPaymentAllocation("MERCHANT_ISSUED_REFUND", "REAMORTIZATION"), //
createPaymentAllocation("PAYOUT_REFUND", "NEXT_INSTALLMENT")));//
final Response<PostLoanProductsResponse> responseLoanProductsRequestLP2AdvPaymentInstallmentFeePercentInterestCharges = loanProductsApi
.createLoanProduct(loanProductsRequestLP2AdvPaymentInstallmentFeePercentInterestCharges).execute();
TestContext.INSTANCE.set(
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_INSTALLMENT_FEE_PERCENT_INTEREST_CHARGES,
responseLoanProductsRequestLP2AdvPaymentInstallmentFeePercentInterestCharges);
// LP2 with progressive loan schedule + horizontal
// charges - Installment Fee Percentage Amount + Interest
// (LP2_ADV_PYMNT_INTEREST_DAILY_INSTALLMENT_FEE_PERCENT_AMOUNT_INTEREST_CHARGES)
final String name119 = DefaultLoanProduct.LP2_ADV_PYMNT_INTEREST_DAILY_INSTALLMENT_FEE_PERCENT_AMOUNT_INTEREST_CHARGES.getName();
final List<LoanProductChargeData> chargesInstallmentFeePercentAmountPlusInterest = new ArrayList<>();
chargesInstallmentFeePercentAmountPlusInterest
.add(new LoanProductChargeData().id(ChargeProductType.LOAN_INSTALLMENT_FEE_PERCENTAGE_AMOUNT_PLUS_INTEREST.value));
final PostLoanProductsRequest loanProductsRequestLP2AdvPaymentInstallmentFeePercentAmountPlusInterestCharges = loanProductsRequestFactory
.defaultLoanProductsRequestLP2()//
.name(name119)//
.charges(chargesInstallmentFeePercentAmountPlusInterest)//
.enableDownPayment(false)//
.enableAutoRepaymentForDownPayment(null)//
.disbursedAmountPercentageForDownPayment(null)//
.transactionProcessingStrategyCode(ADVANCED_PAYMENT_ALLOCATION.getValue())//
.loanScheduleType("PROGRESSIVE") //
.loanScheduleProcessingType("HORIZONTAL")//
.interestRateFrequencyType(3)//
.maxInterestRatePerPeriod(10.0)//
.paymentAllocation(List.of(//
createPaymentAllocation("DEFAULT", "NEXT_INSTALLMENT"), //
createPaymentAllocation("GOODWILL_CREDIT", "LAST_INSTALLMENT"), //
createPaymentAllocation("MERCHANT_ISSUED_REFUND", "REAMORTIZATION"), //
createPaymentAllocation("PAYOUT_REFUND", "NEXT_INSTALLMENT")));//
final Response<PostLoanProductsResponse> responseLoanProductsRequestLP2AdvPaymentInstallmentFeePercentAmountPlusInterestCharges = loanProductsApi
.createLoanProduct(loanProductsRequestLP2AdvPaymentInstallmentFeePercentAmountPlusInterestCharges).execute();
TestContext.INSTANCE.set(
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_INSTALLMENT_FEE_PERCENT_AMOUNT_INTEREST_CHARGES,
responseLoanProductsRequestLP2AdvPaymentInstallmentFeePercentAmountPlusInterestCharges);
// LP2 with progressive loan schedule + horizontal
// charges - Installment Fee All
// (LP2_ADV_PYMNT_INTEREST_DAILY_INSTALLMENT_FEE_ALL_CHARGES)
final String name120 = DefaultLoanProduct.LP2_ADV_PYMNT_INTEREST_DAILY_INSTALLMENT_FEE_ALL_CHARGES.getName();
final List<LoanProductChargeData> chargesInstallmentFeeAll = new ArrayList<>();
chargesInstallmentFeeAll.add(new LoanProductChargeData().id(ChargeProductType.LOAN_INSTALLMENT_FEE_FLAT.value));
chargesInstallmentFeeAll.add(new LoanProductChargeData().id(ChargeProductType.LOAN_INSTALLMENT_FEE_PERCENTAGE_AMOUNT.value));
chargesInstallmentFeeAll.add(new LoanProductChargeData().id(ChargeProductType.LOAN_INSTALLMENT_FEE_PERCENTAGE_INTEREST.value));
chargesInstallmentFeeAll
.add(new LoanProductChargeData().id(ChargeProductType.LOAN_INSTALLMENT_FEE_PERCENTAGE_AMOUNT_PLUS_INTEREST.value));
final PostLoanProductsRequest loanProductsRequestLP2AdvPaymentInstallmentFeeAllCharges = loanProductsRequestFactory
.defaultLoanProductsRequestLP2()//
.name(name120)//
.charges(chargesInstallmentFeeAll)//
.enableDownPayment(false)//
.enableAutoRepaymentForDownPayment(null)//
.disbursedAmountPercentageForDownPayment(null)//
.transactionProcessingStrategyCode(ADVANCED_PAYMENT_ALLOCATION.getValue())//
.loanScheduleType("PROGRESSIVE") //
.loanScheduleProcessingType("HORIZONTAL")//
.interestRateFrequencyType(3)//
.maxInterestRatePerPeriod(10.0)//
.paymentAllocation(List.of(//
createPaymentAllocation("DEFAULT", "NEXT_INSTALLMENT"), //
createPaymentAllocation("GOODWILL_CREDIT", "LAST_INSTALLMENT"), //
createPaymentAllocation("MERCHANT_ISSUED_REFUND", "REAMORTIZATION"), //
createPaymentAllocation("PAYOUT_REFUND", "NEXT_INSTALLMENT")));//
final Response<PostLoanProductsResponse> responseLoanProductsRequestLP2AdvPaymentInstallmentFeeAllCharges = loanProductsApi
.createLoanProduct(loanProductsRequestLP2AdvPaymentInstallmentFeeAllCharges).execute();
TestContext.INSTANCE.set(
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_INSTALLMENT_FEE_ALL_CHARGES,
responseLoanProductsRequestLP2AdvPaymentInstallmentFeeAllCharges);
// LP2 with progressive loan schedule + horizontal + multidisbursal
// charges - Installment Fee Flat + Interest %
// (LP2_ADV_PYMNT_INTEREST_DAILY_INSTALLMENT_FEE_FLAT_INTEREST_CHARGES_TRANCHE)
final String name121 = DefaultLoanProduct.LP2_ADV_PYMNT_INTEREST_DAILY_INSTALLMENT_FEE_FLAT_INTEREST_CHARGES_TRANCHE.getName();
final List<LoanProductChargeData> chargesInstallmentFeeFlatPlusInterest = new ArrayList<>();
chargesInstallmentFeeFlatPlusInterest.add(new LoanProductChargeData().id(ChargeProductType.LOAN_INSTALLMENT_FEE_FLAT.value));
chargesInstallmentFeeFlatPlusInterest
.add(new LoanProductChargeData().id(ChargeProductType.LOAN_INSTALLMENT_FEE_PERCENTAGE_INTEREST.value));
final PostLoanProductsRequest loanProductsRequestLP2AdvPaymentInstallmentFeeFlatPlusInterestChargesMultiDisburse = loanProductsRequestLP2AdvPaymentInstallmentFeePercentInterestCharges//
.name(name121)//
.charges(chargesInstallmentFeeFlatPlusInterest)//
.shortName(Utils.randomNameGenerator(SHORT_NAME_PREFIX_EMI, 3))//
.disallowExpectedDisbursements(true)//
.maxTrancheCount(10)//
.outstandingLoanBalance(10000.0);//
final Response<PostLoanProductsResponse> responseLoanProductsRequestLP2AdvPaymentInstallmentFeeFlatPlusInterestChargesMultiDisburse = loanProductsApi
.createLoanProduct(loanProductsRequestLP2AdvPaymentInstallmentFeeFlatPlusInterestChargesMultiDisburse).execute();
TestContext.INSTANCE.set(
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_INSTALLMENT_FEE_FLAT_INTEREST_CHARGES_TRANCHE,
responseLoanProductsRequestLP2AdvPaymentInstallmentFeeFlatPlusInterestChargesMultiDisburse);
}
public static AdvancedPaymentData createPaymentAllocation(String transactionType, String futureInstallmentAllocationRule,
@@ -90,7 +90,7 @@ public class LoanChargeStepDef extends AbstractStepDef {
Long chargeTypeId = chargeProductType.getValue();
if (chargeTypeId.equals(ChargeProductType.LOAN_DISBURSEMENT_PERCENTAGE_FEE.getValue())
|| chargeTypeId.equals(ChargeProductType.LOAN_TRANCHE_DISBURSEMENT_PERCENTAGE_FEE.getValue())
|| chargeTypeId.equals(ChargeProductType.LOAN_INSTALLMENT_PERCENTAGE_FEE.getValue())) {
|| chargeTypeId.equals(ChargeProductType.LOAN_INSTALLMENT_FEE_PERCENTAGE_AMOUNT_PLUS_INTEREST.getValue())) {
throw new IllegalStateException(String.format("The requested %s charge is NOT due date type, cannot be used here", chargeType));
}
@@ -115,7 +115,8 @@ public class LoanChargeStepDef extends AbstractStepDef {
Long chargeTypeId = chargeProductType.getValue();
if (!chargeTypeId.equals(ChargeProductType.LOAN_DISBURSEMENT_PERCENTAGE_FEE.getValue())
&& !chargeTypeId.equals(ChargeProductType.LOAN_TRANCHE_DISBURSEMENT_PERCENTAGE_FEE.getValue())
&& !chargeTypeId.equals(ChargeProductType.LOAN_INSTALLMENT_PERCENTAGE_FEE.getValue())) {
&& !chargeTypeId.equals(ChargeProductType.LOAN_INSTALLMENT_FEE_PERCENTAGE_AMOUNT.getValue())
&& !chargeTypeId.equals(ChargeProductType.LOAN_INSTALLMENT_FEE_PERCENTAGE_AMOUNT_PLUS_INTEREST.getValue())) {
throw new IllegalStateException(String.format("The requested %s charge is due date type, cannot be used here", chargeType));
}
@@ -128,6 +129,54 @@ public class LoanChargeStepDef extends AbstractStepDef {
testContext().set(TestContextKey.ADD_DUE_DATE_CHARGE_RESPONSE, loanChargeResponse);
}
@When("Admin adds {string} installment charge with {double} amount")
public void addInstallmentFeeCharge(final String chargeType, final double amount) throws IOException {
final Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
assert loanResponse.body() != null;
final long loanId = loanResponse.body().getLoanId();
final ChargeProductType chargeProductType = ChargeProductType.valueOf(chargeType);
final Long chargeTypeId = chargeProductType.getValue();
if (!chargeTypeId.equals(ChargeProductType.LOAN_INSTALLMENT_FEE_FLAT.getValue())
&& !chargeTypeId.equals(ChargeProductType.LOAN_INSTALLMENT_FEE_PERCENTAGE_AMOUNT.getValue())
&& !chargeTypeId.equals(ChargeProductType.LOAN_INSTALLMENT_FEE_PERCENTAGE_INTEREST.getValue())
&& !chargeTypeId.equals(ChargeProductType.LOAN_INSTALLMENT_FEE_PERCENTAGE_AMOUNT_PLUS_INTEREST.getValue())) {
throw new IllegalStateException(
String.format("The requested %s charge is not installment fee type, cannot be used here", chargeType));
}
final PostLoansLoanIdChargesRequest loanIdChargesRequest = LoanChargeRequestFactory.defaultLoanChargeRequest()
.chargeId(chargeTypeId).amount(amount);
final Response<PostLoansLoanIdChargesResponse> loanChargeResponse = loanChargesApi
.executeLoanCharge(loanId, loanIdChargesRequest, "").execute();
ErrorHelper.checkSuccessfulApiCall(loanChargeResponse);
testContext().set(TestContextKey.ADD_INSTALLMENT_FEE_CHARGE_RESPONSE, loanChargeResponse);
}
@Then("Admin fails to add {string} installment charge with {double} amount because of wrong charge calculation type")
public void addInstallmentFeeChargeFails(final String chargeType, final double amount) throws IOException {
final Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
assert loanResponse.body() != null;
final long loanId = loanResponse.body().getLoanId();
final ChargeProductType chargeProductType = ChargeProductType.valueOf(chargeType);
final Long chargeTypeId = chargeProductType.getValue();
final PostLoansLoanIdChargesRequest loanIdChargesRequest = LoanChargeRequestFactory.defaultLoanChargeRequest()
.chargeId(chargeTypeId).amount(amount);
final Response<PostLoansLoanIdChargesResponse> loanChargeResponse = loanChargesApi
.executeLoanCharge(loanId, loanIdChargesRequest, "").execute();
testContext().set(TestContextKey.ADD_INSTALLMENT_FEE_CHARGE_RESPONSE, loanChargeResponse);
final ErrorResponse errorDetails = ErrorResponse.from(loanChargeResponse);
assertThat(errorDetails.getHttpStatusCode()).isEqualTo(400);
assertThat(errorDetails.getSingleError().getDeveloperMessage())
.isEqualTo(chargeProductType.equals(ChargeProductType.LOAN_INSTALLMENT_FEE_PERCENTAGE_INTEREST)
? ErrorMessageHelper.addInstallmentFeeInterestPercentageChargeFailure()
: ErrorMessageHelper.addInstallmentFeePrincipalPercentageChargeFailure());
}
@Then("Admin is not able to add {string} due date charge with {string} due date and {double} EUR transaction amount because the of charged-off account")
public void addChargeDueDateOnChargedOff(String chargeType, String transactionDate, double transactionAmount) throws IOException {
Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
@@ -284,7 +333,7 @@ public class LoanChargeStepDef extends AbstractStepDef {
Long chargeTypeId = chargeProductType.getValue();
if (chargeTypeId.equals(ChargeProductType.LOAN_DISBURSEMENT_PERCENTAGE_FEE.getValue())
|| chargeTypeId.equals(ChargeProductType.LOAN_TRANCHE_DISBURSEMENT_PERCENTAGE_FEE.getValue())
|| chargeTypeId.equals(ChargeProductType.LOAN_INSTALLMENT_PERCENTAGE_FEE.getValue())) {
|| chargeTypeId.equals(ChargeProductType.LOAN_INSTALLMENT_FEE_PERCENTAGE_AMOUNT_PLUS_INTEREST.getValue())) {
throw new IllegalStateException(String.format("The requested %s charge is NOT due date type, cannot be used here", chargeType));
}
@@ -82,6 +82,7 @@ import org.apache.fineract.client.models.GetLoansLoanIdTransactions;
import org.apache.fineract.client.models.GetLoansLoanIdTransactionsResponse;
import org.apache.fineract.client.models.GetLoansLoanIdTransactionsTransactionIdResponse;
import org.apache.fineract.client.models.IsCatchUpRunningDTO;
import org.apache.fineract.client.models.LoanProductChargeData;
import org.apache.fineract.client.models.OldestCOBProcessedLoanDTO;
import org.apache.fineract.client.models.PaymentAllocationOrder;
import org.apache.fineract.client.models.PostAddAndDeleteDisbursementDetailRequest;
@@ -258,6 +259,20 @@ public class LoanStepDef extends AbstractStepDef {
eventCheckHelper.createLoanEventCheck(response);
}
@When("Admin creates a new default Progressive Loan with date: {string}")
public void createProgressiveLoanWithDate(final String date) throws IOException {
final Response<PostClientsResponse> clientResponse = testContext().get(TestContextKey.CLIENT_CREATE_RESPONSE);
final Long clientId = clientResponse.body().getClientId();
final PostLoansRequest loansRequest = loanRequestFactory.defaultProgressiveLoansRequest(clientId).submittedOnDate(date)
.expectedDisbursementDate(date);
final Response<PostLoansResponse> response = loansApi.calculateLoanScheduleOrSubmitLoanApplication(loansRequest, "").execute();
testContext().set(TestContextKey.LOAN_CREATE_RESPONSE, response);
ErrorHelper.checkSuccessfulApiCall(response);
eventCheckHelper.createLoanEventCheck(response);
}
@When("Admin crates a second default loan with date: {string}")
public void createSecondLoanWithDate(String date) throws IOException {
Response<PostClientsResponse> clientResponse = testContext().get(TestContextKey.CLIENT_CREATE_RESPONSE);
@@ -483,6 +498,12 @@ public class LoanStepDef extends AbstractStepDef {
createCustomizedLoan(data.get(1), false);
}
@When("Admin creates a fully customized loan with loan product`s charges and following data:")
public void createFullyCustomizedLoanWithProductCharges(final DataTable table) throws IOException {
final List<List<String>> data = table.asLists();
createCustomizedLoanWithProductCharges(data.get(1));
}
@When("Admin creates a fully customized loan with emi and the following data:")
public void createFullyCustomizedLoanWithEmi(final DataTable table) throws IOException {
final List<List<String>> data = table.asLists();
@@ -3279,6 +3300,77 @@ public class LoanStepDef extends AbstractStepDef {
eventCheckHelper.createLoanEventCheck(response);
}
private void createCustomizedLoanWithProductCharges(final List<String> loanData) throws IOException {
final String loanProduct = loanData.get(0);
final String submitDate = loanData.get(1);
final String principal = loanData.get(2);
final BigDecimal interestRate = new BigDecimal(loanData.get(3));
final String interestTypeStr = loanData.get(4);
final String interestCalculationPeriodStr = loanData.get(5);
final String amortizationTypeStr = loanData.get(6);
final Integer loanTermFrequency = Integer.valueOf(loanData.get(7));
final String loanTermFrequencyType = loanData.get(8);
final Integer repaymentFrequency = Integer.valueOf(loanData.get(9));
final String repaymentFrequencyTypeStr = loanData.get(10);
final Integer numberOfRepayments = Integer.valueOf(loanData.get(11));
final Integer graceOnPrincipalPayment = Integer.valueOf(loanData.get(12));
final Integer graceOnInterestPayment = Integer.valueOf(loanData.get(13));
final Integer graceOnInterestCharged = Integer.valueOf(loanData.get(14));
final String transactionProcessingStrategyCode = loanData.get(15);
final Response<PostClientsResponse> clientResponse = testContext().get(TestContextKey.CLIENT_CREATE_RESPONSE);
final Long clientId = clientResponse.body().getClientId();
final DefaultLoanProduct product = DefaultLoanProduct.valueOf(loanProduct);
final Long loanProductId = loanProductResolver.resolve(product);
final Response<GetLoanProductsProductIdResponse> loanProductDetails = loanProductsApi.retrieveLoanProductDetails(loanProductId)
.execute();
final List<PostLoansRequestChargeData> loanCharges = new ArrayList<>();
assert loanProductDetails.body() != null;
if (loanProductDetails.body().getCharges() != null) {
for (final LoanProductChargeData chargeData : loanProductDetails.body().getCharges()) {
loanCharges.add(new PostLoansRequestChargeData().chargeId(chargeData.getId()).amount(chargeData.getAmount()));
}
}
final LoanTermFrequencyType termFrequencyType = LoanTermFrequencyType.valueOf(loanTermFrequencyType);
final Integer loanTermFrequencyTypeValue = termFrequencyType.getValue();
final RepaymentFrequencyType repaymentFrequencyType = RepaymentFrequencyType.valueOf(repaymentFrequencyTypeStr);
final Integer repaymentFrequencyTypeValue = repaymentFrequencyType.getValue();
final InterestType interestType = InterestType.valueOf(interestTypeStr);
final Integer interestTypeValue = interestType.getValue();
final InterestCalculationPeriodTime interestCalculationPeriod = InterestCalculationPeriodTime.valueOf(interestCalculationPeriodStr);
final Integer interestCalculationPeriodValue = interestCalculationPeriod.getValue();
final AmortizationType amortizationType = AmortizationType.valueOf(amortizationTypeStr);
final Integer amortizationTypeValue = amortizationType.getValue();
final TransactionProcessingStrategyCode processingStrategyCode = TransactionProcessingStrategyCode
.valueOf(transactionProcessingStrategyCode);
final String transactionProcessingStrategyCodeValue = processingStrategyCode.getValue();
final PostLoansRequest loansRequest = loanRequestFactory.defaultLoansRequest(clientId).productId(loanProductId)
.principal(new BigDecimal(principal)).interestRatePerPeriod(interestRate).interestType(interestTypeValue)
.interestCalculationPeriodType(interestCalculationPeriodValue).amortizationType(amortizationTypeValue)
.loanTermFrequency(loanTermFrequency).loanTermFrequencyType(loanTermFrequencyTypeValue)
.numberOfRepayments(numberOfRepayments).repaymentEvery(repaymentFrequency)
.repaymentFrequencyType(repaymentFrequencyTypeValue).submittedOnDate(submitDate).expectedDisbursementDate(submitDate)
.graceOnPrincipalPayment(graceOnPrincipalPayment).graceOnInterestPayment(graceOnInterestPayment)
.graceOnInterestPayment(graceOnInterestCharged).transactionProcessingStrategyCode(transactionProcessingStrategyCodeValue)
.charges(loanCharges);
final Response<PostLoansResponse> response = loansApi.calculateLoanScheduleOrSubmitLoanApplication(loansRequest, "").execute();
testContext().set(TestContextKey.LOAN_CREATE_RESPONSE, response);
ErrorHelper.checkSuccessfulApiCall(response);
eventCheckHelper.createLoanEventCheck(response);
}
public void createFullyCustomizedLoanWithInterestRateFrequency(final List<String> loanData) throws IOException {
final String loanProduct = loanData.get(0);
final String submitDate = loanData.get(1);
@@ -30,6 +30,7 @@ public abstract class TestContextKey {
public static final String LOAN_CREATE_SECOND_LOAN_RESPONSE = "loanCreateSecondLoanResponse";
public static final String LOAN_MODIFY_RESPONSE = "loanModifyResponse";
public static final String ADD_DUE_DATE_CHARGE_RESPONSE = "addDueDateChargeResponse";
public static final String ADD_INSTALLMENT_FEE_CHARGE_RESPONSE = "addInstallmentFeeChargeResponse";
public static final String ADD_PROCESSING_FEE_RESPONSE = "addProcessingFeeResponse";
public static final String ADD_NSF_FEE_RESPONSE = "addNsfFeeResponse";
public static final String WAIVE_CHARGE_RESPONSE = "waiveChargeResponse";
@@ -178,7 +179,10 @@ public abstract class TestContextKey {
public static final String CHARGE_FOR_LOAN_DISBURSEMENET_FEE_CREATE_RESPONSE = "ChargeForLoanDisbursementCreateResponse";
public static final String CHARGE_FOR_LOAN_TRANCHE_DISBURSEMENT_PERCENT_CREATE_RESPONSE = "ChargeForLoanTrancheDisbursementPercentCreateResponse";
public static final String CHARGE_FOR_LOAN_TRANCHE_DISBURSEMENT_CHARGE_PERCENT_CREATE_RESPONSE = "ChargeForLoanTrancheDisbursementChargePercentCreateResponse";
public static final String CHARGE_FOR_LOAN_INSTALLMENT_FEE_CREATE_RESPONSE = "ChargeForLoanInstallmentCreateResponse";
public static final String CHARGE_FOR_LOAN_INSTALLMENT_FEE_PERCENTAGE_AMOUNT_PLUS_INTEREST_CREATE_RESPONSE = "ChargeForLoanInstallmentFeePercentageAmountPlusInterestCreateResponse";
public static final String CHARGE_FOR_LOAN_INSTALLMENT_FEE_PERCENTAGE_AMOUNT_CREATE_RESPONSE = "ChargeForLoanInstallmentFeePercentageAmountCreateResponse";
public static final String CHARGE_FOR_LOAN_INSTALLMENT_FEE_PERCENTAGE_INTEREST_CREATE_RESPONSE = "ChargeForLoanInstallmentFeePercentageInterestCreateResponse";
public static final String CHARGE_FOR_LOAN_INSTALLMENT_FEE_FLAT_CREATE_RESPONSE = "ChargeForLoanInstallmentFeeFlatCreateResponse";
public static final String CHARGE_FOR_CLIENT_FIXED_FEE_CREATE_RESPONSE = "ChargeForClientFixedFeeCreateResponse";
public static final String CHARGE_FOR_LOAN_DISBURSEMENT_CHARGE_CREATE_RESPONSE = "ChargeForLoanDisbursementChargeCreateResponse";
public static final String LOAN_RESPONSE = "loanResponse";
@@ -235,4 +239,10 @@ public abstract class TestContextKey {
public static final String LOAN_BUY_DOWN_FEE_ADJUSTMENT_RESPONSE = "loanBuyDownFeeAdjustmentResponse";
public static final String MANUAL_JOURNAL_ENTRIES_REQUEST = "manualJournalEntriesRequest";
public static final String MANUAL_JOURNAL_ENTRIES_RESPONSE = "manualJournalEntriesResponse";
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALC_DAILY_INSTALLMENT_FEE_FLAT_CHARGES = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyInterestRecalculationInstallmentFeeFlatCharges";
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_INSTALLMENT_FEE_PERCENT_AMOUNT_CHARGES = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyInstallmentFeePercentageAmountCharges";
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_INSTALLMENT_FEE_PERCENT_INTEREST_CHARGES = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyInstallmentFeePercentageInterestCharges";
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_INSTALLMENT_FEE_PERCENT_AMOUNT_INTEREST_CHARGES = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyInstallmentFeeAmountPlusPercentageInterestCharges";
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_INSTALLMENT_FEE_ALL_CHARGES = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyInstallmentFeeAllCharges";
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_INSTALLMENT_FEE_FLAT_INTEREST_CHARGES_TRANCHE = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyInstallmentFeeFlatPlusPercentageInterestChargesMultidisbursal";
}