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()


Reply via email to