FINERACT-1806: Charge-off API

This commit is contained in:
Adam Saghy
2023-01-06 13:42:54 +01:00
committed by Arnold Gálovics
parent bd052acab0
commit c7504680b7
30 changed files with 549 additions and 43 deletions
@@ -19,7 +19,9 @@
package org.apache.fineract.integrationtests;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -89,6 +91,7 @@ import org.apache.fineract.integrationtests.common.savings.AccountTransferHelper
import org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper;
import org.apache.fineract.integrationtests.common.savings.SavingsProductHelper;
import org.apache.fineract.integrationtests.common.savings.SavingsStatusChecker;
import org.apache.fineract.integrationtests.common.system.CodeHelper;
import org.apache.fineract.portfolio.charge.domain.ChargeCalculationType;
import org.apache.fineract.portfolio.charge.domain.ChargePaymentMode;
import org.apache.fineract.portfolio.charge.domain.ChargeTimeType;
@@ -6939,6 +6942,58 @@ public class ClientLoanIntegrationTest {
assertEquals(0.0f, loanSummary.get("totalWaived"));
}
@Test
public void chargeOff() {
final Account assetAccount = this.accountHelper.createAssetAccount();
final Account incomeAccount = this.accountHelper.createIncomeAccount();
final Account expenseAccount = this.accountHelper.createExpenseAccount();
final Account overpaymentAccount = this.accountHelper.createLiabilityAccount();
String randomText = Utils.randomStringGenerator("en", 5) + Utils.randomNumberGenerator(6) + Utils.randomStringGenerator("is", 5);
Integer chargeOffReasonId = CodeHelper.createChargeOffCodeValue(requestSpec, responseSpec, randomText, 1);
final Integer loanProductID = createLoanProductWithPeriodicAccrualAccountingNoInterest(assetAccount, incomeAccount, expenseAccount,
overpaymentAccount);
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, "01 January 2011");
final Integer loanID = applyForLoanApplication(clientID, loanProductID);
HashMap<String, Object> loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(requestSpec, responseSpec, loanID);
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
loanStatusHashMap = this.loanTransactionHelper.approveLoan("02 September 2022", loanID);
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
loanStatusHashMap = this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("03 September 2022", loanID, "1000");
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
GetLoansLoanIdResponse loanDetails = this.loanTransactionHelper.getLoanDetails((long) loanID);
assertTrue(loanDetails.getStatus().getActive());
assertEquals(1000.0, loanDetails.getSummary().getTotalOutstanding());
assertFalse(loanDetails.getChargedOff());
assertNull(loanDetails.getSummary().getChargeOffReasonId());
assertNull(loanDetails.getSummary().getChargeOffReason());
assertNull(loanDetails.getTimeline().getChargedOffOnDate());
assertNull(loanDetails.getTimeline().getChargedOffByUsername());
assertNull(loanDetails.getTimeline().getChargedOffByFirstname());
assertNull(loanDetails.getTimeline().getChargedOffByLastname());
String transactionExternalId = UUID.randomUUID().toString();
this.loanTransactionHelper.chargeOffLoan((long) loanID, new PostLoansLoanIdTransactionsRequest().transactionDate("4 September 2022")
.locale("en").dateFormat("dd MMMM yyyy").externalId(transactionExternalId).chargeOffReasonId((long) chargeOffReasonId));
loanDetails = this.loanTransactionHelper.getLoanDetails((long) loanID);
assertTrue(loanDetails.getStatus().getActive());
assertEquals(1000.0, loanDetails.getSummary().getTotalOutstanding());
assertTrue(loanDetails.getChargedOff());
assertEquals((long) chargeOffReasonId, loanDetails.getSummary().getChargeOffReasonId());
assertEquals(randomText, loanDetails.getSummary().getChargeOffReason());
assertEquals(LocalDate.of(2022, 9, 4), loanDetails.getTimeline().getChargedOffOnDate());
assertEquals("mifos", loanDetails.getTimeline().getChargedOffByUsername());
assertEquals("App", loanDetails.getTimeline().getChargedOffByFirstname());
assertEquals("Administrator", loanDetails.getTimeline().getChargedOffByLastname());
}
private Integer applyForLoanApplication(final Integer clientID, final Integer loanProductID) {
LOG.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
final String loanApplicationJSON = new LoanApplicationTestBuilder().withPrincipal("1000").withLoanTermFrequency("1")
@@ -188,6 +188,7 @@ public class ExternalIdSupportIntegrationTest extends IntegrationTest {
loanTransactionHelper.retrieveTransactionTemplate(loanExternalIdStr, "refundbycash", null, null, null);
loanTransactionHelper.retrieveTransactionTemplate(loanExternalIdStr, "foreclosure", null, null, null);
loanTransactionHelper.retrieveTransactionTemplate(loanExternalIdStr, "creditBalanceRefund", null, null, null);
loanTransactionHelper.retrieveTransactionTemplate(loanExternalIdStr, "charge-off", null, null, null);
// Check whether an external id was generated
String waiveChargeExternalIdStr = UUID.randomUUID().toString();
@@ -1069,6 +1070,23 @@ public class ExternalIdSupportIntegrationTest extends IntegrationTest {
.externalId(transactionExternalId2));
assertEquals(transactionExternalId2, forecloseResult.getResourceExternalId());
String loanExternalIdStr16 = UUID.randomUUID().toString();
String transactionExternalId3 = UUID.randomUUID().toString();
applyForLoanApplication(client.getClientId().intValue(), loanProductID, loanExternalIdStr16);
this.loanTransactionHelper.approveLoan(loanExternalIdStr16,
new PostLoansLoanIdRequest().approvedOnDate("2 September 2022").approvedLoanAmount(new BigDecimal("1000"))
.expectedDisbursementDate("2 September 2022").locale("en").dateFormat("dd MMMM yyyy"));
this.loanTransactionHelper.disburseLoan(loanExternalIdStr16,
new PostLoansLoanIdRequest().actualDisbursementDate("2 September 2022").transactionAmount(new BigDecimal("1000"))
.locale("en").dateFormat("dd MMMM yyyy"));
this.loanTransactionHelper.disburseLoan(loanExternalIdStr16,
new PostLoansLoanIdRequest().actualDisbursementDate("2 September 2022").transactionAmount(new BigDecimal("1000"))
.locale("en").dateFormat("dd MMMM yyyy"));
PostLoansLoanIdTransactionsResponse chargeOffResult = this.loanTransactionHelper.chargeOffLoan(loanExternalIdStr16,
new PostLoansLoanIdTransactionsRequest().transactionDate("2 September 2022").locale("en").dateFormat("dd MMMM yyyy")
.externalId(transactionExternalId3));
assertEquals(transactionExternalId3, chargeOffResult.getResourceExternalId());
} finally {
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
GlobalConfigurationHelper.updateEnabledFlagForGlobalConfiguration(requestSpec, responseSpec, 50, false);
@@ -1719,4 +1719,12 @@ public class LoanTransactionHelper extends IntegrationTest {
public PostLoansLoanIdTransactionsResponse forecloseLoan(String loanExternalId, PostLoansLoanIdTransactionsRequest request) {
return ok(fineract().loanTransactions.executeLoanTransaction1(loanExternalId, request, "foreclosure"));
}
public PostLoansLoanIdTransactionsResponse chargeOffLoan(String loanExternalId, PostLoansLoanIdTransactionsRequest request) {
return ok(fineract().loanTransactions.executeLoanTransaction1(loanExternalId, request, "charge-off"));
}
public PostLoansLoanIdTransactionsResponse chargeOffLoan(Long loanId, PostLoansLoanIdTransactionsRequest request) {
return ok(fineract().loanTransactions.executeLoanTransaction(loanId, request, "charge-off"));
}
}
@@ -34,6 +34,7 @@ public final class CodeHelper {
private static final String COUNTRY_CODE_NAME = "COUNTRY";
private static final String STATE_CODE_NAME = "STATE";
private static final String ADDRESS_TYPE_CODE_NAME = "ADDRESS_TYPE";
private static final String CHARGE_OFF_REASONS_CODE_NAME = "ChargeOffReasons";
private CodeHelper() {
@@ -175,6 +176,13 @@ public final class CodeHelper {
return createCodeValue(requestSpec, responseSpec, countryCode, countryName, position);
}
public static Integer createChargeOffCodeValue(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final String value, final Integer position) {
HashMap<String, Object> code = getCodeByName(requestSpec, responseSpec, CHARGE_OFF_REASONS_CODE_NAME);
Integer countryCode = (Integer) code.get("id");
return createCodeValue(requestSpec, responseSpec, countryCode, value, position);
}
public static Integer createCodeValue(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final Integer codeId, final String codeValueName, final Integer position) {
return (Integer) createCodeValue(requestSpec, responseSpec, codeId, codeValueName, position, SUBRESPONSE_ID_ATTRIBUTE_NAME);