Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3876,4 +3876,13 @@ public CommandWrapperBuilder makeLoanBuyDownFee(final Long loanId) {
this.href = "/loans/" + loanId + "/transactions/template?command=buyDownFee";
return this;
}

public CommandWrapperBuilder updateLoanApprovedAmount(final Long loanId) {
this.actionName = "UPDATE";
this.entityName = "LOAN_APPROVED_AMOUNT";
this.entityId = loanId;
this.loanId = loanId;
this.href = "/loans/" + loanId;
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,36 @@
import java.util.function.Consumer;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;

public final class Validator {

private Validator() {}

public static void validateOrThrow(String resource, Consumer<DataValidatorBuilder> baseDataValidator) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder dataValidatorBuilder = new DataValidatorBuilder(dataValidationErrors).resource(resource);

baseDataValidator.accept(dataValidatorBuilder);
final List<ApiParameterError> dataValidationErrors = getApiParameterErrors(resource, baseDataValidator);

if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
dataValidationErrors);
}
}

public static void validateOrThrowDomainViolation(String resource, Consumer<DataValidatorBuilder> baseDataValidator) {
final List<ApiParameterError> dataValidationErrors = getApiParameterErrors(resource, baseDataValidator);

if (!dataValidationErrors.isEmpty()) {
throw new GeneralPlatformDomainRuleException("validation.msg.validation.errors.exist", "Validation errors exist.",
dataValidationErrors.toArray(new Object[0]));
}
}

private static List<ApiParameterError> getApiParameterErrors(String resource, Consumer<DataValidatorBuilder> baseDataValidator) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder dataValidatorBuilder = new DataValidatorBuilder(dataValidationErrors).resource(resource);

baseDataValidator.accept(dataValidatorBuilder);
return dataValidationErrors;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,15 @@ public enum DefaultLoanProduct implements LoanProduct {
LP2_ADV_PYMNT_INTEREST_DAILY_RECALC_EMI_360_30_APPROVED_OVER_APPLIED_PERCENTAGE_CAPITALIZED_INCOME, //
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_INTEREST_DAILY_RECALC_EMI_360_30_MULTIDISB_APPROVED_OVER_APPLIED_CAPITALIZED_INCOME, //
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, //
LP1_MULTIDISBURSAL_EXPECTS_TRANCHES, //
;

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public static String disburseDateFailure(Integer loanId) {
}

public static String addDisbursementExceedApprovedAmountFailure() {
return "Loan can't be disbursed,disburse amount is exceeding approved principal ";
return "Loan can't be disbursed, disburse amount is exceeding approved principal.";
}

public static String addDisbursementExceedMaxAppliedAmountFailure(String totalDisbAmount, String maxDisbursalAmount) {
Expand Down Expand Up @@ -980,4 +980,16 @@ public static String addInstallmentFeeInterestPercentageChargeFailure() {
public static String addInstallmentFeePrincipalPercentageChargeFailure() {
return "Failed data validation due to: installment.loancharge.with.calculation.type.principal.not.allowed.";
}

public static String updateApprovedLoanExceedPrincipalFailure() {
return "Failed data validation due to: can't.be.greater.than.maximum.applied.loan.amount.calculation.";
}

public static String updateApprovedLoanLessThanDisbursedPrincipalAndCapitalizedIncomeFailure() {
return "Failed data validation due to: less.than.disbursed.principal.and.capitalized.income.";
}

public static String updateApprovedLoanLessMinAllowedAmountFailure() {
return "The parameter `amount` must be greater than 0.";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,14 @@ public static ErrorResponse from(Response retrofitResponse) {
public static class Error {

private String developerMessage;
private List<ErrorMessageArg> args;
}

@NoArgsConstructor
@Getter
@Setter
public static class ErrorMessageArg {

private Object value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3361,6 +3361,67 @@ public void initialize() throws Exception {
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_PROGRESSIVE_ADV_PYMNT_BUYDOWN_FEES_CHARGE_OFF_REASON,
responseLoanProductsRequestLP2ProgressiveAdvPaymentBuyDownFeesWithChargeOffReason);

// LP2 with progressive loan schedule + horizontal + interest EMI + 360/30
// + interest recalculation, preClosureInterestCalculationStrategy= till preclose,
// Frequency for recalculate Outstanding Principal: Daily, Frequency Interval for recalculation: 1
// capitalized income enabled; allow approved/disbursed amount over applied amount is enabled with percentage
// type
final String name129 = DefaultLoanProduct.LP2_ADV_PYMNT_INTEREST_DAILY_RECALC_EMI_360_30_MULTIDISB_APPROVED_OVER_APPLIED_CAPITALIZED_INCOME
.getName();
final PostLoanProductsRequest loanProductsRequestLP2ProgressiveAdvPymnt36030InterestRecalcMultidisbApprovedOverAppliedCapitalizedIncome = loanProductsRequestFactory
.defaultLoanProductsRequestLP2EmiCapitalizedIncome()//
.name(name129)//
.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"))) //
.allowApprovedDisbursedAmountsOverApplied(true)//
.overAppliedCalculationType(OverAppliedCalculationType.PERCENTAGE.value)//
.overAppliedNumber(50)//
.multiDisburseLoan(true)//
.disallowExpectedDisbursements(true)//
.maxTrancheCount(10)//
.outstandingLoanBalance(10000.0);//
final Response<PostLoanProductsResponse> responseLoanProductsRequestLP2ProgressiveAdvPymnt36030InterestRecalcMultidisbApprovedOverAppliedCapitalizedIncome = loanProductsApi
.createLoanProduct(
loanProductsRequestLP2ProgressiveAdvPymnt36030InterestRecalcMultidisbApprovedOverAppliedCapitalizedIncome)
.execute();
TestContext.INSTANCE.set(
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_RECALC_EMI_360_30_MULTIDISB_APPROVED_OVER_APPLIED_CAPITALIZED_INCOME,
responseLoanProductsRequestLP2ProgressiveAdvPymnt36030InterestRecalcMultidisbApprovedOverAppliedCapitalizedIncome);

// LP1 with new due-penalty-fee-interest-principal-in-advance-principal-penalty-fee-interest-strategy payment
// strategy and with 12% FLAT interest
// multidisbursal that expects tranche(s)
// (LP1_PAYMENT_STRATEGY_DUE_IN_ADVANCE_INTEREST_FLAT)
String name130 = DefaultLoanProduct.LP1_MULTIDISBURSAL_EXPECTS_TRANCHES.getName();
PostLoanProductsRequest loanProductsRequestMultidisbursalExpectTranches = loanProductsRequestFactory
// .defaultLoanProductsRequestLP1InterestFlat()//
// .interestType(INTEREST_TYPE_DECLINING_BALANCE)//
.defaultLoanProductsRequestLP1() //
.interestCalculationPeriodType(0)//
// .allowApprovedDisbursedAmountsOverApplied(false)//
.name(name130)//
.transactionProcessingStrategyCode(
TransactionProcessingStrategyCode.DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST.value)//
.multiDisburseLoan(true)//
.disallowExpectedDisbursements(false)//
.maxTrancheCount(10)//
.outstandingLoanBalance(10000.0);//
Response<PostLoanProductsResponse> responseLoanProductMultidisbursalExpectTranches = loanProductsApi
.createLoanProduct(loanProductsRequestMultidisbursalExpectTranches).execute();
TestContext.INSTANCE.set(TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP1_MULTIDISBURSAL_EXPECTS_TRANCHES,
responseLoanProductMultidisbursalExpectTranches);

}

public static AdvancedPaymentData createPaymentAllocation(String transactionType, String futureInstallmentAllocationRule,
Expand Down
Loading
Loading