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 aff009c40 FINERTACT-1724: Advanced payment allocation fixes for Loan 
Schedule
aff009c40 is described below

commit aff009c400d8e6208cfad03119c9519be7014dbe
Author: Jose Alberto Hernandez <[email protected]>
AuthorDate: Tue Nov 28 22:28:58 2023 -0600

    FINERTACT-1724: Advanced payment allocation fixes for Loan Schedule
---
 .../domain/LoanProductRelatedDetail.java           | 15 ++++++++++
 .../service/LoanScheduleAssembler.java             |  6 +---
 .../serialization/LoanProductDataValidator.java    | 34 +++++++++++++++++-----
 .../integrationtests/AccountTransferTest.java      |  2 ++
 ...PaymentAllocationLoanRepaymentScheduleTest.java | 29 +++++++++++++++---
 .../AdvancedPaymentAllocationWaiveLoanCharges.java | 20 +++++++++----
 .../integrationtests/BaseLoanIntegrationTest.java  |  5 ++++
 ...lanceRefundandRepaymentTypeIntegrationTest.java |  2 ++
 .../DelinquencyAndChargebackIntegrationTest.java   |  2 ++
 ...ChargeOffWithAdvancedPaymentAllocationTest.java |  4 +++
 ...eseReplayWithAdvancedPaymentAllocationTest.java |  8 ++++-
 .../LoanCatchUpIntegrationTest.java                |  3 +-
 ...gePaymentWithAdvancedPaymentAllocationTest.java | 15 +++++++---
 ...backOnPaymentTypeRepaymentTransactionsTest.java |  2 ++
 .../LoanPostChargeOffScenariosTest.java            |  2 ++
 .../integrationtests/LoanProductUpdateApiTest.java |  8 +++--
 ...hAdvancedPaymentAllocationIntegrationTests.java |  6 +++-
 .../LoanTransactionChargebackTest.java             |  2 ++
 ...ionFullAmountChargebackForOverpaidLoanTest.java |  2 ++
 ...hAdvancedPaymentAllocationIntegrationTests.java |  8 ++++-
 ...nWriteOffWithAdvancedPaymentAllocationTest.java |  5 +++-
 ...tiveLoansWithAdvancedPaymentAllocationTest.java |  5 ++--
 ...ndoRepaymentWithDownPaymentIntegrationTest.java |  5 +++-
 .../common/accounting/JournalEntryHelper.java      |  4 ++-
 .../common/loans/LoanApplicationTestBuilder.java   | 20 +++++++++++++
 .../common/loans/LoanProductTestBuilder.java       |  5 ++--
 26 files changed, 181 insertions(+), 38 deletions(-)

diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductRelatedDetail.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductRelatedDetail.java
index 1bbb42fe5..793241fd1 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductRelatedDetail.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductRelatedDetail.java
@@ -352,6 +352,21 @@ public class LoanProductRelatedDetail implements 
LoanProductMinimumRepaymentSche
             this.currency = new MonetaryCurrency(currencyCode, 
digitsAfterDecimal, inMultiplesOf);
         }
 
+        final String loanScheduleTypeParamName = 
LoanProductConstants.LOAN_SCHEDULE_TYPE;
+        if (command.isChangeInStringParameterNamed(loanScheduleTypeParamName, 
loanScheduleType.toString())) {
+            LoanScheduleType newLoanScheduleType = 
LoanScheduleType.valueOf(command.stringValueOfParameterNamed(loanScheduleTypeParamName));
+            actualChanges.put(loanScheduleTypeParamName, newLoanScheduleType);
+            loanScheduleType = newLoanScheduleType;
+        }
+
+        final String loanScheduleProcessingTypeParamName = 
LoanProductConstants.LOAN_SCHEDULE_PROCESSING_TYPE;
+        if 
(command.isChangeInStringParameterNamed(loanScheduleProcessingTypeParamName, 
loanScheduleProcessingType.toString())) {
+            LoanScheduleProcessingType newLoanScheduleProcessingType = 
LoanScheduleProcessingType
+                    
.valueOf(command.stringValueOfParameterNamed(loanScheduleProcessingTypeParamName));
+            actualChanges.put(loanScheduleProcessingTypeParamName, 
newLoanScheduleProcessingType);
+            loanScheduleProcessingType = newLoanScheduleProcessingType;
+        }
+
         final Map<String, Object> loanApplicationAttributeChanges = 
updateLoanApplicationAttributes(command, aprCalculator);
 
         actualChanges.putAll(loanApplicationAttributeChanges);
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java
index b6c15d85f..0ec8d3ea1 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java
@@ -41,7 +41,6 @@ import 
org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
 import 
org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
 import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
 import org.apache.fineract.infrastructure.core.service.DateUtils;
-import 
org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.apache.fineract.organisation.holiday.domain.Holiday;
 import org.apache.fineract.organisation.holiday.domain.HolidayRepository;
 import org.apache.fineract.organisation.holiday.domain.HolidayStatusType;
@@ -137,7 +136,6 @@ public class LoanScheduleAssembler {
     private final FloatingRatesReadPlatformService 
floatingRatesReadPlatformService;
     private final VariableLoanScheduleFromApiJsonValidator 
variableLoanScheduleFromApiJsonValidator;
     private final CalendarInstanceRepository calendarInstanceRepository;
-    private final PlatformSecurityContext context;
     private final LoanUtilService loanUtilService;
 
     @Autowired
@@ -150,8 +148,7 @@ public class LoanScheduleAssembler {
             final WorkingDaysRepositoryWrapper workingDaysRepository,
             final FloatingRatesReadPlatformService 
floatingRatesReadPlatformService,
             final VariableLoanScheduleFromApiJsonValidator 
variableLoanScheduleFromApiJsonValidator,
-            final CalendarInstanceRepository calendarInstanceRepository, final 
PlatformSecurityContext context,
-            final LoanUtilService loanUtilService) {
+            final CalendarInstanceRepository calendarInstanceRepository, final 
LoanUtilService loanUtilService) {
         this.fromApiJsonHelper = fromApiJsonHelper;
         this.loanProductRepository = loanProductRepository;
         this.applicationCurrencyRepository = applicationCurrencyRepository;
@@ -167,7 +164,6 @@ public class LoanScheduleAssembler {
         this.floatingRatesReadPlatformService = 
floatingRatesReadPlatformService;
         this.variableLoanScheduleFromApiJsonValidator = 
variableLoanScheduleFromApiJsonValidator;
         this.calendarInstanceRepository = calendarInstanceRepository;
-        this.context = context;
         this.loanUtilService = loanUtilService;
     }
 
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/serialization/LoanProductDataValidator.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/serialization/LoanProductDataValidator.java
index 7e5035294..ced5da046 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/serialization/LoanProductDataValidator.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/serialization/LoanProductDataValidator.java
@@ -781,16 +781,27 @@ public final class LoanProductDataValidator {
                     
.value(enableInstallmentLevelDelinquency).ignoreIfNull().validateForBooleanValue();
         }
 
-        final String loanScheduleType = 
this.fromApiJsonHelper.extractStringNamed(LoanProductConstants.LOAN_SCHEDULE_TYPE,
 element);
-        
baseDataValidator.reset().parameter(LoanProductConstants.LOAN_SCHEDULE_TYPE).value(loanScheduleType).ignoreIfNull()
-                .isOneOfEnumValues(LoanScheduleType.class);
+        String loanScheduleType = LoanScheduleType.CUMULATIVE.name();
+        if 
(this.fromApiJsonHelper.parameterExists(LoanProductConstants.LOAN_SCHEDULE_TYPE,
 element)) {
+            loanScheduleType = 
this.fromApiJsonHelper.extractStringNamed(LoanProductConstants.LOAN_SCHEDULE_TYPE,
 element);
+            
baseDataValidator.reset().parameter(LoanProductConstants.LOAN_SCHEDULE_TYPE).value(loanScheduleType)
+                    .isOneOfEnumValues(LoanScheduleType.class);
+        }
+
+        if 
(!LoanScheduleType.PROGRESSIVE.equals(LoanScheduleType.valueOf(loanScheduleType))
+                && 
AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY
+                        .equals(transactionProcessingStrategyCode)) {
+            
baseDataValidator.reset().parameter(LoanProductConstants.LOAN_SCHEDULE_PROCESSING_TYPE).failWithCode(
+                    "supported.only.for.progressive.loan.schedule.type",
+                    "Progressive repayment schedule processing is only 
available with `Advanced payment allocation` strategy");
+        }
 
         String loanScheduleProcessingType = 
LoanScheduleProcessingType.HORIZONTAL.name();
         if 
(this.fromApiJsonHelper.parameterExists(LoanProductConstants.LOAN_SCHEDULE_PROCESSING_TYPE,
 element)) {
             loanScheduleProcessingType = 
this.fromApiJsonHelper.extractStringNamed(LoanProductConstants.LOAN_SCHEDULE_PROCESSING_TYPE,
                     element);
             
baseDataValidator.reset().parameter(LoanProductConstants.LOAN_SCHEDULE_PROCESSING_TYPE).value(loanScheduleProcessingType)
-                    
.ignoreIfNull().isOneOfEnumValues(LoanScheduleProcessingType.class);
+                    .isOneOfEnumValues(LoanScheduleProcessingType.class);
 
             if 
(LoanScheduleProcessingType.VERTICAL.equals(LoanScheduleProcessingType.valueOf(loanScheduleProcessingType))
                     && 
!AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY
@@ -1784,10 +1795,19 @@ public final class LoanProductDataValidator {
                     
.value(enableInstallmentLevelDelinquency).ignoreIfNull().validateForBooleanValue();
         }
 
+        String loanScheduleType = 
loanProduct.getLoanProductRelatedDetail().getLoanScheduleType().name();
         if 
(this.fromApiJsonHelper.parameterExists(LoanProductConstants.LOAN_SCHEDULE_TYPE,
 element)) {
-            final String loanScheduleType = 
this.fromApiJsonHelper.extractStringNamed(LoanProductConstants.LOAN_SCHEDULE_TYPE,
 element);
-            
baseDataValidator.reset().parameter(LoanProductConstants.LOAN_SCHEDULE_TYPE).value(loanScheduleType).ignoreIfNull()
+            loanScheduleType = 
this.fromApiJsonHelper.extractStringNamed(LoanProductConstants.LOAN_SCHEDULE_TYPE,
 element);
+            
baseDataValidator.reset().parameter(LoanProductConstants.LOAN_SCHEDULE_TYPE).value(loanScheduleType)
                     .isOneOfEnumValues(LoanScheduleType.class);
+
+            if 
(!LoanScheduleType.PROGRESSIVE.equals(LoanScheduleType.valueOf(loanScheduleType))
+                    && 
AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY
+                            .equals(transactionProcessingStrategyCode)) {
+                
baseDataValidator.reset().parameter(LoanProductConstants.LOAN_SCHEDULE_PROCESSING_TYPE).failWithCode(
+                        "supported.only.for.progressive.loan.schedule.type",
+                        "Progressive repayment schedule processing is only 
available with `Advanced payment allocation` strategy");
+            }
         }
 
         String loanScheduleProcessingType = 
loanProduct.getLoanProductRelatedDetail().getLoanScheduleProcessingType().name();
@@ -1795,7 +1815,7 @@ public final class LoanProductDataValidator {
             loanScheduleProcessingType = 
this.fromApiJsonHelper.extractStringNamed(LoanProductConstants.LOAN_SCHEDULE_PROCESSING_TYPE,
                     element);
             
baseDataValidator.reset().parameter(LoanProductConstants.LOAN_SCHEDULE_PROCESSING_TYPE).value(loanScheduleProcessingType)
-                    
.ignoreIfNull().isOneOfEnumValues(LoanScheduleProcessingType.class);
+                    .isOneOfEnumValues(LoanScheduleProcessingType.class);
         }
 
         List<LoanProductPaymentAllocationRule> allocationRules = 
loanProduct.getPaymentAllocationRules();
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AccountTransferTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AccountTransferTest.java
index 6b680a571..f12404848 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AccountTransferTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AccountTransferTest.java
@@ -50,6 +50,7 @@ import 
org.apache.fineract.integrationtests.common.savings.AccountTransferHelper
 import 
org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper;
 import 
org.apache.fineract.integrationtests.common.savings.SavingsProductHelper;
 import 
org.apache.fineract.integrationtests.common.savings.SavingsStatusChecker;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
@@ -479,6 +480,7 @@ public class AccountTransferTest {
                 .withAmortizationTypeAsEqualInstallments() //
                 .withInterestTypeAsDecliningBalance() //
                 .withAccountingRuleAsCashBased(accounts)//
+                .withLoanScheduleType(LoanScheduleType.CUMULATIVE)//
                 .build(null);
         return this.loanTransactionHelper.getLoanProductId(loanProductJSON);
     }
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java
index e47ed1dcc..dcf631239 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java
@@ -2171,7 +2171,7 @@ public class 
AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
         });
     }
 
-    // UC109: Advanced payment allocation, cumulative loan schedule handling, 
rounding test
+    // UC109: Advanced payment allocation, progressive loan schedule handling, 
rounding test
     // ADVANCED_PAYMENT_ALLOCATION_STRATEGY
     // 1. Create a Loan product, 1000 principal, across 3 installment
     // 2. Submit the loan, and check the generated repayment schedule
@@ -2183,7 +2183,7 @@ public class 
AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
             final Account incomeAccount = accountHelper.createIncomeAccount();
             final Account expenseAccount = 
accountHelper.createExpenseAccount();
             final Account overpaymentAccount = 
accountHelper.createLiabilityAccount();
-            Integer localLoanProductId = createLoanProduct("1000", "15", "3", 
false, null, false, LoanScheduleType.CUMULATIVE,
+            Integer localLoanProductId = createLoanProduct("1000", "15", "3", 
false, null, false, LoanScheduleType.PROGRESSIVE,
                     LoanScheduleProcessingType.HORIZONTAL, assetAccount, 
incomeAccount, expenseAccount, overpaymentAccount);
             assertNotNull(localLoanProductId);
 
@@ -2310,7 +2310,7 @@ public class 
AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
         });
     }
 
-    // UC111: Advanced payment allocation, cumulative loan schedule handling, 
rounding test
+    // UC111: Advanced payment allocation, progressive loan schedule handling, 
rounding test
     // ADVANCED_PAYMENT_ALLOCATION_STRATEGY
     // 1. Create a Loan product, 40.50 principal, across 4 installment (1 down 
payment, 3 normal installment)
     // 2. Submit the loan, and check the generated repayment schedule
@@ -2322,7 +2322,7 @@ public class 
AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
             final Account incomeAccount = accountHelper.createIncomeAccount();
             final Account expenseAccount = 
accountHelper.createExpenseAccount();
             final Account overpaymentAccount = 
accountHelper.createLiabilityAccount();
-            Integer localLoanProductId = createLoanProduct("40.50", "15", "3", 
true, "25", false, LoanScheduleType.CUMULATIVE,
+            Integer localLoanProductId = createLoanProduct("40.50", "15", "3", 
true, "25", false, LoanScheduleType.PROGRESSIVE,
                     LoanScheduleProcessingType.HORIZONTAL, assetAccount, 
incomeAccount, expenseAccount, overpaymentAccount);
             assertNotNull(localLoanProductId);
 
@@ -3012,6 +3012,27 @@ public class 
AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
         });
     }
 
+    // UC119: Advanced payment allocation with Loan Schedule as Cumulative
+    // ADVANCED_PAYMENT_ALLOCATION_STRATEGY
+    // 1. Create a Loan product with Adv. Pment. Alloc., but the loan schedule 
as Cumulative -> expect validation error
+    @Test
+    public void uc119() {
+        runAt("02 February 2023", () -> {
+            final Account assetAccount = accountHelper.createAssetAccount();
+            final Account incomeAccount = accountHelper.createIncomeAccount();
+            final Account expenseAccount = 
accountHelper.createExpenseAccount();
+            final Account overpaymentAccount = 
accountHelper.createLiabilityAccount();
+            AdvancedPaymentData defaultPaymentAllocation = 
createDefaultPaymentAllocation();
+
+            ArrayList<HashMap<String, Object>> loanProductErrorData = 
createLoanProductGetError("500", "15", "4", false,
+                    LoanScheduleType.CUMULATIVE, 
LoanScheduleProcessingType.HORIZONTAL, defaultPaymentAllocation, assetAccount,
+                    incomeAccount, expenseAccount, overpaymentAccount);
+            assertNotNull(loanProductErrorData);
+            
assertEquals("validation.msg.loanproduct.loanScheduleProcessingType.supported.only.for.progressive.loan.schedule.type",
+                    
loanProductErrorData.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
+        });
+    }
+
     private static void validateLoanSummaryBalances(GetLoansLoanIdResponse 
loanDetails, Double totalOutstanding, Double totalRepayment,
             Double principalOutstanding, Double principalPaid, Double 
totalOverpaid) {
         assertEquals(totalOutstanding, 
loanDetails.getSummary().getTotalOutstanding());
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationWaiveLoanCharges.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationWaiveLoanCharges.java
index 0bcad0276..2a71e7767 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationWaiveLoanCharges.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationWaiveLoanCharges.java
@@ -35,6 +35,8 @@ import 
org.apache.fineract.client.models.PostLoanProductsResponse;
 import org.apache.fineract.client.models.PostLoansLoanIdChargesChargeIdRequest;
 import org.apache.fineract.integrationtests.common.ClientHelper;
 import 
org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
 import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationType;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
@@ -53,7 +55,9 @@ public class AdvancedPaymentAllocationWaiveLoanCharges 
extends BaseLoanIntegrati
             Long loanProductId = createLoanProductWithAdvancedAllocation();
             // Apply and Approve Loan
             Long loanId = applyAndApproveLoan(clientId, loanProductId, "01 
January 2023", 1000.0, 1,
-                    (req) -> 
req.setTransactionProcessingStrategyCode(ADVANCED_PAYMENT_ALLOCATION_STRATEGY));
+                    (req) -> 
req.transactionProcessingStrategyCode(ADVANCED_PAYMENT_ALLOCATION_STRATEGY)
+                            
.loanScheduleType(LoanScheduleType.PROGRESSIVE.toString())
+                            
.loanScheduleProcessingType(LoanScheduleProcessingType.HORIZONTAL.toString()));
             // Disburse Loan
             disburseLoan(loanId, BigDecimal.valueOf(1000.00), "01 January 
2023");
             // Add Penalty
@@ -85,7 +89,9 @@ public class AdvancedPaymentAllocationWaiveLoanCharges 
extends BaseLoanIntegrati
             Long loanProductId = createLoanProductWithAdvancedAllocation();
             // Apply and Approve Loan
             Long loanId = applyAndApproveLoan(clientId, loanProductId, "01 
January 2023", 1000.0, 1,
-                    (req) -> 
req.setTransactionProcessingStrategyCode(ADVANCED_PAYMENT_ALLOCATION_STRATEGY));
+                    (req) -> 
req.transactionProcessingStrategyCode(ADVANCED_PAYMENT_ALLOCATION_STRATEGY)
+                            
.loanScheduleType(LoanScheduleType.PROGRESSIVE.toString())
+                            
.loanScheduleProcessingType(LoanScheduleProcessingType.HORIZONTAL.toString()));
             // Disburse Loan
             disburseLoan(loanId, BigDecimal.valueOf(1000.00), "01 January 
2023");
             // Add Penalty
@@ -117,8 +123,10 @@ public class AdvancedPaymentAllocationWaiveLoanCharges 
extends BaseLoanIntegrati
             Long loanProductId = createLoanProductWithAdvancedAllocation();
             // Apply and Approve Loan
             Long loanId = applyAndApproveLoan(clientId, loanProductId, "01 
January 2023", 1000.0, 1,
-                    (req) -> 
req.setTransactionProcessingStrategyCode(ADVANCED_PAYMENT_ALLOCATION_STRATEGY));
-            // Disburse Loan
+                    (req) -> 
req.transactionProcessingStrategyCode(ADVANCED_PAYMENT_ALLOCATION_STRATEGY)
+                            
.loanScheduleType(LoanScheduleType.PROGRESSIVE.toString())
+                            
.loanScheduleProcessingType(LoanScheduleProcessingType.HORIZONTAL.toString())); 
// Disburse
+                                                                               
                             // Loan
             disburseLoan(loanId, BigDecimal.valueOf(1000.00), "01 January 
2023");
 
             // set business date to
@@ -180,7 +188,9 @@ public class AdvancedPaymentAllocationWaiveLoanCharges 
extends BaseLoanIntegrati
 
     protected Long createLoanProductWithAdvancedAllocation() {
         PostLoanProductsRequest req = 
createOnePeriod30DaysLongNoInterestPeriodicAccrualProduct();
-        
req.setTransactionProcessingStrategyCode(ADVANCED_PAYMENT_ALLOCATION_STRATEGY);
+        
req.transactionProcessingStrategyCode(ADVANCED_PAYMENT_ALLOCATION_STRATEGY)
+                .loanScheduleType(LoanScheduleType.PROGRESSIVE.toString())
+                
.loanScheduleProcessingType(LoanScheduleProcessingType.HORIZONTAL.toString());
         
req.addPaymentAllocationItem(createDefaultPaymentAllocationWithMixedGrouping());
         PostLoanProductsResponse loanProduct = 
loanTransactionHelper.createLoanProduct(req);
         return loanProduct.getResourceId();
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java
index 12a7a81de..e04e414b0 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java
@@ -71,6 +71,8 @@ import 
org.apache.fineract.integrationtests.common.loans.LoanProductHelper;
 import 
org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
 import 
org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension;
 import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
 import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationType;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -145,6 +147,7 @@ public abstract class BaseLoanIntegrationTest {
                 .interestCalculationPeriodType(1)//
                 .transactionProcessingStrategyCode(
                         
LoanProductTestBuilder.DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST_STRATEGY)//
+                .loanScheduleType(LoanScheduleType.CUMULATIVE.toString()) //
                 .daysInYearType(1)//
                 .daysInMonthType(1)//
                 .canDefineInstallmentAmount(true)//
@@ -206,6 +209,8 @@ public abstract class BaseLoanIntegrationTest {
 
         return createOnePeriod30DaysLongNoInterestPeriodicAccrualProduct() //
                 
.transactionProcessingStrategyCode("advanced-payment-allocation-strategy")//
+                .loanScheduleType(LoanScheduleType.PROGRESSIVE.toString()) //
+                
.loanScheduleProcessingType(LoanScheduleProcessingType.HORIZONTAL.toString()) //
                 .addPaymentAllocationItem(defaultAllocation);
     }
 
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanCreditBalanceRefundandRepaymentTypeIntegrationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanCreditBalanceRefundandRepaymentTypeIntegrationTest.java
index 9a61b658c..a08af46ba 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanCreditBalanceRefundandRepaymentTypeIntegrationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanCreditBalanceRefundandRepaymentTypeIntegrationTest.java
@@ -50,6 +50,7 @@ import 
org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
 import org.apache.fineract.integrationtests.common.loans.LoanStatusChecker;
 import 
org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension;
 import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
 import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationType;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
@@ -735,6 +736,7 @@ public class 
ClientLoanCreditBalanceRefundandRepaymentTypeIntegrationTest extend
         return Stream.of(Arguments.of(Named.of("DEFAULT_STRATEGY", new 
LoanProductTestBuilder().withRepaymentStrategy(DEFAULT_STRATEGY))),
                 Arguments.of(Named.of("ADVANCED_PAYMENT_ALLOCATION_STRATEGY",
                         new 
LoanProductTestBuilder().withRepaymentStrategy(ADVANCED_PAYMENT_ALLOCATION_STRATEGY)
+                                
.withLoanScheduleType(LoanScheduleType.PROGRESSIVE)
                                 
.addAdvancedPaymentAllocation(createDefaultPaymentAllocation(), 
createRepaymentPaymentAllocation()))));
     }
 
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/DelinquencyAndChargebackIntegrationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/DelinquencyAndChargebackIntegrationTest.java
index 0b6dfd6ba..54f2b8fee 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/DelinquencyAndChargebackIntegrationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/DelinquencyAndChargebackIntegrationTest.java
@@ -59,6 +59,7 @@ import 
org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtens
 import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
 import 
org.apache.fineract.integrationtests.common.products.DelinquencyBucketsHelper;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
 import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationType;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Named;
@@ -422,6 +423,7 @@ public class DelinquencyAndChargebackIntegrationTest {
         return Stream.of(Arguments.of(Named.of("DEFAULT_STRATEGY", new 
LoanProductTestBuilder().withRepaymentStrategy(DEFAULT_STRATEGY))),
                 Arguments.of(Named.of("ADVANCED_PAYMENT_ALLOCATION_STRATEGY",
                         new 
LoanProductTestBuilder().withRepaymentStrategy(ADVANCED_PAYMENT_ALLOCATION_STRATEGY)
+                                
.withLoanScheduleType(LoanScheduleType.PROGRESSIVE)
                                 
.addAdvancedPaymentAllocation(createDefaultPaymentAllocation(), 
createRepaymentPaymentAllocation()))));
     }
 
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountChargeOffWithAdvancedPaymentAllocationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountChargeOffWithAdvancedPaymentAllocationTest.java
index ecbc6970e..7f478bbcc 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountChargeOffWithAdvancedPaymentAllocationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountChargeOffWithAdvancedPaymentAllocationTest.java
@@ -71,6 +71,8 @@ import 
org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtens
 import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
 import 
org.apache.fineract.integrationtests.common.products.DelinquencyBucketsHelper;
 import org.apache.fineract.integrationtests.common.system.CodeHelper;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
 import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationType;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
@@ -675,6 +677,8 @@ public class 
LoanAccountChargeOffWithAdvancedPaymentAllocationTest extends BaseL
                 .isEqualAmortization(false)//
                 .interestCalculationPeriodType(1)//
                 
.transactionProcessingStrategyCode("advanced-payment-allocation-strategy")//
+                .loanScheduleType(LoanScheduleType.PROGRESSIVE.toString())//
+                
.loanScheduleProcessingType(LoanScheduleProcessingType.HORIZONTAL.toString())//
                 .addPaymentAllocationItem(defaultAllocation)//
                 .daysInYearType(1)//
                 .daysInMonthType(1)//
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountChargeReveseReplayWithAdvancedPaymentAllocationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountChargeReveseReplayWithAdvancedPaymentAllocationTest.java
index 10e264d0d..52194eb57 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountChargeReveseReplayWithAdvancedPaymentAllocationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountChargeReveseReplayWithAdvancedPaymentAllocationTest.java
@@ -69,6 +69,8 @@ import 
org.apache.fineract.integrationtests.common.loans.LoanProductHelper;
 import 
org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension;
 import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
 import 
org.apache.fineract.integrationtests.common.products.DelinquencyBucketsHelper;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
 import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationType;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
@@ -431,7 +433,9 @@ public class 
LoanAccountChargeReveseReplayWithAdvancedPaymentAllocationTest {
                 .interestType(0)//
                 .isEqualAmortization(false)//
                 .interestCalculationPeriodType(1)//
-                
.transactionProcessingStrategyCode("mifos-standard-strategy").daysInYearType(1)//
+                .transactionProcessingStrategyCode("mifos-standard-strategy")//
+                .loanScheduleType(LoanScheduleType.CUMULATIVE.toString())//
+                .daysInYearType(1)//
                 .daysInMonthType(1)//
                 .canDefineInstallmentAmount(true)//
                 .graceOnArrearsAgeing(3)//
@@ -494,6 +498,8 @@ public class 
LoanAccountChargeReveseReplayWithAdvancedPaymentAllocationTest {
 
             loanProductsRequest //
                     
.transactionProcessingStrategyCode("advanced-payment-allocation-strategy")//
+                    
.loanScheduleType(LoanScheduleType.PROGRESSIVE.toString())//
+                    
.loanScheduleProcessingType(LoanScheduleProcessingType.HORIZONTAL.toString())//
                     .addPaymentAllocationItem(defaultAllocation);
         }
 
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanCatchUpIntegrationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanCatchUpIntegrationTest.java
index a4ce399b9..5aa7e3736 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanCatchUpIntegrationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanCatchUpIntegrationTest.java
@@ -48,6 +48,7 @@ import 
org.apache.fineract.integrationtests.common.loans.LoanStatusChecker;
 import 
org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension;
 import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
 import 
org.apache.fineract.integrationtests.useradministration.users.UserHelper;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
 import org.apache.http.HttpStatus;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
@@ -154,7 +155,7 @@ public class LoanCatchUpIntegrationTest {
         final String loanProductJSON = new 
LoanProductTestBuilder().withPrincipal("15,000.00").withNumberOfRepayments("4")
                 
.withRepaymentAfterEvery("1").withRepaymentTypeAsMonth().withinterestRatePerPeriod("1")
                 
.withInterestRateFrequencyTypeAsMonths().withAmortizationTypeAsEqualInstallments().withInterestTypeAsDecliningBalance()
-                .build(chargeId);
+                
.withLoanScheduleType(LoanScheduleType.CUMULATIVE).build(chargeId);
         return this.loanTransactionHelper.getLoanProductId(loanProductJSON);
     }
 
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargePaymentWithAdvancedPaymentAllocationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargePaymentWithAdvancedPaymentAllocationTest.java
index 737d6c55c..4cdc88609 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargePaymentWithAdvancedPaymentAllocationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargePaymentWithAdvancedPaymentAllocationTest.java
@@ -64,6 +64,8 @@ import 
org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper;
 import 
org.apache.fineract.integrationtests.common.savings.SavingsProductHelper;
 import 
org.apache.fineract.integrationtests.common.savings.SavingsStatusChecker;
 import 
org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.AdvancedPaymentScheduleTransactionProcessor;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
 import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationType;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Assertions;
@@ -258,6 +260,7 @@ public class 
LoanChargePaymentWithAdvancedPaymentAllocationTest {
                 
.withRepaymentTypeAsDays().withRepaymentAfterEvery(repaymentAfterEvery).withNumberOfRepayments(numberOfRepayments)
                 .withEnableDownPayment(true, "25", 
true).withinterestRatePerPeriod("0").withInterestRateFrequencyTypeAsMonths()
                 
.withRepaymentStrategy(AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY)
+                
.withLoanScheduleType(LoanScheduleType.PROGRESSIVE).withLoanScheduleProcessingType(LoanScheduleProcessingType.HORIZONTAL)
                 
.withAmortizationTypeAsEqualPrincipalPayment().withInterestTypeAsFlat().withAccountingRulePeriodicAccrual(accounts)
                 .addAdvancedPaymentAllocation(defaultAllocation, 
goodwillCreditAllocation, merchantIssuedRefundAllocation,
                         payoutRefundAllocation)
@@ -272,10 +275,12 @@ public class 
LoanChargePaymentWithAdvancedPaymentAllocationTest {
         return loanTransactionHelper.applyLoan(new 
PostLoansRequest().clientId(clientId).productId(loanProductId.longValue())
                 
.expectedDisbursementDate(expectedDisbursementDate).dateFormat(DATETIME_PATTERN)
                 
.transactionProcessingStrategyCode(AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY)
-                
.locale("en").submittedOnDate(submittedOnDate).amortizationType(1).interestRatePerPeriod(interestRate)
-                
.interestCalculationPeriodType(1).interestType(0).repaymentFrequencyType(0).repaymentEvery(repaymentAfterEvery)
-                
.repaymentFrequencyType(0).numberOfRepayments(numberOfRepayments).loanTermFrequency(loanTermFrequency)
-                
.loanTermFrequencyType(0).principal(BigDecimal.valueOf(principal)).loanType("individual"));
+                .loanScheduleType(LoanScheduleType.PROGRESSIVE.toString())
+                
.loanScheduleProcessingType(LoanScheduleProcessingType.HORIZONTAL.toString()).locale("en").submittedOnDate(submittedOnDate)
+                
.amortizationType(1).interestRatePerPeriod(interestRate).interestCalculationPeriodType(1).interestType(0)
+                
.repaymentFrequencyType(0).repaymentEvery(repaymentAfterEvery).repaymentFrequencyType(0)
+                
.numberOfRepayments(numberOfRepayments).loanTermFrequency(loanTermFrequency).loanTermFrequencyType(0)
+                
.principal(BigDecimal.valueOf(principal)).loanType("individual"));
     }
 
     private String updateLoanJson(final Integer clientID, final Integer 
loanProductID, String savingsId) {
@@ -297,6 +302,8 @@ public class 
LoanChargePaymentWithAdvancedPaymentAllocationTest {
                 .withRepaymentFrequencyTypeAsDays() //
                 .withInterestRatePerPeriod("0") //
                 
.withRepaymentStrategy(AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY)
+                .withLoanScheduleType(LoanScheduleType.PROGRESSIVE.toString()) 
//
+                
.withLoanScheduleProcessingType(LoanScheduleProcessingType.HORIZONTAL.toString())
 //
                 .withAmortizationTypeAsEqualInstallments() //
                 .withInterestTypeAsDecliningBalance() //
                 .withInterestCalculationPeriodTypeSameAsRepaymentPeriod() //
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargebackOnPaymentTypeRepaymentTransactionsTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargebackOnPaymentTypeRepaymentTransactionsTest.java
index 3fc6d2e34..ce76087d8 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargebackOnPaymentTypeRepaymentTransactionsTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargebackOnPaymentTypeRepaymentTransactionsTest.java
@@ -51,6 +51,7 @@ import 
org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
 import 
org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension;
 import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
 import 
org.apache.fineract.integrationtests.common.products.DelinquencyBucketsHelper;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
 import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationType;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Named;
@@ -328,6 +329,7 @@ public class 
LoanChargebackOnPaymentTypeRepaymentTransactionsTest {
         return Stream.of(Arguments.of(Named.of("DEFAULT_STRATEGY", new 
LoanProductTestBuilder().withRepaymentStrategy(DEFAULT_STRATEGY))),
                 Arguments.of(Named.of("ADVANCED_PAYMENT_ALLOCATION_STRATEGY",
                         new 
LoanProductTestBuilder().withRepaymentStrategy(ADVANCED_PAYMENT_ALLOCATION_STRATEGY)
+                                
.withLoanScheduleType(LoanScheduleType.PROGRESSIVE)
                                 
.addAdvancedPaymentAllocation(createDefaultPaymentAllocation(), 
createRepaymentPaymentAllocation()))));
     }
 
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanPostChargeOffScenariosTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanPostChargeOffScenariosTest.java
index d7bff32ec..ae34f6d59 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanPostChargeOffScenariosTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanPostChargeOffScenariosTest.java
@@ -64,6 +64,7 @@ import 
org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtens
 import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
 import 
org.apache.fineract.integrationtests.common.products.DelinquencyBucketsHelper;
 import org.apache.fineract.integrationtests.common.system.CodeHelper;
+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.Disabled;
@@ -1185,6 +1186,7 @@ public class LoanPostChargeOffScenariosTest {
                 .isEqualAmortization(false)//
                 .interestCalculationPeriodType(1)//
                 .transactionProcessingStrategyCode("mifos-standard-strategy")//
+                .loanScheduleType(LoanScheduleType.CUMULATIVE.toString())//
                 .daysInYearType(1)//
                 .daysInMonthType(1)//
                 .canDefineInstallmentAmount(true)//
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanProductUpdateApiTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanProductUpdateApiTest.java
index 494e6845c..7127f349f 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanProductUpdateApiTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanProductUpdateApiTest.java
@@ -34,6 +34,8 @@ import 
org.apache.fineract.client.models.PutLoanProductsProductIdRequest;
 import org.apache.fineract.integrationtests.common.Utils;
 import 
org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
 import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
 import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationType;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
@@ -139,7 +141,8 @@ public class LoanProductUpdateApiTest {
         String loanProductCreateJSON = new 
LoanProductTestBuilder().withPrincipal("15,000.00").withNumberOfRepayments("4")
                 
.withRepaymentAfterEvery("1").withRepaymentTypeAsMonth().withinterestRatePerPeriod("1")
                 
.withInterestRateFrequencyTypeAsMonths().withAmortizationTypeAsEqualInstallments().withInterestTypeAsDecliningBalance()
-                .addAdvancedPaymentAllocation(advancedPaymentData).build();
+                
.addAdvancedPaymentAllocation(advancedPaymentData).withLoanScheduleType(LoanScheduleType.PROGRESSIVE)
+                
.withLoanScheduleProcessingType(LoanScheduleProcessingType.HORIZONTAL).build();
         return LOAN_TRANSACTION_HELPER.getLoanProductId(loanProductCreateJSON);
 
     }
@@ -149,7 +152,8 @@ public class LoanProductUpdateApiTest {
                 
.withRepaymentAfterEvery("1").withRepaymentTypeAsMonth().withinterestRatePerPeriod("1")
                 
.withInterestRateFrequencyTypeAsMonths().withAmortizationTypeAsEqualInstallments().withInterestTypeAsDecliningBalance()
                 
.withInterestCalculationPeriodTypeAsDays().withAllowPartialPeriodInterestCalculation(false)
-                .addAdvancedPaymentAllocation(advancedPaymentData).build();
+                
.addAdvancedPaymentAllocation(advancedPaymentData).withLoanScheduleType(LoanScheduleType.PROGRESSIVE)
+                
.withLoanScheduleProcessingType(LoanScheduleProcessingType.HORIZONTAL).build();
         return LOAN_TRANSACTION_HELPER.getLoanProductId(loanProductCreateJSON);
 
     }
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanProductWithAdvancedPaymentAllocationIntegrationTests.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanProductWithAdvancedPaymentAllocationIntegrationTests.java
index a899456c7..48c703651 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanProductWithAdvancedPaymentAllocationIntegrationTests.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanProductWithAdvancedPaymentAllocationIntegrationTests.java
@@ -44,6 +44,8 @@ import 
org.apache.fineract.integrationtests.common.accounting.FinancialActivityA
 import 
org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
 import 
org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension;
 import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
 import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationType;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
@@ -238,7 +240,9 @@ public class 
LoanProductWithAdvancedPaymentAllocationIntegrationTests {
                 .withRepaymentTypeAsMonth().withinterestRatePerPeriod("1")
                 .withAccountingRulePeriodicAccrual(new Account[] { 
ASSET_ACCOUNT, EXPENSE_ACCOUNT, INCOME_ACCOUNT, OVERPAYMENT_ACCOUNT })
                 
.withInterestRateFrequencyTypeAsMonths().withAmortizationTypeAsEqualInstallments().withInterestTypeAsDecliningBalance()
-                
.withFeeAndPenaltyAssetAccount(FEE_PENALTY_ACCOUNT).addAdvancedPaymentAllocation(advancedPaymentData).build();
+                
.withFeeAndPenaltyAssetAccount(FEE_PENALTY_ACCOUNT).addAdvancedPaymentAllocation(advancedPaymentData)
+                
.withLoanScheduleType(LoanScheduleType.PROGRESSIVE).withLoanScheduleProcessingType(LoanScheduleProcessingType.HORIZONTAL)
+                .build();
     }
 
     private PutLoanProductsProductIdRequest 
updateLoanProductRequest(AdvancedPaymentData... advancedPaymentData) {
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionChargebackTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionChargebackTest.java
index 5377690b3..6d1c9a159 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionChargebackTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionChargebackTest.java
@@ -61,6 +61,7 @@ import 
org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
 import 
org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension;
 import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
 import 
org.apache.fineract.integrationtests.common.products.DelinquencyBucketsHelper;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
 import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationType;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Named;
@@ -720,6 +721,7 @@ public class LoanTransactionChargebackTest {
         return Stream.of(Arguments.of(Named.of("DEFAULT_STRATEGY", new 
LoanProductTestBuilder().withRepaymentStrategy(DEFAULT_STRATEGY))),
                 Arguments.of(Named.of("ADVANCED_PAYMENT_ALLOCATION_STRATEGY",
                         new 
LoanProductTestBuilder().withRepaymentStrategy(ADVANCED_PAYMENT_ALLOCATION_STRATEGY)
+                                
.withLoanScheduleType(LoanScheduleType.PROGRESSIVE)
                                 
.addAdvancedPaymentAllocation(createDefaultPaymentAllocation(), 
createRepaymentPaymentAllocation()))));
     }
 
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionFullAmountChargebackForOverpaidLoanTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionFullAmountChargebackForOverpaidLoanTest.java
index 13762113c..8fb0b0e45 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionFullAmountChargebackForOverpaidLoanTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionFullAmountChargebackForOverpaidLoanTest.java
@@ -51,6 +51,7 @@ import 
org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
 import 
org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension;
 import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
 import 
org.apache.fineract.integrationtests.common.products.DelinquencyBucketsHelper;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
 import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationType;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Named;
@@ -226,6 +227,7 @@ public class 
LoanTransactionFullAmountChargebackForOverpaidLoanTest {
         return Stream.of(Arguments.of(Named.of("DEFAULT_STRATEGY", new 
LoanProductTestBuilder().withRepaymentStrategy(DEFAULT_STRATEGY))),
                 Arguments.of(Named.of("ADVANCED_PAYMENT_ALLOCATION_STRATEGY",
                         new 
LoanProductTestBuilder().withRepaymentStrategy(ADVANCED_PAYMENT_ALLOCATION_STRATEGY)
+                                
.withLoanScheduleType(LoanScheduleType.PROGRESSIVE)
                                 
.addAdvancedPaymentAllocation(createDefaultPaymentAllocation(), 
createRepaymentPaymentAllocation()))));
     }
 
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanWithAdvancedPaymentAllocationIntegrationTests.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanWithAdvancedPaymentAllocationIntegrationTests.java
index eff7c5073..371cf9e92 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanWithAdvancedPaymentAllocationIntegrationTests.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanWithAdvancedPaymentAllocationIntegrationTests.java
@@ -44,6 +44,8 @@ import 
org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuil
 import 
org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
 import 
org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension;
 import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
 import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationType;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
@@ -132,7 +134,9 @@ public class 
LoanWithAdvancedPaymentAllocationIntegrationTests {
                 .withRepaymentStrategy(ADVANCED_PAYMENT_ALLOCATION_STRATEGY)
                 .withAccountingRulePeriodicAccrual(new Account[] { 
ASSET_ACCOUNT, EXPENSE_ACCOUNT, INCOME_ACCOUNT, OVERPAYMENT_ACCOUNT })
                 
.withInterestRateFrequencyTypeAsMonths().withAmortizationTypeAsEqualInstallments().withInterestTypeAsDecliningBalance()
-                
.withFeeAndPenaltyAssetAccount(FEE_PENALTY_ACCOUNT).addAdvancedPaymentAllocation(advancedPaymentData).build();
+                
.withFeeAndPenaltyAssetAccount(FEE_PENALTY_ACCOUNT).addAdvancedPaymentAllocation(advancedPaymentData)
+                
.withLoanScheduleType(LoanScheduleType.PROGRESSIVE).withLoanScheduleProcessingType(LoanScheduleProcessingType.HORIZONTAL)
+                .build();
         return loanProductJSON;
     }
 
@@ -152,6 +156,8 @@ public class 
LoanWithAdvancedPaymentAllocationIntegrationTests {
                 .withInterestTypeAsDecliningBalance() //
                 .withSubmittedOnDate(operationDate) //
                 .withRepaymentStrategy(ADVANCED_PAYMENT_ALLOCATION_STRATEGY) //
+                .withLoanScheduleType(LoanScheduleType.PROGRESSIVE.toString()) 
//
+                
.withLoanScheduleProcessingType(LoanScheduleProcessingType.HORIZONTAL.toString())
 //
                 .build(clientId, loanProductId, null);
         return loanTransactionHelper.getLoanId(loanApplicationJSON);
     }
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanWriteOffWithAdvancedPaymentAllocationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanWriteOffWithAdvancedPaymentAllocationTest.java
index c7571504f..f4c4e06f9 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanWriteOffWithAdvancedPaymentAllocationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanWriteOffWithAdvancedPaymentAllocationTest.java
@@ -49,6 +49,8 @@ import 
org.apache.fineract.integrationtests.common.charges.ChargesHelper;
 import 
org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder;
 import 
org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
 import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
 import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationType;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
@@ -227,7 +229,8 @@ public class LoanWriteOffWithAdvancedPaymentAllocationTest {
         String loanProductCreateJSON = new 
LoanProductTestBuilder().withPrincipal("15,000.00").withNumberOfRepayments("4")
                 
.withRepaymentAfterEvery("1").withRepaymentTypeAsMonth().withinterestRatePerPeriod("1")
                 
.withInterestRateFrequencyTypeAsMonths().withAmortizationTypeAsEqualInstallments().withInterestTypeAsDecliningBalance()
-                .addAdvancedPaymentAllocation(advancedPaymentData).build();
+                
.addAdvancedPaymentAllocation(advancedPaymentData).withLoanScheduleType(LoanScheduleType.PROGRESSIVE)
+                
.withLoanScheduleProcessingType(LoanScheduleProcessingType.HORIZONTAL).build();
         return LOAN_TRANSACTION_HELPER.getLoanProductId(loanProductCreateJSON);
 
     }
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/RefundForActiveLoansWithAdvancedPaymentAllocationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/RefundForActiveLoansWithAdvancedPaymentAllocationTest.java
index 29c9817fd..77fb17645 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/RefundForActiveLoansWithAdvancedPaymentAllocationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/RefundForActiveLoansWithAdvancedPaymentAllocationTest.java
@@ -498,8 +498,9 @@ public class 
RefundForActiveLoansWithAdvancedPaymentAllocationTest {
                 
.withRepaymentStrategy(AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY)
                 
.withLoanScheduleType(LoanScheduleType.PROGRESSIVE).withLoanScheduleProcessingType(loanScheduleProcessingType)
                 
.withAmortizationTypeAsEqualPrincipalPayment().withInterestTypeAsFlat().withAccountingRulePeriodicAccrual(accounts)
-                
.addAdvancedPaymentAllocation(defaultAllocation).withDaysInMonth("30").withDaysInYear("365").withMoratorium("0",
 "0")
-                .build(null);
+                
.addAdvancedPaymentAllocation(defaultAllocation).withLoanScheduleType(LoanScheduleType.PROGRESSIVE)
+                
.withLoanScheduleProcessingType(LoanScheduleProcessingType.HORIZONTAL).withDaysInMonth("30").withDaysInYear("365")
+                .withMoratorium("0", "0").build(null);
         return loanTransactionHelper.getLoanProductId(loanProductJSON);
     }
 
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/UndoRepaymentWithDownPaymentIntegrationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/UndoRepaymentWithDownPaymentIntegrationTest.java
index 59b0b0e7d..6b8da6b7d 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/UndoRepaymentWithDownPaymentIntegrationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/UndoRepaymentWithDownPaymentIntegrationTest.java
@@ -66,6 +66,8 @@ import 
org.apache.fineract.integrationtests.common.loans.LoanProductHelper;
 import 
org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension;
 import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
 import 
org.apache.fineract.integrationtests.common.products.DelinquencyBucketsHelper;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
+import 
org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
 import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationType;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
@@ -270,8 +272,9 @@ public class UndoRepaymentWithDownPaymentIntegrationTest {
                 .interestType(0)//
                 .isEqualAmortization(false)//
                 .interestCalculationPeriodType(1)//
+                .loanScheduleType(LoanScheduleType.PROGRESSIVE.toString())//
                 
.transactionProcessingStrategyCode("advanced-payment-allocation-strategy")//
-                .addPaymentAllocationItem(defaultAllocation)//
+                
.loanScheduleProcessingType(LoanScheduleProcessingType.HORIZONTAL.toString()).addPaymentAllocationItem(defaultAllocation)//
                 .daysInYearType(1)//
                 .daysInMonthType(1)//
                 .canDefineInstallmentAmount(true)//
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/JournalEntryHelper.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/JournalEntryHelper.java
index a46407468..8eaf1b42f 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/JournalEntryHelper.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/JournalEntryHelper.java
@@ -93,7 +93,9 @@ public class JournalEntryHelper {
                     break;
                 }
             }
-            Assertions.assertTrue(matchFound, "Journal Entry not found");
+            if (entry.getTransactionAmount() > 0) {
+                Assertions.assertTrue(matchFound, "Journal Entry not found");
+            }
         }
     }
 
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanApplicationTestBuilder.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanApplicationTestBuilder.java
index 55e7e95e6..92a6033f5 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanApplicationTestBuilder.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanApplicationTestBuilder.java
@@ -59,6 +59,8 @@ public class LoanApplicationTestBuilder {
     private String amortizationType = EQUAL_PRINCIPAL_PAYMENTS;
     private String interestCalculationPeriodType = 
CALCULATION_PERIOD_SAME_AS_REPAYMENT_PERIOD;
     private String transactionProcessingCode = DEFAULT_STRATEGY;
+    private String loanScheduleProcessingType = null;
+    private String loanScheduleType = null;
     private String expectedDisbursmentDate = "";
     private String submittedOnDate = "";
     private String loanType = "individual";
@@ -158,6 +160,14 @@ public class LoanApplicationTestBuilder {
         map.put("collateral", this.collaterals);
         map.put("interestChargedFromDate", this.interestChargedFromDate);
 
+        if (loanScheduleType != null) {
+            map.put("loanScheduleType", this.loanScheduleType);
+        }
+
+        if (loanScheduleProcessingType != null) {
+            map.put("loanScheduleProcessingType", 
this.loanScheduleProcessingType);
+        }
+
         if (this.externalId != null) {
             map.put("externalId", this.externalId);
         }
@@ -357,6 +367,16 @@ public class LoanApplicationTestBuilder {
         return this;
     }
 
+    public LoanApplicationTestBuilder withLoanScheduleType(final String 
loanScheduleType) {
+        this.loanScheduleType = loanScheduleType;
+        return this;
+    }
+
+    public LoanApplicationTestBuilder withLoanScheduleProcessingType(final 
String loanScheduleProcessingType) {
+        this.loanScheduleProcessingType = loanScheduleProcessingType;
+        return this;
+    }
+
     public LoanApplicationTestBuilder withFirstRepaymentDate(final String 
firstRepaymentDate) {
         this.repaymentsStartingFromDate = firstRepaymentDate;
         return this;
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
index 2c0608dbe..6104bcd91 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
@@ -203,6 +203,9 @@ public class LoanProductTestBuilder {
         map.put("maxPrincipal", this.maxPrincipal);
         map.put("isEqualAmortization", this.isEqualAmortization);
         map.put("overdueDaysForNPA", this.overdueDaysForNPA);
+        map.put("loanScheduleType", loanScheduleType);
+        map.put("loanScheduleProcessingType", loanScheduleProcessingType);
+
         if (this.minimumDaysBetweenDisbursalAndFirstRepayment != null) {
             map.put("minimumDaysBetweenDisbursalAndFirstRepayment", 
this.minimumDaysBetweenDisbursalAndFirstRepayment);
         }
@@ -312,8 +315,6 @@ public class LoanProductTestBuilder {
         if (disableScheduleExtensionForDownPayment) {
             map.put("disableScheduleExtensionForDownPayment", 
disableScheduleExtensionForDownPayment);
         }
-        map.put("loanScheduleType", loanScheduleType);
-        map.put("loanScheduleProcessingType", loanScheduleProcessingType);
 
         return map;
     }

Reply via email to