FINERACT-2389: Fix the handling of nullable field overrides
This commit is contained in:
committed by
Adam Saghy
parent
b32837e9b4
commit
adc4ee3545
+2
@@ -170,6 +170,8 @@ public enum DefaultLoanProduct implements LoanProduct {
|
||||
LP1_INTEREST_FLAT_DAILY_RECALCULATION_DAILY_360_30_MULTIDISB, //
|
||||
LP1_INTEREST_FLAT_SAR_RECALCULATION_SAME_AS_REPAYMENT_MULTIDISB_AUTO_DOWNPAYMENT, //
|
||||
LP2_ADV_CUSTOM_PMT_ALLOC_PROGRESSIVE_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY, //
|
||||
LP1_WITH_OVERRIDES, //
|
||||
LP1_NO_OVERRIDES //
|
||||
;
|
||||
|
||||
@Override
|
||||
|
||||
+49
@@ -36,6 +36,7 @@ import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.client.models.AdvancedPaymentData;
|
||||
import org.apache.fineract.client.models.AllowAttributeOverrides;
|
||||
import org.apache.fineract.client.models.CreditAllocationData;
|
||||
import org.apache.fineract.client.models.CreditAllocationOrder;
|
||||
import org.apache.fineract.client.models.LoanProductChargeData;
|
||||
@@ -4056,6 +4057,54 @@ public class LoanProductGlobalInitializerStep implements FineractGlobalInitializ
|
||||
TestContext.INSTANCE.set(
|
||||
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_CUSTOM_PMT_ALLOC_PROGRESSIVE_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY,
|
||||
responseLoanProductsResponseAdvCustomPaymentAllocationProgressiveLoanInterestDailyEmi36030InterestRecalculationDaily);
|
||||
|
||||
// (LP1_WITH_OVERRIDES) - Loan product with all attribute overrides ENABLED
|
||||
final String nameWithOverrides = DefaultLoanProduct.LP1_WITH_OVERRIDES.getName();
|
||||
final PostLoanProductsRequest loanProductsRequestWithOverrides = loanProductsRequestFactory.defaultLoanProductsRequestLP1() //
|
||||
.name(nameWithOverrides) //
|
||||
.interestRatePerPeriod(1.0) //
|
||||
.maxInterestRatePerPeriod(30.0) //
|
||||
.inArrearsTolerance(10) //
|
||||
.graceOnPrincipalPayment(1) //
|
||||
.graceOnInterestPayment(1) //
|
||||
.graceOnArrearsAgeing(3) //
|
||||
.numberOfRepayments(6) //
|
||||
.allowAttributeOverrides(new AllowAttributeOverrides() //
|
||||
.amortizationType(true) //
|
||||
.interestType(true) //
|
||||
.transactionProcessingStrategyCode(true) //
|
||||
.interestCalculationPeriodType(true) //
|
||||
.inArrearsTolerance(true) //
|
||||
.repaymentEvery(true) //
|
||||
.graceOnPrincipalAndInterestPayment(true) //
|
||||
.graceOnArrearsAgeing(true));
|
||||
final Response<PostLoanProductsResponse> responseWithOverrides = loanProductsApi.createLoanProduct(loanProductsRequestWithOverrides)
|
||||
.execute();
|
||||
TestContext.INSTANCE.set(TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP1_WITH_OVERRIDES, responseWithOverrides);
|
||||
|
||||
// (LP1_NO_OVERRIDES) - Loan product with all attribute overrides DISABLED
|
||||
final String nameNoOverrides = DefaultLoanProduct.LP1_NO_OVERRIDES.getName();
|
||||
final PostLoanProductsRequest loanProductsRequestNoOverrides = loanProductsRequestFactory.defaultLoanProductsRequestLP1() //
|
||||
.name(nameNoOverrides) //
|
||||
.interestRatePerPeriod(1.0) //
|
||||
.maxInterestRatePerPeriod(30.0) //
|
||||
.inArrearsTolerance(10) //
|
||||
.graceOnPrincipalPayment(1) //
|
||||
.graceOnInterestPayment(1) //
|
||||
.graceOnArrearsAgeing(3) //
|
||||
.numberOfRepayments(6) //
|
||||
.allowAttributeOverrides(new AllowAttributeOverrides() //
|
||||
.amortizationType(false) //
|
||||
.interestType(false) //
|
||||
.transactionProcessingStrategyCode(false) //
|
||||
.interestCalculationPeriodType(false) //
|
||||
.inArrearsTolerance(false) //
|
||||
.repaymentEvery(false) //
|
||||
.graceOnPrincipalAndInterestPayment(false) //
|
||||
.graceOnArrearsAgeing(false));
|
||||
final Response<PostLoanProductsResponse> responseNoOverrides = loanProductsApi.createLoanProduct(loanProductsRequestNoOverrides)
|
||||
.execute();
|
||||
TestContext.INSTANCE.set(TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP1_NO_OVERRIDES, responseNoOverrides);
|
||||
}
|
||||
|
||||
public static AdvancedPaymentData createPaymentAllocation(String transactionType, String futureInstallmentAllocationRule,
|
||||
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* 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.stepdef.loan;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
import io.cucumber.datatable.DataTable;
|
||||
import io.cucumber.java.en.Then;
|
||||
import io.cucumber.java.en.When;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Map;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
|
||||
import org.apache.fineract.client.models.PostClientsResponse;
|
||||
import org.apache.fineract.client.models.PostLoansRequest;
|
||||
import org.apache.fineract.client.models.PostLoansResponse;
|
||||
import org.apache.fineract.client.services.LoansApi;
|
||||
import org.apache.fineract.test.data.loanproduct.DefaultLoanProduct;
|
||||
import org.apache.fineract.test.data.loanproduct.LoanProductResolver;
|
||||
import org.apache.fineract.test.factory.LoanRequestFactory;
|
||||
import org.apache.fineract.test.helper.ErrorHelper;
|
||||
import org.apache.fineract.test.stepdef.AbstractStepDef;
|
||||
import org.apache.fineract.test.support.TestContextKey;
|
||||
import retrofit2.Response;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class LoanOverrideFieldsStepDef extends AbstractStepDef {
|
||||
|
||||
private final LoanRequestFactory loanRequestFactory;
|
||||
private final LoanProductResolver loanProductResolver;
|
||||
private final LoansApi loansApi;
|
||||
|
||||
@Then("LoanDetails has {string} field with value: {string}")
|
||||
public void checkLoanDetailsFieldWithValue(final String fieldName, final String expectedValue) throws IOException {
|
||||
final Response<PostLoansResponse> loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
|
||||
assertNotNull(loanResponse.body());
|
||||
final Long loanId = loanResponse.body().getLoanId();
|
||||
|
||||
final Response<GetLoansLoanIdResponse> loanDetails = loansApi.retrieveLoan(loanId, false, "", "", "").execute();
|
||||
ErrorHelper.checkSuccessfulApiCall(loanDetails);
|
||||
assertNotNull(loanDetails.body());
|
||||
|
||||
verifyFieldValue(loanDetails.body(), fieldName, expectedValue);
|
||||
}
|
||||
|
||||
private void verifyFieldValue(final GetLoansLoanIdResponse loanDetails, final String fieldName, final String expectedValue) {
|
||||
final Integer actualValue = getIntFieldValue(loanDetails, fieldName);
|
||||
final Integer expected = Integer.valueOf(expectedValue);
|
||||
assertThat(actualValue).as("Expected %s to be %d but was %s", fieldName, expected, actualValue).isEqualTo(expected);
|
||||
}
|
||||
|
||||
private Integer getIntFieldValue(final GetLoansLoanIdResponse loanDetails, final String fieldName) {
|
||||
return switch (fieldName) {
|
||||
case "inArrearsTolerance" -> loanDetails.getInArrearsTolerance();
|
||||
case "graceOnPrincipalPayment" -> loanDetails.getGraceOnPrincipalPayment();
|
||||
case "graceOnInterestPayment" -> loanDetails.getGraceOnInterestPayment();
|
||||
case "graceOnArrearsAgeing" -> loanDetails.getGraceOnArrearsAgeing();
|
||||
default -> throw new IllegalArgumentException("Unknown override field: " + fieldName);
|
||||
};
|
||||
}
|
||||
|
||||
@When("Admin creates a new Loan with the following override data:")
|
||||
public void createLoanWithOverrideData(final DataTable dataTable) throws IOException {
|
||||
final Response<PostClientsResponse> clientResponse = testContext().get(TestContextKey.CLIENT_CREATE_RESPONSE);
|
||||
assertNotNull(clientResponse.body());
|
||||
final Long clientId = clientResponse.body().getClientId();
|
||||
|
||||
final Map<String, String> overrideData = dataTable.asMap(String.class, String.class);
|
||||
|
||||
final String loanProductName = overrideData.get("loanProduct");
|
||||
if (loanProductName == null) {
|
||||
throw new IllegalArgumentException("loanProduct is required in override data");
|
||||
}
|
||||
|
||||
final PostLoansRequest loansRequest = loanRequestFactory.defaultLoansRequest(clientId)
|
||||
.productId(loanProductResolver.resolve(DefaultLoanProduct.valueOf(loanProductName))).numberOfRepayments(6)
|
||||
.loanTermFrequency(180).interestRatePerPeriod(new BigDecimal(1));
|
||||
|
||||
overrideData.forEach((fieldName, value) -> {
|
||||
if (!"loanProduct".equals(fieldName)) {
|
||||
applyOverrideField(loansRequest, fieldName, value);
|
||||
}
|
||||
});
|
||||
|
||||
final Response<PostLoansResponse> response = loansApi.calculateLoanScheduleOrSubmitLoanApplication(loansRequest, "").execute();
|
||||
testContext().set(TestContextKey.LOAN_CREATE_RESPONSE, response);
|
||||
ErrorHelper.checkSuccessfulApiCall(response);
|
||||
}
|
||||
|
||||
private void applyOverrideField(final PostLoansRequest request, final String fieldName, final String value) {
|
||||
final boolean isNull = "null".equals(value);
|
||||
|
||||
switch (fieldName) {
|
||||
case "inArrearsTolerance" -> request.inArrearsTolerance(isNull ? null : new BigDecimal(value));
|
||||
case "graceOnInterestPayment" -> request.graceOnInterestPayment(isNull ? null : Integer.valueOf(value));
|
||||
case "graceOnPrincipalPayment" -> request.graceOnPrincipalPayment(isNull ? null : Integer.valueOf(value));
|
||||
case "graceOnArrearsAgeing" -> request.graceOnArrearsAgeing(isNull ? null : Integer.valueOf(value));
|
||||
default -> throw new IllegalArgumentException("Unknown override field: " + fieldName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+2
@@ -275,4 +275,6 @@ public abstract class TestContextKey {
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_PROGRESSIVE_ADV_PYMNT_INTEREST_RECALC_360_30_MULTIDISB_OVER_APPLIED_EXPECTED_TRANCHES = "loanProductCreateResponseLP2ProgressiveAdvancedPaymentInterestRecalculationMultidisbursalApprovedOverAppliedAmountExpectedTransches";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY_TILL_PRECLOSE_MIN_INT_3_MAX_INT_20 = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030InterestRecalculationDailyTillPreCloseMinInt3MaxInt20";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_PROGRESSIVE_ADV_PYMNT_WRITE_OFF_REASON_MAP = "loanProductCreateResponseLP2ProgressiveAdvancedPaymentWriteOffReasonMap";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP1_WITH_OVERRIDES = "loanProductCreateResponseLP1WithOverrides";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP1_NO_OVERRIDES = "loanProductCreateResponseLP1NoOverrides";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user