This is an automated email from the ASF dual-hosted git repository.
adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
The following commit(s) were added to refs/heads/develop by this push:
new d2afd1aac FINERACT-1806: Fix mapping to handle multiple loan product
configuration
d2afd1aac is described below
commit d2afd1aac7617f2e225a32b09f5a295c14976e26
Author: Adam Saghy <[email protected]>
AuthorDate: Wed Jan 8 11:22:50 2025 +0100
FINERACT-1806: Fix mapping to handle multiple loan product configuration
---
.../ProductToGLAccountMappingRepository.java | 5 +-
.../service/AccountingProcessorHelper.java | 5 +-
.../AccrualBasedAccountingProcessorForLoan.java | 3 +-
.../CreateJournalEntriesForChargeOffLoanTest.java | 13 +-
.../LoanChargeOffAccountingTest.java | 1186 ++++++++++----------
5 files changed, 636 insertions(+), 576 deletions(-)
diff --git
a/fineract-accounting/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/ProductToGLAccountMappingRepository.java
b/fineract-accounting/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/ProductToGLAccountMappingRepository.java
index 4f05f8a43..2b2bc2117 100644
---
a/fineract-accounting/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/ProductToGLAccountMappingRepository.java
+++
b/fineract-accounting/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/ProductToGLAccountMappingRepository.java
@@ -66,8 +66,9 @@ public interface ProductToGLAccountMappingRepository
List<ProductToGLAccountMapping>
findAllChargeOffReasonsMappings(@Param("productId") Long productId,
@Param("productType") int productType);
- @Query("select mapping from ProductToGLAccountMapping mapping where
mapping.chargeOffReason.id =:chargeOffReasonId")
- ProductToGLAccountMapping
findChargeOffReasonMappingById(@Param("chargeOffReasonId") Long
chargeOffReasonId);
+ @Query("select mapping from ProductToGLAccountMapping mapping where
mapping.chargeOffReason.id =:chargeOffReasonId AND mapping.productId
=:productId AND mapping.productType =:productType")
+ ProductToGLAccountMapping findChargeOffReasonMapping(@Param("productId")
Long productId, @Param("productType") Integer productType,
+ @Param("chargeOffReasonId") Long chargeOffReasonId);
@Query("select mapping from ProductToGLAccountMapping mapping where
mapping.productId =:productId AND mapping.productType =:productType AND
mapping.charge IS NULL AND mapping.paymentType IS NULL AND
mapping.chargeOffReason IS NULL")
List<ProductToGLAccountMapping> findAllRegularMappings(@Param("productId")
Long productId, @Param("productType") Integer productType);
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java
index 49098705f..d9ee4a5fb 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java
@@ -177,8 +177,9 @@ public class AccountingProcessorHelper {
chargeOffReasonCodeValue);
}
- public ProductToGLAccountMapping getChargeOffMappingByCodeValue(Long
chargeOffReasonCodeValue) {
- return
accountMappingRepository.findChargeOffReasonMappingById(chargeOffReasonCodeValue);
+ public ProductToGLAccountMapping getChargeOffMappingByCodeValue(Long
loanProductId, PortfolioProductType productType,
+ Long chargeOffReasonId) {
+ return
accountMappingRepository.findChargeOffReasonMapping(loanProductId,
productType.getValue(), chargeOffReasonId);
}
public SavingsDTO populateSavingsDtoFromMap(final Map<String, Object>
accountingBridgeData, final boolean cashBasedAccountingEnabled,
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java
index 17c437874..999df7c37 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java
@@ -37,6 +37,7 @@ import
org.apache.fineract.accounting.journalentry.data.LoanTransactionDTO;
import
org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGLAccountMapping;
import org.apache.fineract.infrastructure.core.service.MathUtil;
import org.apache.fineract.organisation.office.domain.Office;
+import org.apache.fineract.portfolio.PortfolioProductType;
import org.apache.fineract.portfolio.loanaccount.data.LoanTransactionEnumData;
import org.springframework.stereotype.Component;
@@ -233,7 +234,7 @@ public class AccrualBasedAccountingProcessorForLoan
implements AccountingProcess
Long chargeOffReasonCodeValue = loanDTO.getChargeOffReasonCodeValue();
ProductToGLAccountMapping mapping = chargeOffReasonCodeValue != null
- ?
helper.getChargeOffMappingByCodeValue(chargeOffReasonCodeValue)
+ ? helper.getChargeOffMappingByCodeValue(loanProductId,
PortfolioProductType.LOAN, chargeOffReasonCodeValue)
: null;
if (mapping != null) {
GLAccount accountCredit =
this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
diff --git
a/fineract-provider/src/test/java/org/apache/fineract/accounting/journalentry/CreateJournalEntriesForChargeOffLoanTest.java
b/fineract-provider/src/test/java/org/apache/fineract/accounting/journalentry/CreateJournalEntriesForChargeOffLoanTest.java
index 9f7be1503..61960d64a 100644
---
a/fineract-provider/src/test/java/org/apache/fineract/accounting/journalentry/CreateJournalEntriesForChargeOffLoanTest.java
+++
b/fineract-provider/src/test/java/org/apache/fineract/accounting/journalentry/CreateJournalEntriesForChargeOffLoanTest.java
@@ -37,6 +37,7 @@ import
org.apache.fineract.accounting.journalentry.service.AccountingProcessorHe
import
org.apache.fineract.accounting.journalentry.service.AccrualBasedAccountingProcessorForLoan;
import
org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGLAccountMapping;
import org.apache.fineract.organisation.office.domain.Office;
+import org.apache.fineract.portfolio.PortfolioProductType;
import org.apache.fineract.portfolio.loanaccount.data.LoanTransactionEnumData;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -48,7 +49,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
class CreateJournalEntriesForChargeOffLoanTest {
- private static final Long chargeOffReasons = 15L;
+ private static final Long chargeOffReasonId = 15L;
@Mock
private AccountingProcessorHelper helper;
@@ -71,7 +72,7 @@ class CreateJournalEntriesForChargeOffLoanTest {
transactionType, new BigDecimal("500.00"), new
BigDecimal("500.00"), null, null, null, null, false, Collections.emptyList(),
Collections.emptyList(), false, "", null, null, null, null);
- loanDTO = new LoanDTO(1L, 1L, 1L, "USD", false, true, true,
List.of(loanTransactionDTO), false, false, chargeOffReasons);
+ loanDTO = new LoanDTO(1L, 1L, 1L, "USD", false, true, true,
List.of(loanTransactionDTO), false, false, chargeOffReasonId);
}
@Test
@@ -84,7 +85,7 @@ class CreateJournalEntriesForChargeOffLoanTest {
ProductToGLAccountMapping chargeToGLAccountMapper = new
ProductToGLAccountMapping();
chargeToGLAccountMapper.setGlAccount(chargeOffGLAccount);
-
when(helper.getChargeOffMappingByCodeValue(chargeOffReasons)).thenReturn(chargeToGLAccountMapper);
+ when(helper.getChargeOffMappingByCodeValue(1L,
PortfolioProductType.LOAN,
chargeOffReasonId)).thenReturn(chargeToGLAccountMapper);
GLAccount loanPortfolioGLAccount = new GLAccount();
loanPortfolioGLAccount.setId(20L);
@@ -96,7 +97,7 @@ class CreateJournalEntriesForChargeOffLoanTest {
processor.createJournalEntriesForLoan(loanDTO);
- verify(helper,
times(1)).getChargeOffMappingByCodeValue(chargeOffReasons);
+ verify(helper, times(1)).getChargeOffMappingByCodeValue(1L,
PortfolioProductType.LOAN, chargeOffReasonId);
verify(helper, times(1)).getLinkedGLAccountForLoanProduct(1L,
AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(), 1L);
verify(helper,
times(1)).createCreditJournalEntryOrReversalForLoan(helper.getOfficeById(1L),
"USD",
AccrualAccountsForLoan.LOAN_PORTFOLIO, 1L, null, 1L,
"txn-123", LocalDate.now(ZoneId.systemDefault()),
@@ -110,7 +111,7 @@ class CreateJournalEntriesForChargeOffLoanTest {
void shouldCreateJournalEntriesForChargeOffWithFraud() {
loanDTO.setMarkedAsFraud(true);
-
when(helper.getChargeOffMappingByCodeValue(chargeOffReasons)).thenReturn(null);
+ when(helper.getChargeOffMappingByCodeValue(1L,
PortfolioProductType.LOAN, chargeOffReasonId)).thenReturn(null);
GLAccount loanPortfolioGLAccount = new GLAccount();
loanPortfolioGLAccount.setId(20L);
@@ -138,7 +139,7 @@ class CreateJournalEntriesForChargeOffLoanTest {
void shouldCreateJournalEntriesForChargeOffWithoutFraud() {
loanDTO.setMarkedAsFraud(false);
-
when(helper.getChargeOffMappingByCodeValue(chargeOffReasons)).thenReturn(null);
+ when(helper.getChargeOffMappingByCodeValue(1L,
PortfolioProductType.LOAN, chargeOffReasonId)).thenReturn(null);
GLAccount loanPortfolioGLAccount = new GLAccount();
loanPortfolioGLAccount.setId(20L);
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargeOffAccountingTest.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargeOffAccountingTest.java
index 4b458b0bc..5f9e29a6f 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargeOffAccountingTest.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargeOffAccountingTest.java
@@ -64,6 +64,7 @@ import
org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
import org.apache.fineract.integrationtests.common.system.CodeHelper;
import org.apache.fineract.integrationtests.inlinecob.InlineLoanCOBHelper;
import
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -104,595 +105,614 @@ public class LoanChargeOffAccountingTest extends
BaseLoanIntegrationTest {
@Test
public void
loanChargeOffAccountingTreatmentTestForPeriodicAccrualAccounting() {
- // Loan ExternalId
- String loanExternalIdStr = UUID.randomUUID().toString();
-
- // Product to GL account mapping for test
- // ASSET
- //
-fundSourceAccountId,loanPortfolioAccountId,transfersInSuspenseAccountId,receivableFeeAccountId,receivablePenaltyAccountId,receivableInterestAccountId
- //
INCOME-interestOnLoanAccountId,incomeFromFeeAccountId,incomeFromPenaltyAccountId,incomeFromRecoveryAccountId,incomeFromChargeOffInterestAccountId,incomeFromChargeOffFeesAccountId,incomeFromChargeOffPenaltyAccountId,incomeFromGoodwillCreditInterestAccountId,incomeFromGoodwillCreditFeesAccountId,incomeFromGoodwillCreditPenaltyAccountId
- //
EXPENSE-writeOffAccountId,goodwillCreditAccountId,chargeOffExpenseAccountId,chargeOffFraudExpenseAccountId
- // LIABILITY-overpaymentLiabilityAccountId
-
- final Integer loanProductID =
createLoanProductWithPeriodicAccrualAccounting(assetAccount, incomeAccount,
expenseAccount,
- overpaymentAccount);
- final Integer clientId =
clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId().intValue();
- final Integer loanId = createLoanAccount(clientId, loanProductID,
loanExternalIdStr);
-
- // apply charges
- Integer feeCharge = ChargesHelper.createCharges(requestSpec,
responseSpec,
-
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", false));
-
- LocalDate targetDate = LocalDate.of(2022, 9, 5);
- final String feeCharge1AddedDate = dateFormatter.format(targetDate);
- Integer feeLoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
-
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(feeCharge),
feeCharge1AddedDate, "10"));
-
- // apply penalty
- Integer penalty = ChargesHelper.createCharges(requestSpec,
responseSpec,
-
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", true));
-
- final String penaltyCharge1AddedDate =
dateFormatter.format(targetDate);
-
- Integer penalty1LoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
-
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty),
penaltyCharge1AddedDate, "10"));
-
- // set loan as chargeoff
- String randomText = Utils.randomStringGenerator("en", 5) +
Utils.randomNumberGenerator(6) + Utils.randomStringGenerator("is", 5);
- Integer chargeOffReasonId =
CodeHelper.createChargeOffCodeValue(requestSpec, responseSpec, randomText, 1);
- String transactionExternalId = UUID.randomUUID().toString();
- this.loanTransactionHelper.chargeOffLoan((long) loanId, new
PostLoansLoanIdTransactionsRequest().transactionDate("6 September 2022")
- .locale("en").dateFormat("dd MMMM
yyyy").externalId(transactionExternalId).chargeOffReasonId((long)
chargeOffReasonId));
-
- GetLoansLoanIdResponse loanDetails =
this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getActive());
- assertTrue(loanDetails.getChargedOff());
-
- // verify Journal Entries For ChargeOff Transaction
- this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount,
"6 September 2022",
- new JournalEntry(1020, JournalEntry.TransactionType.CREDIT));
-
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "6
September 2022",
- new JournalEntry(1000, JournalEntry.TransactionType.DEBIT));
-
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6
September 2022",
- new JournalEntry(20, JournalEntry.TransactionType.DEBIT));
-
- // make Repayment
- final PostLoansLoanIdTransactionsResponse repaymentTransaction =
loanTransactionHelper.makeLoanRepayment(loanExternalIdStr,
- new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM
yyyy").transactionDate("7 September 2022").locale("en")
- .transactionAmount(100.0));
-
- loanDetails = this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getActive());
- assertTrue(loanDetails.getChargedOff());
-
- // verify Journal Entries for Repayment transaction
-
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "7
September 2022",
- new JournalEntry(100, JournalEntry.TransactionType.CREDIT));
- this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount,
"7 September 2022",
- new JournalEntry(100, JournalEntry.TransactionType.DEBIT));
-
- // Merchant Refund
- final PostLoansLoanIdTransactionsResponse merchantIssuedRefund_1 =
loanTransactionHelper.makeMerchantIssuedRefund((long) loanId,
- new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM
yyyy").transactionDate("8 September 2022").locale("en")
- .transactionAmount(100.0));
-
- loanDetails = this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getActive());
- assertTrue(loanDetails.getChargedOff());
-
- // verify Journal Entries for Merchant Refund
-
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "8
September 2022",
- new JournalEntry(100, JournalEntry.TransactionType.CREDIT));
- this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount,
"8 September 2022",
- new JournalEntry(100, JournalEntry.TransactionType.DEBIT));
-
- // Payout Refund
- final PostLoansLoanIdTransactionsResponse payoutRefund_1 =
loanTransactionHelper.makePayoutRefund((long) loanId,
- new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM
yyyy").transactionDate("9 September 2022").locale("en")
- .transactionAmount(100.0));
-
- loanDetails = this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getActive());
- assertTrue(loanDetails.getChargedOff());
-
- // verify Journal Entries for Payout Refund
-
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "9
September 2022",
- new JournalEntry(100, JournalEntry.TransactionType.CREDIT));
- this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount,
"9 September 2022",
- new JournalEntry(100, JournalEntry.TransactionType.DEBIT));
-
- // Goodwill Credit
- final PostLoansLoanIdTransactionsResponse goodwillCredit_1 =
loanTransactionHelper.makeGoodwillCredit((long) loanId,
- new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM
yyyy").transactionDate("10 September 2022").locale("en")
- .transactionAmount(100.0));
-
- loanDetails = this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getActive());
- assertTrue(loanDetails.getChargedOff());
-
- // verify Journal Entries for Goodwill Credit
-
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "10
September 2022",
- new JournalEntry(100, JournalEntry.TransactionType.DEBIT));
-
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "10
September 2022",
- new JournalEntry(100, JournalEntry.TransactionType.CREDIT));
-
- // make overpaid repayment
- final PostLoansLoanIdTransactionsResponse repaymentTransaction_1 =
loanTransactionHelper.makeLoanRepayment(loanExternalIdStr,
- new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM
yyyy").transactionDate("11 September 2022").locale("en")
- .transactionAmount(720.0));
-
- loanDetails = this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getOverpaid());
- assertTrue(loanDetails.getChargedOff());
-
- // verify Journal entries for overpaid repayment
-
this.journalEntryHelper.checkJournalEntryForLiabilityAccount(overpaymentAccount,
"11 September 2022",
- new JournalEntry(100, JournalEntry.TransactionType.CREDIT));
-
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "11
September 2022",
- new JournalEntry(620, JournalEntry.TransactionType.CREDIT));
- this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount,
"11 September 2022",
- new JournalEntry(720, JournalEntry.TransactionType.DEBIT));
-
- // CBR for making loan active again
- final PostLoansLoanIdTransactionsResponse cbr_transaction =
loanTransactionHelper.makeCreditBalanceRefund(loanExternalIdStr,
- new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM
yyyy").transactionDate("12 September 2022").locale("en")
- .transactionAmount(100.0));
-
- // Charge Adjustment making loan overpaid
- final PostLoansLoanIdChargesChargeIdResponse chargeAdjustmentResult =
loanTransactionHelper.chargeAdjustment((long) loanId,
- (long) feeLoanChargeId, new
PostLoansLoanIdChargesChargeIdRequest().amount(10.0).locale("en"));
-
- loanDetails = this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getOverpaid());
-
- final LocalDate todaysDate = Utils.getLocalDateOfTenant();
- String transactionDate = Utils.dateFormatter.format(todaysDate);
-
- // verify Journal entries for Charge Adjustment
-
this.journalEntryHelper.checkJournalEntryForLiabilityAccount(overpaymentAccount,
transactionDate,
- new JournalEntry(10, JournalEntry.TransactionType.CREDIT));
-
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount,
transactionDate,
- new JournalEntry(10, JournalEntry.TransactionType.DEBIT));
+ runAt("12 September 2022", () -> {
+
+ // Loan ExternalId
+ String loanExternalIdStr = UUID.randomUUID().toString();
+
+ // Product to GL account mapping for test
+ // ASSET
+ //
-fundSourceAccountId,loanPortfolioAccountId,transfersInSuspenseAccountId,receivableFeeAccountId,receivablePenaltyAccountId,receivableInterestAccountId
+ //
INCOME-interestOnLoanAccountId,incomeFromFeeAccountId,incomeFromPenaltyAccountId,incomeFromRecoveryAccountId,incomeFromChargeOffInterestAccountId,incomeFromChargeOffFeesAccountId,incomeFromChargeOffPenaltyAccountId,incomeFromGoodwillCreditInterestAccountId,incomeFromGoodwillCreditFeesAccountId,incomeFromGoodwillCreditPenaltyAccountId
+ //
EXPENSE-writeOffAccountId,goodwillCreditAccountId,chargeOffExpenseAccountId,chargeOffFraudExpenseAccountId
+ // LIABILITY-overpaymentLiabilityAccountId
+
+ final Integer loanProductID =
createLoanProductWithPeriodicAccrualAccounting(assetAccount, incomeAccount,
expenseAccount,
+ overpaymentAccount);
+ final Integer clientId =
clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId().intValue();
+ final Integer loanId = createLoanAccount(clientId, loanProductID,
loanExternalIdStr);
+
+ // apply charges
+ Integer feeCharge = ChargesHelper.createCharges(requestSpec,
responseSpec,
+
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", false));
+
+ LocalDate targetDate = LocalDate.of(2022, 9, 5);
+ final String feeCharge1AddedDate =
dateFormatter.format(targetDate);
+ Integer feeLoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
+
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(feeCharge),
feeCharge1AddedDate, "10"));
+
+ // apply penalty
+ Integer penalty = ChargesHelper.createCharges(requestSpec,
responseSpec,
+
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", true));
+
+ final String penaltyCharge1AddedDate =
dateFormatter.format(targetDate);
+
+ Integer penalty1LoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
+
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty),
penaltyCharge1AddedDate, "10"));
+
+ // set loan as chargeoff
+ String randomText = Utils.randomStringGenerator("en", 5) +
Utils.randomNumberGenerator(6)
+ + Utils.randomStringGenerator("is", 5);
+ Integer chargeOffReasonId =
CodeHelper.createChargeOffCodeValue(requestSpec, responseSpec, randomText, 1);
+ String transactionExternalId = UUID.randomUUID().toString();
+ this.loanTransactionHelper.chargeOffLoan((long) loanId,
+ new
PostLoansLoanIdTransactionsRequest().transactionDate("6 September
2022").locale("en").dateFormat("dd MMMM yyyy")
+
.externalId(transactionExternalId).chargeOffReasonId((long) chargeOffReasonId));
+
+ GetLoansLoanIdResponse loanDetails =
this.loanTransactionHelper.getLoanDetails((long) loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+ assertTrue(loanDetails.getChargedOff());
+
+ // verify Journal Entries For ChargeOff Transaction
+
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "6
September 2022",
+ new JournalEntry(1020,
JournalEntry.TransactionType.CREDIT));
+
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "6
September 2022",
+ new JournalEntry(1000,
JournalEntry.TransactionType.DEBIT));
+
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6
September 2022",
+ new JournalEntry(20, JournalEntry.TransactionType.DEBIT));
+
+ // make Repayment
+ final PostLoansLoanIdTransactionsResponse repaymentTransaction =
loanTransactionHelper.makeLoanRepayment(loanExternalIdStr,
+ new PostLoansLoanIdTransactionsRequest().dateFormat("dd
MMMM yyyy").transactionDate("7 September 2022").locale("en")
+ .transactionAmount(100.0));
+
+ loanDetails = this.loanTransactionHelper.getLoanDetails((long)
loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+ assertTrue(loanDetails.getChargedOff());
+
+ // verify Journal Entries for Repayment transaction
+
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "7
September 2022",
+ new JournalEntry(100,
JournalEntry.TransactionType.CREDIT));
+
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "7
September 2022",
+ new JournalEntry(100, JournalEntry.TransactionType.DEBIT));
+
+ // Merchant Refund
+ final PostLoansLoanIdTransactionsResponse merchantIssuedRefund_1 =
loanTransactionHelper.makeMerchantIssuedRefund((long) loanId,
+ new PostLoansLoanIdTransactionsRequest().dateFormat("dd
MMMM yyyy").transactionDate("8 September 2022").locale("en")
+ .transactionAmount(100.0));
+
+ loanDetails = this.loanTransactionHelper.getLoanDetails((long)
loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+ assertTrue(loanDetails.getChargedOff());
+
+ // verify Journal Entries for Merchant Refund
+
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "8
September 2022",
+ new JournalEntry(100,
JournalEntry.TransactionType.CREDIT));
+
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "8
September 2022",
+ new JournalEntry(100, JournalEntry.TransactionType.DEBIT));
+
+ // Payout Refund
+ final PostLoansLoanIdTransactionsResponse payoutRefund_1 =
loanTransactionHelper.makePayoutRefund((long) loanId,
+ new PostLoansLoanIdTransactionsRequest().dateFormat("dd
MMMM yyyy").transactionDate("9 September 2022").locale("en")
+ .transactionAmount(100.0));
+
+ loanDetails = this.loanTransactionHelper.getLoanDetails((long)
loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+ assertTrue(loanDetails.getChargedOff());
+
+ // verify Journal Entries for Payout Refund
+
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "9
September 2022",
+ new JournalEntry(100,
JournalEntry.TransactionType.CREDIT));
+
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "9
September 2022",
+ new JournalEntry(100, JournalEntry.TransactionType.DEBIT));
+
+ // Goodwill Credit
+ final PostLoansLoanIdTransactionsResponse goodwillCredit_1 =
loanTransactionHelper.makeGoodwillCredit((long) loanId,
+ new PostLoansLoanIdTransactionsRequest().dateFormat("dd
MMMM yyyy").transactionDate("10 September 2022").locale("en")
+ .transactionAmount(100.0));
+
+ loanDetails = this.loanTransactionHelper.getLoanDetails((long)
loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+ assertTrue(loanDetails.getChargedOff());
+
+ // verify Journal Entries for Goodwill Credit
+
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "10
September 2022",
+ new JournalEntry(100, JournalEntry.TransactionType.DEBIT));
+
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "10
September 2022",
+ new JournalEntry(100,
JournalEntry.TransactionType.CREDIT));
+
+ // make overpaid repayment
+ final PostLoansLoanIdTransactionsResponse repaymentTransaction_1 =
loanTransactionHelper.makeLoanRepayment(loanExternalIdStr,
+ new PostLoansLoanIdTransactionsRequest().dateFormat("dd
MMMM yyyy").transactionDate("11 September 2022").locale("en")
+ .transactionAmount(720.0));
+
+ loanDetails = this.loanTransactionHelper.getLoanDetails((long)
loanId);
+ assertTrue(loanDetails.getStatus().getOverpaid());
+ assertTrue(loanDetails.getChargedOff());
+
+ // verify Journal entries for overpaid repayment
+
this.journalEntryHelper.checkJournalEntryForLiabilityAccount(overpaymentAccount,
"11 September 2022",
+ new JournalEntry(100,
JournalEntry.TransactionType.CREDIT));
+
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "11
September 2022",
+ new JournalEntry(620,
JournalEntry.TransactionType.CREDIT));
+
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "11
September 2022",
+ new JournalEntry(720, JournalEntry.TransactionType.DEBIT));
+
+ // CBR for making loan active again
+ final PostLoansLoanIdTransactionsResponse cbr_transaction =
loanTransactionHelper.makeCreditBalanceRefund(loanExternalIdStr,
+ new PostLoansLoanIdTransactionsRequest().dateFormat("dd
MMMM yyyy").transactionDate("12 September 2022").locale("en")
+ .transactionAmount(100.0));
+
+ // Charge Adjustment making loan overpaid
+ final PostLoansLoanIdChargesChargeIdResponse
chargeAdjustmentResult = loanTransactionHelper.chargeAdjustment((long) loanId,
+ (long) feeLoanChargeId, new
PostLoansLoanIdChargesChargeIdRequest().amount(10.0).locale("en"));
+
+ loanDetails = this.loanTransactionHelper.getLoanDetails((long)
loanId);
+ assertTrue(loanDetails.getStatus().getOverpaid());
+
+ // verify Journal entries for Charge Adjustment
+
this.journalEntryHelper.checkJournalEntryForLiabilityAccount(overpaymentAccount,
"12 September 2022",
+ new JournalEntry(10, JournalEntry.TransactionType.CREDIT));
+
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "12
September 2022",
+ new JournalEntry(10, JournalEntry.TransactionType.DEBIT));
+
+ });
}
@Test
public void
loanChargeOffFraudAccountingTreatmentTestForCashBasedAccounting() {
- // Loan ExternalId
- String loanExternalIdStr = UUID.randomUUID().toString();
-
- // Product to GL account mapping for test
- // ASSET
- //
-fundSourceAccountId,loanPortfolioAccountId,transfersInSuspenseAccountId
- //
INCOME-interestOnLoanAccountId,incomeFromFeeAccountId,incomeFromPenaltyAccountId,incomeFromRecoveryAccountId,incomeFromChargeOffInterestAccountId,incomeFromChargeOffFeesAccountId,incomeFromChargeOffPenaltyAccountId,incomeFromGoodwillCreditInterestAccountId,incomeFromGoodwillCreditFeesAccountId,incomeFromGoodwillCreditPenaltyAccountId
- //
EXPENSE-writeOffAccountId,goodwillCreditAccountId,chargeOffExpenseAccountId,chargeOffFraudExpenseAccountId
- // LIABILITY-overpaymentLiabilityAccountId
-
- final Integer loanProductID =
createLoanProductWithCashBasedAccounting(assetAccount, incomeAccount,
expenseAccount,
- overpaymentAccount);
- final Integer clientId =
clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId().intValue();
- final Integer loanId = createLoanAccount(clientId, loanProductID,
loanExternalIdStr);
-
- // apply charges
- Integer feeCharge = ChargesHelper.createCharges(requestSpec,
responseSpec,
-
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", false));
-
- LocalDate targetDate = LocalDate.of(2022, 9, 5);
- final String feeCharge1AddedDate = dateFormatter.format(targetDate);
- Integer feeLoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
-
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(feeCharge),
feeCharge1AddedDate, "10"));
-
- // apply penalty
- Integer penalty = ChargesHelper.createCharges(requestSpec,
responseSpec,
-
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", true));
-
- final String penaltyCharge1AddedDate =
dateFormatter.format(targetDate);
-
- Integer penalty1LoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
-
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty),
penaltyCharge1AddedDate, "10"));
-
- // set loan as fraud
- final String command = "markAsFraud";
- String payload =
loanTransactionHelper.getLoanFraudPayloadAsJSON("fraud", "true");
- PutLoansLoanIdResponse putLoansLoanIdResponse =
loanTransactionHelper.modifyLoanCommand(loanId, command, payload,
- this.responseSpec);
-
- GetLoansLoanIdResponse loanDetails =
this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getActive());
- assertTrue(loanDetails.getFraud());
-
- // set loan as chargeoff
- String randomText = Utils.randomStringGenerator("en", 5) +
Utils.randomNumberGenerator(6) + Utils.randomStringGenerator("is", 5);
- Integer chargeOffReasonId =
CodeHelper.createChargeOffCodeValue(requestSpec, responseSpec, randomText, 1);
- String transactionExternalId = UUID.randomUUID().toString();
- this.loanTransactionHelper.chargeOffLoan((long) loanId, new
PostLoansLoanIdTransactionsRequest().transactionDate("6 September 2022")
- .locale("en").dateFormat("dd MMMM
yyyy").externalId(transactionExternalId).chargeOffReasonId((long)
chargeOffReasonId));
-
- loanDetails = this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getActive());
- assertTrue(loanDetails.getFraud());
- assertTrue(loanDetails.getChargedOff());
-
- // verify Journal Entries For ChargeOff Transaction
- this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount,
"6 September 2022",
- new JournalEntry(1000, JournalEntry.TransactionType.CREDIT));
-
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6
September 2022",
- new JournalEntry(20, JournalEntry.TransactionType.CREDIT));
-
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "6
September 2022",
- new JournalEntry(1000, JournalEntry.TransactionType.DEBIT));
-
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6
September 2022",
- new JournalEntry(20, JournalEntry.TransactionType.DEBIT));
-
- // make Repayment
- final PostLoansLoanIdTransactionsResponse repaymentTransaction =
loanTransactionHelper.makeLoanRepayment(loanExternalIdStr,
- new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM
yyyy").transactionDate("7 September 2022").locale("en")
- .transactionAmount(100.0));
-
- loanDetails = this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getActive());
- assertTrue(loanDetails.getFraud());
- assertTrue(loanDetails.getChargedOff());
-
- // verify Journal Entries for Repayment transaction
-
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "7
September 2022",
- new JournalEntry(100, JournalEntry.TransactionType.CREDIT));
- this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount,
"7 September 2022",
- new JournalEntry(100, JournalEntry.TransactionType.DEBIT));
-
- // Merchant Refund
- final PostLoansLoanIdTransactionsResponse merchantIssuedRefund_1 =
loanTransactionHelper.makeMerchantIssuedRefund((long) loanId,
- new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM
yyyy").transactionDate("8 September 2022").locale("en")
- .transactionAmount(100.0));
-
- loanDetails = this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getActive());
- assertTrue(loanDetails.getFraud());
- assertTrue(loanDetails.getChargedOff());
-
- // verify Journal Entries for Merchant Refund
-
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "8
September 2022",
- new JournalEntry(100, JournalEntry.TransactionType.CREDIT));
- this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount,
"8 September 2022",
- new JournalEntry(100, JournalEntry.TransactionType.DEBIT));
-
- // Payout Refund
- final PostLoansLoanIdTransactionsResponse payoutRefund_1 =
loanTransactionHelper.makePayoutRefund((long) loanId,
- new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM
yyyy").transactionDate("9 September 2022").locale("en")
- .transactionAmount(100.0));
-
- loanDetails = this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getActive());
- assertTrue(loanDetails.getFraud());
- assertTrue(loanDetails.getChargedOff());
-
- // verify Journal Entries for Payout Refund
-
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "9
September 2022",
- new JournalEntry(100, JournalEntry.TransactionType.CREDIT));
- this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount,
"9 September 2022",
- new JournalEntry(100, JournalEntry.TransactionType.DEBIT));
-
- // Goodwill Credit
- final PostLoansLoanIdTransactionsResponse goodwillCredit_1 =
loanTransactionHelper.makeGoodwillCredit((long) loanId,
- new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM
yyyy").transactionDate("10 September 2022").locale("en")
- .transactionAmount(100.0));
-
- loanDetails = this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getActive());
- assertTrue(loanDetails.getFraud());
- assertTrue(loanDetails.getChargedOff());
-
- // verify Journal Entries for Goodwill Credit
-
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "10
September 2022",
- new JournalEntry(100, JournalEntry.TransactionType.DEBIT));
-
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "10
September 2022",
- new JournalEntry(100, JournalEntry.TransactionType.CREDIT));
-
- // make overpaid repayment
- final PostLoansLoanIdTransactionsResponse repaymentTransaction_1 =
loanTransactionHelper.makeLoanRepayment(loanExternalIdStr,
- new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM
yyyy").transactionDate("11 September 2022").locale("en")
- .transactionAmount(720.0));
-
- loanDetails = this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getOverpaid());
- assertTrue(loanDetails.getFraud());
- assertTrue(loanDetails.getChargedOff());
-
- // verify Journal entries for overpaid repayment
-
this.journalEntryHelper.checkJournalEntryForLiabilityAccount(overpaymentAccount,
"11 September 2022",
- new JournalEntry(100, JournalEntry.TransactionType.CREDIT));
-
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "11
September 2022",
- new JournalEntry(620, JournalEntry.TransactionType.CREDIT));
- this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount,
"11 September 2022",
- new JournalEntry(720, JournalEntry.TransactionType.DEBIT));
-
- // CBR for making loan active again
- final PostLoansLoanIdTransactionsResponse cbr_transaction =
loanTransactionHelper.makeCreditBalanceRefund(loanExternalIdStr,
- new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM
yyyy").transactionDate("12 September 2022").locale("en")
- .transactionAmount(100.0));
-
- // Charge Adjustment making loan overpaid
- final PostLoansLoanIdChargesChargeIdResponse chargeAdjustmentResult =
loanTransactionHelper.chargeAdjustment((long) loanId,
- (long) feeLoanChargeId, new
PostLoansLoanIdChargesChargeIdRequest().amount(10.0).locale("en"));
-
- loanDetails = this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getOverpaid());
-
- final LocalDate todaysDate = Utils.getLocalDateOfTenant();
- String transactionDate = Utils.dateFormatter.format(todaysDate);
-
- // verify Journal entries for Charge Adjustment
-
this.journalEntryHelper.checkJournalEntryForLiabilityAccount(overpaymentAccount,
transactionDate,
- new JournalEntry(10, JournalEntry.TransactionType.CREDIT));
-
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount,
transactionDate,
- new JournalEntry(10, JournalEntry.TransactionType.DEBIT));
+ runAt("12 September 2022", () -> {
+
+ // Loan ExternalId
+ String loanExternalIdStr = UUID.randomUUID().toString();
+
+ // Product to GL account mapping for test
+ // ASSET
+ //
-fundSourceAccountId,loanPortfolioAccountId,transfersInSuspenseAccountId
+ //
INCOME-interestOnLoanAccountId,incomeFromFeeAccountId,incomeFromPenaltyAccountId,incomeFromRecoveryAccountId,incomeFromChargeOffInterestAccountId,incomeFromChargeOffFeesAccountId,incomeFromChargeOffPenaltyAccountId,incomeFromGoodwillCreditInterestAccountId,incomeFromGoodwillCreditFeesAccountId,incomeFromGoodwillCreditPenaltyAccountId
+ //
EXPENSE-writeOffAccountId,goodwillCreditAccountId,chargeOffExpenseAccountId,chargeOffFraudExpenseAccountId
+ // LIABILITY-overpaymentLiabilityAccountId
+
+ final Integer loanProductID =
createLoanProductWithCashBasedAccounting(assetAccount, incomeAccount,
expenseAccount,
+ overpaymentAccount);
+ final Integer clientId =
clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId().intValue();
+ final Integer loanId = createLoanAccount(clientId, loanProductID,
loanExternalIdStr);
+
+ // apply charges
+ Integer feeCharge = ChargesHelper.createCharges(requestSpec,
responseSpec,
+
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", false));
+
+ LocalDate targetDate = LocalDate.of(2022, 9, 5);
+ final String feeCharge1AddedDate =
dateFormatter.format(targetDate);
+ Integer feeLoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
+
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(feeCharge),
feeCharge1AddedDate, "10"));
+
+ // apply penalty
+ Integer penalty = ChargesHelper.createCharges(requestSpec,
responseSpec,
+
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", true));
+
+ final String penaltyCharge1AddedDate =
dateFormatter.format(targetDate);
+
+ Integer penalty1LoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
+
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty),
penaltyCharge1AddedDate, "10"));
+
+ // set loan as fraud
+ final String command = "markAsFraud";
+ String payload =
loanTransactionHelper.getLoanFraudPayloadAsJSON("fraud", "true");
+ PutLoansLoanIdResponse putLoansLoanIdResponse =
loanTransactionHelper.modifyLoanCommand(loanId, command, payload,
+ this.responseSpec);
+
+ GetLoansLoanIdResponse loanDetails =
this.loanTransactionHelper.getLoanDetails((long) loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+ assertTrue(loanDetails.getFraud());
+
+ // set loan as chargeoff
+ String randomText = Utils.randomStringGenerator("en", 5) +
Utils.randomNumberGenerator(6)
+ + Utils.randomStringGenerator("is", 5);
+ Integer chargeOffReasonId =
CodeHelper.createChargeOffCodeValue(requestSpec, responseSpec, randomText, 1);
+ String transactionExternalId = UUID.randomUUID().toString();
+ this.loanTransactionHelper.chargeOffLoan((long) loanId,
+ new
PostLoansLoanIdTransactionsRequest().transactionDate("6 September
2022").locale("en").dateFormat("dd MMMM yyyy")
+
.externalId(transactionExternalId).chargeOffReasonId((long) chargeOffReasonId));
+
+ loanDetails = this.loanTransactionHelper.getLoanDetails((long)
loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+ assertTrue(loanDetails.getFraud());
+ assertTrue(loanDetails.getChargedOff());
+
+ // verify Journal Entries For ChargeOff Transaction
+
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "6
September 2022",
+ new JournalEntry(1000,
JournalEntry.TransactionType.CREDIT));
+
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6
September 2022",
+ new JournalEntry(20, JournalEntry.TransactionType.CREDIT));
+
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "6
September 2022",
+ new JournalEntry(1000,
JournalEntry.TransactionType.DEBIT));
+
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6
September 2022",
+ new JournalEntry(20, JournalEntry.TransactionType.DEBIT));
+
+ // make Repayment
+ final PostLoansLoanIdTransactionsResponse repaymentTransaction =
loanTransactionHelper.makeLoanRepayment(loanExternalIdStr,
+ new PostLoansLoanIdTransactionsRequest().dateFormat("dd
MMMM yyyy").transactionDate("7 September 2022").locale("en")
+ .transactionAmount(100.0));
+
+ loanDetails = this.loanTransactionHelper.getLoanDetails((long)
loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+ assertTrue(loanDetails.getFraud());
+ assertTrue(loanDetails.getChargedOff());
+
+ // verify Journal Entries for Repayment transaction
+
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "7
September 2022",
+ new JournalEntry(100,
JournalEntry.TransactionType.CREDIT));
+
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "7
September 2022",
+ new JournalEntry(100, JournalEntry.TransactionType.DEBIT));
+
+ // Merchant Refund
+ final PostLoansLoanIdTransactionsResponse merchantIssuedRefund_1 =
loanTransactionHelper.makeMerchantIssuedRefund((long) loanId,
+ new PostLoansLoanIdTransactionsRequest().dateFormat("dd
MMMM yyyy").transactionDate("8 September 2022").locale("en")
+ .transactionAmount(100.0));
+
+ loanDetails = this.loanTransactionHelper.getLoanDetails((long)
loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+ assertTrue(loanDetails.getFraud());
+ assertTrue(loanDetails.getChargedOff());
+
+ // verify Journal Entries for Merchant Refund
+
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "8
September 2022",
+ new JournalEntry(100,
JournalEntry.TransactionType.CREDIT));
+
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "8
September 2022",
+ new JournalEntry(100, JournalEntry.TransactionType.DEBIT));
+
+ // Payout Refund
+ final PostLoansLoanIdTransactionsResponse payoutRefund_1 =
loanTransactionHelper.makePayoutRefund((long) loanId,
+ new PostLoansLoanIdTransactionsRequest().dateFormat("dd
MMMM yyyy").transactionDate("9 September 2022").locale("en")
+ .transactionAmount(100.0));
+
+ loanDetails = this.loanTransactionHelper.getLoanDetails((long)
loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+ assertTrue(loanDetails.getFraud());
+ assertTrue(loanDetails.getChargedOff());
+
+ // verify Journal Entries for Payout Refund
+
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "9
September 2022",
+ new JournalEntry(100,
JournalEntry.TransactionType.CREDIT));
+
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "9
September 2022",
+ new JournalEntry(100, JournalEntry.TransactionType.DEBIT));
+
+ // Goodwill Credit
+ final PostLoansLoanIdTransactionsResponse goodwillCredit_1 =
loanTransactionHelper.makeGoodwillCredit((long) loanId,
+ new PostLoansLoanIdTransactionsRequest().dateFormat("dd
MMMM yyyy").transactionDate("10 September 2022").locale("en")
+ .transactionAmount(100.0));
+
+ loanDetails = this.loanTransactionHelper.getLoanDetails((long)
loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+ assertTrue(loanDetails.getFraud());
+ assertTrue(loanDetails.getChargedOff());
+
+ // verify Journal Entries for Goodwill Credit
+
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "10
September 2022",
+ new JournalEntry(100, JournalEntry.TransactionType.DEBIT));
+
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "10
September 2022",
+ new JournalEntry(100,
JournalEntry.TransactionType.CREDIT));
+
+ // make overpaid repayment
+ final PostLoansLoanIdTransactionsResponse repaymentTransaction_1 =
loanTransactionHelper.makeLoanRepayment(loanExternalIdStr,
+ new PostLoansLoanIdTransactionsRequest().dateFormat("dd
MMMM yyyy").transactionDate("11 September 2022").locale("en")
+ .transactionAmount(720.0));
+
+ loanDetails = this.loanTransactionHelper.getLoanDetails((long)
loanId);
+ assertTrue(loanDetails.getStatus().getOverpaid());
+ assertTrue(loanDetails.getFraud());
+ assertTrue(loanDetails.getChargedOff());
+
+ // verify Journal entries for overpaid repayment
+
this.journalEntryHelper.checkJournalEntryForLiabilityAccount(overpaymentAccount,
"11 September 2022",
+ new JournalEntry(100,
JournalEntry.TransactionType.CREDIT));
+
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "11
September 2022",
+ new JournalEntry(620,
JournalEntry.TransactionType.CREDIT));
+
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "11
September 2022",
+ new JournalEntry(720, JournalEntry.TransactionType.DEBIT));
+
+ // CBR for making loan active again
+ final PostLoansLoanIdTransactionsResponse cbr_transaction =
loanTransactionHelper.makeCreditBalanceRefund(loanExternalIdStr,
+ new PostLoansLoanIdTransactionsRequest().dateFormat("dd
MMMM yyyy").transactionDate("12 September 2022").locale("en")
+ .transactionAmount(100.0));
+
+ // Charge Adjustment making loan overpaid
+ final PostLoansLoanIdChargesChargeIdResponse
chargeAdjustmentResult = loanTransactionHelper.chargeAdjustment((long) loanId,
+ (long) feeLoanChargeId, new
PostLoansLoanIdChargesChargeIdRequest().amount(10.0).locale("en"));
+
+ loanDetails = this.loanTransactionHelper.getLoanDetails((long)
loanId);
+ assertTrue(loanDetails.getStatus().getOverpaid());
+
+ // verify Journal entries for Charge Adjustment
+
this.journalEntryHelper.checkJournalEntryForLiabilityAccount(overpaymentAccount,
"12 September 2022",
+ new JournalEntry(10, JournalEntry.TransactionType.CREDIT));
+
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "12
September 2022",
+ new JournalEntry(10, JournalEntry.TransactionType.DEBIT));
+ });
}
// Tests for Goodwill Credit accounting changes
@Test
public void
loanAccountingTreatmentTestForGoodwillCreditPeriodicAccrualAccounting_NoChargeOff()
{
- // Loan ExternalId
- String loanExternalIdStr = UUID.randomUUID().toString();
-
- // Product to GL account mapping for test
- // ASSET
- //
-fundSourceAccountId,loanPortfolioAccountId,transfersInSuspenseAccountId,receivableFeeAccountId,receivablePenaltyAccountId,receivableInterestAccountId
- //
INCOME-interestOnLoanAccountId,incomeFromFeeAccountId,incomeFromPenaltyAccountId,incomeFromRecoveryAccountId,incomeFromChargeOffInterestAccountId,incomeFromChargeOffFeesAccountId,incomeFromChargeOffPenaltyAccountId,incomeFromGoodwillCreditInterestAccountId,incomeFromGoodwillCreditFeesAccountId,incomeFromGoodwillCreditPenaltyAccountId
- //
EXPENSE-writeOffAccountId,goodwillCreditAccountId,chargeOffExpenseAccountId,chargeOffFraudExpenseAccountId
- // LIABILITY-overpaymentLiabilityAccountId
-
- final Integer loanProductID =
createLoanProductWithPeriodicAccrualAccounting(assetAccount, incomeAccount,
expenseAccount,
- overpaymentAccount);
- final Integer clientId =
clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId().intValue();
- final Integer loanId = createLoanAccount(clientId, loanProductID,
loanExternalIdStr);
-
- // apply charges
- Integer feeCharge = ChargesHelper.createCharges(requestSpec,
responseSpec,
-
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", false));
-
- LocalDate targetDate = LocalDate.of(2022, 9, 5);
- final String feeCharge1AddedDate = dateFormatter.format(targetDate);
- Integer feeLoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
-
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(feeCharge),
feeCharge1AddedDate, "10"));
-
- // apply penalty
- Integer penalty = ChargesHelper.createCharges(requestSpec,
responseSpec,
-
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"110", true));
-
- final String penaltyCharge1AddedDate =
dateFormatter.format(targetDate);
-
- Integer penalty1LoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
-
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty),
penaltyCharge1AddedDate, "10"));
-
- GetLoansLoanIdResponse loanDetails =
this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getActive());
-
- // Goodwill Credit
- final PostLoansLoanIdTransactionsResponse goodwillCredit_1 =
loanTransactionHelper.makeGoodwillCredit((long) loanId,
- new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM
yyyy").transactionDate("06 September 2022").locale("en")
- .transactionAmount(800.0));
-
- loanDetails = this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getActive());
-
- // verify Journal Entries for Goodwill Credit
- this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount,
"6 September 2022",
- new JournalEntry(800, JournalEntry.TransactionType.CREDIT));
-
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "6
September 2022",
- new JournalEntry(780, JournalEntry.TransactionType.DEBIT));
-
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6
September 2022",
- new JournalEntry(20, JournalEntry.TransactionType.DEBIT));
+ runAt("12 September 2022", () -> {
+
+ // Loan ExternalId
+ String loanExternalIdStr = UUID.randomUUID().toString();
+
+ // Product to GL account mapping for test
+ // ASSET
+ //
-fundSourceAccountId,loanPortfolioAccountId,transfersInSuspenseAccountId,receivableFeeAccountId,receivablePenaltyAccountId,receivableInterestAccountId
+ //
INCOME-interestOnLoanAccountId,incomeFromFeeAccountId,incomeFromPenaltyAccountId,incomeFromRecoveryAccountId,incomeFromChargeOffInterestAccountId,incomeFromChargeOffFeesAccountId,incomeFromChargeOffPenaltyAccountId,incomeFromGoodwillCreditInterestAccountId,incomeFromGoodwillCreditFeesAccountId,incomeFromGoodwillCreditPenaltyAccountId
+ //
EXPENSE-writeOffAccountId,goodwillCreditAccountId,chargeOffExpenseAccountId,chargeOffFraudExpenseAccountId
+ // LIABILITY-overpaymentLiabilityAccountId
+
+ final Integer loanProductID =
createLoanProductWithPeriodicAccrualAccounting(assetAccount, incomeAccount,
expenseAccount,
+ overpaymentAccount);
+ final Integer clientId =
clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId().intValue();
+ final Integer loanId = createLoanAccount(clientId, loanProductID,
loanExternalIdStr);
+
+ // apply charges
+ Integer feeCharge = ChargesHelper.createCharges(requestSpec,
responseSpec,
+
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", false));
+
+ LocalDate targetDate = LocalDate.of(2022, 9, 5);
+ final String feeCharge1AddedDate =
dateFormatter.format(targetDate);
+ Integer feeLoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
+
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(feeCharge),
feeCharge1AddedDate, "10"));
+
+ // apply penalty
+ Integer penalty = ChargesHelper.createCharges(requestSpec,
responseSpec,
+
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"110", true));
+
+ final String penaltyCharge1AddedDate =
dateFormatter.format(targetDate);
+
+ Integer penalty1LoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
+
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty),
penaltyCharge1AddedDate, "10"));
+
+ GetLoansLoanIdResponse loanDetails =
this.loanTransactionHelper.getLoanDetails((long) loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+
+ // Goodwill Credit
+ final PostLoansLoanIdTransactionsResponse goodwillCredit_1 =
loanTransactionHelper.makeGoodwillCredit((long) loanId,
+ new PostLoansLoanIdTransactionsRequest().dateFormat("dd
MMMM yyyy").transactionDate("06 September 2022").locale("en")
+ .transactionAmount(800.0));
+
+ loanDetails = this.loanTransactionHelper.getLoanDetails((long)
loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+
+ // verify Journal Entries for Goodwill Credit
+
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "6
September 2022",
+ new JournalEntry(800,
JournalEntry.TransactionType.CREDIT));
+
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "6
September 2022",
+ new JournalEntry(780, JournalEntry.TransactionType.DEBIT));
+
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6
September 2022",
+ new JournalEntry(20, JournalEntry.TransactionType.DEBIT));
+ });
}
@Test
public void
loanAccountingTreatmentTestForGoodwillCreditPeriodicAccrualAccounting_ChargeOff()
{
- // Loan ExternalId
- String loanExternalIdStr = UUID.randomUUID().toString();
-
- // Product to GL account mapping for test
- // ASSET
- //
-fundSourceAccountId,loanPortfolioAccountId,transfersInSuspenseAccountId,receivableFeeAccountId,receivablePenaltyAccountId,receivableInterestAccountId
- //
INCOME-interestOnLoanAccountId,incomeFromFeeAccountId,incomeFromPenaltyAccountId,incomeFromRecoveryAccountId,incomeFromChargeOffInterestAccountId,incomeFromChargeOffFeesAccountId,incomeFromChargeOffPenaltyAccountId,incomeFromGoodwillCreditInterestAccountId,incomeFromGoodwillCreditFeesAccountId,incomeFromGoodwillCreditPenaltyAccountId
- //
EXPENSE-writeOffAccountId,goodwillCreditAccountId,chargeOffExpenseAccountId,chargeOffFraudExpenseAccountId
- // LIABILITY-overpaymentLiabilityAccountId
-
- final Integer loanProductID =
createLoanProductWithPeriodicAccrualAccounting(assetAccount, incomeAccount,
expenseAccount,
- overpaymentAccount);
- final Integer clientId =
clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId().intValue();
- final Integer loanId = createLoanAccount(clientId, loanProductID,
loanExternalIdStr);
-
- // apply charges
- Integer feeCharge = ChargesHelper.createCharges(requestSpec,
responseSpec,
-
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", false));
-
- LocalDate targetDate = LocalDate.of(2022, 9, 5);
- final String feeCharge1AddedDate = dateFormatter.format(targetDate);
- Integer feeLoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
-
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(feeCharge),
feeCharge1AddedDate, "10"));
-
- // apply penalty
- Integer penalty = ChargesHelper.createCharges(requestSpec,
responseSpec,
-
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", true));
-
- final String penaltyCharge1AddedDate =
dateFormatter.format(targetDate);
-
- Integer penalty1LoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
-
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty),
penaltyCharge1AddedDate, "10"));
-
- // set loan as chargeoff
- String randomText = Utils.randomStringGenerator("en", 5) +
Utils.randomNumberGenerator(6) + Utils.randomStringGenerator("is", 5);
- Integer chargeOffReasonId =
CodeHelper.createChargeOffCodeValue(requestSpec, responseSpec, randomText, 1);
- String transactionExternalId = UUID.randomUUID().toString();
- this.loanTransactionHelper.chargeOffLoan((long) loanId, new
PostLoansLoanIdTransactionsRequest().transactionDate("6 September 2022")
- .locale("en").dateFormat("dd MMMM
yyyy").externalId(transactionExternalId).chargeOffReasonId((long)
chargeOffReasonId));
-
- GetLoansLoanIdResponse loanDetails =
this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getActive());
- assertTrue(loanDetails.getChargedOff());
-
- // verify Journal Entries For ChargeOff Transaction
- this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount,
"6 September 2022",
- new JournalEntry(1020, JournalEntry.TransactionType.CREDIT));
-
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "6
September 2022",
- new JournalEntry(1000, JournalEntry.TransactionType.DEBIT));
-
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6
September 2022",
- new JournalEntry(20, JournalEntry.TransactionType.DEBIT));
-
- // Goodwill Credit
- final PostLoansLoanIdTransactionsResponse goodwillCredit_1 =
loanTransactionHelper.makeGoodwillCredit((long) loanId,
- new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM
yyyy").transactionDate("08 September 2022").locale("en")
- .transactionAmount(800.0));
-
- loanDetails = this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getActive());
- assertTrue(loanDetails.getChargedOff());
-
- // verify Journal Entries for Goodwill Credit
-
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "8
September 2022",
- new JournalEntry(800, JournalEntry.TransactionType.CREDIT));
-
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "8
September 2022",
- new JournalEntry(20, JournalEntry.TransactionType.DEBIT));
-
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "8
September 2022",
- new JournalEntry(780, JournalEntry.TransactionType.DEBIT));
+ runAt("12 September 2022", () -> {
+
+ // Loan ExternalId
+ String loanExternalIdStr = UUID.randomUUID().toString();
+
+ // Product to GL account mapping for test
+ // ASSET
+ //
-fundSourceAccountId,loanPortfolioAccountId,transfersInSuspenseAccountId,receivableFeeAccountId,receivablePenaltyAccountId,receivableInterestAccountId
+ //
INCOME-interestOnLoanAccountId,incomeFromFeeAccountId,incomeFromPenaltyAccountId,incomeFromRecoveryAccountId,incomeFromChargeOffInterestAccountId,incomeFromChargeOffFeesAccountId,incomeFromChargeOffPenaltyAccountId,incomeFromGoodwillCreditInterestAccountId,incomeFromGoodwillCreditFeesAccountId,incomeFromGoodwillCreditPenaltyAccountId
+ //
EXPENSE-writeOffAccountId,goodwillCreditAccountId,chargeOffExpenseAccountId,chargeOffFraudExpenseAccountId
+ // LIABILITY-overpaymentLiabilityAccountId
+ final Integer loanProductID =
createLoanProductWithPeriodicAccrualAccounting(assetAccount, incomeAccount,
expenseAccount,
+ overpaymentAccount);
+ final Integer clientId =
clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId().intValue();
+ final Integer loanId = createLoanAccount(clientId, loanProductID,
loanExternalIdStr);
+
+ // apply charges
+ Integer feeCharge = ChargesHelper.createCharges(requestSpec,
responseSpec,
+
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", false));
+
+ LocalDate targetDate = LocalDate.of(2022, 9, 5);
+ final String feeCharge1AddedDate =
dateFormatter.format(targetDate);
+ Integer feeLoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
+
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(feeCharge),
feeCharge1AddedDate, "10"));
+
+ // apply penalty
+ Integer penalty = ChargesHelper.createCharges(requestSpec,
responseSpec,
+
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", true));
+
+ final String penaltyCharge1AddedDate =
dateFormatter.format(targetDate);
+
+ Integer penalty1LoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
+
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty),
penaltyCharge1AddedDate, "10"));
+
+ // set loan as chargeoff
+ String randomText = Utils.randomStringGenerator("en", 5) +
Utils.randomNumberGenerator(6)
+ + Utils.randomStringGenerator("is", 5);
+ Integer chargeOffReasonId =
CodeHelper.createChargeOffCodeValue(requestSpec, responseSpec, randomText, 1);
+ String transactionExternalId = UUID.randomUUID().toString();
+ this.loanTransactionHelper.chargeOffLoan((long) loanId,
+ new
PostLoansLoanIdTransactionsRequest().transactionDate("6 September
2022").locale("en").dateFormat("dd MMMM yyyy")
+
.externalId(transactionExternalId).chargeOffReasonId((long) chargeOffReasonId));
+
+ GetLoansLoanIdResponse loanDetails =
this.loanTransactionHelper.getLoanDetails((long) loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+ assertTrue(loanDetails.getChargedOff());
+
+ // verify Journal Entries For ChargeOff Transaction
+
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "6
September 2022",
+ new JournalEntry(1020,
JournalEntry.TransactionType.CREDIT));
+
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "6
September 2022",
+ new JournalEntry(1000,
JournalEntry.TransactionType.DEBIT));
+
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6
September 2022",
+ new JournalEntry(20, JournalEntry.TransactionType.DEBIT));
+
+ // Goodwill Credit
+ final PostLoansLoanIdTransactionsResponse goodwillCredit_1 =
loanTransactionHelper.makeGoodwillCredit((long) loanId,
+ new PostLoansLoanIdTransactionsRequest().dateFormat("dd
MMMM yyyy").transactionDate("08 September 2022").locale("en")
+ .transactionAmount(800.0));
+
+ loanDetails = this.loanTransactionHelper.getLoanDetails((long)
loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+ assertTrue(loanDetails.getChargedOff());
+
+ // verify Journal Entries for Goodwill Credit
+
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "8
September 2022",
+ new JournalEntry(800,
JournalEntry.TransactionType.CREDIT));
+
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "8
September 2022",
+ new JournalEntry(20, JournalEntry.TransactionType.DEBIT));
+
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "8
September 2022",
+ new JournalEntry(780, JournalEntry.TransactionType.DEBIT));
+ });
}
@Test
public void
loanAccountingTreatmentTestForCashBasedAccounting_NoChargeOff() {
- // Loan ExternalId
- String loanExternalIdStr = UUID.randomUUID().toString();
-
- // Product to GL account mapping for test
- // ASSET
- //
-fundSourceAccountId,loanPortfolioAccountId,transfersInSuspenseAccountId
- //
INCOME-interestOnLoanAccountId,incomeFromFeeAccountId,incomeFromPenaltyAccountId,incomeFromRecoveryAccountId,incomeFromChargeOffInterestAccountId,incomeFromChargeOffFeesAccountId,incomeFromChargeOffPenaltyAccountId,incomeFromGoodwillCreditInterestAccountId,incomeFromGoodwillCreditFeesAccountId,incomeFromGoodwillCreditPenaltyAccountId
- //
EXPENSE-writeOffAccountId,goodwillCreditAccountId,chargeOffExpenseAccountId,chargeOffFraudExpenseAccountId
- // LIABILITY-overpaymentLiabilityAccountId
-
- final Integer loanProductID =
createLoanProductWithCashBasedAccounting(assetAccount, incomeAccount,
expenseAccount,
- overpaymentAccount);
- final Integer clientId =
clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId().intValue();
- final Integer loanId = createLoanAccount(clientId, loanProductID,
loanExternalIdStr);
-
- // apply charges
- Integer feeCharge = ChargesHelper.createCharges(requestSpec,
responseSpec,
-
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", false));
-
- LocalDate targetDate = LocalDate.of(2022, 9, 5);
- final String feeCharge1AddedDate = dateFormatter.format(targetDate);
- Integer feeLoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
-
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(feeCharge),
feeCharge1AddedDate, "10"));
-
- // apply penalty
- Integer penalty = ChargesHelper.createCharges(requestSpec,
responseSpec,
-
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", true));
-
- final String penaltyCharge1AddedDate =
dateFormatter.format(targetDate);
-
- Integer penalty1LoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
-
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty),
penaltyCharge1AddedDate, "10"));
-
- GetLoansLoanIdResponse loanDetails =
this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getActive());
-
- // Goodwill Credit
- final PostLoansLoanIdTransactionsResponse goodwillCredit_1 =
loanTransactionHelper.makeGoodwillCredit((long) loanId,
- new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM
yyyy").transactionDate("06 September 2022").locale("en")
- .transactionAmount(800.0));
-
- loanDetails = this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getActive());
-
- // verify Journal Entries for Goodwill Credit
- this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount,
"6 September 2022",
- new JournalEntry(780, JournalEntry.TransactionType.CREDIT));
-
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6
September 2022",
- new JournalEntry(10, JournalEntry.TransactionType.CREDIT));
-
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6
September 2022",
- new JournalEntry(10, JournalEntry.TransactionType.CREDIT));
-
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "6
September 2022",
- new JournalEntry(780, JournalEntry.TransactionType.DEBIT));
-
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6
September 2022",
- new JournalEntry(20, JournalEntry.TransactionType.DEBIT));
+ runAt("12 September 2022", () -> {
+
+ // Loan ExternalId
+ String loanExternalIdStr = UUID.randomUUID().toString();
+
+ // Product to GL account mapping for test
+ // ASSET
+ //
-fundSourceAccountId,loanPortfolioAccountId,transfersInSuspenseAccountId
+ //
INCOME-interestOnLoanAccountId,incomeFromFeeAccountId,incomeFromPenaltyAccountId,incomeFromRecoveryAccountId,incomeFromChargeOffInterestAccountId,incomeFromChargeOffFeesAccountId,incomeFromChargeOffPenaltyAccountId,incomeFromGoodwillCreditInterestAccountId,incomeFromGoodwillCreditFeesAccountId,incomeFromGoodwillCreditPenaltyAccountId
+ //
EXPENSE-writeOffAccountId,goodwillCreditAccountId,chargeOffExpenseAccountId,chargeOffFraudExpenseAccountId
+ // LIABILITY-overpaymentLiabilityAccountId
+
+ final Integer loanProductID =
createLoanProductWithCashBasedAccounting(assetAccount, incomeAccount,
expenseAccount,
+ overpaymentAccount);
+ final Integer clientId =
clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId().intValue();
+ final Integer loanId = createLoanAccount(clientId, loanProductID,
loanExternalIdStr);
+
+ // apply charges
+ Integer feeCharge = ChargesHelper.createCharges(requestSpec,
responseSpec,
+
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", false));
+
+ LocalDate targetDate = LocalDate.of(2022, 9, 5);
+ final String feeCharge1AddedDate =
dateFormatter.format(targetDate);
+ Integer feeLoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
+
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(feeCharge),
feeCharge1AddedDate, "10"));
+
+ // apply penalty
+ Integer penalty = ChargesHelper.createCharges(requestSpec,
responseSpec,
+
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", true));
+
+ final String penaltyCharge1AddedDate =
dateFormatter.format(targetDate);
+
+ Integer penalty1LoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
+
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty),
penaltyCharge1AddedDate, "10"));
+
+ GetLoansLoanIdResponse loanDetails =
this.loanTransactionHelper.getLoanDetails((long) loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+ // Goodwill Credit
+ final PostLoansLoanIdTransactionsResponse goodwillCredit_1 =
loanTransactionHelper.makeGoodwillCredit((long) loanId,
+ new PostLoansLoanIdTransactionsRequest().dateFormat("dd
MMMM yyyy").transactionDate("06 September 2022").locale("en")
+ .transactionAmount(800.0));
+
+ loanDetails = this.loanTransactionHelper.getLoanDetails((long)
loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+
+ // verify Journal Entries for Goodwill Credit
+
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "6
September 2022",
+ new JournalEntry(780,
JournalEntry.TransactionType.CREDIT));
+
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6
September 2022",
+ new JournalEntry(10, JournalEntry.TransactionType.CREDIT));
+
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6
September 2022",
+ new JournalEntry(10, JournalEntry.TransactionType.CREDIT));
+
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "6
September 2022",
+ new JournalEntry(780, JournalEntry.TransactionType.DEBIT));
+
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6
September 2022",
+ new JournalEntry(20, JournalEntry.TransactionType.DEBIT));
+ });
}
@Test
public void loanAccountingTreatmentTestForCashBasedAccounting_ChargeOff() {
- // Loan ExternalId
- String loanExternalIdStr = UUID.randomUUID().toString();
-
- // Product to GL account mapping for test
- // ASSET
- //
-fundSourceAccountId,loanPortfolioAccountId,transfersInSuspenseAccountId
- //
INCOME-interestOnLoanAccountId,incomeFromFeeAccountId,incomeFromPenaltyAccountId,incomeFromRecoveryAccountId,incomeFromChargeOffInterestAccountId,incomeFromChargeOffFeesAccountId,incomeFromChargeOffPenaltyAccountId,incomeFromGoodwillCreditInterestAccountId,incomeFromGoodwillCreditFeesAccountId,incomeFromGoodwillCreditPenaltyAccountId
- //
EXPENSE-writeOffAccountId,goodwillCreditAccountId,chargeOffExpenseAccountId,chargeOffFraudExpenseAccountId
- // LIABILITY-overpaymentLiabilityAccountId
-
- final Integer loanProductID =
createLoanProductWithCashBasedAccounting(assetAccount, incomeAccount,
expenseAccount,
- overpaymentAccount);
- final Integer clientId =
clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId().intValue();
- final Integer loanId = createLoanAccount(clientId, loanProductID,
loanExternalIdStr);
-
- // apply charges
- Integer feeCharge = ChargesHelper.createCharges(requestSpec,
responseSpec,
-
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", false));
-
- LocalDate targetDate = LocalDate.of(2022, 9, 5);
- final String feeCharge1AddedDate = dateFormatter.format(targetDate);
- Integer feeLoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
-
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(feeCharge),
feeCharge1AddedDate, "10"));
-
- // apply penalty
- Integer penalty = ChargesHelper.createCharges(requestSpec,
responseSpec,
-
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", true));
-
- final String penaltyCharge1AddedDate =
dateFormatter.format(targetDate);
-
- Integer penalty1LoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
-
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty),
penaltyCharge1AddedDate, "10"));
-
- GetLoansLoanIdResponse loanDetails =
this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getActive());
-
- // set loan as chargeoff
- String randomText = Utils.randomStringGenerator("en", 5) +
Utils.randomNumberGenerator(6) + Utils.randomStringGenerator("is", 5);
- Integer chargeOffReasonId =
CodeHelper.createChargeOffCodeValue(requestSpec, responseSpec, randomText, 1);
- String transactionExternalId = UUID.randomUUID().toString();
- this.loanTransactionHelper.chargeOffLoan((long) loanId, new
PostLoansLoanIdTransactionsRequest().transactionDate("6 September 2022")
- .locale("en").dateFormat("dd MMMM
yyyy").externalId(transactionExternalId).chargeOffReasonId((long)
chargeOffReasonId));
-
- loanDetails = this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getActive());
- assertTrue(loanDetails.getChargedOff());
-
- // verify Journal Entries For ChargeOff Transaction
- this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount,
"6 September 2022",
- new JournalEntry(1000, JournalEntry.TransactionType.CREDIT));
-
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6
September 2022",
- new JournalEntry(20, JournalEntry.TransactionType.CREDIT));
-
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "6
September 2022",
- new JournalEntry(1000, JournalEntry.TransactionType.DEBIT));
-
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6
September 2022",
- new JournalEntry(20, JournalEntry.TransactionType.DEBIT));
-
- // Goodwill Credit
- final PostLoansLoanIdTransactionsResponse goodwillCredit_1 =
loanTransactionHelper.makeGoodwillCredit((long) loanId,
- new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM
yyyy").transactionDate("10 September 2022").locale("en")
- .transactionAmount(800.0));
-
- loanDetails = this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getActive());
- assertTrue(loanDetails.getChargedOff());
-
- // verify Journal Entries for Goodwill Credit
- this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount,
"6 September 2022",
- new JournalEntry(1000, JournalEntry.TransactionType.CREDIT));
-
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6
September 2022",
- new JournalEntry(20, JournalEntry.TransactionType.CREDIT));
-
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "6
September 2022",
- new JournalEntry(1000, JournalEntry.TransactionType.DEBIT));
-
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6
September 2022",
- new JournalEntry(20, JournalEntry.TransactionType.DEBIT));
+ runAt("12 September 2022", () -> {
+
+ // Loan ExternalId
+ String loanExternalIdStr = UUID.randomUUID().toString();
+
+ // Product to GL account mapping for test
+ // ASSET
+ //
-fundSourceAccountId,loanPortfolioAccountId,transfersInSuspenseAccountId
+ //
INCOME-interestOnLoanAccountId,incomeFromFeeAccountId,incomeFromPenaltyAccountId,incomeFromRecoveryAccountId,incomeFromChargeOffInterestAccountId,incomeFromChargeOffFeesAccountId,incomeFromChargeOffPenaltyAccountId,incomeFromGoodwillCreditInterestAccountId,incomeFromGoodwillCreditFeesAccountId,incomeFromGoodwillCreditPenaltyAccountId
+ //
EXPENSE-writeOffAccountId,goodwillCreditAccountId,chargeOffExpenseAccountId,chargeOffFraudExpenseAccountId
+ // LIABILITY-overpaymentLiabilityAccountId
+
+ final Integer loanProductID =
createLoanProductWithCashBasedAccounting(assetAccount, incomeAccount,
expenseAccount,
+ overpaymentAccount);
+ final Integer clientId =
clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId().intValue();
+ final Integer loanId = createLoanAccount(clientId, loanProductID,
loanExternalIdStr);
+
+ // apply charges
+ Integer feeCharge = ChargesHelper.createCharges(requestSpec,
responseSpec,
+
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", false));
+
+ LocalDate targetDate = LocalDate.of(2022, 9, 5);
+ final String feeCharge1AddedDate =
dateFormatter.format(targetDate);
+ Integer feeLoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
+
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(feeCharge),
feeCharge1AddedDate, "10"));
+
+ // apply penalty
+ Integer penalty = ChargesHelper.createCharges(requestSpec,
responseSpec,
+
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", true));
+
+ final String penaltyCharge1AddedDate =
dateFormatter.format(targetDate);
+
+ Integer penalty1LoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
+
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty),
penaltyCharge1AddedDate, "10"));
+
+ GetLoansLoanIdResponse loanDetails =
this.loanTransactionHelper.getLoanDetails((long) loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+
+ // set loan as chargeoff
+ String randomText = Utils.randomStringGenerator("en", 5) +
Utils.randomNumberGenerator(6)
+ + Utils.randomStringGenerator("is", 5);
+ Integer chargeOffReasonId =
CodeHelper.createChargeOffCodeValue(requestSpec, responseSpec, randomText, 1);
+ String transactionExternalId = UUID.randomUUID().toString();
+ this.loanTransactionHelper.chargeOffLoan((long) loanId,
+ new
PostLoansLoanIdTransactionsRequest().transactionDate("6 September
2022").locale("en").dateFormat("dd MMMM yyyy")
+
.externalId(transactionExternalId).chargeOffReasonId((long) chargeOffReasonId));
+
+ loanDetails = this.loanTransactionHelper.getLoanDetails((long)
loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+ assertTrue(loanDetails.getChargedOff());
+
+ // verify Journal Entries For ChargeOff Transaction
+
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "6
September 2022",
+ new JournalEntry(1000,
JournalEntry.TransactionType.CREDIT));
+
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6
September 2022",
+ new JournalEntry(20, JournalEntry.TransactionType.CREDIT));
+
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "6
September 2022",
+ new JournalEntry(1000,
JournalEntry.TransactionType.DEBIT));
+
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6
September 2022",
+ new JournalEntry(20, JournalEntry.TransactionType.DEBIT));
+
+ // Goodwill Credit
+ final PostLoansLoanIdTransactionsResponse goodwillCredit_1 =
loanTransactionHelper.makeGoodwillCredit((long) loanId,
+ new PostLoansLoanIdTransactionsRequest().dateFormat("dd
MMMM yyyy").transactionDate("10 September 2022").locale("en")
+ .transactionAmount(800.0));
+
+ loanDetails = this.loanTransactionHelper.getLoanDetails((long)
loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+ assertTrue(loanDetails.getChargedOff());
+
+ // verify Journal Entries for Goodwill Credit
+
this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "6
September 2022",
+ new JournalEntry(1000,
JournalEntry.TransactionType.CREDIT));
+
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6
September 2022",
+ new JournalEntry(20, JournalEntry.TransactionType.CREDIT));
+
this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "6
September 2022",
+ new JournalEntry(1000,
JournalEntry.TransactionType.DEBIT));
+
this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6
September 2022",
+ new JournalEntry(20, JournalEntry.TransactionType.DEBIT));
+ });
}
@Test
@@ -810,6 +830,10 @@ public class LoanChargeOffAccountingTest extends
BaseLoanIntegrationTest {
Long clientId =
clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
PostLoanProductsResponse productsResponse =
createLoanProductWithAdvancedChargeOffAccounting(chargeOffReason,
chargeOffDelinquentExpenseAccount);
+ // We are creating a 2nd product to test, the mapping is correct!
+ PostLoanProductsResponse secondProduct =
createLoanProductWithAdvancedChargeOffAccounting(chargeOffReason,
+ chargeOffDelinquentExpenseAccount);
+ Assertions.assertNotNull(secondProduct.getResourceId());
// Apply and Approve Loan
Long loanId = applyAndApproveLoan(clientId,
productsResponse.getResourceId(), "01 January 2023", 1000.0, 1);
// Disburse Loan
@@ -824,6 +848,38 @@ public class LoanChargeOffAccountingTest extends
BaseLoanIntegrationTest {
});
}
+ @Test
+ public void advancedAccountingForChargeOffFallbackToRegular() {
+ runAt("02 January 2023", () -> {
+ final Account chargeOffDelinquentExpenseAccount = accountHelper
+
.createExpenseAccount("delinquent_expense_for_charge_off_reason");
+ GetCodesResponse chargeOffReasonCode = fetchChargeOffReasonCode();
+ PostCodeValueDataResponse chargeOffReason =
codeHelper.createCodeValue(chargeOffReasonCode.getId(),
+ new
PostCodeValuesDataRequest().name(Utils.uniqueRandomStringGenerator("DELINQUENT_",
6)).isActive(true).position(10));
+ GetCodesResponse secondChargeOffReason =
fetchChargeOffReasonCode();
+ PostCodeValueDataResponse secondChargeOffReasonResponse =
codeHelper.createCodeValue(secondChargeOffReason.getId(),
+ new
PostCodeValuesDataRequest().name(Utils.uniqueRandomStringGenerator("FRAUD_",
6)).isActive(true).position(10));
+ Long clientId =
clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+ PostLoanProductsResponse productsResponse =
createLoanProductWithAdvancedChargeOffAccounting(chargeOffReason,
+ chargeOffDelinquentExpenseAccount);
+ // We are creating a 2nd product to test, the mapping is correct!
+ PostLoanProductsResponse secondProduct =
createLoanProductWithAdvancedChargeOffAccounting(chargeOffReason,
+ chargeOffDelinquentExpenseAccount);
+ Assertions.assertNotNull(secondProduct.getResourceId());
+ // Apply and Approve Loan
+ Long loanId = applyAndApproveLoan(clientId,
productsResponse.getResourceId(), "01 January 2023", 1000.0, 1);
+ // Disburse Loan
+ disburseLoan(loanId, BigDecimal.valueOf(1000.00), "01 January
2023");
+
+ PostLoansLoanIdTransactionsResponse chargeOffTransaction =
this.loanTransactionHelper.chargeOffLoan(loanId,
+ new
PostLoansLoanIdTransactionsRequest().transactionDate("02 January
2023").locale("en").dateFormat("dd MMMM yyyy")
+
.chargeOffReasonId(secondChargeOffReasonResponse.getSubResourceId()));
+ // verify journal entries
+ verifyTRJournalEntries(chargeOffTransaction.getResourceId(),
journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
+ journalEntry(1000.0, chargeOffExpenseAccount, "DEBIT"));
+ });
+ }
+
private PostLoanProductsResponse
createLoanProductWithAdvancedChargeOffAccounting(PostCodeValueDataResponse
chargeOffReason,
Account chargeOffDelinquentExpenseAccount) {
return this.loanTransactionHelper.createLoanProduct(new
PostLoanProductsRequest()