blob: 88c3b484cd1c11d6a6833a53b7c3915c4cdfa405 [file] [log] [blame]
/**
* 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.integrationtests;
import static org.apache.fineract.portfolio.delinquency.domain.DelinquencyAction.PAUSE;
import static org.apache.fineract.portfolio.delinquency.domain.DelinquencyAction.RESUME;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.google.gson.Gson;
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.builder.ResponseSpecBuilder;
import io.restassured.http.ContentType;
import io.restassured.specification.RequestSpecification;
import io.restassured.specification.ResponseSpecification;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.fineract.client.models.BusinessDateResponse;
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.GetLoansLoanIdDelinquencySummary;
import org.apache.fineract.client.models.GetLoansLoanIdLoanInstallmentLevelDelinquency;
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.PostLoansDelinquencyActionResponse;
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.client.models.PutLoanProductsProductIdRequest;
import org.apache.fineract.client.models.PutLoanProductsProductIdResponse;
import org.apache.fineract.cob.data.JobBusinessStepConfigData;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.integrationtests.common.BusinessDateHelper;
import org.apache.fineract.integrationtests.common.BusinessStepConfigurationHelper;
import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.CommonConstants;
import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper;
import org.apache.fineract.integrationtests.common.SchedulerJobHelper;
import org.apache.fineract.integrationtests.common.Utils;
import org.apache.fineract.integrationtests.common.charges.ChargesHelper;
import org.apache.fineract.integrationtests.common.loans.CobHelper;
import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder;
import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
import org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension;
import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
import org.apache.fineract.integrationtests.common.products.DelinquencyBucketsHelper;
import org.apache.fineract.integrationtests.common.products.DelinquencyRangesHelper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@Slf4j
@ExtendWith(LoanTestLifecycleExtension.class)
public class DelinquencyBucketsIntegrationTest extends BaseLoanIntegrationTest {
private ResponseSpecification responseSpec;
private RequestSpecification requestSpec;
private BusinessDateHelper businessDateHelper;
private static final String principalAmount = "10000";
@BeforeEach
public void setup() {
Utils.initializeRESTAssured();
requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
this.businessDateHelper = new BusinessDateHelper();
}
@Test
public void testCreateDelinquencyRanges() {
// given
final String jsonRange = DelinquencyRangesHelper.getAsJSON(1, 3);
// when
final PostDelinquencyRangeResponse delinquencyRangeResponse01 = DelinquencyRangesHelper.createDelinquencyRange(requestSpec,
responseSpec, jsonRange);
final ArrayList<GetDelinquencyRangesResponse> ranges = DelinquencyRangesHelper.getDelinquencyRanges(requestSpec, responseSpec);
// then
assertNotNull(delinquencyRangeResponse01);
assertNotNull(ranges);
assertFalse(ranges.isEmpty());
GetDelinquencyRangesResponse range = ranges.get(ranges.size() - 1);
assertEquals(1, range.getMinimumAgeDays(), "Expected Min Age Days to 1");
assertEquals(3, range.getMaximumAgeDays(), "Expected Max Age Days to 3");
}
@Test
public void testUpdateDelinquencyRanges() {
// given
String jsonRange = DelinquencyRangesHelper.getAsJSON(1, 3);
final PostDelinquencyRangeResponse delinquencyRangeResponse01 = DelinquencyRangesHelper.createDelinquencyRange(requestSpec,
responseSpec, jsonRange);
jsonRange = DelinquencyRangesHelper.getAsJSON(1, 7);
assertNotNull(delinquencyRangeResponse01);
// when
final PutDelinquencyRangeResponse delinquencyRangeResponse02 = DelinquencyRangesHelper.updateDelinquencyRange(requestSpec,
responseSpec, delinquencyRangeResponse01.getResourceId(), jsonRange);
final GetDelinquencyRangesResponse range = DelinquencyRangesHelper.getDelinquencyRange(requestSpec, responseSpec,
delinquencyRangeResponse01.getResourceId());
final DeleteDelinquencyRangeResponse deleteDelinquencyRangeResponse = DelinquencyRangesHelper.deleteDelinquencyRange(requestSpec,
responseSpec, delinquencyRangeResponse01.getResourceId());
// then
assertNotNull(delinquencyRangeResponse02);
assertNotNull(deleteDelinquencyRangeResponse);
assertNotNull(range);
assertNotEquals(3, range.getMaximumAgeDays());
assertEquals(1, range.getMinimumAgeDays());
assertEquals(7, range.getMaximumAgeDays());
}
@Test
public void testDelinquencyBuckets() {
// given
ArrayList<Integer> rangeIds = new ArrayList<>();
String jsonRange = DelinquencyRangesHelper.getAsJSON(1, 3);
PostDelinquencyRangeResponse delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec, responseSpec,
jsonRange);
rangeIds.add(delinquencyRangeResponse.getResourceId());
jsonRange = DelinquencyRangesHelper.getAsJSON(4, 30);
// Create
delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec, responseSpec, jsonRange);
rangeIds.add(delinquencyRangeResponse.getResourceId());
String jsonBucket = DelinquencyBucketsHelper.getAsJSON(rangeIds);
PostDelinquencyBucketResponse delinquencyBucketResponse = DelinquencyBucketsHelper.createDelinquencyBucket(requestSpec,
responseSpec, jsonBucket);
// Update
jsonRange = DelinquencyRangesHelper.getAsJSON(31, 60);
rangeIds.add(delinquencyRangeResponse.getResourceId());
jsonBucket = DelinquencyBucketsHelper.getAsJSON(rangeIds);
PutDelinquencyBucketResponse updateDelinquencyBucketResponse = DelinquencyBucketsHelper.updateDelinquencyBucket(requestSpec,
responseSpec, delinquencyBucketResponse.getResourceId(), jsonBucket);
delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec, responseSpec, jsonRange);
rangeIds.add(delinquencyRangeResponse.getResourceId());
// Read
final GetDelinquencyBucketsResponse delinquencyBucket = DelinquencyBucketsHelper.getDelinquencyBucket(requestSpec, responseSpec,
delinquencyBucketResponse.getResourceId());
// when
final ArrayList<GetDelinquencyBucketsResponse> bucketList = DelinquencyBucketsHelper.getDelinquencyBuckets(requestSpec,
responseSpec);
// then
assertNotNull(bucketList);
assertNotNull(delinquencyBucket);
assertEquals(2, delinquencyBucket.getRanges().size());
assertNotNull(delinquencyBucketResponse);
assertNotNull(updateDelinquencyBucketResponse);
}
@Test
public void testDelinquencyBucketDelete() {
// given
ArrayList<Integer> rangeIds = new ArrayList<>();
String jsonRange = DelinquencyRangesHelper.getAsJSON(1, 3);
PostDelinquencyRangeResponse delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec, responseSpec,
jsonRange);
rangeIds.add(delinquencyRangeResponse.getResourceId());
jsonRange = DelinquencyRangesHelper.getAsJSON(4, 30);
// Create
delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec, responseSpec, jsonRange);
rangeIds.add(delinquencyRangeResponse.getResourceId());
String jsonBucket = DelinquencyBucketsHelper.getAsJSON(rangeIds);
PostDelinquencyBucketResponse delinquencyBucketResponse = DelinquencyBucketsHelper.createDelinquencyBucket(requestSpec,
responseSpec, jsonBucket);
// Delete
DeleteDelinquencyBucketResponse deleteDelinquencyBucketResponse = DelinquencyBucketsHelper.deleteDelinquencyBucket(requestSpec,
responseSpec, delinquencyBucketResponse.getResourceId());
// when
final ArrayList<GetDelinquencyBucketsResponse> bucketList = DelinquencyBucketsHelper.getDelinquencyBuckets(requestSpec,
responseSpec);
// then
assertNotNull(bucketList);
assertNotNull(delinquencyBucketResponse);
assertNotNull(deleteDelinquencyBucketResponse);
}
@Test
public void testDelinquencyBucketsRangeAgeOverlaped() {
// Given
ArrayList<Integer> rangeIds = new ArrayList<>();
String jsonRange = DelinquencyRangesHelper.getAsJSON(1, 3);
PostDelinquencyRangeResponse delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec, responseSpec,
jsonRange);
rangeIds.add(delinquencyRangeResponse.getResourceId());
jsonRange = DelinquencyRangesHelper.getAsJSON(3, 30);
// Create
delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec, responseSpec, jsonRange);
rangeIds.add(delinquencyRangeResponse.getResourceId());
String jsonBucket = DelinquencyBucketsHelper.getAsJSON(rangeIds);
final ResponseSpecification response403Spec = new ResponseSpecBuilder().expectStatusCode(403).build();
// When
DelinquencyBucketsHelper.createDelinquencyBucket(requestSpec, response403Spec, jsonBucket);
}
@Test
public void testDelinquencyBucketsNameDuplication() {
// Given
ArrayList<Integer> rangeIds = new ArrayList<>();
String jsonRange = DelinquencyRangesHelper.getAsJSON(1, 3);
PostDelinquencyRangeResponse delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec, responseSpec,
jsonRange);
rangeIds.add(delinquencyRangeResponse.getResourceId());
jsonRange = DelinquencyRangesHelper.getAsJSON(4, 30);
// Create
delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec, responseSpec, jsonRange);
rangeIds.add(delinquencyRangeResponse.getResourceId());
String jsonBucket = DelinquencyBucketsHelper.getAsJSON(rangeIds);
final ResponseSpecification response403Spec = new ResponseSpecBuilder().expectStatusCode(403).build();
// When
DelinquencyBucketsHelper.createDelinquencyBucket(requestSpec, responseSpec, jsonBucket);
// Then
DelinquencyBucketsHelper.createDelinquencyBucket(requestSpec, response403Spec, jsonBucket);
}
@Test
public void testLoanProductCreationWithAndWithoutDelinquencyBucket() {
// 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());
// Loan product creation without Delinquency bucket
GetLoanProductsProductIdResponse getLoanProductResponse = createLoanProduct(loanTransactionHelper, null, null);
assertNotNull(getLoanProductResponse);
assertNull(getLoanProductResponse.getDelinquencyBucket().getId());
// Loan product creation with Delinquency bucket
getLoanProductResponse = createLoanProduct(loanTransactionHelper, Math.toIntExact(delinquencyBucket.getId()), null);
assertNotNull(getLoanProductResponse);
log.info("Loan Product Bucket Name: {}", getLoanProductResponse.getDelinquencyBucket().getName());
assertEquals(getLoanProductResponse.getDelinquencyBucket().getName(), delinquencyBucket.getName());
// Update Loan product to remove the Delinquency bucket
final Long loanProductId = getLoanProductResponse.getId();
loanTransactionHelper.updateLoanProduct(loanProductId, "{delinquencyBucketId: null}");
getLoanProductResponse = loanTransactionHelper.getLoanProduct(loanProductId.intValue());
assertNotNull(getLoanProductResponse);
assertNull(getLoanProductResponse.getDelinquencyBucket().getId());
}
@Test
public void testLoanClassificationRealtime() {
try {
// Given
final LoanTransactionHelper loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.TRUE);
final LocalDate bussinesLocalDate = Utils.getDateAsLocalDate("01 March 2012");
log.info("Current date {}", bussinesLocalDate);
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, bussinesLocalDate);
final BusinessDateResponse businessDateResponse = this.businessDateHelper.getBusinessDateByType(requestSpec, responseSpec,
BusinessDateType.BUSINESS_DATE);
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,
Math.toIntExact(delinquencyBucket.getId()), null);
assertNotNull(getLoanProductsProductResponse);
log.info("Loan Product Bucket Name: {}", getLoanProductsProductResponse.getDelinquencyBucket().getName());
assertEquals(getLoanProductsProductResponse.getDelinquencyBucket().getName(), delinquencyBucket.getName());
// Older date to have more than one overdue installment
final LocalDate transactionDate = bussinesLocalDate.minusDays(50);
String operationDate = Utils.dateFormatter.format(transactionDate);
// Create Loan Account
final Integer loanId = createLoanAccount(loanTransactionHelper, clientId.toString(),
getLoanProductsProductResponse.getId().toString(), operationDate, null);
GetLoansLoanIdResponse getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
assertNotNull(getLoansLoanIdResponse);
assertNotNull(getLoansLoanIdResponse.getDelinquencyRange());
log.info("Loan Delinquency Range after Disbursement {}", getLoansLoanIdResponse.getDelinquencyRange().getClassification());
// First Loan Delinquency Classification after Disbursement command
assertEquals(getLoansLoanIdResponse.getDelinquencyRange().getClassification(), classificationExpected);
loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
// Apply a partial repayment
operationDate = Utils.dateFormatter.format(bussinesLocalDate);
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(), businessDateResponse.getDate());
assertEquals(getDelinquencyTagsHistory.get(0).getLiftedOnDate(), businessDateResponse.getDate());
assertEquals(getDelinquencyTagsHistory.get(0).getDelinquencyRange().getClassification(), classificationExpected);
log.info("Delinquency Tag Item with Lifted On {}", getDelinquencyTagsHistory.get(0).getLiftedOnDate());
} finally {
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
}
}
@Test
public void testLoanClassificationRealtimeWithCharges() {
try {
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.TRUE);
final LocalDate bussinesLocalDate = Utils.getDateAsLocalDate("01 April 2012");
log.info("Current date {}", bussinesLocalDate);
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, bussinesLocalDate);
// 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,
Math.toIntExact(delinquencyBucket.getId()), null);
assertNotNull(getLoanProductsProductResponse);
log.info("Loan Product Bucket Name: {}", getLoanProductsProductResponse.getDelinquencyBucket().getName());
assertEquals(getLoanProductsProductResponse.getDelinquencyBucket().getName(), delinquencyBucket.getName());
// Older date to have more than one overdue installment
LocalDate transactionDate = bussinesLocalDate.minusMonths(2).minusDays(5);
String operationDate = Utils.dateFormatter.format(transactionDate);
// Create Loan Account
final Integer loanId = createLoanAccount(loanTransactionHelper, clientId.toString(),
getLoanProductsProductResponse.getId().toString(), operationDate, null);
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);
loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
// Apply a repayment to get a full paid installment
operationDate = Utils.dateFormatter.format(bussinesLocalDate);
loanTransactionHelper.makeLoanRepayment(operationDate, 2049.99f, loanId);
getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
assertNotNull(getLoansLoanIdResponse);
// The Loan Delinquency Classification after Repayment command must be null
log.info("Loan Delinquency Range after Repayment {}", getLoansLoanIdResponse.getDelinquencyRange());
assertNull(getLoansLoanIdResponse.getDelinquencyRange());
loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
transactionDate = bussinesLocalDate.minusDays(18);
operationDate = Utils.dateFormatter.format(transactionDate);
// Create and apply Charge for Specific Due Date
final Integer chargeId = ChargesHelper.createCharges(requestSpec, responseSpec,
ChargesHelper.getLoanSpecifiedDueDateJSON(1, "30", false));
assertNotNull(chargeId);
final Integer loanChargeId = loanTransactionHelper.addChargesForLoan(loanId, getChargeApplyJSON(chargeId, operationDate),
responseSpec);
assertNotNull(loanChargeId);
getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
log.info("Loan Delinquency Range after add Loan Charge {}", getLoansLoanIdResponse.getDelinquencyRange());
assertNotNull(getLoansLoanIdResponse.getDelinquencyRange());
// Evaluate a Delinquency Tag set after add charge to the Loan
assertEquals(getLoansLoanIdResponse.getDelinquencyRange().getClassification(), classificationExpected);
} finally {
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
}
}
@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,
Math.toIntExact(delinquencyBucket.getId()), null);
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
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, null);
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);
loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
// Apply a repayment to get a first full paid installment
transactionDate = todaysDate.minusDays(1);
operationDate = Utils.dateFormatter.format(transactionDate);
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,
Math.toIntExact(delinquencyBucket.getId()), null);
assertNotNull(getLoanProductsProductResponse);
log.info("Loan Product Bucket Name: {}", getLoanProductsProductResponse.getDelinquencyBucket().getName());
assertEquals(getLoanProductsProductResponse.getDelinquencyBucket().getName(), delinquencyBucket.getName());
final LocalDate todaysDate = Utils.getLocalDateOfTenant();
log.info("Local date of Tenant: {}", todaysDate);
// Older date to have more than one overdue installment
final LocalDate transactionDate = todaysDate.minusDays(50);
String operationDate = Utils.dateFormatter.format(transactionDate);
// Create Loan Account
final Integer loanId = createLoanAccount(loanTransactionHelper, clientId.toString(),
getLoanProductsProductResponse.getId().toString(), operationDate, null);
GetLoansLoanIdResponse getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
loanTransactionHelper.printDelinquencyData(getLoansLoanIdResponse);
log.info("Loan Delinquency Range after Disbursement in null? {}", (getLoansLoanIdResponse.getDelinquencyRange() == null));
assertNotNull(getLoansLoanIdResponse);
assertNotNull(getLoansLoanIdResponse.getDelinquencyRange());
log.info("Loan Delinquency Range after Disbursement {}", getLoansLoanIdResponse.getDelinquencyRange());
// First Loan Delinquency Classification after Disbursement command
assertEquals(getLoansLoanIdResponse.getDelinquencyRange().getClassification(), classificationExpected);
loanTransactionHelper.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.reverseLoanTransaction(loanId,
loansLoanIdTransactions.getResourceId(), operationDate, responseSpec);
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());
}
@Test
public void testLoanClassificationJob() {
try {
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.TRUE);
LocalDate businessDate = Utils.getLocalDateOfTenant();
businessDate = businessDate.minusDays(37);
log.info("Current date {}", businessDate);
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, businessDate);
final LoanTransactionHelper loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
final SchedulerJobHelper schedulerJobHelper = new SchedulerJobHelper(requestSpec);
ArrayList<Integer> rangeIds = new ArrayList<>();
String jsonRange = DelinquencyRangesHelper.getAsJSON(1, 3);
PostDelinquencyRangeResponse delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec,
responseSpec, jsonRange);
rangeIds.add(delinquencyRangeResponse.getResourceId());
jsonRange = DelinquencyRangesHelper.getAsJSON(4, 60);
// Create
delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec, responseSpec, jsonRange);
rangeIds.add(delinquencyRangeResponse.getResourceId());
final GetDelinquencyRangesResponse range = DelinquencyRangesHelper.getDelinquencyRange(requestSpec, responseSpec,
delinquencyRangeResponse.getResourceId());
final String classificationExpected = range.getClassification();
log.info("Expected Delinquency Range classification {}", classificationExpected);
String jsonBucket = DelinquencyBucketsHelper.getAsJSON(rangeIds);
PostDelinquencyBucketResponse delinquencyBucketResponse = DelinquencyBucketsHelper.createDelinquencyBucket(requestSpec,
responseSpec, jsonBucket);
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,
Math.toIntExact(delinquencyBucket.getId()), null);
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(57);
String operationDate = Utils.dateFormatter.format(transactionDate);
// Create Loan Account
final Integer loanId = createLoanAccount(loanTransactionHelper, clientId.toString(),
getLoanProductsProductResponse.getId().toString(), operationDate, null);
// Run first time the Job
final String jobName = "Loan Delinquency Classification";
schedulerJobHelper.executeAndAwaitJob(jobName);
// Get loan details expecting to have not a delinquency classification
GetLoansLoanIdResponse getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
loanTransactionHelper.printDelinquencyData(getLoansLoanIdResponse);
final GetDelinquencyRangesResponse firstTestCase = getLoansLoanIdResponse.getDelinquencyRange();
log.info("Loan Delinquency Range is null {}", (firstTestCase == null));
loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
// Move the Business date to get older the loan and to have an overdue loan
businessDate = businessDate.plusMonths(1);
log.info("Current date {}", businessDate);
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, businessDate);
// Run Second time the Job
schedulerJobHelper.executeAndAwaitJob(jobName);
// Get loan details expecting to have a delinquency classification
getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
loanTransactionHelper.printDelinquencyData(getLoansLoanIdResponse);
final GetDelinquencyRangesResponse secondTestCase = getLoansLoanIdResponse.getDelinquencyRange();
assertNotNull(secondTestCase);
log.info("Loan Delinquency Range is {}", secondTestCase.getClassification());
// Then
assertNotNull(delinquencyBucketResponse);
assertNotNull(getLoanProductsProductResponse);
assertNull(firstTestCase);
assertEquals(getLoanProductsProductResponse.getDelinquencyBucket().getName(), delinquencyBucket.getName());
assertEquals(secondTestCase.getClassification(), classificationExpected);
} finally {
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
}
}
@Test
public void testLoanClassificationStepAsPartOfCOB() {
try {
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.TRUE);
LocalDate bussinesLocalDate = Utils.getDateAsLocalDate("01 April 2012");
log.info("Current date {}", bussinesLocalDate);
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, bussinesLocalDate);
// Given
final LoanTransactionHelper loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
final SchedulerJobHelper schedulerJobHelper = new SchedulerJobHelper(requestSpec);
ArrayList<Integer> rangeIds = new ArrayList<>();
String jsonRange = DelinquencyRangesHelper.getAsJSON(1, 3);
PostDelinquencyRangeResponse delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec,
responseSpec, jsonRange);
rangeIds.add(delinquencyRangeResponse.getResourceId());
final GetDelinquencyRangesResponse range = DelinquencyRangesHelper.getDelinquencyRange(requestSpec, responseSpec,
delinquencyRangeResponse.getResourceId());
final String classificationExpected = range.getClassification();
log.info("Expected Delinquency Range classification {}", classificationExpected);
jsonRange = DelinquencyRangesHelper.getAsJSON(4, 60);
delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec, responseSpec, jsonRange);
rangeIds.add(delinquencyRangeResponse.getResourceId());
String jsonBucket = DelinquencyBucketsHelper.getAsJSON(rangeIds);
PostDelinquencyBucketResponse delinquencyBucketResponse = DelinquencyBucketsHelper.createDelinquencyBucket(requestSpec,
responseSpec, jsonBucket);
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,
Math.toIntExact(delinquencyBucket.getId()), null);
assertNotNull(getLoanProductsProductResponse);
log.info("Loan Product Bucket Name: {}", getLoanProductsProductResponse.getDelinquencyBucket().getName());
assertEquals(getLoanProductsProductResponse.getDelinquencyBucket().getName(), delinquencyBucket.getName());
// Older date to have more than one overdue installment
final LocalDate transactionDate = bussinesLocalDate.minusDays(31);
String operationDate = Utils.dateFormatter.format(transactionDate);
// Create Loan Account
final Integer loanId = createLoanAccount(loanTransactionHelper, clientId.toString(),
getLoanProductsProductResponse.getId().toString(), operationDate, null);
// COB Step Validation
final JobBusinessStepConfigData jobBusinessStepConfigData = BusinessStepConfigurationHelper
.getConfiguredBusinessStepsByJobName(requestSpec, responseSpec, BusinessConfigurationApiTest.LOAN_JOB_NAME);
assertNotNull(jobBusinessStepConfigData);
assertEquals(BusinessConfigurationApiTest.LOAN_JOB_NAME, jobBusinessStepConfigData.getJobName());
assertTrue(jobBusinessStepConfigData.getBusinessSteps().size() > 0);
assertTrue(jobBusinessStepConfigData.getBusinessSteps().stream().anyMatch(
businessStep -> BusinessConfigurationApiTest.LOAN_DELINQUENCY_CLASSIFICATION.equals(businessStep.getStepName())));
// Run first time the Loan COB Job
final String jobName = "Loan COB";
schedulerJobHelper.executeAndAwaitJob(jobName);
// Get loan details expecting to have not a delinquency classification
GetLoansLoanIdResponse getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
final GetDelinquencyRangesResponse firstTestCase = getLoansLoanIdResponse.getDelinquencyRange();
log.info("Loan Delinquency Range is null {}", (firstTestCase == null));
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());
}
}
// Move the Business date to get older the loan and to have an overdue loan
LocalDate lastLoanCOBBusinessDate = bussinesLocalDate;
bussinesLocalDate = bussinesLocalDate.plusDays(3);
schedulerJobHelper.fastForwardTime(lastLoanCOBBusinessDate, bussinesLocalDate, jobName, responseSpec);
log.info("Current date {}", bussinesLocalDate);
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, bussinesLocalDate);
// Run Second time the Job
schedulerJobHelper.executeAndAwaitJob(jobName);
// Get loan details expecting to have a delinquency classification
getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
final GetDelinquencyRangesResponse secondTestCase = getLoansLoanIdResponse.getDelinquencyRange();
assertNotNull(secondTestCase);
log.info("Loan Delinquency Range is {}", secondTestCase.getClassification());
// Then
assertNotNull(delinquencyBucketResponse);
assertNotNull(getLoanProductsProductResponse);
assertNull(firstTestCase);
assertEquals(getLoanProductsProductResponse.getDelinquencyBucket().getName(), delinquencyBucket.getName());
assertEquals(secondTestCase.getClassification(), classificationExpected);
} finally {
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
}
}
@Test
public void testLoanClassificationToValidateNegatives() {
try {
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.TRUE);
LocalDate bussinesLocalDate = Utils.getDateAsLocalDate("01 January 2012");
log.info("Current date {}", bussinesLocalDate);
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, bussinesLocalDate);
// Given
final LoanTransactionHelper loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
final SchedulerJobHelper schedulerJobHelper = new SchedulerJobHelper(requestSpec);
ArrayList<Integer> rangeIds = new ArrayList<>();
String jsonRange = DelinquencyRangesHelper.getAsJSON(1, 3);
PostDelinquencyRangeResponse delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec,
responseSpec, jsonRange);
rangeIds.add(delinquencyRangeResponse.getResourceId());
final GetDelinquencyRangesResponse range = DelinquencyRangesHelper.getDelinquencyRange(requestSpec, responseSpec,
delinquencyRangeResponse.getResourceId());
final String classificationExpected = range.getClassification();
log.info("Expected Delinquency Range classification {}", classificationExpected);
jsonRange = DelinquencyRangesHelper.getAsJSON(4, 60);
delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec, responseSpec, jsonRange);
rangeIds.add(delinquencyRangeResponse.getResourceId());
String jsonBucket = DelinquencyBucketsHelper.getAsJSON(rangeIds);
PostDelinquencyBucketResponse delinquencyBucketResponse = DelinquencyBucketsHelper.createDelinquencyBucket(requestSpec,
responseSpec, jsonBucket);
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,
Math.toIntExact(delinquencyBucket.getId()), "3");
assertNotNull(getLoanProductsProductResponse);
log.info("Loan Product Bucket Name: {}", getLoanProductsProductResponse.getDelinquencyBucket().getName());
assertEquals(getLoanProductsProductResponse.getDelinquencyBucket().getName(), delinquencyBucket.getName());
// Older date to have more than one overdue installment
final LocalDate transactionDate = bussinesLocalDate;
String operationDate = Utils.dateFormatter.format(transactionDate);
// Create Loan Account
final Integer loanId = createLoanAccount(loanTransactionHelper, clientId.toString(),
getLoanProductsProductResponse.getId().toString(), operationDate, null);
// Get loan details expecting to have a delinquency classification
GetLoansLoanIdResponse getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
final GetDelinquencyRangesResponse firstTestCase = getLoansLoanIdResponse.getDelinquencyRange();
log.info("Loan Delinquency Range is null {}", (firstTestCase == null));
loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
final String jobName = "Loan COB";
bussinesLocalDate = Utils.getDateAsLocalDate("31 January 2012");
LocalDate lastLoanCOBBusinessDate = bussinesLocalDate.minusDays(1);
schedulerJobHelper.fastForwardTime(lastLoanCOBBusinessDate, bussinesLocalDate, jobName, responseSpec);
log.info("Current date {}", bussinesLocalDate);
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, bussinesLocalDate);
// Run Second time the Job
schedulerJobHelper.executeAndAwaitJob(jobName);
// Get loan details expecting to have a delinquency classification
getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
loanTransactionHelper.printDelinquencyData(getLoansLoanIdResponse);
GetLoansLoanIdDelinquencySummary getLoansLoanIdCollectionData = getLoansLoanIdResponse.getDelinquent();
assertNotNull(getLoansLoanIdCollectionData);
assertEquals(0, getLoansLoanIdCollectionData.getDelinquentDays());
assertEquals(0, getLoansLoanIdCollectionData.getPastDueDays());
} finally {
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
}
}
@Test
public void testLoanClassificationUsingAgeingArrears() {
try {
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.TRUE);
LocalDate bussinesLocalDate = Utils.getDateAsLocalDate("01 January 2012");
log.info("Current date {}", bussinesLocalDate);
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, bussinesLocalDate);
// Given
final LoanTransactionHelper loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
final SchedulerJobHelper schedulerJobHelper = new SchedulerJobHelper(requestSpec);
ArrayList<Integer> rangeIds = new ArrayList<>();
String jsonRange = DelinquencyRangesHelper.getAsJSON(1, 3);
PostDelinquencyRangeResponse delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec,
responseSpec, jsonRange);
rangeIds.add(delinquencyRangeResponse.getResourceId());
final GetDelinquencyRangesResponse range = DelinquencyRangesHelper.getDelinquencyRange(requestSpec, responseSpec,
delinquencyRangeResponse.getResourceId());
final String classificationExpected = range.getClassification();
log.info("Expected Delinquency Range classification {}", classificationExpected);
jsonRange = DelinquencyRangesHelper.getAsJSON(4, 60);
delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec, responseSpec, jsonRange);
rangeIds.add(delinquencyRangeResponse.getResourceId());
String jsonBucket = DelinquencyBucketsHelper.getAsJSON(rangeIds);
PostDelinquencyBucketResponse delinquencyBucketResponse = DelinquencyBucketsHelper.createDelinquencyBucket(requestSpec,
responseSpec, jsonBucket);
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,
Math.toIntExact(delinquencyBucket.getId()), "3");
assertNotNull(getLoanProductsProductResponse);
log.info("Loan Product Arrears: {}", getLoanProductsProductResponse.getInArrearsTolerance());
assertEquals(3, getLoanProductsProductResponse.getInArrearsTolerance());
// Older date to have more than one overdue installment
final LocalDate transactionDate = bussinesLocalDate;
String operationDate = Utils.dateFormatter.format(transactionDate);
// Create Loan Account
final Integer loanId = createLoanAccount(loanTransactionHelper, clientId.toString(),
getLoanProductsProductResponse.getId().toString(), operationDate, "3");
// Get loan details expecting to have a delinquency classification
GetLoansLoanIdResponse getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
final GetDelinquencyRangesResponse firstTestCase = getLoansLoanIdResponse.getDelinquencyRange();
log.info("Loan Delinquency Range is null {}", (firstTestCase == null));
loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
log.info("Loan Account Arrears {}", getLoansLoanIdResponse.getInArrearsTolerance());
assertEquals(3, getLoansLoanIdResponse.getInArrearsTolerance());
// Update the Loan Product
updateLoanProduct(loanTransactionHelper, getLoanProductsProductResponse.getId(), 0);
GetLoanProductsProductIdResponse loanProductsProductIdResponseUpd = loanTransactionHelper
.getLoanProduct(getLoanProductsProductResponse.getId().intValue());
assertNotNull(loanProductsProductIdResponseUpd);
log.info("Loan Product Arrears: {}", loanProductsProductIdResponseUpd.getInArrearsTolerance());
assertEquals(0, loanProductsProductIdResponseUpd.getInArrearsTolerance());
final String jobName = "Loan COB";
bussinesLocalDate = Utils.getDateAsLocalDate("31 January 2012");
LocalDate lastLoanCOBBusinessDate = bussinesLocalDate.minusDays(1);
schedulerJobHelper.fastForwardTime(lastLoanCOBBusinessDate, bussinesLocalDate, jobName, responseSpec);
log.info("Current date {}", bussinesLocalDate);
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, bussinesLocalDate);
// Run Second time the Job
schedulerJobHelper.executeAndAwaitJob(jobName);
// Get loan details expecting to have a delinquency classification
getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
loanTransactionHelper.printDelinquencyData(getLoansLoanIdResponse);
GetLoansLoanIdDelinquencySummary getLoansLoanIdCollectionData = getLoansLoanIdResponse.getDelinquent();
assertNotNull(getLoansLoanIdCollectionData);
assertEquals(0, getLoansLoanIdCollectionData.getDelinquentDays());
assertEquals(0, getLoansLoanIdCollectionData.getPastDueDays());
} finally {
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
}
}
@Test
public void testDelinquencyWithPauseLettingPauseExpire() {
runAt("01 January 2012", () -> {
Integer delinquencyBucketId = DelinquencyBucketsHelper.createDelinquencyBucket(requestSpec, responseSpec, List.of(//
Pair.of(1, 3), //
Pair.of(4, 60) //
));
LocalDate bussinesLocalDate = Utils.getDateAsLocalDate("01 January 2012");
final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2012");
final GetLoanProductsProductIdResponse getLoanProductsProductResponse = createLoanProduct(loanTransactionHelper,
delinquencyBucketId, "3");
assertNotNull(getLoanProductsProductResponse);
log.info("Loan Product Arrears: {}", getLoanProductsProductResponse.getInArrearsTolerance());
assertEquals(3, getLoanProductsProductResponse.getInArrearsTolerance());
final LocalDate transactionDate = bussinesLocalDate;
String operationDate = Utils.dateFormatter.format(transactionDate);
final Integer loanId = createLoanAccount(loanTransactionHelper, clientId.toString(),
getLoanProductsProductResponse.getId().toString(), operationDate, "3");
GetLoansLoanIdResponse getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
final GetDelinquencyRangesResponse firstTestCase = getLoansLoanIdResponse.getDelinquencyRange();
log.info("Loan Delinquency Range is null {}", (firstTestCase == null));
loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
log.info("Loan Account Arrears {}", getLoansLoanIdResponse.getInArrearsTolerance());
assertEquals(3, getLoansLoanIdResponse.getInArrearsTolerance());
final String jobName = "Loan COB";
CobHelper.fastForwardLoansLastCOBDate(requestSpec, responseSpec204, loanId, "04 February 2012");
updateBusinessDate("06 February 2012");
schedulerJobHelper.executeAndAwaitJob(jobName);
verifyDelinquency(loanId, "01 February 2012", 1033.33, 5);
PostLoansDelinquencyActionResponse pauseDelinquencyResponse = loanTransactionHelper
.createLoanDelinquencyAction(loanId.longValue(), PAUSE, "06 February 2012", "10 February 2012");
CobHelper.fastForwardLoansLastCOBDate(requestSpec, responseSpec204, loanId, "07 February 2012");
updateBusinessDate("09 February 2012");
schedulerJobHelper.executeAndAwaitJob(jobName);
verifyDelinquency(loanId, "01 February 2012", 1033.33, 5);
CobHelper.fastForwardLoansLastCOBDate(requestSpec, responseSpec204, loanId, "10 March 2012");
updateBusinessDate("12 March 2012");
schedulerJobHelper.executeAndAwaitJob(jobName);
verifyDelinquency(loanId, "01 February 2012", 2049.99, 36);
});
}
@Test
public void testDelinquencyWithPauseResumeBeforePauseExpires() {
runAt("01 January 2012", () -> {
Integer delinquencyBucketId = DelinquencyBucketsHelper.createDelinquencyBucket(requestSpec, responseSpec, List.of(//
Pair.of(1, 3), //
Pair.of(4, 60) //
));
LocalDate bussinesLocalDate = Utils.getDateAsLocalDate("01 January 2012");
final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2012");
final GetLoanProductsProductIdResponse getLoanProductsProductResponse = createLoanProduct(loanTransactionHelper,
delinquencyBucketId, "3");
assertNotNull(getLoanProductsProductResponse);
log.info("Loan Product Arrears: {}", getLoanProductsProductResponse.getInArrearsTolerance());
assertEquals(3, getLoanProductsProductResponse.getInArrearsTolerance());
final LocalDate transactionDate = bussinesLocalDate;
String operationDate = Utils.dateFormatter.format(transactionDate);
final Integer loanId = createLoanAccount(loanTransactionHelper, clientId.toString(),
getLoanProductsProductResponse.getId().toString(), operationDate, "3");
GetLoansLoanIdResponse getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
final GetDelinquencyRangesResponse firstTestCase = getLoansLoanIdResponse.getDelinquencyRange();
log.info("Loan Delinquency Range is null {}", (firstTestCase == null));
loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
log.info("Loan Account Arrears {}", getLoansLoanIdResponse.getInArrearsTolerance());
assertEquals(3, getLoansLoanIdResponse.getInArrearsTolerance());
final String jobName = "Loan COB";
CobHelper.fastForwardLoansLastCOBDate(requestSpec, responseSpec204, loanId, "04 February 2012");
updateBusinessDate("06 February 2012");
schedulerJobHelper.executeAndAwaitJob(jobName);
verifyDelinquency(loanId, "01 February 2012", 1033.33, 5);
PostLoansDelinquencyActionResponse pauseDelinquencyResponse = loanTransactionHelper
.createLoanDelinquencyAction(loanId.longValue(), PAUSE, "06 February 2012", "10 March 2012");
CobHelper.fastForwardLoansLastCOBDate(requestSpec, responseSpec204, loanId, "07 February 2012");
updateBusinessDate("09 February 2012");
schedulerJobHelper.executeAndAwaitJob(jobName);
verifyDelinquency(loanId, "01 February 2012", 1033.33, 5);
bussinesLocalDate = Utils.getDateAsLocalDate("10 February 2012");
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, bussinesLocalDate);
loanTransactionHelper.createLoanDelinquencyAction(loanId.longValue(), RESUME, "10 February 2012");
CobHelper.fastForwardLoansLastCOBDate(requestSpec, responseSpec204, loanId, "10 March 2012");
updateBusinessDate("12 March 2012");
schedulerJobHelper.executeAndAwaitJob(jobName);
verifyDelinquency(loanId, "01 February 2012", 2049.99, 36);
});
}
@Test
public void testDelinquencyWithMultiplePausePeriods() {
runAt("01 January 2012", () -> {
Integer delinquencyBucketId = DelinquencyBucketsHelper.createDelinquencyBucket(requestSpec, responseSpec, List.of(//
Pair.of(1, 3), //
Pair.of(4, 60) //
));
final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2012");
final GetLoanProductsProductIdResponse getLoanProductsProductResponse = createLoanProduct(loanTransactionHelper,
delinquencyBucketId, "3");
assertNotNull(getLoanProductsProductResponse);
log.info("Loan Product Arrears: {}", getLoanProductsProductResponse.getInArrearsTolerance());
assertEquals(3, getLoanProductsProductResponse.getInArrearsTolerance());
final Integer loanId = createLoanAccount(loanTransactionHelper, clientId.toString(),
getLoanProductsProductResponse.getId().toString(), "01 January 2012", "3");
GetLoansLoanIdResponse getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
final GetDelinquencyRangesResponse firstTestCase = getLoansLoanIdResponse.getDelinquencyRange();
log.info("Loan Delinquency Range is null {}", (firstTestCase == null));
loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
log.info("Loan Account Arrears {}", getLoansLoanIdResponse.getInArrearsTolerance());
assertEquals(3, getLoansLoanIdResponse.getInArrearsTolerance());
final String jobName = "Loan COB";
// delinquent days: 5
CobHelper.fastForwardLoansLastCOBDate(requestSpec, responseSpec204, loanId, "04 February 2012");
updateBusinessDate("06 February 2012");
schedulerJobHelper.executeAndAwaitJob(jobName);
verifyDelinquency(loanId, "01 February 2012", 1033.33, 5);
// Add delinquency pause on 06 February 2012
PostLoansDelinquencyActionResponse pauseDelinquencyResponse = loanTransactionHelper
.createLoanDelinquencyAction(loanId.longValue(), PAUSE, "06 February 2012", "10 March 2012");
CobHelper.fastForwardLoansLastCOBDate(requestSpec, responseSpec204, loanId, "07 February 2012");
updateBusinessDate("09 February 2012");
schedulerJobHelper.executeAndAwaitJob(jobName);
verifyDelinquency(loanId, "01 February 2012", 1033.33, 5);
// Add delinquency resume on 10 February 2012
updateBusinessDate("10 February 2012");
loanTransactionHelper.createLoanDelinquencyAction(loanId.longValue(), RESUME, "10 February 2012");
CobHelper.fastForwardLoansLastCOBDate(requestSpec, responseSpec204, loanId, "11 February 2012");
updateBusinessDate("13 February 2012");
schedulerJobHelper.executeAndAwaitJob(jobName);
verifyDelinquency(loanId, "01 February 2012", 1033.33, 8);
// Add new pause on 13 February 2012
pauseDelinquencyResponse = loanTransactionHelper.createLoanDelinquencyAction(loanId.longValue(), PAUSE, "13 February 2012",
"18 February 2012");
CobHelper.fastForwardLoansLastCOBDate(requestSpec, responseSpec204, loanId, "21 February 2012");
updateBusinessDate("23 February 2012");
schedulerJobHelper.executeAndAwaitJob(jobName);
verifyDelinquency(loanId, "01 February 2012", 1033.33, 13);
// Add new pause on 23 February 2012
pauseDelinquencyResponse = loanTransactionHelper.createLoanDelinquencyAction(loanId.longValue(), PAUSE, "23 February 2012",
"28 February 2012");
updateBusinessDate("25 February 2012");
loanTransactionHelper.createLoanDelinquencyAction(loanId.longValue(), RESUME, "25 February 2012");
CobHelper.fastForwardLoansLastCOBDate(requestSpec, responseSpec204, loanId, "10 March 2012");
updateBusinessDate("12 March 2012");
schedulerJobHelper.executeAndAwaitJob(jobName);
verifyDelinquency(loanId, "01 February 2012", 2049.99, 29);
});
}
private void verifyDelinquency(Integer loanId, String date, Double amount, int delinquentDays) {
GetLoansLoanIdResponse getLoansLoanIdResponse;
GetLoansLoanIdDelinquencySummary delinquent;
getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
loanTransactionHelper.printDelinquencyData(getLoansLoanIdResponse);
delinquent = getLoansLoanIdResponse.getDelinquent();
assertEquals(amount, delinquent.getDelinquentAmount());
assertEquals(LocalDate.parse(date, dateTimeFormatter), delinquent.getDelinquentDate());
assertEquals(delinquentDays, delinquent.getDelinquentDays());
}
@Test
public void testDelinquencyWithMultiplePausePeriodsWithInstallmentLevelDelinquency() {
runAt("01 January 2012", () -> {
Integer delinquencyBucketId = DelinquencyBucketsHelper.createDelinquencyBucket(requestSpec, responseSpec, List.of(//
Pair.of(1, 3), //
Pair.of(4, 60) //
));
final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2012");
final GetLoanProductsProductIdResponse getLoanProductsProductResponse = createLoanProductWithInstallmentLevelDelinquency(
loanTransactionHelper, delinquencyBucketId, "3");
assertNotNull(getLoanProductsProductResponse);
log.info("Loan Product Arrears: {}", getLoanProductsProductResponse.getInArrearsTolerance());
assertEquals(3, getLoanProductsProductResponse.getInArrearsTolerance());
final Integer loanId = createLoanAccount(loanTransactionHelper, clientId.toString(),
getLoanProductsProductResponse.getId().toString(), "01 January 2012", "3");
GetLoansLoanIdResponse getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
final GetDelinquencyRangesResponse firstTestCase = getLoansLoanIdResponse.getDelinquencyRange();
log.info("Loan Delinquency Range is null {}", (firstTestCase == null));
loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
log.info("Loan Account Arrears {}", getLoansLoanIdResponse.getInArrearsTolerance());
assertEquals(3, getLoansLoanIdResponse.getInArrearsTolerance());
final String jobName = "Loan COB";
// delinquent days: 5
CobHelper.fastForwardLoansLastCOBDate(requestSpec, responseSpec204, loanId, "04 February 2012");
updateBusinessDate("06 February 2012");
schedulerJobHelper.executeAndAwaitJob(jobName);
verifyDelinquency(loanId, "01 February 2012", 1033.33, 5);
PostLoansDelinquencyActionResponse pauseDelinquencyResponse = loanTransactionHelper
.createLoanDelinquencyAction(loanId.longValue(), PAUSE, "06 February 2012", "10 March 2012");
CobHelper.fastForwardLoansLastCOBDate(requestSpec, responseSpec204, loanId, "07 February 2012");
updateBusinessDate("09 February 2012");
schedulerJobHelper.executeAndAwaitJob(jobName);
verifyDelinquency(loanId, "01 February 2012", 1033.33, 5);
updateBusinessDate("10 February 2012");
loanTransactionHelper.createLoanDelinquencyAction(loanId.longValue(), RESUME, "10 February 2012");
CobHelper.fastForwardLoansLastCOBDate(requestSpec, responseSpec204, loanId, "11 February 2012");
updateBusinessDate("13 February 2012");
schedulerJobHelper.executeAndAwaitJob(jobName);
verifyDelinquency(loanId, "01 February 2012", 1033.33, 8);
pauseDelinquencyResponse = loanTransactionHelper.createLoanDelinquencyAction(loanId.longValue(), PAUSE, "13 February 2012",
"18 February 2012");
CobHelper.fastForwardLoansLastCOBDate(requestSpec, responseSpec204, loanId, "21 February 2012");
updateBusinessDate("23 February 2012");
schedulerJobHelper.executeAndAwaitJob(jobName);
verifyDelinquency(loanId, "01 February 2012", 1033.33, 13);
pauseDelinquencyResponse = loanTransactionHelper.createLoanDelinquencyAction(loanId.longValue(), PAUSE, "23 February 2012",
"28 February 2012");
updateBusinessDate("25 February 2012");
loanTransactionHelper.createLoanDelinquencyAction(loanId.longValue(), RESUME, "25 February 2012");
CobHelper.fastForwardLoansLastCOBDate(requestSpec, responseSpec204, loanId, "12 March 2012");
updateBusinessDate("14 March 2012");
schedulerJobHelper.executeAndAwaitJob(jobName);
getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
loanTransactionHelper.printDelinquencyData(getLoansLoanIdResponse);
GetLoansLoanIdDelinquencySummary delinquent = getLoansLoanIdResponse.getDelinquent();
assertEquals(2049.99, delinquent.getDelinquentAmount());
assertEquals(LocalDate.of(2012, 2, 1), delinquent.getDelinquentDate());
assertEquals(31, delinquent.getDelinquentDays());
assertEquals(2, delinquent.getInstallmentLevelDelinquency().size());
GetLoansLoanIdLoanInstallmentLevelDelinquency firstInstallmentDelinquent = delinquent.getInstallmentLevelDelinquency().get(0);
assertEquals(BigDecimal.valueOf(1016.66), firstInstallmentDelinquent.getDelinquentAmount().stripTrailingZeros());
GetLoansLoanIdLoanInstallmentLevelDelinquency secondInstallmentDelinquent = delinquent.getInstallmentLevelDelinquency().get(1);
assertEquals(BigDecimal.valueOf(1033.33), secondInstallmentDelinquent.getDelinquentAmount().stripTrailingZeros());
});
}
@Test
public void testLoanClassificationOnlyForActiveLoan() {
// 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());
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,
Math.toIntExact(delinquencyBucket.getId()), null);
assertNotNull(getLoanProductsProductResponse);
final LocalDate todaysDate = Utils.getLocalDateOfTenant();
// Older date to have more than one overdue installment
LocalDate transactionDate = todaysDate.minusDays(37);
String operationDate = Utils.dateFormatter.format(transactionDate);
// Create Loan Application
final Integer loanId = createLoanApplication(loanTransactionHelper, clientId.toString(),
getLoanProductsProductResponse.getId().toString(), operationDate, null);
// Evaluate default delinquent values in No Active Loan
GetLoansLoanIdResponse getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
assertNotNull(getLoansLoanIdResponse);
assertNotNull(getLoansLoanIdResponse.getDelinquent());
assertEquals(0, getLoansLoanIdResponse.getDelinquent().getDelinquentDays());
assertEquals(0, getLoansLoanIdResponse.getDelinquent().getDelinquentAmount());
// Loan Disbursement
disburseLoanAccount(loanTransactionHelper, loanId, operationDate);
// Evaluate default delinquent values in No Active Loan
getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
assertNotNull(getLoansLoanIdResponse);
assertNotNull(getLoansLoanIdResponse.getDelinquent());
assertNotEquals(0, getLoansLoanIdResponse.getDelinquent().getDelinquentDays());
assertNotEquals(0, getLoansLoanIdResponse.getDelinquent().getDelinquentAmount());
}
@Test
public void testLoanClassificationOnlyForActiveLoanWithCOB() {
try {
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.TRUE);
final String operationDate = "01 January 2012";
LocalDate bussinesLocalDate = Utils.getDateAsLocalDate(operationDate);
log.info("Current date {}", bussinesLocalDate);
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, bussinesLocalDate);
// Given
final LoanTransactionHelper loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
final SchedulerJobHelper schedulerJobHelper = new SchedulerJobHelper(requestSpec);
ArrayList<Integer> rangeIds = new ArrayList<>();
// First Range
String jsonRange = DelinquencyRangesHelper.getAsJSON(4, 30);
PostDelinquencyRangeResponse delinquencyRangeResponse = DelinquencyRangesHelper.createDelinquencyRange(requestSpec,
responseSpec, jsonRange);
rangeIds.add(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 creation
final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec, operationDate);
final GetLoanProductsProductIdResponse getLoanProductsProductResponse = createLoanProduct(loanTransactionHelper,
Math.toIntExact(delinquencyBucket.getId()), null);
assertNotNull(getLoanProductsProductResponse);
// Create Loan Application
final Integer loanId = createLoanApplication(loanTransactionHelper, clientId.toString(),
getLoanProductsProductResponse.getId().toString(), operationDate, null);
// run cob for business date 01 January 2012
final String jobName = "Loan COB";
bussinesLocalDate = Utils.getDateAsLocalDate(operationDate);
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, bussinesLocalDate);
schedulerJobHelper.executeAndAwaitJob(jobName);
// Loan delinquency data
GetLoansLoanIdResponse getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
loanTransactionHelper.printDelinquencyData(getLoansLoanIdResponse);
GetLoansLoanIdDelinquencySummary delinquent = getLoansLoanIdResponse.getDelinquent();
assertNotNull(getLoansLoanIdResponse);
assertNotNull(delinquent);
assertEquals(0, delinquent.getDelinquentDays());
assertEquals(0, delinquent.getDelinquentAmount());
} finally {
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
}
}
private GetLoanProductsProductIdResponse createLoanProduct(final LoanTransactionHelper loanTransactionHelper,
final Integer delinquencyBucketId, final String inArrearsTolerance) {
final HashMap<String, Object> loanProductMap = new LoanProductTestBuilder().withInArrearsTolerance(inArrearsTolerance).build(null,
delinquencyBucketId);
final Integer loanProductId = loanTransactionHelper.getLoanProductId(Utils.convertToJson(loanProductMap));
return loanTransactionHelper.getLoanProduct(loanProductId);
}
private GetLoanProductsProductIdResponse createLoanProductWithInstallmentLevelDelinquency(
final LoanTransactionHelper loanTransactionHelper, final Integer delinquencyBucketId, final String inArrearsTolerance) {
final HashMap<String, Object> loanProductMap = new LoanProductTestBuilder().withInArrearsTolerance(inArrearsTolerance).build(null,
delinquencyBucketId);
loanProductMap.put("enableInstallmentLevelDelinquency", true);
final Integer loanProductId = loanTransactionHelper.getLoanProductId(Utils.convertToJson(loanProductMap));
return loanTransactionHelper.getLoanProduct(loanProductId);
}
private PutLoanProductsProductIdResponse updateLoanProduct(LoanTransactionHelper loanTransactionHelper, Long id,
final Integer inArrearsTolerance) {
final PutLoanProductsProductIdRequest requestModifyLoan = new PutLoanProductsProductIdRequest()
.inArrearsTolerance(inArrearsTolerance);
return loanTransactionHelper.updateLoanProduct(id, requestModifyLoan);
}
private Integer createLoanApplication(final LoanTransactionHelper loanTransactionHelper, final String clientId,
final String loanProductId, final String operationDate, final String inArrearsTolerance) {
final String loanApplicationJSON = new LoanApplicationTestBuilder().withPrincipal(principalAmount).withLoanTermFrequency("12")
.withLoanTermFrequencyAsMonths().withNumberOfRepayments("12").withRepaymentEveryAfter("1")
.withRepaymentFrequencyTypeAsMonths() //
.withInterestRatePerPeriod("2") //
.withExpectedDisbursementDate(operationDate) //
.withInterestTypeAsDecliningBalance() //
.withSubmittedOnDate(operationDate) //
.withInArrearsTolerance(inArrearsTolerance) //
.build(clientId, loanProductId, null);
final Integer loanId = loanTransactionHelper.getLoanId(loanApplicationJSON);
loanTransactionHelper.approveLoan(operationDate, principalAmount, loanId, null);
return loanId;
}
private void disburseLoanAccount(final LoanTransactionHelper loanTransactionHelper, final Integer loanId, final String operationDate) {
loanTransactionHelper.disburseLoanWithNetDisbursalAmount(operationDate, loanId, principalAmount);
}
private Integer createLoanAccount(final LoanTransactionHelper loanTransactionHelper, final String clientId, final String loanProductId,
final String operationDate, final String inArrearsTolerance) {
final Integer loanId = createLoanApplication(loanTransactionHelper, clientId, loanProductId, operationDate, inArrearsTolerance);
disburseLoanAccount(loanTransactionHelper, loanId, operationDate);
return loanId;
}
private String getChargeApplyJSON(final Integer chargeId, final String dueDate) {
final HashMap<String, Object> map = new HashMap<>();
map.put("chargeId", chargeId);
map.put("amount", 12.0f);
map.put("dueDate", dueDate);
map.put("dateFormat", Utils.DATE_FORMAT);
map.put("locale", CommonConstants.LOCALE);
final String chargeApplyJSON = new Gson().toJson(map);
log.info("{}", chargeApplyJSON);
return chargeApplyJSON;
}
}