Real time Loan Delinquency Classification

This commit is contained in:
Jose Alberto Hernandez
2022-09-06 12:13:45 +02:00
committed by Arnold Gálovics
parent 17b36a0919
commit 3f1743a3d4
10 changed files with 451 additions and 43 deletions
@@ -36,12 +36,14 @@ import org.apache.fineract.client.models.DeleteDelinquencyBucketResponse;
import org.apache.fineract.client.models.DeleteDelinquencyRangeResponse;
import org.apache.fineract.client.models.GetDelinquencyBucketsResponse;
import org.apache.fineract.client.models.GetDelinquencyRangesResponse;
import org.apache.fineract.client.models.GetDelinquencyTagHistoryResponse;
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentPeriod;
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentSchedule;
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
import org.apache.fineract.client.models.PostDelinquencyBucketResponse;
import org.apache.fineract.client.models.PostDelinquencyRangeResponse;
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
import org.apache.fineract.client.models.PutDelinquencyBucketResponse;
import org.apache.fineract.client.models.PutDelinquencyRangeResponse;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
@@ -63,6 +65,7 @@ public class DelinquencyBucketsIntegrationTest {
private ResponseSpecification responseSpec;
private RequestSpecification requestSpec;
private static final String principalAmount = "10000";
@BeforeEach
public void setup() {
@@ -259,27 +262,22 @@ public class DelinquencyBucketsIntegrationTest {
final GetDelinquencyBucketsResponse delinquencyBucket = DelinquencyBucketsHelper.getDelinquencyBucket(requestSpec, responseSpec,
delinquencyBucketResponse.getResourceId());
// Client and Loan account creation
final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2012");
final HashMap<String, Object> loanProductMap = new LoanProductTestBuilder().build(null, delinquencyBucket.getId());
final Integer loanProductId = loanTransactionHelper.getLoanProductId(Utils.convertToJson(loanProductMap));
final GetLoanProductsProductIdResponse getLoanProductsProductResponse = loanTransactionHelper.getLoanProduct(loanProductId);
final GetLoanProductsProductIdResponse getLoanProductsProductResponse = createLoanProduct(loanTransactionHelper,
delinquencyBucket.getId());
assertNotNull(getLoanProductsProductResponse);
log.info("Loan Product Bucket Name: {}", getLoanProductsProductResponse.getDelinquencyBucket().getName());
assertEquals(getLoanProductsProductResponse.getDelinquencyBucket().getName(), delinquencyBucket.getName());
final String operationDate = Utils.dateFormatter.format(businessDate);
final String principalAmount = "10000";
final LocalDate todaysDate = Utils.getLocalDateOfTenant();
// Older date to have more than one overdue installment
final LocalDate transactionDate = todaysDate.minusDays(65);
String operationDate = Utils.dateFormatter.format(transactionDate);
String loanApplicationJSON = new LoanApplicationTestBuilder().withPrincipal(principalAmount).withLoanTermFrequency("12")
.withLoanTermFrequencyAsMonths().withNumberOfRepayments("12").withRepaymentEveryAfter("1")
.withRepaymentFrequencyTypeAsMonths() //
.withInterestRatePerPeriod("2") //
.withExpectedDisbursementDate(operationDate) //
.withInterestTypeAsDecliningBalance() //
.withSubmittedOnDate(operationDate) //
.build(clientId.toString(), loanProductId.toString(), null);
final Integer loanId = loanTransactionHelper.getLoanId(loanApplicationJSON);
loanTransactionHelper.approveLoan(operationDate, principalAmount, loanId, null);
loanTransactionHelper.disburseLoanWithNetDisbursalAmount(operationDate, loanId, principalAmount);
// Create Loan Account
final Integer loanId = createLoanAccount(loanTransactionHelper, clientId.toString(),
getLoanProductsProductResponse.getId().toString(), operationDate);
// When
// Run first time the Job
@@ -294,7 +292,8 @@ public class DelinquencyBucketsIntegrationTest {
if (getLoanRepaymentSchedule != null) {
log.info("Loan with {} periods", getLoanRepaymentSchedule.getPeriods().size());
for (GetLoansLoanIdRepaymentPeriod period : getLoanRepaymentSchedule.getPeriods()) {
log.info("Period number {} for due date {}", period.getPeriod(), period.getDueDate());
log.info("Period number {} for due date {} and outstanding {}", period.getPeriod(), period.getDueDate(),
period.getTotalOutstandingForPeriod());
}
}
@@ -321,4 +320,324 @@ public class DelinquencyBucketsIntegrationTest {
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
}
@Test
public void testLoanClassificationRealtime() {
// Given
final LoanTransactionHelper loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
ArrayList<Integer> rangeIds = new ArrayList<>();
// First Range
String jsonRange = DelinquencyRangesHelper.getAsJSON(1, 3);
PostDelinquencyRangeResponse delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec, responseSpec,
jsonRange);
rangeIds.add(delinquencyRangeResponse.getResourceId());
jsonRange = DelinquencyRangesHelper.getAsJSON(4, 60);
GetDelinquencyRangesResponse range = DelinquencyRangesHelper.getDelinquencyRange(requestSpec, responseSpec,
delinquencyRangeResponse.getResourceId());
// Second Range
delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec, responseSpec, jsonRange);
rangeIds.add(delinquencyRangeResponse.getResourceId());
range = DelinquencyRangesHelper.getDelinquencyRange(requestSpec, responseSpec, delinquencyRangeResponse.getResourceId());
final String classificationExpected = range.getClassification();
log.info("Expected Delinquency Range classification after Disbursement {}", classificationExpected);
String jsonBucket = DelinquencyBucketsHelper.getAsJSON(rangeIds);
PostDelinquencyBucketResponse delinquencyBucketResponse = DelinquencyBucketsHelper.createDelinquencyBucket(requestSpec,
responseSpec, jsonBucket);
assertNotNull(delinquencyBucketResponse);
final GetDelinquencyBucketsResponse delinquencyBucket = DelinquencyBucketsHelper.getDelinquencyBucket(requestSpec, responseSpec,
delinquencyBucketResponse.getResourceId());
// Client and Loan account creation
final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2012");
final GetLoanProductsProductIdResponse getLoanProductsProductResponse = createLoanProduct(loanTransactionHelper,
delinquencyBucket.getId());
assertNotNull(getLoanProductsProductResponse);
log.info("Loan Product Bucket Name: {}", getLoanProductsProductResponse.getDelinquencyBucket().getName());
assertEquals(getLoanProductsProductResponse.getDelinquencyBucket().getName(), delinquencyBucket.getName());
final LocalDate todaysDate = Utils.getLocalDateOfTenant();
// Older date to have more than one overdue installment
final LocalDate transactionDate = todaysDate.minusDays(45);
String operationDate = Utils.dateFormatter.format(transactionDate);
// Create Loan Account
final Integer loanId = createLoanAccount(loanTransactionHelper, clientId.toString(),
getLoanProductsProductResponse.getId().toString(), operationDate);
GetLoansLoanIdResponse getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
log.info("Loan Delinquency Range after Disbursement {}", getLoansLoanIdResponse.getDelinquencyRange().getClassification());
assertNotNull(getLoansLoanIdResponse);
// First Loan Delinquency Classification after Disbursement command
assertEquals(getLoansLoanIdResponse.getDelinquencyRange().getClassification(), classificationExpected);
printRepaymentSchedule(getLoansLoanIdResponse);
// Apply a partial repayment
operationDate = Utils.dateFormatter.format(todaysDate);
loanTransactionHelper.makeLoanRepayment(operationDate, 100.0f, loanId);
getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
log.info("Loan Delinquency Range after Repayment {}", getLoansLoanIdResponse.getDelinquencyRange());
assertNotNull(getLoansLoanIdResponse.getDelinquencyRange());
// First Loan Delinquency Classification remains after Repayment because the installment is not fully paid
assertEquals(getLoansLoanIdResponse.getDelinquencyRange().getClassification(), classificationExpected);
// Apply a repayment to get a full paid installment
loanTransactionHelper.makeLoanRepayment(operationDate, 1000.0f, loanId);
getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
log.info("Loan Delinquency Range after Repayment {}", getLoansLoanIdResponse.getDelinquencyRange());
assertNotNull(getLoansLoanIdResponse);
// The Loan Delinquency Classification after Repayment command must be null
assertNull(getLoansLoanIdResponse.getDelinquencyRange());
// Get the Delinquency Tags
ArrayList<GetDelinquencyTagHistoryResponse> getDelinquencyTagsHistory = loanTransactionHelper.getLoanDelinquencyTags(requestSpec,
responseSpec, loanId);
assertNotNull(getDelinquencyTagsHistory);
log.info("Delinquency Tag History items {}", getDelinquencyTagsHistory.size());
assertEquals(1, getDelinquencyTagsHistory.size());
assertNotNull(getDelinquencyTagsHistory.get(0).getLiftedOnDate());
assertEquals(getDelinquencyTagsHistory.get(0).getAddedOnDate(), Utils.getLocalDateOfTenant());
assertEquals(getDelinquencyTagsHistory.get(0).getLiftedOnDate(), Utils.getLocalDateOfTenant());
assertEquals(getDelinquencyTagsHistory.get(0).getDelinquencyRange().getClassification(), classificationExpected);
log.info("Delinquency Tag Item with Lifted On {}", getDelinquencyTagsHistory.get(0).getLiftedOnDate());
}
@Test
public void testLoanClassificationRealtimeOlderLoan() {
// Given
final LoanTransactionHelper loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
ArrayList<Integer> rangeIds = new ArrayList<>();
// First Range
String jsonRange = DelinquencyRangesHelper.getAsJSON(4, 30);
PostDelinquencyRangeResponse delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec, responseSpec,
jsonRange);
rangeIds.add(delinquencyRangeResponse.getResourceId());
GetDelinquencyRangesResponse range = DelinquencyRangesHelper.getDelinquencyRange(requestSpec, responseSpec,
delinquencyRangeResponse.getResourceId());
final String classificationExpected02 = range.getClassification();
log.info("Expected Delinquency Range classification after first repayment {}", classificationExpected02);
// Second Range
jsonRange = DelinquencyRangesHelper.getAsJSON(31, 60);
delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec, responseSpec, jsonRange);
rangeIds.add(delinquencyRangeResponse.getResourceId());
range = DelinquencyRangesHelper.getDelinquencyRange(requestSpec, responseSpec, delinquencyRangeResponse.getResourceId());
final String classificationExpected01 = range.getClassification();
log.info("Expected Delinquency Range classification after Disbursement {}", classificationExpected01);
// Third Range
jsonRange = DelinquencyRangesHelper.getAsJSON(61, 90);
delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec, responseSpec, jsonRange);
rangeIds.add(delinquencyRangeResponse.getResourceId());
range = DelinquencyRangesHelper.getDelinquencyRange(requestSpec, responseSpec, delinquencyRangeResponse.getResourceId());
String jsonBucket = DelinquencyBucketsHelper.getAsJSON(rangeIds);
PostDelinquencyBucketResponse delinquencyBucketResponse = DelinquencyBucketsHelper.createDelinquencyBucket(requestSpec,
responseSpec, jsonBucket);
assertNotNull(delinquencyBucketResponse);
final GetDelinquencyBucketsResponse delinquencyBucket = DelinquencyBucketsHelper.getDelinquencyBucket(requestSpec, responseSpec,
delinquencyBucketResponse.getResourceId());
// Client and Loan account creation
final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2012");
final GetLoanProductsProductIdResponse getLoanProductsProductResponse = createLoanProduct(loanTransactionHelper,
delinquencyBucket.getId());
assertNotNull(getLoanProductsProductResponse);
log.info("Loan Product Bucket Name: {}", getLoanProductsProductResponse.getDelinquencyBucket().getName());
assertEquals(getLoanProductsProductResponse.getDelinquencyBucket().getName(), delinquencyBucket.getName());
final LocalDate todaysDate = Utils.getLocalDateOfTenant();
// Older date to have more than one overdue installment
final LocalDate transactionDate = todaysDate.minusDays(85);
String operationDate = Utils.dateFormatter.format(transactionDate);
// Create Loan Account
final Integer loanId = createLoanAccount(loanTransactionHelper, clientId.toString(),
getLoanProductsProductResponse.getId().toString(), operationDate);
GetLoansLoanIdResponse getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
assertNotNull(getLoansLoanIdResponse);
log.info("Loan Delinquency Range after Disbursement in null? {}", (getLoansLoanIdResponse.getDelinquencyRange() == null));
assertNotNull(getLoansLoanIdResponse.getDelinquencyRange());
log.info("Loan Delinquency Range after Disbursement {}", getLoansLoanIdResponse.getDelinquencyRange());
// First Loan Delinquency Classification after Disbursement command
assertEquals(getLoansLoanIdResponse.getDelinquencyRange().getClassification(), classificationExpected01);
printRepaymentSchedule(getLoansLoanIdResponse);
// Apply a repayment to get a first full paid installment
operationDate = Utils.dateFormatter.format(todaysDate);
PostLoansLoanIdTransactionsResponse loansLoanIdTransactions = loanTransactionHelper.makeLoanRepayment(operationDate, 1050.0f,
loanId);
assertNotNull(loansLoanIdTransactions);
log.info("Loan repayment transaction id {}", loansLoanIdTransactions.getResourceId());
getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
log.info("Loan Delinquency Range after first Repayment {}", getLoansLoanIdResponse.getDelinquencyRange());
assertNotNull(getLoansLoanIdResponse.getDelinquencyRange());
// First Loan Delinquency Classification remains after Repayment because the installment is not fully paid
assertEquals(getLoansLoanIdResponse.getDelinquencyRange().getClassification(), classificationExpected02);
ArrayList<GetDelinquencyTagHistoryResponse> getDelinquencyTagsHistory = loanTransactionHelper.getLoanDelinquencyTags(requestSpec,
responseSpec, loanId);
assertNotNull(getDelinquencyTagsHistory);
log.info("Delinquency Tag History items {}", getDelinquencyTagsHistory.size());
log.info("Delinquency Tag Item with Lifted On {}", getDelinquencyTagsHistory.get(0).getLiftedOnDate());
assertEquals(getDelinquencyTagsHistory.get(0).getAddedOnDate(), Utils.getLocalDateOfTenant());
assertEquals(getDelinquencyTagsHistory.get(0).getLiftedOnDate(), Utils.getLocalDateOfTenant());
assertEquals(getDelinquencyTagsHistory.get(0).getDelinquencyRange().getClassification(), classificationExpected01);
log.info("Loan Id {} with Loan status {}", getLoansLoanIdResponse.getId(), getLoansLoanIdResponse.getStatus().getCode());
// Apply a repayment to get a second full paid installment
loansLoanIdTransactions = loanTransactionHelper.makeLoanRepayment(operationDate, 1020.0f, loanId);
assertNotNull(loansLoanIdTransactions);
log.info("Loan repayment transaction id {}", loansLoanIdTransactions.getResourceId());
getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
log.info("Loan Delinquency Range after second Repayment {}", getLoansLoanIdResponse.getDelinquencyRange());
assertNotNull(getLoansLoanIdResponse);
// The Loan Delinquency Classification after Repayment command must be null
assertNull(getLoansLoanIdResponse.getDelinquencyRange());
getDelinquencyTagsHistory = loanTransactionHelper.getLoanDelinquencyTags(requestSpec, responseSpec, loanId);
assertNotNull(getDelinquencyTagsHistory);
log.info("Delinquency Tag History items {}", getDelinquencyTagsHistory.size());
log.info("Delinquency Tag Item with Lifted On {}", getDelinquencyTagsHistory.get(1).getLiftedOnDate());
assertEquals(getDelinquencyTagsHistory.get(1).getAddedOnDate(), Utils.getLocalDateOfTenant());
assertEquals(getDelinquencyTagsHistory.get(1).getLiftedOnDate(), Utils.getLocalDateOfTenant());
assertEquals(getDelinquencyTagsHistory.get(1).getDelinquencyRange().getClassification(), classificationExpected02);
log.info("Loan Id {} with final Loan status {}", getLoansLoanIdResponse.getId(), getLoansLoanIdResponse.getStatus().getCode());
}
@Test
public void testLoanClassificationRealtimeWithReversedRepayment() {
// Given
final LoanTransactionHelper loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
ArrayList<Integer> rangeIds = new ArrayList<>();
// First Range
String jsonRange = DelinquencyRangesHelper.getAsJSON(4, 30);
PostDelinquencyRangeResponse delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec, responseSpec,
jsonRange);
rangeIds.add(delinquencyRangeResponse.getResourceId());
GetDelinquencyRangesResponse range = DelinquencyRangesHelper.getDelinquencyRange(requestSpec, responseSpec,
delinquencyRangeResponse.getResourceId());
final String classificationExpected = range.getClassification();
log.info("Expected Delinquency Range classification after first repayment {}", classificationExpected);
String jsonBucket = DelinquencyBucketsHelper.getAsJSON(rangeIds);
PostDelinquencyBucketResponse delinquencyBucketResponse = DelinquencyBucketsHelper.createDelinquencyBucket(requestSpec,
responseSpec, jsonBucket);
assertNotNull(delinquencyBucketResponse);
final GetDelinquencyBucketsResponse delinquencyBucket = DelinquencyBucketsHelper.getDelinquencyBucket(requestSpec, responseSpec,
delinquencyBucketResponse.getResourceId());
// Client and Loan account creation
final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2012");
final GetLoanProductsProductIdResponse getLoanProductsProductResponse = createLoanProduct(loanTransactionHelper,
delinquencyBucket.getId());
assertNotNull(getLoanProductsProductResponse);
log.info("Loan Product Bucket Name: {}", getLoanProductsProductResponse.getDelinquencyBucket().getName());
assertEquals(getLoanProductsProductResponse.getDelinquencyBucket().getName(), delinquencyBucket.getName());
final LocalDate todaysDate = Utils.getLocalDateOfTenant();
// Older date to have more than one overdue installment
final LocalDate transactionDate = todaysDate.minusDays(45);
String operationDate = Utils.dateFormatter.format(transactionDate);
// Create Loan Account
final Integer loanId = createLoanAccount(loanTransactionHelper, clientId.toString(),
getLoanProductsProductResponse.getId().toString(), operationDate);
GetLoansLoanIdResponse getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
assertNotNull(getLoansLoanIdResponse);
log.info("Loan Delinquency Range after Disbursement in null? {}", (getLoansLoanIdResponse.getDelinquencyRange() == null));
assertNotNull(getLoansLoanIdResponse.getDelinquencyRange());
log.info("Loan Delinquency Range after Disbursement {}", getLoansLoanIdResponse.getDelinquencyRange());
// First Loan Delinquency Classification after Disbursement command
assertEquals(getLoansLoanIdResponse.getDelinquencyRange().getClassification(), classificationExpected);
printRepaymentSchedule(getLoansLoanIdResponse);
// Apply a repayment to get a full paid installment
operationDate = Utils.dateFormatter.format(todaysDate);
PostLoansLoanIdTransactionsResponse loansLoanIdTransactions = loanTransactionHelper.makeLoanRepayment(operationDate, 1050.0f,
loanId);
assertNotNull(loansLoanIdTransactions);
log.info("Loan repayment transaction id {}", loansLoanIdTransactions.getResourceId());
getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
log.info("Loan Delinquency Range after Repayment {}", getLoansLoanIdResponse.getDelinquencyRange());
// Loan Delinquency Classification removed after Repayment because the installment is fully paid
assertNull(getLoansLoanIdResponse.getDelinquencyRange());
ArrayList<GetDelinquencyTagHistoryResponse> getDelinquencyTagsHistory = loanTransactionHelper.getLoanDelinquencyTags(requestSpec,
responseSpec, loanId);
assertNotNull(getDelinquencyTagsHistory);
log.info("Delinquency Tag History items {}", getDelinquencyTagsHistory.size());
log.info("Delinquency Tag Item with Lifted On {}", getDelinquencyTagsHistory.get(0).getLiftedOnDate());
assertEquals(getDelinquencyTagsHistory.get(0).getAddedOnDate(), Utils.getLocalDateOfTenant());
assertEquals(getDelinquencyTagsHistory.get(0).getLiftedOnDate(), Utils.getLocalDateOfTenant());
assertEquals(getDelinquencyTagsHistory.get(0).getDelinquencyRange().getClassification(), classificationExpected);
log.info("Loan Id {} with Loan status {}", getLoansLoanIdResponse.getId(), getLoansLoanIdResponse.getStatus().getCode());
// Reverse the Previous Loan Repayment
PostLoansLoanIdTransactionsResponse loansLoanIdReverseTransactions = loanTransactionHelper.reverseLoanRepayment(loanId,
loansLoanIdTransactions.getResourceId(), operationDate);
assertNotNull(loansLoanIdReverseTransactions);
log.info("Loan repayment reverse transaction id {}", loansLoanIdReverseTransactions.getResourceId());
getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
log.info("Loan Delinquency Range after Reverse Repayment {}", getLoansLoanIdResponse.getDelinquencyRange());
// Loan Delinquency Classification goes back after Repayment because the installment is not paid
assertEquals(getLoansLoanIdResponse.getDelinquencyRange().getClassification(), classificationExpected);
getDelinquencyTagsHistory = loanTransactionHelper.getLoanDelinquencyTags(requestSpec, responseSpec, loanId);
assertNotNull(getDelinquencyTagsHistory);
log.info("Delinquency Tag History items {}", getDelinquencyTagsHistory.size());
log.info("Delinquency Tag Item with Lifted On {}", getDelinquencyTagsHistory.get(1).getLiftedOnDate());
assertEquals(getDelinquencyTagsHistory.get(1).getAddedOnDate(), Utils.getLocalDateOfTenant());
// Second record is open with liftedOn in null
assertNull(getDelinquencyTagsHistory.get(1).getLiftedOnDate());
assertEquals(getDelinquencyTagsHistory.get(1).getDelinquencyRange().getClassification(), classificationExpected);
log.info("Loan Id {} with final Loan status {}", getLoansLoanIdResponse.getId(), getLoansLoanIdResponse.getStatus().getCode());
}
private GetLoanProductsProductIdResponse createLoanProduct(final LoanTransactionHelper loanTransactionHelper,
final Integer delinquencyBucketId) {
final HashMap<String, Object> loanProductMap = new LoanProductTestBuilder().build(null, delinquencyBucketId);
final Integer loanProductId = loanTransactionHelper.getLoanProductId(Utils.convertToJson(loanProductMap));
return loanTransactionHelper.getLoanProduct(loanProductId);
}
private Integer createLoanAccount(final LoanTransactionHelper loanTransactionHelper, final String clientId, final String loanProductId,
final String operationDate) {
final String loanApplicationJSON = new LoanApplicationTestBuilder().withPrincipal(principalAmount).withLoanTermFrequency("12")
.withLoanTermFrequencyAsMonths().withNumberOfRepayments("12").withRepaymentEveryAfter("1")
.withRepaymentFrequencyTypeAsMonths() //
.withInterestRatePerPeriod("2") //
.withExpectedDisbursementDate(operationDate) //
.withInterestTypeAsDecliningBalance() //
.withSubmittedOnDate(operationDate) //
.build(clientId, loanProductId, null);
final Integer loanId = loanTransactionHelper.getLoanId(loanApplicationJSON);
loanTransactionHelper.approveLoan(operationDate, principalAmount, loanId, null);
loanTransactionHelper.disburseLoanWithNetDisbursalAmount(operationDate, loanId, principalAmount);
return loanId;
}
private void printRepaymentSchedule(GetLoansLoanIdResponse getLoansLoanIdResponse) {
GetLoansLoanIdRepaymentSchedule getLoanRepaymentSchedule = getLoansLoanIdResponse.getRepaymentSchedule();
if (getLoanRepaymentSchedule != null) {
log.info("Loan with {} periods", getLoanRepaymentSchedule.getPeriods().size());
for (GetLoansLoanIdRepaymentPeriod period : getLoanRepaymentSchedule.getPeriods()) {
log.info("Period number {} for due date {} and outstanding {}", period.getPeriod(), period.getDueDate(),
period.getTotalOutstandingForPeriod());
}
}
}
}
@@ -22,12 +22,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.google.gson.Gson;
import com.linecorp.armeria.internal.shaded.guava.reflect.TypeToken;
import io.restassured.specification.RequestSpecification;
import io.restassured.specification.ResponseSpecification;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
@@ -38,8 +40,10 @@ import java.util.Map;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.client.models.GetDelinquencyTagHistoryResponse;
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
import org.apache.fineract.client.util.JSON;
import org.apache.fineract.integrationtests.common.CommonConstants;
import org.apache.fineract.integrationtests.common.Utils;
@@ -188,6 +192,14 @@ public class LoanTransactionHelper {
return Utils.performServerGet(requestSpec, responseSpec, URL, null);
}
public ArrayList<GetDelinquencyTagHistoryResponse> getLoanDelinquencyTags(final RequestSpecification requestSpec,
final ResponseSpecification responseSpec, final Integer loanID) {
final String URL = "/fineract-provider/api/v1/loans/" + loanID + "/delinquencytags?" + Utils.TENANT_IDENTIFIER;
final String response = Utils.performServerGet(requestSpec, responseSpec, URL);
Type delinquencyTagsListType = new TypeToken<ArrayList<GetDelinquencyTagHistoryResponse>>() {}.getType();
return GSON.fromJson(response, delinquencyTagsListType);
}
public Object getLoanProductDetail(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final Integer loanProductId, final String jsonAttributeToGetBack) {
final String URL = "/fineract-provider/api/v1/loanproducts/" + loanProductId + "?associations=all&" + Utils.TENANT_IDENTIFIER;
@@ -397,6 +409,14 @@ public class LoanTransactionHelper {
return (HashMap) performLoanTransaction(createLoanTransactionURL(UNDO, loanId, transactionId), getUndoJsonBody(date), "");
}
public PostLoansLoanIdTransactionsResponse makeLoanRepayment(final String date, final Float amountToBePaid, final Integer loanID) {
return postLoanTransaction(createLoanTransactionURL(MAKE_REPAYMENT_COMMAND, loanID), getRepaymentBodyAsJSON(date, amountToBePaid));
}
public PostLoansLoanIdTransactionsResponse reverseLoanRepayment(final Integer loanId, final Integer transactionId, String date) {
return postLoanTransaction(createLoanTransactionURL(UNDO, loanId, transactionId), getUndoJsonBody(date));
}
public HashMap makeRepaymentWithPDC(final String date, final Float amountToBePaid, final Integer loanID, final Integer paymentType) {
return (HashMap) performLoanTransaction(createLoanTransactionURL(MAKE_REPAYMENT_COMMAND, loanID),
getRepaymentWithPDCBodyAsJSON(date, amountToBePaid, paymentType), "");
@@ -785,7 +805,6 @@ public class LoanTransactionHelper {
}
private HashMap performLoanTransaction(final String postURLForLoanTransaction, final String jsonToBeSent) {
final HashMap response = Utils.performServerPost(this.requestSpec, this.responseSpec, postURLForLoanTransaction, jsonToBeSent,
"changes");
return (HashMap) response.get("status");
@@ -803,6 +822,11 @@ public class LoanTransactionHelper {
return Utils.performServerPost(this.requestSpec, this.responseSpec, postURLForLoanTransaction, jsonToBeSent, responseAttribute);
}
private PostLoansLoanIdTransactionsResponse postLoanTransaction(final String postURLForLoanTransaction, final String jsonToBeSent) {
final String response = Utils.performServerPost(this.requestSpec, this.responseSpec, postURLForLoanTransaction, jsonToBeSent);
return GSON.fromJson(response, PostLoansLoanIdTransactionsResponse.class);
}
private Object performLoanTransaction(final String postURLForLoanTransaction, final String jsonToBeSent,
ResponseSpecification responseValidationError) {