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

commit 641f75519358d505549bf28eedd713add12e41fb
Author: Peter Kovacs <[email protected]>
AuthorDate: Fri Sep 26 11:37:54 2025 +0200

    FINERACT-2374: Advance Accounting rule for classification type - E2E tests
---
 .../service/ProductToGLAccountMappingHelper.java   | 10 +--
 .../test/data/loanproduct/DefaultLoanProduct.java  |  2 +
 .../global/LoanProductGlobalInitializerStep.java   | 90 ++++++++++++++++++++++
 .../fineract/test/stepdef/loan/LoanStepDef.java    | 52 +++++++++++++
 .../fineract/test/support/TestContextKey.java      |  2 +
 .../resources/features/LoanBuyDownFees.feature     | 77 +++++++++++++++++-
 .../features/LoanCapitalizedIncome.feature         | 75 ++++++++++++++++++
 7 files changed, 302 insertions(+), 6 deletions(-)

diff --git 
a/fineract-accounting/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingHelper.java
 
b/fineract-accounting/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingHelper.java
index b37580c872..dfbd94c529 100644
--- 
a/fineract-accounting/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingHelper.java
+++ 
b/fineract-accounting/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingHelper.java
@@ -297,7 +297,7 @@ public class ProductToGLAccountMappingHelper {
 
             // If input map is empty, delete all existing mappings
             if (inputChargeToIncomeAccountMap.size() == 0) {
-                
this.accountMappingRepository.deleteAllInBatch(existingChargeToIncomeAccountMappings);
+                
this.accountMappingRepository.deleteAll(existingChargeToIncomeAccountMappings);
             } /**
                * Else, <br/>
                * update existing mappings OR <br/>
@@ -377,7 +377,7 @@ public class ProductToGLAccountMappingHelper {
 
             // If input map is empty, delete all existing mappings
             if (inputPaymentChannelFundSourceMap.isEmpty()) {
-                
this.accountMappingRepository.deleteAllInBatch(existingPaymentChannelToFundSourceMappings);
+                
this.accountMappingRepository.deleteAll(existingPaymentChannelToFundSourceMappings);
             } /**
                * Else, <br/>
                * update existing mappings OR <br/>
@@ -440,7 +440,7 @@ public class ProductToGLAccountMappingHelper {
 
             // If input map is empty, delete all existing mappings
             if (inputChargeOffReasonToGLAccountMap.isEmpty()) {
-                
this.accountMappingRepository.deleteAllInBatch(existingChargeOffReasonToGLAccountMappings);
+                
this.accountMappingRepository.deleteAll(existingChargeOffReasonToGLAccountMappings);
             } else {
                 for (final ProductToGLAccountMapping 
existingChargeOffReasonToGLAccountMapping : 
existingChargeOffReasonToGLAccountMappings) {
                     final Long currentChargeOffReasonId = 
existingChargeOffReasonToGLAccountMapping.getChargeOffReason().getId();
@@ -504,7 +504,7 @@ public class ProductToGLAccountMappingHelper {
 
             // If input map is empty, delete all existing mappings
             if (inputClassificationToGLAccountMap.isEmpty()) {
-                
this.accountMappingRepository.deleteAllInBatch(existingClassificationToGLAccountMappings);
+                
this.accountMappingRepository.deleteAll(existingClassificationToGLAccountMappings);
             } else {
                 for (final ProductToGLAccountMapping 
existingClassificationToGLAccountMapping : 
existingClassificationToGLAccountMappings) {
                     final Long currentClassificationId = 
classificationParameter
@@ -699,7 +699,7 @@ public class ProductToGLAccountMappingHelper {
         final List<ProductToGLAccountMapping> productToGLAccountMappings = 
this.accountMappingRepository
                 .findByProductIdAndProductType(loanProductId, 
portfolioProductType.getValue());
         if (productToGLAccountMappings != null && 
!productToGLAccountMappings.isEmpty()) {
-            
this.accountMappingRepository.deleteAllInBatch(productToGLAccountMappings);
+            
this.accountMappingRepository.deleteAll(productToGLAccountMappings);
         }
     }
 
diff --git 
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/data/loanproduct/DefaultLoanProduct.java
 
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/data/loanproduct/DefaultLoanProduct.java
index e5cb647e6d..a6ce2ab508 100644
--- 
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/data/loanproduct/DefaultLoanProduct.java
+++ 
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/data/loanproduct/DefaultLoanProduct.java
@@ -136,8 +136,10 @@ public enum DefaultLoanProduct implements LoanProduct {
     LP2_PROGRESSIVE_ADVANCED_PAYMENT_ALLOCATION_BUYDOWN_FEES_NON_MERCHANT, //
     
LP2_PROGRESSIVE_ADVANCED_PAYMENT_ALLOCATION_BUYDOWN_FEES_CHARGE_OFF_REASON, //
     
LP2_PROGRESSIVE_ADVANCED_PAYMENT_ALLOCATION_BUYDOWN_FEES_NON_MERCHANT_CHARGE_OFF_REASON,
 //
+    
LP2_PROGRESSIVE_ADVANCED_PAYMENT_ALLOCATION_BUYDOWN_FEES_CLASSIFICATION_INCOME_MAP,
 //
     
LP2_PROGRESSIVE_ADV_PYMNT_INTEREST_RECALC_360_30_MULTIDISB_OVER_APPLIED_EXPECTED_TRANCHES,
 //
     
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALC_DAILY_CAPITALIZED_INCOME_ADJ_CUSTOM_ALLOC,
 //
+    
LP2_PROGRESSIVE_ADV_PMNT_ALLOCATION_CAPITALIZED_INCOME_ADJ_CUSTOM_ALLOC_CLASSIFICATION_INCOME_MAP,
 //
     
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALC_DAILY_CAPITALIZED_INCOME,
 //
     
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALC_DAILY_CAPITALIZED_INCOME_FEE,
 //
     
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALC_DAILY_MULTIDISBURSAL_CAPITALIZED_INCOME,
 //
diff --git 
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/initializer/global/LoanProductGlobalInitializerStep.java
 
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/initializer/global/LoanProductGlobalInitializerStep.java
index e4c901c2fa..319affea7c 100644
--- 
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/initializer/global/LoanProductGlobalInitializerStep.java
+++ 
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/initializer/global/LoanProductGlobalInitializerStep.java
@@ -40,6 +40,7 @@ import 
org.apache.fineract.client.models.CreditAllocationOrder;
 import org.apache.fineract.client.models.LoanProductChargeData;
 import org.apache.fineract.client.models.LoanProductPaymentAllocationRule;
 import org.apache.fineract.client.models.PaymentAllocationOrder;
+import 
org.apache.fineract.client.models.PostClassificationToIncomeAccountMappings;
 import org.apache.fineract.client.models.PostLoanProductsRequest;
 import org.apache.fineract.client.models.PostLoanProductsResponse;
 import org.apache.fineract.client.services.LoanProductsApi;
@@ -3728,6 +3729,95 @@ public class LoanProductGlobalInitializerStep implements 
FineractGlobalInitializ
         TestContext.INSTANCE.set(
                 
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADVANCED_CUSTOM_PAYMENT_ALLOCATION_PROGRESSIVE_LOAN_SCHEDULE_ZERO_CHARGE_OFF,
                 
responseLoanProductsRequestAdvCustomPaymentAllocationProgressiveLoanScheduleZeroChargeOff);
+
+        // LP2 with progressive loan schedule + horizontal + interest EMI + 
360/30
+        // + interest recalculation, buy down fees enabled
+        // + Classification income map
+        final String name140 = 
DefaultLoanProduct.LP2_PROGRESSIVE_ADVANCED_PAYMENT_ALLOCATION_BUYDOWN_FEES_CLASSIFICATION_INCOME_MAP
+                .getName();
+
+        List<PostClassificationToIncomeAccountMappings> 
buydownfeeClassificationToIncomeAccountMappings = new ArrayList<>();
+        PostClassificationToIncomeAccountMappings 
classificationToIncomeAccountMappings = new 
PostClassificationToIncomeAccountMappings();
+        
classificationToIncomeAccountMappings.setClassificationCodeValueId(25L);
+        classificationToIncomeAccountMappings.setIncomeAccountId(10L);
+        
buydownfeeClassificationToIncomeAccountMappings.add(classificationToIncomeAccountMappings);
+
+        final PostLoanProductsRequest 
loanProductsRequestLP2ProgressiveAdvPaymentBuyDownFeesClassificationIncomeMap = 
loanProductsRequestFactory
+                .defaultLoanProductsRequestLP2BuyDownFees()//
+                .name(name140)//
+                
.transactionProcessingStrategyCode(ADVANCED_PAYMENT_ALLOCATION.getValue())//
+                .loanScheduleType("PROGRESSIVE") //
+                .isInterestRecalculationEnabled(true)//
+                .preClosureInterestCalculationStrategy(1)//
+                .rescheduleStrategyMethod(4)//
+                .interestRecalculationCompoundingMethod(0)//
+                .recalculationRestFrequencyType(2)//
+                .recalculationRestFrequencyInterval(1)//
+                .paymentAllocation(List.of(//
+                        createPaymentAllocation("DEFAULT", 
"NEXT_INSTALLMENT"), //
+                        createPaymentAllocation("GOODWILL_CREDIT", 
"LAST_INSTALLMENT"), //
+                        createPaymentAllocation("MERCHANT_ISSUED_REFUND", 
"REAMORTIZATION"), //
+                        createPaymentAllocation("PAYOUT_REFUND", 
"NEXT_INSTALLMENT")))//
+                
.buydownfeeClassificationToIncomeAccountMappings(buydownfeeClassificationToIncomeAccountMappings);//
+
+        final Response<PostLoanProductsResponse> 
responseLoanProductsRequestLP2ProgressiveAdvPaymentBuyDownFeesClassificationIncomeMap
 = loanProductsApi
+                
.createLoanProduct(loanProductsRequestLP2ProgressiveAdvPaymentBuyDownFeesClassificationIncomeMap).execute();
+        TestContext.INSTANCE.set(
+                
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_PROGRESSIVE_ADV_PYMNT_BUYDOWN_FEES_CLASSIFICATION_INCOME_MAP,
+                
responseLoanProductsRequestLP2ProgressiveAdvPaymentBuyDownFeesClassificationIncomeMap);
+
+        // LP2 with progressive loan schedule + horizontal + interest EMI + 
360/30 + custom allocation capital
+        // adjustment
+        // + interest recalculation, preClosureInterestCalculationStrategy= 
till preclose,
+        // Frequency for recalculate Outstanding Principal: Daily, Frequency 
Interval for recalculation: 1
+        // capitalized income enabled + income type - fee
+        // + Classification income map
+        final String name141 = 
DefaultLoanProduct.LP2_PROGRESSIVE_ADV_PMNT_ALLOCATION_CAPITALIZED_INCOME_ADJ_CUSTOM_ALLOC_CLASSIFICATION_INCOME_MAP
+                .getName();
+
+        List<PostClassificationToIncomeAccountMappings> 
capitalizedIncomeClassificationToIncomeAccountMappings = new ArrayList<>();
+        PostClassificationToIncomeAccountMappings 
classificationToIncomeAccountMappingsCapitalizedIncome = new 
PostClassificationToIncomeAccountMappings();
+        
classificationToIncomeAccountMappingsCapitalizedIncome.setClassificationCodeValueId(24L);
+        
classificationToIncomeAccountMappingsCapitalizedIncome.setIncomeAccountId(15L);
+        
capitalizedIncomeClassificationToIncomeAccountMappings.add(classificationToIncomeAccountMappingsCapitalizedIncome);
+
+        final PostLoanProductsRequest 
loanProductsRequestLP2ProgressiveAdvPaymAllocCapitaizedIncomeClassificationIncomeMap
 = loanProductsRequestFactory
+                .defaultLoanProductsRequestLP2EmiCapitalizedIncome()//
+                .name(name141)//
+                .daysInYearType(DaysInYearType.DAYS360.value)//
+                .daysInMonthType(DaysInMonthType.DAYS30.value)//
+                .isInterestRecalculationEnabled(true)//
+                .preClosureInterestCalculationStrategy(1)//
+                .rescheduleStrategyMethod(4)//
+                .interestRecalculationCompoundingMethod(0)//
+                .recalculationRestFrequencyType(2)//
+                .recalculationRestFrequencyInterval(1)//
+                .paymentAllocation(List.of(//
+                        createPaymentAllocation("DEFAULT", 
"NEXT_INSTALLMENT"), //
+                        createPaymentAllocation("GOODWILL_CREDIT", 
"LAST_INSTALLMENT"), //
+                        createPaymentAllocation("MERCHANT_ISSUED_REFUND", 
"REAMORTIZATION"), //
+                        
createPaymentAllocation("CAPITALIZED_INCOME_ADJUSTMENT", "NEXT_INSTALLMENT",
+                                
LoanProductPaymentAllocationRule.AllocationTypesEnum.PAST_DUE_PRINCIPAL, //
+                                
LoanProductPaymentAllocationRule.AllocationTypesEnum.PAST_DUE_INTEREST, //
+                                
LoanProductPaymentAllocationRule.AllocationTypesEnum.PAST_DUE_FEE, //
+                                
LoanProductPaymentAllocationRule.AllocationTypesEnum.PAST_DUE_PENALTY, //
+                                
LoanProductPaymentAllocationRule.AllocationTypesEnum.DUE_PRINCIPAL, //
+                                
LoanProductPaymentAllocationRule.AllocationTypesEnum.DUE_INTEREST, //
+                                
LoanProductPaymentAllocationRule.AllocationTypesEnum.DUE_FEE, //
+                                
LoanProductPaymentAllocationRule.AllocationTypesEnum.DUE_PENALTY, //
+                                
LoanProductPaymentAllocationRule.AllocationTypesEnum.IN_ADVANCE_PRINCIPAL, //
+                                
LoanProductPaymentAllocationRule.AllocationTypesEnum.IN_ADVANCE_INTEREST, //
+                                
LoanProductPaymentAllocationRule.AllocationTypesEnum.IN_ADVANCE_FEE, //
+                                
LoanProductPaymentAllocationRule.AllocationTypesEnum.IN_ADVANCE_PENALTY), //
+                        createPaymentAllocation("PAYOUT_REFUND", 
"NEXT_INSTALLMENT")))//
+                
.capitalizedIncomeClassificationToIncomeAccountMappings(capitalizedIncomeClassificationToIncomeAccountMappings);//
+
+        final Response<PostLoanProductsResponse> 
responseLoanProductsRequestLP2ProgressiveAdvPaymAllocCapitaizedIncomeClassificationIncomeMap
 = loanProductsApi
+                
.createLoanProduct(loanProductsRequestLP2ProgressiveAdvPaymAllocCapitaizedIncomeClassificationIncomeMap).execute();
+
+        TestContext.INSTANCE.set(
+                
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_PROGRESSIVE_ADV_PMNT_ALLOCATION_CAPITALIZED_INCOME_ADJ_CUSTOM_ALLOC_CLASSIFICATION_INCOME_MAP,
+                
responseLoanProductsRequestLP2ProgressiveAdvPaymAllocCapitaizedIncomeClassificationIncomeMap);
     }
 
     public static AdvancedPaymentData createPaymentAllocation(String 
transactionType, String futureInstallmentAllocationRule,
diff --git 
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanStepDef.java
 
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanStepDef.java
index 983696b9a4..dbaa1bc6ba 100644
--- 
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanStepDef.java
+++ 
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanStepDef.java
@@ -4773,6 +4773,23 @@ public class LoanStepDef extends AbstractStepDef {
         return capitalizedIncomeResponse;
     }
 
+    public Response<PostLoansLoanIdTransactionsResponse> 
addCapitalizedIncomeToTheLoanOnWithEURTransactionAmountWithClassificationScheduledPayment(
+            final String transactionPaymentType, final String transactionDate, 
final String amount) throws IOException {
+        final Response<PostLoansResponse> loanResponse = 
testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
+        final long loanId = loanResponse.body().getLoanId();
+
+        final DefaultPaymentType paymentType = 
DefaultPaymentType.valueOf(transactionPaymentType);
+        final Long paymentTypeValue = paymentTypeResolver.resolve(paymentType);
+
+        final PostLoansLoanIdTransactionsRequest capitalizedIncomeRequest = 
LoanRequestFactory.defaultCapitalizedIncomeRequest()
+                
.transactionDate(transactionDate).transactionAmount(Double.valueOf(amount)).paymentTypeId(paymentTypeValue)
+                .externalId("EXT-CAP-INC-" + 
UUID.randomUUID()).classificationId(24L);
+
+        final Response<PostLoansLoanIdTransactionsResponse> 
capitalizedIncomeResponse = loanTransactionsApi
+                .executeLoanTransaction(loanId, capitalizedIncomeRequest, 
"capitalizedIncome").execute();
+        return capitalizedIncomeResponse;
+    }
+
     @And("Admin adds capitalized income with {string} payment type to the loan 
on {string} with {string} EUR transaction amount")
     public void 
adminAddsCapitalizedIncomeToTheLoanOnWithEURTransactionAmount(final String 
transactionPaymentType,
             final String transactionDate, final String amount) throws 
IOException {
@@ -4782,6 +4799,15 @@ public class LoanStepDef extends AbstractStepDef {
         ErrorHelper.checkSuccessfulApiCall(capitalizedIncomeResponse);
     }
 
+    @And("Admin adds capitalized income with {string} payment type to the loan 
on {string} with {string} EUR transaction amount and classification: 
scheduled_payment")
+    public void 
adminAddsCapitalizedIncomeToTheLoanOnWithEURTransactionAmountWithClassificationScheduledPayment(
+            final String transactionPaymentType, final String transactionDate, 
final String amount) throws IOException {
+        final Response<PostLoansLoanIdTransactionsResponse> 
capitalizedIncomeResponse = 
addCapitalizedIncomeToTheLoanOnWithEURTransactionAmountWithClassificationScheduledPayment(
+                transactionPaymentType, transactionDate, amount);
+        testContext().set(TestContextKey.LOAN_CAPITALIZED_INCOME_RESPONSE, 
capitalizedIncomeResponse);
+        ErrorHelper.checkSuccessfulApiCall(capitalizedIncomeResponse);
+    }
+
     @And("Admin adds capitalized income with {string} payment type to the loan 
on {string} with {string} EUR transaction amount and {string} classification")
     public void adminAddsCapitalizedIncomeWithClassification(final String 
transactionPaymentType, final String transactionDate,
             final String amount, final String classificationCodeName) throws 
IOException {
@@ -5214,6 +5240,23 @@ public class LoanStepDef extends AbstractStepDef {
         return buyDownFeeResponse;
     }
 
+    public Response<PostLoansLoanIdTransactionsResponse> 
addBuyDownFeeToTheLoanOnWithEURTransactionAmountWithClassification(
+            final String transactionPaymentType, final String transactionDate, 
final String amount) throws IOException {
+        final Response<PostLoansResponse> loanResponse = 
testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
+        final long loanId = loanResponse.body().getLoanId();
+
+        final DefaultPaymentType paymentType = 
DefaultPaymentType.valueOf(transactionPaymentType);
+        final Long paymentTypeValue = paymentTypeResolver.resolve(paymentType);
+
+        final PostLoansLoanIdTransactionsRequest buyDownFeeRequest = 
LoanRequestFactory.defaultBuyDownFeeIncomeRequest()
+                
.transactionDate(transactionDate).transactionAmount(Double.valueOf(amount)).paymentTypeId(paymentTypeValue)
+                .externalId("EXT-BUY-DOWN-FEE" + 
UUID.randomUUID()).classificationId(25L);
+
+        final Response<PostLoansLoanIdTransactionsResponse> buyDownFeeResponse 
= loanTransactionsApi
+                .executeLoanTransaction(loanId, buyDownFeeRequest, 
"buyDownFee").execute();
+        return buyDownFeeResponse;
+    }
+
     public Response<PostLoansLoanIdTransactionsResponse> 
adjustBuyDownFee(final String transactionPaymentType, final String 
transactionDate,
             final String amount, final Long transactionId) throws IOException {
         final Response<PostLoansResponse> loanResponse = 
testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
@@ -5242,6 +5285,15 @@ public class LoanStepDef extends AbstractStepDef {
         ErrorHelper.checkSuccessfulApiCall(buyDownFeesIncomeResponse);
     }
 
+    @And("Admin adds buy down fee with {string} payment type to the loan on 
{string} with {string} EUR transaction amount and classification: 
pending_bankruptcy")
+    public void 
adminAddsBuyDownFeesToTheLoanOnWithEURTransactionAmountWithClassification(final 
String transactionPaymentType,
+            final String transactionDate, final String amount) throws 
IOException {
+        final Response<PostLoansLoanIdTransactionsResponse> 
buyDownFeesIncomeResponse = 
addBuyDownFeeToTheLoanOnWithEURTransactionAmountWithClassification(
+                transactionPaymentType, transactionDate, amount);
+        testContext().set(TestContextKey.LOAN_BUY_DOWN_FEE_RESPONSE, 
buyDownFeesIncomeResponse);
+        ErrorHelper.checkSuccessfulApiCall(buyDownFeesIncomeResponse);
+    }
+
     @When("Admin adds buy down fee with {string} payment type to the loan on 
{string} with {string} EUR transaction amount and {string} classification")
     public void adminAddsBuyDownFeeWithClassification(final String 
transactionPaymentType, final String transactionDate,
             final String amount, final String classificationCodeName) throws 
IOException {
diff --git 
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/support/TestContextKey.java
 
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/support/TestContextKey.java
index c27b20a8ea..08bb6cbae7 100644
--- 
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/support/TestContextKey.java
+++ 
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/support/TestContextKey.java
@@ -161,7 +161,9 @@ public abstract class TestContextKey {
     public static final String 
DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_PROGRESSIVE_ADV_PYMNT_BUYDOWN_FEES_CHARGE_OFF_REASON
 = 
"loanProductCreateResponseLP2ProgressiveAdvancedPaymentBuyDownFeesWithChargeOffReason";
     public static final String 
DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_PROGRESSIVE_ADV_PYMNT_BUYDOWN_FEES_NON_MERCHANT
 = 
"loanProductCreateResponseLP2ProgressiveAdvancedPaymentBuyDownFeesNonMerchant";
     public static final String 
DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_PROGRESSIVE_ADV_PYMNT_BUYDOWN_FEES_NON_MERCHANT_CHARGE_OFF_REASON
 = 
"loanProductCreateResponseLP2ProgressiveAdvancedPaymentBuyDownFeesNonMerchantWithChargeOffReason";
+    public static final String 
DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_PROGRESSIVE_ADV_PYMNT_BUYDOWN_FEES_CLASSIFICATION_INCOME_MAP
 = 
"loanProductCreateResponseLP2ProgressiveAdvancedPaymentBuyDownFeesClassificationIncomeMap";
     public static final String 
DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALC_DAILY_CAPITALIZED_INCOME_ADJ_CUSTOM_ALLOC
 = 
"loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030InterestRecalculationDailyCapitalizedIncomeAdjCustomAlloc";
+    public static final String 
DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_PROGRESSIVE_ADV_PMNT_ALLOCATION_CAPITALIZED_INCOME_ADJ_CUSTOM_ALLOC_CLASSIFICATION_INCOME_MAP
 = 
"loanProductCreateResponseLP2AdvancedPaymentCapitalizedIncomeAdjCustomAllocClassificationIncomeMao";
     public static final String 
DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_RECALC_EMI_360_30_MULTIDISB_OVER_APPLIED_PERCENTAGE_CAPITALIZED_INCOME
 = 
"loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030InterestRecalculationDailyMultidisbursalApprovedOVerAppliedPercentageCapitalizedIncome";
     public static final String 
DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_RECALC_EMI_360_30_MULTIDISB_OVER_APPLIED_FLAT_CAPITALIZED_INCOME
 = 
"loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030InterestRecalculationDailyMultidisbursalApprovedOVerAppliedFlatCapitalizedIncome";
     public static final String 
DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_RECALC_EMI_360_30_APPROVED_OVER_APPLIED_PERCENTAGE_CAPITALIZED_INCOME
 = 
"loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030InterestRecalculationDailyApprovedOVerAppliedAmountPercentageCapitalizedIncome";
diff --git 
a/fineract-e2e-tests-runner/src/test/resources/features/LoanBuyDownFees.feature 
b/fineract-e2e-tests-runner/src/test/resources/features/LoanBuyDownFees.feature
index e8d59eb8aa..6cff314888 100644
--- 
a/fineract-e2e-tests-runner/src/test/resources/features/LoanBuyDownFees.feature
+++ 
b/fineract-e2e-tests-runner/src/test/resources/features/LoanBuyDownFees.feature
@@ -3771,4 +3771,79 @@ Feature:Feature: Buy Down Fees
       | 16 January 2024 | AM   | 0.2    |
     And Buy down fee by external-id contains the following data:
       | Date            | Fee Amount | Amortized Amount | Not Yet Amortized 
Amount | Adjusted Amount | Charged Off Amount |
-      | 01 January 2024 | 1.0        | 0.5              | 0.0                  
    | 0.3             | 0.2                |
\ No newline at end of file
+      | 01 January 2024 | 1.0        | 0.5              | 0.0                  
    | 0.3             | 0.2                |
+
+  @TestRailId:C4092
+  Scenario: Verify GL entries for Buydown Fee Amortization - UC1: Amortization 
for Buydown fee with NO classification rule
+    When Admin sets the business date to "01 January 2024"
+    And Admin creates a client with random data
+    And Admin creates a fully customized loan with the following data:
+      | LoanProduct                                                            
            | submitted on date | with Principal | ANNUAL interest rate % | 
interest type     | interest calculation period | amortization type  | 
loanTermFrequency | loanTermFrequencyType | repaymentEvery | 
repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | 
graceOnInterestPayment | interest free period | Payment strategy            |
+      | 
LP2_PROGRESSIVE_ADVANCED_PAYMENT_ALLOCATION_BUYDOWN_FEES_CLASSIFICATION_INCOME_MAP
 | 01 January 2024   | 350            | 7                      | 
DECLINING_BALANCE | DAILY                       | EQUAL_INSTALLMENTS | 3        
         | MONTHS                | 1              | MONTHS                 | 3  
                | 0                       | 0                      | 0          
          | ADVANCED_PAYMENT_ALLOCATION |
+    And Admin successfully approves the loan on "01 January 2024" with "350" 
amount and expected disbursement date on "01 January 2024"
+    And Admin successfully disburse the loan on "01 January 2024" with "100" 
EUR transaction amount
+    And Admin adds buy down fee with "AUTOPAY" payment type to the loan on "01 
January 2024" with "50" EUR transaction amount
+    And Admin sets the business date to "02 January 2024"
+    And Admin runs inline COB job for Loan
+    Then Loan Transactions tab has a "BUY_DOWN_FEE" transaction with date "01 
January 2024" which has the following Journal entries:
+      | Type      | Account code | Account name                | Debit | 
Credit |
+      | EXPENSE   | 450280       | Buy Down Expense            | 50.0  |       
 |
+      | LIABILITY | 145024       | Deferred Capitalized Income |       | 50.0  
 |
+    And Loan Transactions tab has a "BUY_DOWN_FEE_AMORTIZATION" transaction 
with date "01 January 2024" which has the following Journal entries:
+      | Type      | Account code | Account name                | Debit | 
Credit |
+      | INCOME    | 450281       | Income From Buy Down        |       | 0.55  
 |
+      | LIABILITY | 145024       | Deferred Capitalized Income | 0.55  |       
 |
+
+  @TestRailId:C4093
+  Scenario: Verify GL entries for Buydown Fee Amortization - UC2: Amortization 
for Buydown fee with classification rule: pending_bankruptcy
+    When Admin sets the business date to "01 January 2024"
+    And Admin creates a client with random data
+    When Admin creates a fully customized loan with the following data:
+      | LoanProduct                                                            
            | submitted on date | with Principal | ANNUAL interest rate % | 
interest type     | interest calculation period | amortization type  | 
loanTermFrequency | loanTermFrequencyType | repaymentEvery | 
repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | 
graceOnInterestPayment | interest free period | Payment strategy            |
+      | 
LP2_PROGRESSIVE_ADVANCED_PAYMENT_ALLOCATION_BUYDOWN_FEES_CLASSIFICATION_INCOME_MAP
 | 01 January 2024   | 350            | 7                      | 
DECLINING_BALANCE | DAILY                       | EQUAL_INSTALLMENTS | 3        
         | MONTHS                | 1              | MONTHS                 | 3  
                | 0                       | 0                      | 0          
          | ADVANCED_PAYMENT_ALLOCATION |
+    And Admin successfully approves the loan on "01 January 2024" with "350" 
amount and expected disbursement date on "01 January 2024"
+    And Admin successfully disburse the loan on "01 January 2024" with "100" 
EUR transaction amount
+    And Admin adds buy down fee with "AUTOPAY" payment type to the loan on "01 
January 2024" with "50" EUR transaction amount and classification: 
pending_bankruptcy
+    And Admin sets the business date to "02 January 2024"
+    And Admin runs inline COB job for Loan
+    Then Loan Transactions tab has a "BUY_DOWN_FEE" transaction with date "01 
January 2024" which has the following Journal entries:
+      | Type      | Account code | Account name                | Debit | 
Credit |
+      | EXPENSE   | 450280       | Buy Down Expense            | 50.0  |       
 |
+      | LIABILITY | 145024       | Deferred Capitalized Income |       | 50.0  
 |
+    And Loan Transactions tab has a "BUY_DOWN_FEE_AMORTIZATION" transaction 
with date "01 January 2024" which has the following Journal entries:
+      | Type      | Account code | Account name                | Debit | 
Credit |
+      | INCOME    | 404007       | Fee Income                  |       | 0.55  
 |
+      | LIABILITY | 145024       | Deferred Capitalized Income | 0.55  |       
 |
+
+  @TestRailId:C4094
+  Scenario: Verify GL entries for Buydown Fee Amortization - UC3: Amortization 
for Buydown fees with NO classification and with classification rule: 
pending_bankruptcy
+    When Admin sets the business date to "01 January 2024"
+    And Admin creates a client with random data
+    When Admin creates a fully customized loan with the following data:
+      | LoanProduct                                                            
            | submitted on date | with Principal | ANNUAL interest rate % | 
interest type     | interest calculation period | amortization type  | 
loanTermFrequency | loanTermFrequencyType | repaymentEvery | 
repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | 
graceOnInterestPayment | interest free period | Payment strategy            |
+      | 
LP2_PROGRESSIVE_ADVANCED_PAYMENT_ALLOCATION_BUYDOWN_FEES_CLASSIFICATION_INCOME_MAP
 | 01 January 2024   | 350            | 7                      | 
DECLINING_BALANCE | DAILY                       | EQUAL_INSTALLMENTS | 3        
         | MONTHS                | 1              | MONTHS                 | 3  
                | 0                       | 0                      | 0          
          | ADVANCED_PAYMENT_ALLOCATION |
+    And Admin successfully approves the loan on "01 January 2024" with "350" 
amount and expected disbursement date on "01 January 2024"
+    And Admin successfully disburse the loan on "01 January 2024" with "100" 
EUR transaction amount
+    And Admin adds buy down fee with "AUTOPAY" payment type to the loan on "01 
January 2024" with "50" EUR transaction amount
+    And Admin sets the business date to "02 January 2024"
+    And Admin runs inline COB job for Loan
+    And Admin adds buy down fee with "AUTOPAY" payment type to the loan on "02 
January 2024" with "20" EUR transaction amount and classification: 
pending_bankruptcy
+    And Admin sets the business date to "03 January 2024"
+    And Admin runs inline COB job for Loan
+    Then Loan Transactions tab has a "BUY_DOWN_FEE" transaction with date "01 
January 2024" which has the following Journal entries:
+      | Type      | Account code | Account name                | Debit | 
Credit |
+      | EXPENSE   | 450280       | Buy Down Expense            | 50.0  |       
 |
+      | LIABILITY | 145024       | Deferred Capitalized Income |       | 50.0  
 |
+    And Loan Transactions tab has a "BUY_DOWN_FEE_AMORTIZATION" transaction 
with date "01 January 2024" which has the following Journal entries:
+      | Type      | Account code | Account name                | Debit | 
Credit |
+      | INCOME    | 450281       | Income From Buy Down        |       | 0.55  
 |
+      | LIABILITY | 145024       | Deferred Capitalized Income | 0.55  |       
 |
+    And Loan Transactions tab has a "BUY_DOWN_FEE" transaction with date "02 
January 2024" which has the following Journal entries:
+      | Type      | Account code | Account name                | Debit | 
Credit |
+      | EXPENSE   | 450280       | Buy Down Expense            | 20.0  |       
 |
+      | LIABILITY | 145024       | Deferred Capitalized Income |       | 20.0  
 |
+    And Loan Transactions tab has a "BUY_DOWN_FEE_AMORTIZATION" transaction 
with date "02 January 2024" which has the following Journal entries:
+      | Type      | Account code | Account name                | Debit | 
Credit |
+      | INCOME    | 404007       | Fee Income                  |       | 0.22  
 |
+      | INCOME    | 450281       | Income From Buy Down        |       | 0.55  
 |
+      | LIABILITY | 145024       | Deferred Capitalized Income | 0.77  |       
 |
diff --git 
a/fineract-e2e-tests-runner/src/test/resources/features/LoanCapitalizedIncome.feature
 
b/fineract-e2e-tests-runner/src/test/resources/features/LoanCapitalizedIncome.feature
index 8146057331..09cef0ae6b 100644
--- 
a/fineract-e2e-tests-runner/src/test/resources/features/LoanCapitalizedIncome.feature
+++ 
b/fineract-e2e-tests-runner/src/test/resources/features/LoanCapitalizedIncome.feature
@@ -8101,3 +8101,78 @@ Feature: Capitalized Income
     And Deferred Capitalized Income by external-id contains the following data:
       | Amount | Amortized Amount | Unrecognized Amount | Adjusted Amount | 
Charged Off Amount |
       | 1.0    | 0.5              | 0.0                 | 0.3             | 
0.2                |
+
+  @TestRailId:C4095
+  Scenario: Verify GL entries for Capitalized Income Amortization - UC1: 
Amortization for Capitalized Income with NO classification rule
+    When Admin sets the business date to "01 January 2024"
+    And Admin creates a client with random data
+    When Admin creates a fully customized loan with the following data:
+      | LoanProduct                                                            
                           | submitted on date | with Principal | ANNUAL 
interest rate % | interest type     | interest calculation period | 
amortization type  | loanTermFrequency | loanTermFrequencyType | repaymentEvery 
| repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | 
graceOnInterestPayment | interest free period | Payment strategy            |
+      | 
LP2_PROGRESSIVE_ADV_PMNT_ALLOCATION_CAPITALIZED_INCOME_ADJ_CUSTOM_ALLOC_CLASSIFICATION_INCOME_MAP
 | 01 January 2024   | 350            | 7                      | 
DECLINING_BALANCE | DAILY                       | EQUAL_INSTALLMENTS | 3        
         | MONTHS                | 1              | MONTHS                 | 3  
                | 0                       | 0                      | 0          
          | ADVANCED_PAYMENT_ALLOCATION |
+    And Admin successfully approves the loan on "01 January 2024" with "350" 
amount and expected disbursement date on "01 January 2024"
+    And Admin successfully disburse the loan on "01 January 2024" with "100" 
EUR transaction amount
+    And Admin adds capitalized income with "AUTOPAY" payment type to the loan 
on "01 January 2024" with "50" EUR transaction amount
+    When Admin sets the business date to "02 January 2024"
+    And Admin runs inline COB job for Loan
+    Then Loan Transactions tab has a "CAPITALIZED_INCOME" transaction with 
date "01 January 2024" which has the following Journal entries:
+      | Type      | Account code | Account name                | Debit | 
Credit |
+      | LIABILITY | 145024       | Deferred Capitalized Income |       | 50.0  
 |
+      | ASSET     | 112601       | Loans Receivable            | 50.0  |       
 |
+    And Loan Transactions tab has a "CAPITALIZED_INCOME_AMORTIZATION" 
transaction with date "01 January 2024" which has the following Journal entries:
+      | Type      | Account code | Account name                | Debit | 
Credit |
+      | INCOME    | 404000       | Interest Income             |       | 0.55  
 |
+      | LIABILITY | 145024       | Deferred Capitalized Income | 0.55  |       
 |
+
+  @TestRailId:C4096
+  Scenario: Verify GL entries for Capitalized Income Amortization - UC2: 
Amortization for Capitalized Income with classification rule: pending_bankruptcy
+    When Admin sets the business date to "01 January 2024"
+    And Admin creates a client with random data
+    When Admin creates a fully customized loan with the following data:
+      | LoanProduct                                                            
                           | submitted on date | with Principal | ANNUAL 
interest rate % | interest type     | interest calculation period | 
amortization type  | loanTermFrequency | loanTermFrequencyType | repaymentEvery 
| repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | 
graceOnInterestPayment | interest free period | Payment strategy            |
+      | 
LP2_PROGRESSIVE_ADV_PMNT_ALLOCATION_CAPITALIZED_INCOME_ADJ_CUSTOM_ALLOC_CLASSIFICATION_INCOME_MAP
 | 01 January 2024   | 350            | 7                      | 
DECLINING_BALANCE | DAILY                       | EQUAL_INSTALLMENTS | 3        
         | MONTHS                | 1              | MONTHS                 | 3  
                | 0                       | 0                      | 0          
          | ADVANCED_PAYMENT_ALLOCATION |
+    And Admin successfully approves the loan on "01 January 2024" with "350" 
amount and expected disbursement date on "01 January 2024"
+    And Admin successfully disburse the loan on "01 January 2024" with "100" 
EUR transaction amount
+    And Admin adds capitalized income with "AUTOPAY" payment type to the loan 
on "01 January 2024" with "50" EUR transaction amount and classification: 
scheduled_payment
+    When Admin sets the business date to "02 January 2024"
+    And Admin runs inline COB job for Loan
+    Then Loan Transactions tab has a "CAPITALIZED_INCOME" transaction with 
date "01 January 2024" which has the following Journal entries:
+      | Type      | Account code | Account name                | Debit | 
Credit |
+      | LIABILITY | 145024       | Deferred Capitalized Income |       | 50.0  
 |
+      | ASSET     | 112601       | Loans Receivable            | 50.0  |       
 |
+    And Loan Transactions tab has a "CAPITALIZED_INCOME_AMORTIZATION" 
transaction with date "01 January 2024" which has the following Journal entries:
+      | Type      | Account code | Account name                | Debit | 
Credit |
+      | INCOME    | 744008       | Recoveries                  |       | 0.55  
 |
+      | LIABILITY | 145024       | Deferred Capitalized Income | 0.55  |       
 |
+
+  @TestRailId:C4097
+  Scenario: Verify GL entries for Capitalized Income Amortization - UC3: 
Amortization for Capitalized Incomes with NO classification and with 
classification rule: pending_bankruptcy
+    When Admin sets the business date to "01 January 2024"
+    And Admin creates a client with random data
+    When Admin creates a fully customized loan with the following data:
+      | LoanProduct                                                            
                           | submitted on date | with Principal | ANNUAL 
interest rate % | interest type     | interest calculation period | 
amortization type  | loanTermFrequency | loanTermFrequencyType | repaymentEvery 
| repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | 
graceOnInterestPayment | interest free period | Payment strategy            |
+      | 
LP2_PROGRESSIVE_ADV_PMNT_ALLOCATION_CAPITALIZED_INCOME_ADJ_CUSTOM_ALLOC_CLASSIFICATION_INCOME_MAP
 | 01 January 2024   | 350            | 7                      | 
DECLINING_BALANCE | DAILY                       | EQUAL_INSTALLMENTS | 3        
         | MONTHS                | 1              | MONTHS                 | 3  
                | 0                       | 0                      | 0          
          | ADVANCED_PAYMENT_ALLOCATION |
+    And Admin successfully approves the loan on "01 January 2024" with "350" 
amount and expected disbursement date on "01 January 2024"
+    And Admin successfully disburse the loan on "01 January 2024" with "100" 
EUR transaction amount
+    And Admin adds capitalized income with "AUTOPAY" payment type to the loan 
on "01 January 2024" with "50" EUR transaction amount
+    When Admin sets the business date to "02 January 2024"
+    And Admin runs inline COB job for Loan
+    And Admin adds capitalized income with "AUTOPAY" payment type to the loan 
on "02 January 2024" with "20" EUR transaction amount and classification: 
scheduled_payment
+    When Admin sets the business date to "03 January 2024"
+    And Admin runs inline COB job for Loan
+    Then Loan Transactions tab has a "CAPITALIZED_INCOME" transaction with 
date "01 January 2024" which has the following Journal entries:
+      | Type      | Account code | Account name                | Debit | 
Credit |
+      | LIABILITY | 145024       | Deferred Capitalized Income |       | 50.0  
 |
+      | ASSET     | 112601       | Loans Receivable            | 50.0  |       
 |
+    And Loan Transactions tab has a "CAPITALIZED_INCOME_AMORTIZATION" 
transaction with date "01 January 2024" which has the following Journal entries:
+      | Type      | Account code | Account name                | Debit | 
Credit |
+      | INCOME    | 404000       | Interest Income             |       | 0.55  
 |
+      | LIABILITY | 145024       | Deferred Capitalized Income | 0.55  |       
 |
+    Then Loan Transactions tab has a "CAPITALIZED_INCOME" transaction with 
date "02 January 2024" which has the following Journal entries:
+      | Type      | Account code | Account name                | Debit | 
Credit |
+      | LIABILITY | 145024       | Deferred Capitalized Income |       | 20.0  
 |
+      | ASSET     | 112601       | Loans Receivable            | 20.0  |       
 |
+    And Loan Transactions tab has a "CAPITALIZED_INCOME_AMORTIZATION" 
transaction with date "02 January 2024" which has the following Journal entries:
+      | Type      | Account code | Account name                | Debit | 
Credit |
+      | INCOME    | 744008       | Recoveries                  |       | 0.22  
 |
+      | INCOME    | 404000       | Interest Income             |       | 0.55  
 |
+      | LIABILITY | 145024       | Deferred Capitalized Income | 0.77  |       
 |


Reply via email to