Skip to content

Commit

Permalink
FINERACT-2058: loan can be marked as fraud in any status
Browse files Browse the repository at this point in the history
  • Loading branch information
taskain7 authored and adamsaghy committed Mar 1, 2024
1 parent ef1bcda commit 49b3c01
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2550,11 +2550,6 @@ public CommandProcessingResult markLoanAsFraud(Long loanId, JsonCommand command)

Loan loan = this.loanAssembler.assembleFrom(loanId);
final Map<String, Object> changes = new LinkedHashMap<>();

if (loan.isApproved() || loan.isSubmittedAndPendingApproval()) {
throw new GeneralPlatformDomainRuleException("error.msg.loan.mark.as.fraud.not.allowed",
"Loan Id: " + loanId + " mark as fraud is not allowed as loan status is not active", loan.getStatus().getCode());
}
final boolean fraud = command.booleanPrimitiveValueOfParameterNamed(LoanApiConstants.FRAUD_ATTRIBUTE_NAME);
if (loan.isFraud() != fraud) {
loan.markAsFraud(fraud);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,10 @@ protected void disburseLoan(Long loanId, BigDecimal amount, String date) {
.transactionAmount(amount).locale("en"));
}

protected void undoDisbursement(Integer loanId) {
loanTransactionHelper.undoDisbursal(loanId);
}

protected void verifyJournalEntries(Long loanId, Journal... entries) {
GetJournalEntriesTransactionIdResponse journalEntriesForLoan = journalEntryHelper.getJournalEntriesForLoan(loanId);
Assertions.assertEquals(entries.length, journalEntriesForLoan.getPageItems().size());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,63 +21,50 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

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.HashMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
import org.apache.fineract.client.models.PostLoanProductsRequest;
import org.apache.fineract.client.models.PostLoanProductsResponse;
import org.apache.fineract.client.models.PostLoansLoanIdResponse;
import org.apache.fineract.client.models.PostLoansResponse;
import org.apache.fineract.client.models.PutLoansLoanIdResponse;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.integrationtests.common.BusinessDateHelper;
import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper;
import org.apache.fineract.integrationtests.common.Utils;
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.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

@Slf4j
@ExtendWith(LoanTestLifecycleExtension.class)
public class LoanAccountFraudTest {
public class LoanAccountFraudTest extends BaseLoanIntegrationTest {

private ResponseSpecification responseSpec;
private ResponseSpecification responseSpecError;
private RequestSpecification requestSpec;
private LoanTransactionHelper loanTransactionHelper;
private final String amountVal = "1000";
private static final double AMOUNT = 100.0;
private static final String COMMAND = "markAsFraud";
private LocalDate todaysDate;
private String operationDate;

@BeforeEach
public void setup() {
Utils.initializeRESTAssured();
this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
this.responseSpecError = new ResponseSpecBuilder().expectStatusCode(403).build();
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);

this.todaysDate = Utils.getLocalDateOfTenant();
this.operationDate = Utils.dateFormatter.format(this.todaysDate);
}

@Test
public void testMarkLoanAsFraud() {
try {
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.TRUE);
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, todaysDate);
final String command = "markAsFraud";
// Client and Loan account creation
final Integer loanId = createAccounts(15, 1);
runAt(operationDate, () -> {

final Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();

PostLoanProductsRequest loanProductsRequest = createOnePeriod30DaysLongNoInterestPeriodicAccrualProduct();
PostLoanProductsResponse loanProductResponse = loanProductHelper.createLoanProduct(loanProductsRequest);

PostLoansResponse postLoansResponse = loanTransactionHelper
.applyLoan(applyLoanRequest(clientId, loanProductResponse.getResourceId(), operationDate, AMOUNT, 1));
Integer loanId = postLoansResponse.getLoanId().intValue();

GetLoansLoanIdResponse getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
assertNotNull(getLoansLoanIdResponse);
Expand All @@ -87,16 +74,46 @@ public void testMarkLoanAsFraud() {
assertEquals(Boolean.FALSE, getLoansLoanIdResponse.getFraud());

String payload = loanTransactionHelper.getLoanFraudPayloadAsJSON("fraud", "true");
// Send the request, not expecting any errors (because only open loan restriction removed)
PutLoansLoanIdResponse putLoansLoanIdResponse = loanTransactionHelper.modifyLoanCommand(loanId, command, payload,
this.responseSpecError);
PutLoansLoanIdResponse putLoansLoanIdResponse = loanTransactionHelper.modifyLoanCommand(loanId, COMMAND, payload, responseSpec);
assertNotNull(putLoansLoanIdResponse);

getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
assertNotNull(getLoansLoanIdResponse);
assertNotNull(getLoansLoanIdResponse.getFraud());
assertEquals(Boolean.TRUE, getLoansLoanIdResponse.getFraud());
String statusCode = getLoansLoanIdResponse.getStatus().getCode();
log.info("Loan with Id {} is with Status {}", getLoansLoanIdResponse.getId(), statusCode);

payload = loanTransactionHelper.getLoanFraudPayloadAsJSON("fraud", "false");
putLoansLoanIdResponse = loanTransactionHelper.modifyLoanCommand(loanId, COMMAND, payload, responseSpec);
assertNotNull(putLoansLoanIdResponse);

getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
assertNotNull(getLoansLoanIdResponse);
assertNotNull(getLoansLoanIdResponse.getFraud());
assertEquals(Boolean.FALSE, getLoansLoanIdResponse.getFraud());
statusCode = getLoansLoanIdResponse.getStatus().getCode();
log.info("Loan with Id {} is with Status {}", getLoansLoanIdResponse.getId(), statusCode);

// Approve the Loan active
loanTransactionHelper.approveLoan(operationDate, this.amountVal, loanId, null);
putLoansLoanIdResponse = loanTransactionHelper.modifyLoanCommand(loanId, command, payload, this.responseSpecError);
PostLoansLoanIdResponse approvedLoanResult = loanTransactionHelper.approveLoan(postLoansResponse.getResourceId(),
approveLoanRequest(AMOUNT, operationDate));
assertNotNull(approvedLoanResult);

payload = loanTransactionHelper.getLoanFraudPayloadAsJSON("fraud", "true");
putLoansLoanIdResponse = loanTransactionHelper.modifyLoanCommand(loanId, COMMAND, payload, responseSpec);
assertNotNull(putLoansLoanIdResponse);

getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
assertNotNull(getLoansLoanIdResponse);
assertNotNull(getLoansLoanIdResponse.getFraud());
assertEquals(Boolean.TRUE, getLoansLoanIdResponse.getFraud());
statusCode = getLoansLoanIdResponse.getStatus().getCode();
log.info("Loan with Id {} is with Status {}", getLoansLoanIdResponse.getId(), statusCode);

payload = loanTransactionHelper.getLoanFraudPayloadAsJSON("fraud", "false");
putLoansLoanIdResponse = loanTransactionHelper.modifyLoanCommand(loanId, COMMAND, payload, responseSpec);
assertNotNull(putLoansLoanIdResponse);

// Default values Not Null and False
getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
Expand All @@ -106,10 +123,11 @@ public void testMarkLoanAsFraud() {
statusCode = getLoansLoanIdResponse.getStatus().getCode();
log.info("Loan with Id {} is with Status {}", getLoansLoanIdResponse.getId(), statusCode);

loanTransactionHelper.disburseLoanWithNetDisbursalAmount(operationDate, loanId, this.amountVal);
disburseLoan(loanId.longValue(), BigDecimal.valueOf(AMOUNT), operationDate);

// Mark On the Fraud
putLoansLoanIdResponse = loanTransactionHelper.modifyLoanCommand(loanId, command, payload, this.responseSpec);
payload = loanTransactionHelper.getLoanFraudPayloadAsJSON("fraud", "true");
putLoansLoanIdResponse = loanTransactionHelper.modifyLoanCommand(loanId, COMMAND, payload, responseSpec);
assertNotNull(putLoansLoanIdResponse);

getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
Expand All @@ -119,49 +137,33 @@ public void testMarkLoanAsFraud() {

// Mark Off the Fraud
payload = loanTransactionHelper.getLoanFraudPayloadAsJSON("fraud", "false");
putLoansLoanIdResponse = loanTransactionHelper.modifyLoanCommand(loanId, command, payload, this.responseSpec);
putLoansLoanIdResponse = loanTransactionHelper.modifyLoanCommand(loanId, COMMAND, payload, this.responseSpec);
assertNotNull(putLoansLoanIdResponse);

getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
assertNotNull(getLoansLoanIdResponse);
assertNotNull(getLoansLoanIdResponse.getFraud());
assertEquals(Boolean.FALSE, getLoansLoanIdResponse.getFraud());
} finally {
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
}
}

private Integer createAccounts(final Integer daysToSubtract, final Integer numberOfRepayments) {
// Client and Loan account creation
final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2012");
final GetLoanProductsProductIdResponse getLoanProductsProductResponse = createLoanProduct(loanTransactionHelper, null);

// Older date to have more than one overdue installment
final LocalDate transactionDate = this.todaysDate.minusDays(daysToSubtract + (30 * (numberOfRepayments - 1)));
String operationDate = Utils.dateFormatter.format(transactionDate);
payload = loanTransactionHelper.getLoanFraudPayloadAsJSON("fraud", "true");
putLoansLoanIdResponse = loanTransactionHelper.modifyLoanCommand(loanId, COMMAND, payload, responseSpec);
assertNotNull(putLoansLoanIdResponse);

return createLoanAccount(loanTransactionHelper, clientId.toString(), getLoanProductsProductResponse.getId().toString(),
operationDate, amountVal, numberOfRepayments.toString());
}
getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
assertNotNull(getLoansLoanIdResponse);
assertNotNull(getLoansLoanIdResponse.getFraud());
assertEquals(Boolean.TRUE, getLoansLoanIdResponse.getFraud());
statusCode = getLoansLoanIdResponse.getStatus().getCode();
log.info("Loan with Id {} is with Status {}", getLoansLoanIdResponse.getId(), statusCode);

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);
}
undoDisbursement(loanId);

private Integer createLoanAccount(final LoanTransactionHelper loanTransactionHelper, final String clientId, final String loanProductId,
final String operationDate, final String principalAmount, final String numberOfRepayments) {
final String loanApplicationJSON = new LoanApplicationTestBuilder().withPrincipal(principalAmount)
.withLoanTermFrequency(numberOfRepayments).withLoanTermFrequencyAsMonths().withNumberOfRepayments(numberOfRepayments)
.withRepaymentEveryAfter("1").withRepaymentFrequencyTypeAsMonths() //
.withInterestRatePerPeriod("0") //
.withExpectedDisbursementDate(operationDate) //
.withInterestTypeAsDecliningBalance() //
.withSubmittedOnDate(operationDate) //
.build(clientId, loanProductId, null);
return loanTransactionHelper.getLoanId(loanApplicationJSON);
getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
assertNotNull(getLoansLoanIdResponse);
assertNotNull(getLoansLoanIdResponse.getFraud());
assertEquals(Boolean.TRUE, getLoansLoanIdResponse.getFraud());
statusCode = getLoansLoanIdResponse.getStatus().getCode();
log.info("Loan with Id {} is with Status {}", getLoansLoanIdResponse.getId(), statusCode);
});
}

}

0 comments on commit 49b3c01

Please sign in to comment.