You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by ad...@apache.org on 2025/04/15 17:45:32 UTC

(fineract) 01/02: FINERACT-2232: Progressive loan income capitalization config

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 7df7be2b16dc3ec4b80dd252d901fc7b49a23052
Author: adam.magyari <ma...@gmail.com>
AuthorDate: Thu Apr 10 09:04:43 2025 +0200

    FINERACT-2232: Progressive loan income capitalization config
---
 .../LoanCapitalizedIncomeCalculationType.java      |  48 +++++++
 .../domain/LoanCapitalizedIncomeStrategy.java      |  47 +++++++
 .../loanschedule/domain/LoanApplicationTerms.java  |  47 ++++++-
 .../loanproduct/LoanProductConstants.java          |   5 +
 .../api/LoanProductsApiResourceSwagger.java        |  34 +++++
 .../loanproduct/data/LoanProductData.java          |  48 ++++++-
 .../portfolio/loanproduct/domain/LoanProduct.java  |   9 +-
 .../domain/LoanProductRelatedDetail.java           |  27 +++-
 .../loanaccount/api/LoansApiResource.java          |   6 +-
 .../loanaccount/api/LoansApiResourceSwagger.java   |  12 ++
 .../loanaccount/data/LoanAccountData.java          |  21 ++-
 .../service/LoanScheduleAssembler.java             |   5 +-
 .../loanaccount/service/LoanProductAssembler.java  |  11 +-
 .../LoanProductRelatedDetailUpdateUtil.java        |  24 ++++
 .../service/LoanReadPlatformServiceImpl.java       |  13 +-
 .../loanproduct/api/LoanProductsApiResource.java   |  13 +-
 .../serialization/LoanProductDataValidator.java    |  45 ++++++-
 .../LoanProductReadPlatformServiceImpl.java        |  16 ++-
 .../db/changelog/tenant/changelog-tenant.xml       |   1 +
 .../tenant/parts/0171_loan_capitalized_income.xml  |  49 +++++++
 .../domain/DefaultScheduledDateGeneratorTest.java  |   5 +-
 .../fineract/integrationtests/LoanProductTest.java | 147 +++++++++++++++++++++
 22 files changed, 601 insertions(+), 32 deletions(-)

diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCapitalizedIncomeCalculationType.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCapitalizedIncomeCalculationType.java
new file mode 100644
index 0000000000..5916b0074e
--- /dev/null
+++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCapitalizedIncomeCalculationType.java
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.portfolio.loanaccount.domain;
+
+import java.util.Arrays;
+import java.util.List;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.fineract.infrastructure.core.data.StringEnumOptionData;
+
+@Getter
+@RequiredArgsConstructor
+public enum LoanCapitalizedIncomeCalculationType {
+
+    FLAT("loanCapitalizedIncomeCalculationType.flat", "Flat");
+
+    private final String code;
+    private final String humanReadableName;
+
+    public static List<StringEnumOptionData> getValuesAsStringEnumOptionDataList() {
+        return Arrays.stream(values()).map(v -> new StringEnumOptionData(v.name(), v.getCode(), v.getHumanReadableName())).toList();
+    }
+
+    public StringEnumOptionData getValueAsStringEnumOptionData() {
+        return new StringEnumOptionData(name(), getCode(), getHumanReadableName());
+    }
+
+    public static StringEnumOptionData getStringEnumOptionData(String name) {
+        return name == null || name.trim().isEmpty() ? null
+                : LoanCapitalizedIncomeCalculationType.valueOf(name).getValueAsStringEnumOptionData();
+    }
+}
diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCapitalizedIncomeStrategy.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCapitalizedIncomeStrategy.java
new file mode 100644
index 0000000000..b0d489ce6b
--- /dev/null
+++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCapitalizedIncomeStrategy.java
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.portfolio.loanaccount.domain;
+
+import java.util.Arrays;
+import java.util.List;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.fineract.infrastructure.core.data.StringEnumOptionData;
+
+@Getter
+@RequiredArgsConstructor
+public enum LoanCapitalizedIncomeStrategy {
+
+    EQUAL_AMORTIZATION("capitalizedIncome.strategy.equalAmortization", "Equal amortization");
+
+    private final String code;
+    private final String humanReadableName;
+
+    public static List<StringEnumOptionData> getValuesAsStringEnumOptionDataList() {
+        return Arrays.stream(values()).map(v -> new StringEnumOptionData(v.name(), v.getCode(), v.getHumanReadableName())).toList();
+    }
+
+    public StringEnumOptionData getValueAsStringEnumOptionData() {
+        return new StringEnumOptionData(name(), getCode(), getHumanReadableName());
+    }
+
+    public static StringEnumOptionData getStringEnumOptionData(String name) {
+        return name == null || name.trim().isEmpty() ? null : LoanCapitalizedIncomeStrategy.valueOf(name).getValueAsStringEnumOptionData();
+    }
+}
diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanApplicationTerms.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanApplicationTerms.java
index 0dcc262483..f517a1b240 100644
--- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanApplicationTerms.java
+++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanApplicationTerms.java
@@ -46,6 +46,8 @@ import org.apache.fineract.portfolio.loanaccount.data.DisbursementData;
 import org.apache.fineract.portfolio.loanaccount.data.HolidayDetailDTO;
 import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsData;
 import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsDataWrapper;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanChargeOffBehaviour;
 import org.apache.fineract.portfolio.loanproduct.data.LoanProductRelatedDetailMinimumData;
 import org.apache.fineract.portfolio.loanproduct.domain.AmortizationMethod;
@@ -232,6 +234,9 @@ public final class LoanApplicationTerms {
     private LoanChargeOffBehaviour chargeOffBehaviour;
     private boolean interestRecognitionOnDisbursementDate;
     private DaysInYearCustomStrategyType daysInYearCustomStrategy;
+    private boolean enableIncomeCapitalization;
+    private LoanCapitalizedIncomeCalculationType capitalizedIncomeCalculationType;
+    private LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy;
 
     private LoanApplicationTerms(Builder builder) {
         this.currency = builder.currency;
@@ -268,6 +273,9 @@ public final class LoanApplicationTerms {
         } else {
             this.downPaymentAmount = Money.zero(getCurrency(), builder.mc);
         }
+        this.enableIncomeCapitalization = builder.enableIncomeCapitalization;
+        this.capitalizedIncomeCalculationType = builder.capitalizedIncomeCalculationType;
+        this.capitalizedIncomeStrategy = builder.capitalizedIncomeStrategy;
     }
 
     public static class Builder {
@@ -297,6 +305,9 @@ public final class LoanApplicationTerms {
         private MathContext mc;
         private Boolean interestRecognitionOnDisbursementDate;
         private DaysInYearCustomStrategyType daysInYearCustomStrategy;
+        private boolean enableIncomeCapitalization;
+        private LoanCapitalizedIncomeCalculationType capitalizedIncomeCalculationType;
+        private LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy;
 
         public Builder currency(CurrencyData currency) {
             this.currency = currency;
@@ -413,6 +424,21 @@ public final class LoanApplicationTerms {
             return this;
         }
 
+        public Builder enableIncomeCapitalization(boolean value) {
+            this.enableIncomeCapitalization = value;
+            return this;
+        }
+
+        public Builder capitalizedIncomeCalculationType(LoanCapitalizedIncomeCalculationType value) {
+            this.capitalizedIncomeCalculationType = value;
+            return this;
+        }
+
+        public Builder capitalizedIncomeStrategy(LoanCapitalizedIncomeStrategy value) {
+            this.capitalizedIncomeStrategy = value;
+            return this;
+        }
+
         public LoanApplicationTerms build() {
             return new LoanApplicationTerms(this);
         }
@@ -480,7 +506,9 @@ public final class LoanApplicationTerms {
             final LoanScheduleProcessingType loanScheduleProcessingType, final Integer fixedLength,
             final boolean enableAccrualActivityPosting, final List<LoanSupportedInterestRefundTypes> supportedInterestRefundTypes,
             final LoanChargeOffBehaviour chargeOffBehaviour, final boolean interestRecognitionOnDisbursementDate,
-            final DaysInYearCustomStrategyType daysInYearCustomStrategy) {
+            final DaysInYearCustomStrategyType daysInYearCustomStrategy, final boolean enableIncomeCapitalization,
+            final LoanCapitalizedIncomeCalculationType capitalizedIncomeCalculationType,
+            final LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy) {
 
         final LoanRescheduleStrategyMethod rescheduleStrategyMethod = null;
         final CalendarHistoryDataWrapper calendarHistoryDataWrapper = null;
@@ -500,7 +528,8 @@ public final class LoanApplicationTerms {
                 isPrincipalCompoundingDisabledForOverdueLoans, enableDownPayment, disbursedAmountPercentageForDownPayment,
                 isAutoRepaymentForDownPaymentEnabled, repaymentStartDateType, submittedOnDate, loanScheduleType, loanScheduleProcessingType,
                 fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes, chargeOffBehaviour,
-                interestRecognitionOnDisbursementDate, daysInYearCustomStrategy);
+                interestRecognitionOnDisbursementDate, daysInYearCustomStrategy, enableIncomeCapitalization,
+                capitalizedIncomeCalculationType, capitalizedIncomeStrategy);
 
     }
 
@@ -574,7 +603,9 @@ public final class LoanApplicationTerms {
                 disbursedAmountPercentageForDownPayment, isAutoRepaymentForDownPaymentEnabled, repaymentStartDateType, submittedOnDate,
                 loanScheduleType, loanScheduleProcessingType, fixedLength, loanProductRelatedDetail.isEnableAccrualActivityPosting(),
                 loanProductRelatedDetail.getSupportedInterestRefundTypes(), loanProductRelatedDetail.getChargeOffBehaviour(),
-                loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate(), loanProductRelatedDetail.getDaysInYearCustomStrategy());
+                loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate(), loanProductRelatedDetail.getDaysInYearCustomStrategy(),
+                loanProductRelatedDetail.isEnableIncomeCapitalization(), loanProductRelatedDetail.getCapitalizedIncomeCalculationType(),
+                loanProductRelatedDetail.getCapitalizedIncomeStrategy());
     }
 
     private LoanApplicationTerms(final CurrencyData currency, final Integer loanTermFrequency,
@@ -605,7 +636,9 @@ public final class LoanApplicationTerms {
             final RepaymentStartDateType repaymentStartDateType, final LocalDate submittedOnDate, final LoanScheduleType loanScheduleType,
             final LoanScheduleProcessingType loanScheduleProcessingType, final Integer fixedLength, boolean enableAccrualActivityPosting,
             final List<LoanSupportedInterestRefundTypes> supportedInterestRefundTypes, final LoanChargeOffBehaviour chargeOffBehaviour,
-            final boolean interestRecognitionOnDisbursementDate, final DaysInYearCustomStrategyType daysInYearCustomStrategy) {
+            final boolean interestRecognitionOnDisbursementDate, final DaysInYearCustomStrategyType daysInYearCustomStrategy,
+            final boolean enableIncomeCapitalization, final LoanCapitalizedIncomeCalculationType capitalizedIncomeCalculationType,
+            final LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy) {
 
         this.currency = currency;
         this.loanTermFrequency = loanTermFrequency;
@@ -707,6 +740,9 @@ public final class LoanApplicationTerms {
         this.chargeOffBehaviour = chargeOffBehaviour;
         this.interestRecognitionOnDisbursementDate = interestRecognitionOnDisbursementDate;
         this.daysInYearCustomStrategy = daysInYearCustomStrategy;
+        this.enableIncomeCapitalization = enableIncomeCapitalization;
+        this.capitalizedIncomeCalculationType = capitalizedIncomeCalculationType;
+        this.capitalizedIncomeStrategy = capitalizedIncomeStrategy;
     }
 
     public Money adjustPrincipalIfLastRepaymentPeriod(final Money principalForPeriod, final Money totalCumulativePrincipalToDate,
@@ -1568,7 +1604,8 @@ public final class LoanApplicationTerms {
                 this.interestRecalculationEnabled, this.isEqualAmortization, this.isDownPaymentEnabled,
                 this.disbursedAmountPercentageForDownPayment, this.isAutoRepaymentForDownPaymentEnabled, this.loanScheduleType,
                 this.loanScheduleProcessingType, this.fixedLength, this.enableAccrualActivityPosting, this.supportedInterestRefundTypes,
-                this.chargeOffBehaviour, this.interestRecognitionOnDisbursementDate, this.daysInYearCustomStrategy);
+                this.chargeOffBehaviour, this.interestRecognitionOnDisbursementDate, this.daysInYearCustomStrategy,
+                this.enableIncomeCapitalization, this.capitalizedIncomeCalculationType, this.capitalizedIncomeStrategy);
     }
 
     public LoanProductMinimumRepaymentScheduleRelatedDetail toLoanProductRelatedDetailMinimumData() {
diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/LoanProductConstants.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/LoanProductConstants.java
index 7ee57241e7..1e803ab0af 100644
--- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/LoanProductConstants.java
+++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/LoanProductConstants.java
@@ -171,4 +171,9 @@ public interface LoanProductConstants {
     String CHARGE_OFF_BEHAVIOUR = "chargeOffBehaviour";
 
     String INTEREST_RECOGNITION_ON_DISBURSEMENT_DATE = "interestRecognitionOnDisbursementDate";
+
+    // Capitalized income
+    String ENABLE_INCOME_CAPITALIZATION_PARAM_NAME = "enableIncomeCapitalization";
+    String CAPITALIZED_INCOME_CALCULATION_TYPE_PARAM_NAME = "capitalizedIncomeCalculationType";
+    String CAPITALIZED_INCOME_STRATEGY_PARAM_NAME = "capitalizedIncomeStrategy";
 }
diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/api/LoanProductsApiResourceSwagger.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/api/LoanProductsApiResourceSwagger.java
index 8e01a143cc..caf9183f79 100644
--- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/api/LoanProductsApiResourceSwagger.java
+++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/api/LoanProductsApiResourceSwagger.java
@@ -195,6 +195,12 @@ public final class LoanProductsApiResourceSwagger {
         public Boolean enableAccrualActivityPosting;
         @Schema(example = "false")
         public Boolean interestRecognitionOnDisbursementDate;
+        @Schema(example = "false")
+        public Boolean enableIncomeCapitalization;
+        @Schema(example = "FLAT", allowableValues = "FLAT")
+        public String capitalizedIncomeCalculationType;
+        @Schema(example = "EQUAL_AMORTIZATION", allowableValues = "EQUAL_AMORTIZATION")
+        public String capitalizedIncomeStrategy;
 
         // Interest Recalculation
         @Schema(example = "false")
@@ -651,6 +657,12 @@ public final class LoanProductsApiResourceSwagger {
         public StringEnumOptionData chargeOffBehaviour;
         @Schema(example = "false")
         public Boolean interestRecognitionOnDisbursementDate;
+        @Schema(example = "false")
+        public Boolean enableIncomeCapitalization;
+        @Schema(example = "FLAT")
+        public StringEnumOptionData capitalizedIncomeCalculationType;
+        @Schema(example = "EQUAL_AMORTIZATION")
+        public StringEnumOptionData capitalizedIncomeStrategy;
     }
 
     @Schema(description = "GetLoanProductsTemplateResponse")
@@ -1097,6 +1109,14 @@ public final class LoanProductsApiResourceSwagger {
         public List<GetLoanProductsChargeOffReasonOptions> chargeOffReasonOptions;
         public StringEnumOptionData chargeOffBehaviour;
         public List<StringEnumOptionData> chargeOffBehaviourOptions;
+        @Schema(example = "false")
+        public Boolean enableIncomeCapitalization;
+        @Schema(example = "FLAT")
+        public StringEnumOptionData capitalizedIncomeCalculationType;
+        @Schema(example = "EQUAL_AMORTIZATION")
+        public StringEnumOptionData capitalizedIncomeStrategy;
+        public List<StringEnumOptionData> capitalizedIncomeCalculationTypeOptions;
+        public List<StringEnumOptionData> capitalizedIncomeStrategyOptions;
     }
 
     @Schema(description = "GetLoanProductsProductIdResponse")
@@ -1416,6 +1436,14 @@ public final class LoanProductsApiResourceSwagger {
         public StringEnumOptionData chargeOffBehaviour;
         @Schema(example = "false")
         public Boolean interestRecognitionOnDisbursementDate;
+        @Schema(example = "false")
+        public Boolean enableIncomeCapitalization;
+        @Schema(example = "FLAT")
+        public StringEnumOptionData capitalizedIncomeCalculationType;
+        @Schema(example = "EQUAL_AMORTIZATION")
+        public StringEnumOptionData capitalizedIncomeStrategy;
+        public List<StringEnumOptionData> capitalizedIncomeCalculationTypeOptions;
+        public List<StringEnumOptionData> capitalizedIncomeStrategyOptions;
     }
 
     @Schema(description = "PutLoanProductsProductIdRequest")
@@ -1669,6 +1697,12 @@ public final class LoanProductsApiResourceSwagger {
         public List<String> supportedInterestRefundTypes;
         @Schema(example = "REGULAR")
         public String chargeOffBehaviour;
+        @Schema(example = "false")
+        public Boolean enableIncomeCapitalization;
+        @Schema(example = "FLAT", allowableValues = "FLAT")
+        public String capitalizedIncomeCalculationType;
+        @Schema(example = "EQUAL_AMORTIZATION", allowableValues = "EQUAL_AMORTIZATION")
+        public String capitalizedIncomeStrategy;
     }
 
     public static final class AdvancedPaymentData {
diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/data/LoanProductData.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/data/LoanProductData.java
index bd579d9840..4ed7c23820 100644
--- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/data/LoanProductData.java
+++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/data/LoanProductData.java
@@ -48,6 +48,8 @@ import org.apache.fineract.portfolio.delinquency.data.DelinquencyBucketData;
 import org.apache.fineract.portfolio.floatingrates.data.FloatingRateData;
 import org.apache.fineract.portfolio.fund.data.FundData;
 import org.apache.fineract.portfolio.loanaccount.data.LoanInterestRecalculationData;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanChargeOffBehaviour;
 import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
 import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
@@ -238,6 +240,11 @@ public class LoanProductData implements Serializable {
     private final boolean interestRecognitionOnDisbursementDate;
     private final List<StringEnumOptionData> daysInYearCustomStrategyOptions;
     private final StringEnumOptionData daysInYearCustomStrategy;
+    private Boolean enableIncomeCapitalization;
+    private StringEnumOptionData capitalizedIncomeCalculationType;
+    private StringEnumOptionData capitalizedIncomeStrategy;
+    private List<StringEnumOptionData> capitalizedIncomeCalculationTypeOptions;
+    private List<StringEnumOptionData> capitalizedIncomeStrategyOptions;
 
     /**
      * Used when returning lookup information about loan product for dropdowns.
@@ -342,6 +349,9 @@ public class LoanProductData implements Serializable {
         final StringEnumOptionData chargeOffBehaviour = null;
         final boolean interestRecognitionOnDisbursementDate = false;
         final StringEnumOptionData daysInYearTypeCustomStrategy = null;
+        final boolean enableIncomeCapitalization = false;
+        final StringEnumOptionData capitalizedIncomeCalculationType = null;
+        final StringEnumOptionData capitalizedIncomeStrategy = null;
 
         return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
                 numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
@@ -363,7 +373,8 @@ public class LoanProductData implements Serializable {
                 overDueDaysForRepaymentEvent, enableDownPayment, disbursedAmountPercentageDownPayment, enableAutoRepaymentForDownPayment,
                 paymentAllocation, creditAllocation, repaymentStartDateType, enableInstallmentLevelDelinquency, loanScheduleType,
                 loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes, chargeOffBehaviour,
-                interestRecognitionOnDisbursementDate, daysInYearTypeCustomStrategy);
+                interestRecognitionOnDisbursementDate, daysInYearTypeCustomStrategy, enableIncomeCapitalization,
+                capitalizedIncomeCalculationType, capitalizedIncomeStrategy);
 
     }
 
@@ -468,6 +479,9 @@ public class LoanProductData implements Serializable {
         final StringEnumOptionData chargeOffBehaviour = null;
         final boolean interestRecognitionOnDisbursementDate = false;
         final StringEnumOptionData daysInYearTypeCustomStrategy = null;
+        final boolean enableIncomeCapitalization = false;
+        final StringEnumOptionData capitalizedIncomeCalculationType = null;
+        final StringEnumOptionData capitalizedIncomeStrategy = null;
 
         return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
                 numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
@@ -489,7 +503,8 @@ public class LoanProductData implements Serializable {
                 overDueDaysForRepaymentEvent, enableDownPayment, disbursedAmountPercentageDownPayment, enableAutoRepaymentForDownPayment,
                 paymentAllocation, creditAllocation, repaymentStartDateType, enableInstallmentLevelDelinquency, loanScheduleType,
                 loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes, chargeOffBehaviour,
-                interestRecognitionOnDisbursementDate, daysInYearTypeCustomStrategy);
+                interestRecognitionOnDisbursementDate, daysInYearTypeCustomStrategy, enableIncomeCapitalization,
+                capitalizedIncomeCalculationType, capitalizedIncomeStrategy);
 
     }
 
@@ -601,6 +616,9 @@ public class LoanProductData implements Serializable {
         final StringEnumOptionData chargeOffBehaviour = LoanChargeOffBehaviour.REGULAR.getValueAsStringEnumOptionData();
         final boolean interestRecognitionOnDisbursementDate = false;
         final StringEnumOptionData daysInYearTypeCustomStrategy = null;
+        final boolean enableIncomeCapitalization = false;
+        final StringEnumOptionData capitalizedIncomeCalculationType = null;
+        final StringEnumOptionData capitalizedIncomeStrategy = null;
 
         return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
                 numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
@@ -622,7 +640,8 @@ public class LoanProductData implements Serializable {
                 overDueDaysForRepaymentEvent, enableDownPayment, disbursedAmountPercentageDownPayment, enableAutoRepaymentForDownPayment,
                 paymentAllocation, creditAllocation, repaymentStartDateType, enableInstallmentLevelDelinquency, loanScheduleType,
                 loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes, chargeOffBehaviour,
-                interestRecognitionOnDisbursementDate, daysInYearTypeCustomStrategy);
+                interestRecognitionOnDisbursementDate, daysInYearTypeCustomStrategy, enableIncomeCapitalization,
+                capitalizedIncomeCalculationType, capitalizedIncomeStrategy);
 
     }
 
@@ -728,6 +747,9 @@ public class LoanProductData implements Serializable {
         final StringEnumOptionData chargeOffBehaviour = null;
         final boolean interestRecognitionOnDisbursementDate = false;
         final StringEnumOptionData daysInYearTypeCustomStrategy = null;
+        final boolean enableIncomeCapitalization = false;
+        final StringEnumOptionData capitalizedIncomeCalculationType = null;
+        final StringEnumOptionData capitalizedIncomeStrategy = null;
 
         return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
                 numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
@@ -749,7 +771,8 @@ public class LoanProductData implements Serializable {
                 overDueDaysForRepaymentEvent, enableDownPayment, disbursedAmountPercentageDownPayment, enableAutoRepaymentForDownPayment,
                 paymentAllocation, creditAllocationData, repaymentStartDateType, enableInstallmentLevelDelinquency, loanScheduleType,
                 loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes, chargeOffBehaviour,
-                interestRecognitionOnDisbursementDate, daysInYearTypeCustomStrategy);
+                interestRecognitionOnDisbursementDate, daysInYearTypeCustomStrategy, enableIncomeCapitalization,
+                capitalizedIncomeCalculationType, capitalizedIncomeStrategy);
     }
 
     public static LoanProductData withAccountingDetails(final LoanProductData productData, final Map<String, Object> accountingMappings,
@@ -804,7 +827,8 @@ public class LoanProductData implements Serializable {
             final EnumOptionData loanScheduleType, final EnumOptionData loanScheduleProcessingType, final Integer fixedLength,
             final boolean enableAccrualActivityPosting, final List<StringEnumOptionData> supportedInterestRefundTypes,
             StringEnumOptionData chargeOffBehaviour, final boolean interestRecognitionOnDisbursementDate,
-            final StringEnumOptionData daysInYearCustomStrategy) {
+            final StringEnumOptionData daysInYearCustomStrategy, final boolean enableIncomeCapitalization,
+            final StringEnumOptionData capitalizedIncomeCalculationType, final StringEnumOptionData capitalizedIncomeStrategy) {
         this.id = id;
         this.name = name;
         this.shortName = shortName;
@@ -861,6 +885,9 @@ public class LoanProductData implements Serializable {
         this.rates = rates;
         this.isRatesEnabled = isRatesEnabled;
         this.daysInYearCustomStrategy = daysInYearCustomStrategy;
+        this.enableIncomeCapitalization = enableIncomeCapitalization;
+        this.capitalizedIncomeCalculationType = capitalizedIncomeCalculationType;
+        this.capitalizedIncomeStrategy = capitalizedIncomeStrategy;
 
         this.chargeOptions = null;
         this.penaltyOptions = null;
@@ -950,6 +977,8 @@ public class LoanProductData implements Serializable {
         this.chargeOffReasonOptions = null;
         this.interestRecognitionOnDisbursementDate = interestRecognitionOnDisbursementDate;
         this.daysInYearCustomStrategyOptions = DaysInYearCustomStrategyType.getValuesAsStringEnumOptionDataList();
+        this.capitalizedIncomeCalculationTypeOptions = LoanCapitalizedIncomeCalculationType.getValuesAsStringEnumOptionDataList();
+        this.capitalizedIncomeStrategyOptions = LoanCapitalizedIncomeStrategy.getValuesAsStringEnumOptionDataList();
     }
 
     public LoanProductData(final LoanProductData productData, final Collection<ChargeData> chargeOptions,
@@ -974,7 +1003,9 @@ public class LoanProductData implements Serializable {
             final List<EnumOptionData> creditAllocationAllocationTypes,
             final List<StringEnumOptionData> supportedInterestRefundTypesOptions,
             final List<StringEnumOptionData> chargeOffBehaviourOptions, final List<CodeValueData> chargeOffReasonOptions,
-            final List<StringEnumOptionData> daysInYearCustomStrategyOptions) {
+            final List<StringEnumOptionData> daysInYearCustomStrategyOptions,
+            final List<StringEnumOptionData> capitalizedIncomeCalculationTypeOptions,
+            final List<StringEnumOptionData> capitalizedIncomeStrategyOptions) {
 
         this.id = productData.id;
         this.name = productData.name;
@@ -1138,6 +1169,11 @@ public class LoanProductData implements Serializable {
         this.interestRecognitionOnDisbursementDate = productData.interestRecognitionOnDisbursementDate;
         this.daysInYearCustomStrategyOptions = daysInYearCustomStrategyOptions;
         this.daysInYearCustomStrategy = productData.daysInYearCustomStrategy;
+        this.enableIncomeCapitalization = productData.enableIncomeCapitalization;
+        this.capitalizedIncomeCalculationType = productData.capitalizedIncomeCalculationType;
+        this.capitalizedIncomeStrategy = productData.capitalizedIncomeStrategy;
+        this.capitalizedIncomeCalculationTypeOptions = capitalizedIncomeCalculationTypeOptions;
+        this.capitalizedIncomeStrategyOptions = capitalizedIncomeStrategyOptions;
     }
 
     private Collection<ChargeData> nullIfEmpty(final Collection<ChargeData> charges) {
diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProduct.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProduct.java
index c9b85ac25f..31e4ab8a1d 100644
--- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProduct.java
+++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProduct.java
@@ -59,6 +59,8 @@ import org.apache.fineract.portfolio.floatingrates.data.FloatingRateDTO;
 import org.apache.fineract.portfolio.floatingrates.data.FloatingRatePeriodData;
 import org.apache.fineract.portfolio.floatingrates.domain.FloatingRate;
 import org.apache.fineract.portfolio.fund.domain.Fund;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanChargeOffBehaviour;
 import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
 import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
@@ -280,7 +282,9 @@ public class LoanProduct extends AbstractPersistableCustom<Long> {
             final LoanScheduleProcessingType loanScheduleProcessingType, final Integer fixedLength,
             final boolean enableAccrualActivityPosting, final List<LoanSupportedInterestRefundTypes> supportedInterestRefundTypes,
             final LoanChargeOffBehaviour chargeOffBehaviour, final boolean isInterestRecognitionOnDisbursementDate,
-            final DaysInYearCustomStrategyType daysInYearCustomStrategy) {
+            final DaysInYearCustomStrategyType daysInYearCustomStrategy, final boolean enableIncomeCapitalization,
+            final LoanCapitalizedIncomeCalculationType capitalizedIncomeCalculationType,
+            final LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy) {
         this.fund = fund;
         this.transactionProcessingStrategyCode = transactionProcessingStrategyCode;
 
@@ -330,7 +334,8 @@ public class LoanProduct extends AbstractPersistableCustom<Long> {
                 inArrearsTolerance, graceOnArrearsAgeing, daysInMonthType.getValue(), daysInYearType.getValue(),
                 isInterestRecalculationEnabled, isEqualAmortization, enableDownPayment, disbursedAmountPercentageForDownPayment,
                 enableAutoRepaymentForDownPayment, loanScheduleType, loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting,
-                supportedInterestRefundTypes, chargeOffBehaviour, isInterestRecognitionOnDisbursementDate, daysInYearCustomStrategy);
+                supportedInterestRefundTypes, chargeOffBehaviour, isInterestRecognitionOnDisbursementDate, daysInYearCustomStrategy,
+                enableIncomeCapitalization, capitalizedIncomeCalculationType, capitalizedIncomeStrategy);
 
         this.loanProductMinMaxConstraints = new LoanProductMinMaxConstraints(defaultMinPrincipal, defaultMaxPrincipal,
                 defaultMinNominalInterestRatePerPeriod, defaultMaxNominalInterestRatePerPeriod, defaultMinNumberOfInstallments,
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 a1a68ae214..29b18e6cea 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
@@ -36,6 +36,8 @@ import org.apache.fineract.portfolio.common.domain.DaysInYearCustomStrategyType;
 import org.apache.fineract.portfolio.common.domain.DaysInYearType;
 import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
 import org.apache.fineract.portfolio.loanaccount.domain.Loan;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanChargeOffBehaviour;
 import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
 import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
@@ -168,6 +170,17 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
     @Column(name = "days_in_year_custom_strategy")
     private DaysInYearCustomStrategyType daysInYearCustomStrategy;
 
+    @Column(name = "enable_income_capitalization")
+    private boolean enableIncomeCapitalization = false;
+
+    @Enumerated(EnumType.STRING)
+    @Column(name = "capitalized_income_calculation_type")
+    private LoanCapitalizedIncomeCalculationType capitalizedIncomeCalculationType;
+
+    @Enumerated(EnumType.STRING)
+    @Column(name = "capitalized_income_strategy")
+    private LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy;
+
     public static LoanProductRelatedDetail createFrom(final CurrencyData currencyData, final BigDecimal principal,
             final BigDecimal nominalInterestRatePerPeriod, final PeriodFrequencyType interestRatePeriodFrequencyType,
             final BigDecimal nominalAnnualInterestRate, final InterestMethod interestMethod,
@@ -182,7 +195,9 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
             final LoanScheduleProcessingType loanScheduleProcessingType, final Integer fixedLength,
             final boolean enableAccrualActivityPosting, final List<LoanSupportedInterestRefundTypes> supportedInterestRefundTypes,
             final LoanChargeOffBehaviour chargeOffBehaviour, final boolean interestRecognitionOnDisbursementDate,
-            final DaysInYearCustomStrategyType daysInYearCustomStrategy) {
+            final DaysInYearCustomStrategyType daysInYearCustomStrategy, final boolean enableIncomeCapitalization,
+            final LoanCapitalizedIncomeCalculationType capitalizedIncomeCalculationType,
+            final LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy) {
 
         final MonetaryCurrency currency = MonetaryCurrency.fromCurrencyData(currencyData);
         return new LoanProductRelatedDetail(currency, principal, nominalInterestRatePerPeriod, interestRatePeriodFrequencyType,
@@ -192,7 +207,8 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
                 inArrearsTolerance, graceOnArrearsAgeing, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
                 isEqualAmortization, enableDownPayment, disbursedAmountPercentageForDownPayment, enableAutoRepaymentForDownPayment,
                 loanScheduleType, loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes,
-                chargeOffBehaviour, interestRecognitionOnDisbursementDate, daysInYearCustomStrategy);
+                chargeOffBehaviour, interestRecognitionOnDisbursementDate, daysInYearCustomStrategy, enableIncomeCapitalization,
+                capitalizedIncomeCalculationType, capitalizedIncomeStrategy);
     }
 
     protected LoanProductRelatedDetail() {
@@ -213,7 +229,9 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
             final LoanScheduleProcessingType loanScheduleProcessingType, final Integer fixedLength,
             final boolean enableAccrualActivityPosting, List<LoanSupportedInterestRefundTypes> supportedInterestRefundTypes,
             final LoanChargeOffBehaviour chargeOffBehaviour, final boolean interestRecognitionOnDisbursementDate,
-            final DaysInYearCustomStrategyType daysInYearCustomStrategy) {
+            final DaysInYearCustomStrategyType daysInYearCustomStrategy, final boolean enableIncomeCapitalization,
+            final LoanCapitalizedIncomeCalculationType capitalizedIncomeCalculationType,
+            final LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy) {
         this.currency = currency;
         this.principal = defaultPrincipal;
         this.nominalInterestRatePerPeriod = defaultNominalInterestRatePerPeriod;
@@ -251,6 +269,9 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
         this.chargeOffBehaviour = chargeOffBehaviour;
         this.interestRecognitionOnDisbursementDate = interestRecognitionOnDisbursementDate;
         this.daysInYearCustomStrategy = daysInYearCustomStrategy;
+        this.enableIncomeCapitalization = enableIncomeCapitalization;
+        this.capitalizedIncomeCalculationType = capitalizedIncomeCalculationType;
+        this.capitalizedIncomeStrategy = capitalizedIncomeStrategy;
     }
 
     private Integer defaultToNullIfZero(final Integer value) {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResource.java
index ef4a8c075f..b57888bc03 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResource.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResource.java
@@ -132,6 +132,8 @@ import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsData;
 import org.apache.fineract.portfolio.loanaccount.data.LoanTransactionData;
 import org.apache.fineract.portfolio.loanaccount.data.PaidInAdvanceData;
 import org.apache.fineract.portfolio.loanaccount.data.RepaymentScheduleRelatedLoanData;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanSummaryBalancesRepository;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanTermVariationType;
@@ -1135,7 +1137,9 @@ public class LoansApiResource {
                 loanCollateralOptions, calendarOptions, notes, accountLinkingOptions, linkedAccount, disbursementData, emiAmountVariations,
                 overdueCharges, paidInAdvanceTemplate, interestRatesPeriods, clientActiveLoanOptions, rates, isRatesEnabled, collectionData,
                 LoanScheduleType.getValuesAsEnumOptionDataList(), LoanScheduleProcessingType.getValuesAsEnumOptionDataList(),
-                loanTermVariations, DaysInYearCustomStrategyType.getValuesAsStringEnumOptionDataList());
+                loanTermVariations, DaysInYearCustomStrategyType.getValuesAsStringEnumOptionDataList(),
+                LoanCapitalizedIncomeCalculationType.getValuesAsStringEnumOptionDataList(),
+                LoanCapitalizedIncomeStrategy.getValuesAsStringEnumOptionDataList());
 
         final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters(),
                 mandatoryResponseParameters);
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResourceSwagger.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResourceSwagger.java
index d549371e4f..17787426d8 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResourceSwagger.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResourceSwagger.java
@@ -1206,6 +1206,12 @@ final class LoansApiResourceSwagger {
         public StringEnumOptionData chargeOffBehaviour;
         @Schema(example = "false")
         public Boolean interestRecognitionOnDisbursementDate;
+        @Schema(example = "false")
+        public Boolean enableIncomeCapitalization;
+        @Schema(example = "FLAT")
+        public StringEnumOptionData capitalizedIncomeCalculationType;
+        @Schema(example = "EQUAL_AMORTIZATION")
+        public StringEnumOptionData capitalizedIncomeStrategy;
     }
 
     @Schema(description = "GetLoansResponse")
@@ -1309,6 +1315,12 @@ final class LoansApiResourceSwagger {
         public BigDecimal fixedEmiAmount;
         @Schema(example = "false")
         public Boolean interestRecognitionOnDisbursementDate;
+        @Schema(example = "false")
+        public Boolean enableIncomeCapitalization;
+        @Schema(example = "FLAT", allowableValues = "FLAT")
+        public String capitalizedIncomeCalculationType;
+        @Schema(example = "EQUAL_AMORTIZATION", allowableValues = "EQUAL_AMORTIZATION")
+        public String capitalizedIncomeStrategy;
 
         public List<PostLoansRequestChargeData> charges;
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java
index 1d7a6f21c0..825293fdb6 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java
@@ -172,6 +172,8 @@ public class LoanAccountData {
     private List<EnumOptionData> loanScheduleTypeOptions;
     private List<EnumOptionData> loanScheduleProcessingTypeOptions;
     private List<StringEnumOptionData> daysInYearCustomStrategyOptions;
+    private List<StringEnumOptionData> capitalizedIncomeCalculationTypeOptions;
+    private List<StringEnumOptionData> capitalizedIncomeStrategyOptions;
 
     @Transient
     private BigDecimal feeChargesAtDisbursementCharged;
@@ -274,6 +276,9 @@ public class LoanAccountData {
     private EnumOptionData loanScheduleProcessingType;
 
     private StringEnumOptionData chargeOffBehaviour;
+    private Boolean enableIncomeCapitalization;
+    private StringEnumOptionData capitalizedIncomeCalculationType;
+    private StringEnumOptionData capitalizedIncomeStrategy;
 
     public static LoanAccountData importInstanceIndividual(EnumOptionData loanTypeEnumOption, Long clientId, Long productId,
             Long loanOfficerId, LocalDate submittedOnDate, Long fundId, BigDecimal principal, Integer numberOfRepayments,
@@ -464,7 +469,9 @@ public class LoanAccountData {
             final BigDecimal disbursedAmountPercentageForDownPayment, final boolean enableAutoRepaymentForDownPayment,
             final boolean enableInstallmentLevelDelinquency, final EnumOptionData loanScheduleType,
             final EnumOptionData loanScheduleProcessingType, final Integer fixedLength, final StringEnumOptionData chargeOffBehaviour,
-            final boolean isInterestRecognitionOnDisbursementDate, final StringEnumOptionData daysInYearCustomStrategy) {
+            final boolean isInterestRecognitionOnDisbursementDate, final StringEnumOptionData daysInYearCustomStrategy,
+            final boolean enableIncomeCapitalization, final StringEnumOptionData capitalizedIncomeCalculationType,
+            final StringEnumOptionData capitalizedIncomeStrategy) {
 
         final CollectionData delinquent = CollectionData.template();
 
@@ -510,7 +517,9 @@ public class LoanAccountData {
                 .setEnableInstallmentLevelDelinquency(enableInstallmentLevelDelinquency).setLoanScheduleType(loanScheduleType)
                 .setLoanScheduleProcessingType(loanScheduleProcessingType).setFixedLength(fixedLength)
                 .setChargeOffBehaviour(chargeOffBehaviour).setInterestRecognitionOnDisbursementDate(isInterestRecognitionOnDisbursementDate)
-                .setDaysInYearCustomStrategy(daysInYearCustomStrategy);
+                .setDaysInYearCustomStrategy(daysInYearCustomStrategy).setEnableIncomeCapitalization(enableIncomeCapitalization)
+                .setCapitalizedIncomeCalculationType(capitalizedIncomeCalculationType)
+                .setCapitalizedIncomeStrategy(capitalizedIncomeStrategy);
     }
 
     /*
@@ -536,7 +545,9 @@ public class LoanAccountData {
             final Collection<LoanAccountSummaryData> clientActiveLoanOptions, final List<RateData> rates, final Boolean isRatesEnabled,
             final CollectionData delinquent, final List<EnumOptionData> loanScheduleTypeOptions,
             final List<EnumOptionData> loanScheduleProcessingTypeOptions, final List<LoanTermVariationsData> loanTermVariations,
-            final List<StringEnumOptionData> daysInYearCustomStrategyOptions) {
+            final List<StringEnumOptionData> daysInYearCustomStrategyOptions,
+            final List<StringEnumOptionData> capitalizedIncomeCalculationTypeOptions,
+            final List<StringEnumOptionData> capitalizedIncomeStrategyOptions) {
 
         // TODO: why are these variables 'calendarData', 'chargeTemplate' never used (see original private constructor)
 
@@ -557,7 +568,9 @@ public class LoanAccountData {
                 .setClientActiveLoanOptions(clientActiveLoanOptions).setRates(rates).setIsRatesEnabled(isRatesEnabled)
                 .setDelinquent(delinquent).setLoanScheduleTypeOptions(loanScheduleTypeOptions)
                 .setLoanScheduleProcessingTypeOptions(loanScheduleProcessingTypeOptions).setLoanTermVariations(loanTermVariations)
-                .setDaysInYearCustomStrategyOptions(daysInYearCustomStrategyOptions);
+                .setDaysInYearCustomStrategyOptions(daysInYearCustomStrategyOptions)
+                .setCapitalizedIncomeCalculationTypeOptions(capitalizedIncomeCalculationTypeOptions)
+                .setCapitalizedIncomeStrategyOptions(capitalizedIncomeStrategyOptions);
     }
 
     public LoanAccountData associationsAndTemplate(final Collection<LoanProductData> productOptions,
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 f6fb5578f3..b4ac0b05c5 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
@@ -544,7 +544,10 @@ public class LoanScheduleAssembler {
                 loanProduct.getLoanProductRelatedDetail().isEnableAccrualActivityPosting(),
                 loanProduct.getLoanProductRelatedDetail().getSupportedInterestRefundTypes(),
                 loanProduct.getLoanProductRelatedDetail().getChargeOffBehaviour(), interestRecognitionOnDisbursementDate,
-                loanProduct.getLoanProductRelatedDetail().getDaysInYearCustomStrategy());
+                loanProduct.getLoanProductRelatedDetail().getDaysInYearCustomStrategy(),
+                loanProduct.getLoanProductRelatedDetail().isEnableIncomeCapitalization(),
+                loanProduct.getLoanProductRelatedDetail().getCapitalizedIncomeCalculationType(),
+                loanProduct.getLoanProductRelatedDetail().getCapitalizedIncomeStrategy());
     }
 
     private CalendarInstance createCalendarForSameAsRepayment(final Integer repaymentEvery,
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanProductAssembler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanProductAssembler.java
index 67b748065d..85522bed1a 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanProductAssembler.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanProductAssembler.java
@@ -40,6 +40,8 @@ import org.apache.fineract.portfolio.common.domain.DaysInYearType;
 import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
 import org.apache.fineract.portfolio.floatingrates.domain.FloatingRate;
 import org.apache.fineract.portfolio.fund.domain.Fund;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanChargeOffBehaviour;
 import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.AprCalculator;
 import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
@@ -305,6 +307,13 @@ public class LoanProductAssembler {
             chargeOffBehaviour = LoanChargeOffBehaviour.REGULAR;
         }
 
+        final boolean enableIncomeCapitalization = command
+                .booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ENABLE_INCOME_CAPITALIZATION_PARAM_NAME);
+        final LoanCapitalizedIncomeCalculationType capitalizedIncomeCalculationType = command.enumValueOfParameterNamed(
+                LoanProductConstants.CAPITALIZED_INCOME_CALCULATION_TYPE_PARAM_NAME, LoanCapitalizedIncomeCalculationType.class);
+        final LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy = command.enumValueOfParameterNamed(
+                LoanProductConstants.CAPITALIZED_INCOME_STRATEGY_PARAM_NAME, LoanCapitalizedIncomeStrategy.class);
+
         return new LoanProduct(fund, loanTransactionProcessingStrategy, loanProductPaymentAllocationRules, loanProductCreditAllocationRules,
                 name, shortName, description, currency, principal, minPrincipal, maxPrincipal, interestRatePerPeriod,
                 minInterestRatePerPeriod, maxInterestRatePerPeriod, interestFrequencyType, annualInterestRate, interestMethod,
@@ -325,7 +334,7 @@ public class LoanProductAssembler {
                 overDueDaysForRepaymentEvent, enableDownPayment, disbursedAmountPercentageDownPayment, enableAutoRepaymentForDownPayment,
                 repaymentStartDateType, enableInstallmentLevelDelinquency, loanScheduleType, loanScheduleProcessingType, fixedLength,
                 enableAccrualActivityPosting, supportedInterestRefundTypes, chargeOffBehaviour, interestRecognitionOnDisbursementDate,
-                daysInYearCustomStrategy);
+                daysInYearCustomStrategy, enableIncomeCapitalization, capitalizedIncomeCalculationType, capitalizedIncomeStrategy);
 
     }
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanProductRelatedDetailUpdateUtil.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanProductRelatedDetailUpdateUtil.java
index 9e286fe24d..da78ccf984 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanProductRelatedDetailUpdateUtil.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanProductRelatedDetailUpdateUtil.java
@@ -26,6 +26,8 @@ import org.apache.fineract.infrastructure.core.api.JsonCommand;
 import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
 import org.apache.fineract.portfolio.common.domain.DaysInYearCustomStrategyType;
 import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
 import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.AprCalculator;
 import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
 import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
@@ -296,6 +298,28 @@ public class LoanProductRelatedDetailUpdateUtil {
             loanRepaymentScheduleDetail.updateInterestRecognitionOnDisbursementDate(newValue);
         }
 
+        if (command.isChangeInBooleanParameterNamed(LoanProductConstants.ENABLE_INCOME_CAPITALIZATION_PARAM_NAME,
+                loanRepaymentScheduleDetail.isEnableIncomeCapitalization())) {
+            final boolean newValue = command
+                    .booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ENABLE_INCOME_CAPITALIZATION_PARAM_NAME);
+            actualChanges.put(LoanProductConstants.ENABLE_INCOME_CAPITALIZATION_PARAM_NAME, newValue);
+            loanRepaymentScheduleDetail.setEnableIncomeCapitalization(newValue);
+        }
+
+        if (command.parameterExists(LoanProductConstants.CAPITALIZED_INCOME_CALCULATION_TYPE_PARAM_NAME)) {
+            final LoanCapitalizedIncomeCalculationType newValue = command.enumValueOfParameterNamed(
+                    LoanProductConstants.CAPITALIZED_INCOME_CALCULATION_TYPE_PARAM_NAME, LoanCapitalizedIncomeCalculationType.class);
+            actualChanges.put(LoanProductConstants.CAPITALIZED_INCOME_CALCULATION_TYPE_PARAM_NAME, newValue);
+            loanRepaymentScheduleDetail.setCapitalizedIncomeCalculationType(newValue);
+        }
+
+        if (command.parameterExists(LoanProductConstants.CAPITALIZED_INCOME_STRATEGY_PARAM_NAME)) {
+            final LoanCapitalizedIncomeStrategy newValue = command.enumValueOfParameterNamed(
+                    LoanProductConstants.CAPITALIZED_INCOME_STRATEGY_PARAM_NAME, LoanCapitalizedIncomeStrategy.class);
+            actualChanges.put(LoanProductConstants.CAPITALIZED_INCOME_STRATEGY_PARAM_NAME, newValue);
+            loanRepaymentScheduleDetail.setCapitalizedIncomeStrategy(newValue);
+        }
+
         return actualChanges;
     }
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java
index f5f61cdf2b..e2399aeeab 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java
@@ -106,6 +106,8 @@ import org.apache.fineract.portfolio.loanaccount.data.PaidInAdvanceData;
 import org.apache.fineract.portfolio.loanaccount.data.RepaymentScheduleRelatedLoanData;
 import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO;
 import org.apache.fineract.portfolio.loanaccount.domain.Loan;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanChargeOffBehaviour;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory;
@@ -722,6 +724,9 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
                     + " l.is_floating_interest_rate as isFloatingInterestRate, "
                     + " l.interest_rate_differential as interestRateDifferential, "
                     + " l.days_in_year_custom_strategy as daysInYearCustomStrategy, "
+                    + " l.enable_income_capitalization as enableIncomeCapitalization, "
+                    + " l.capitalized_income_calculation_type as capitalizedIncomeCalculationType, "
+                    + " l.capitalized_income_strategy as capitalizedIncomeStrategy, "
                     + " l.create_standing_instruction_at_disbursement as createStandingInstructionAtDisbursement, "
                     + " lpvi.minimum_gap as minimuminstallmentgap, lpvi.maximum_gap as maximuminstallmentgap, "
                     + " lp.can_use_for_topup as canUseForTopup, l.is_topup as isTopup, topup.closure_loan_id as closureLoanId, "
@@ -1098,6 +1103,11 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
             final boolean interestRecognitionOnDisbursementDate = rs.getBoolean("interestRecognitionOnDisbursementDate");
             final StringEnumOptionData daysInYearCustomStrategy = DaysInYearCustomStrategyType
                     .getStringEnumOptionData(rs.getString("daysInYearCustomStrategy"));
+            final boolean enableIncomeCapitalization = rs.getBoolean("enableIncomeCapitalization");
+            final StringEnumOptionData capitalizedIncomeCalculationType = LoanCapitalizedIncomeCalculationType
+                    .getStringEnumOptionData(rs.getString("capitalizedIncomeCalculationType"));
+            final StringEnumOptionData capitalizedIncomeStrategy = LoanCapitalizedIncomeStrategy
+                    .getStringEnumOptionData(rs.getString("capitalizedIncomeStrategy"));
 
             return LoanAccountData.basicLoanDetails(id, accountNo, status, externalId, clientId, clientAccountNo, clientName,
                     clientOfficeId, clientExternalId, groupData, loanType, loanProductId, loanProductName, loanProductDescription,
@@ -1117,7 +1127,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
                     lastClosedBusinessDate, overpaidOnDate, isChargedOff, enableDownPayment, disbursedAmountPercentageForDownPayment,
                     enableAutoRepaymentForDownPayment, enableInstallmentLevelDelinquency, loanScheduleType.asEnumOptionData(),
                     loanScheduleProcessingType.asEnumOptionData(), fixedLength, chargeOffBehaviour.getValueAsStringEnumOptionData(),
-                    interestRecognitionOnDisbursementDate, daysInYearCustomStrategy);
+                    interestRecognitionOnDisbursementDate, daysInYearCustomStrategy, enableIncomeCapitalization,
+                    capitalizedIncomeCalculationType, capitalizedIncomeStrategy);
         }
     }
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/api/LoanProductsApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/api/LoanProductsApiResource.java
index f45322979d..271b1f7107 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/api/LoanProductsApiResource.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/api/LoanProductsApiResource.java
@@ -81,6 +81,8 @@ import org.apache.fineract.portfolio.floatingrates.service.FloatingRatesReadPlat
 import org.apache.fineract.portfolio.fund.data.FundData;
 import org.apache.fineract.portfolio.fund.service.FundReadPlatformService;
 import org.apache.fineract.portfolio.loanaccount.api.LoanApiConstants;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanChargeOffBehaviour;
 import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
 import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
@@ -127,7 +129,10 @@ public class LoanProductsApiResource {
             LoanApiConstants.fixedPrincipalPercentagePerInstallmentParamName, LoanProductConstants.DUE_DAYS_FOR_REPAYMENT_EVENT,
             LoanProductConstants.OVER_DUE_DAYS_FOR_REPAYMENT_EVENT, LoanProductConstants.ENABLE_DOWN_PAYMENT,
             LoanProductConstants.DISBURSED_AMOUNT_PERCENTAGE_DOWN_PAYMENT, LoanProductConstants.ENABLE_AUTO_REPAYMENT_DOWN_PAYMENT,
-            LoanProductConstants.REPAYMENT_START_DATE_TYPE, LoanProductConstants.DAYS_IN_YEAR_CUSTOM_STRATEGY_TYPE_PARAMETER_NAME));
+            LoanProductConstants.REPAYMENT_START_DATE_TYPE, LoanProductConstants.DAYS_IN_YEAR_CUSTOM_STRATEGY_TYPE_PARAMETER_NAME,
+            LoanProductConstants.ENABLE_INCOME_CAPITALIZATION_PARAM_NAME,
+            LoanProductConstants.CAPITALIZED_INCOME_CALCULATION_TYPE_PARAM_NAME,
+            LoanProductConstants.CAPITALIZED_INCOME_STRATEGY_PARAM_NAME));
 
     private static final Set<String> PRODUCT_MIX_DATA_PARAMETERS = new HashSet<>(
             Arrays.asList("productId", "productName", "restrictedProducts", "allowedProducts", "productOptions"));
@@ -439,6 +444,10 @@ public class LoanProductsApiResource {
                 .retrieveCodeValuesByCode(LoanApiConstants.CHARGE_OFF_REASONS);
         final List<StringEnumOptionData> daysInYearCustomStrategyOptions = DaysInYearCustomStrategyType
                 .getValuesAsStringEnumOptionDataList();
+        final List<StringEnumOptionData> capitalizedIncomeCalculationTypeOptions = LoanCapitalizedIncomeCalculationType
+                .getValuesAsStringEnumOptionDataList();
+        final List<StringEnumOptionData> capitalizedIncomeStrategyOptions = LoanCapitalizedIncomeStrategy
+                .getValuesAsStringEnumOptionDataList();
 
         return new LoanProductData(productData, chargeOptions, penaltyOptions, paymentTypeOptions, currencyOptions, amortizationTypeOptions,
                 interestTypeOptions, interestCalculationPeriodTypeOptions, repaymentFrequencyTypeOptions, interestRateFrequencyTypeOptions,
@@ -451,7 +460,7 @@ public class LoanProductsApiResource {
                 advancedPaymentAllocationTypes, LoanScheduleType.getValuesAsEnumOptionDataList(),
                 LoanScheduleProcessingType.getValuesAsEnumOptionDataList(), creditAllocationTransactionTypes,
                 creditAllocationAllocationTypes, supportedInterestRefundTypesOptions, chargeOffBehaviourOptions, chargeOffReasonOptions,
-                daysInYearCustomStrategyOptions);
+                daysInYearCustomStrategyOptions, capitalizedIncomeCalculationTypeOptions, capitalizedIncomeStrategyOptions);
     }
 
 }
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 d2e29d0add..81c8d5b878 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
@@ -49,6 +49,8 @@ import org.apache.fineract.infrastructure.core.service.MathUtil;
 import org.apache.fineract.portfolio.calendar.service.CalendarUtils;
 import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
 import org.apache.fineract.portfolio.loanaccount.api.LoanApiConstants;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanChargeOffBehaviour;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory;
 import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.AdvancedPaymentScheduleTransactionProcessor;
@@ -186,7 +188,10 @@ public final class LoanProductDataValidator {
             LoanProductConstants.LOAN_SCHEDULE_PROCESSING_TYPE, LoanProductConstants.FIXED_LENGTH,
             LoanProductConstants.ENABLE_ACCRUAL_ACTIVITY_POSTING, LoanProductConstants.SUPPORTED_INTEREST_REFUND_TYPES,
             LoanProductConstants.CHARGE_OFF_BEHAVIOUR, LoanProductConstants.INTEREST_RECOGNITION_ON_DISBURSEMENT_DATE,
-            LoanProductConstants.DAYS_IN_YEAR_CUSTOM_STRATEGY_TYPE_PARAMETER_NAME));
+            LoanProductConstants.DAYS_IN_YEAR_CUSTOM_STRATEGY_TYPE_PARAMETER_NAME,
+            LoanProductConstants.ENABLE_INCOME_CAPITALIZATION_PARAM_NAME,
+            LoanProductConstants.CAPITALIZED_INCOME_CALCULATION_TYPE_PARAM_NAME,
+            LoanProductConstants.CAPITALIZED_INCOME_STRATEGY_PARAM_NAME));
 
     private static final String[] SUPPORTED_LOAN_CONFIGURABLE_ATTRIBUTES = { LoanProductConstants.amortizationTypeParamName,
             LoanProductConstants.interestTypeParamName, LoanProductConstants.transactionProcessingStrategyCodeParamName,
@@ -877,6 +882,8 @@ public final class LoanProductDataValidator {
                     "Charge off behaviour is only supported for Progressive loans");
         }
 
+        validateIncomeCapitalization(transactionProcessingStrategyCode, element, baseDataValidator);
+
         throwExceptionIfValidationWarningsExist(dataValidationErrors);
     }
 
@@ -1922,6 +1929,9 @@ public final class LoanProductDataValidator {
 
         validateRepaymentPeriodWithGraceSettings(numberOfRepayments, graceOnPrincipalPayment, graceOnInterestPayment,
                 graceOnInterestCharged, recurringMoratoriumOnPrincipalPeriods, baseDataValidator);
+
+        validateIncomeCapitalization(transactionProcessingStrategyCode, element, baseDataValidator);
+
         throwExceptionIfValidationWarningsExist(dataValidationErrors);
     }
 
@@ -2660,6 +2670,39 @@ public final class LoanProductDataValidator {
         }
     }
 
+    private void validateIncomeCapitalization(String transactionProcessingStrategyCode, JsonElement element,
+            DataValidatorBuilder baseDataValidator) {
+        if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.CAPITALIZED_INCOME_CALCULATION_TYPE_PARAM_NAME, element)) {
+            final String capitalizedIncomeCalculationType = this.fromApiJsonHelper
+                    .extractStringNamed(LoanProductConstants.CAPITALIZED_INCOME_CALCULATION_TYPE_PARAM_NAME, element);
+            baseDataValidator.reset().parameter(LoanProductConstants.CAPITALIZED_INCOME_CALCULATION_TYPE_PARAM_NAME)
+                    .value(capitalizedIncomeCalculationType).isOneOfEnumValues(LoanCapitalizedIncomeCalculationType.class);
+        }
+
+        if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.CAPITALIZED_INCOME_STRATEGY_PARAM_NAME, element)) {
+            final String capitalizedIncomeStrategy = this.fromApiJsonHelper
+                    .extractStringNamed(LoanProductConstants.CAPITALIZED_INCOME_STRATEGY_PARAM_NAME, element);
+            baseDataValidator.reset().parameter(LoanProductConstants.CAPITALIZED_INCOME_STRATEGY_PARAM_NAME)
+                    .value(capitalizedIncomeStrategy).isOneOfEnumValues(LoanCapitalizedIncomeStrategy.class);
+        }
+
+        if (AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY.equals(transactionProcessingStrategyCode)
+                && this.fromApiJsonHelper.parameterExists(LoanProductConstants.ENABLE_INCOME_CAPITALIZATION_PARAM_NAME, element)) {
+            Boolean enableIncomeCapitalization = this.fromApiJsonHelper
+                    .extractBooleanNamed(LoanProductConstants.ENABLE_INCOME_CAPITALIZATION_PARAM_NAME, element);
+            baseDataValidator.reset().parameter(LoanProductConstants.ENABLE_INCOME_CAPITALIZATION_PARAM_NAME)
+                    .value(enableIncomeCapitalization).ignoreIfNull().validateForBooleanValue();
+        } else if (this.fromApiJsonHelper.parameterExists(LoanProductConstants.ENABLE_INCOME_CAPITALIZATION_PARAM_NAME, element)) {
+            Boolean enableIncomeCapitalization = this.fromApiJsonHelper
+                    .extractBooleanNamed(LoanProductConstants.ENABLE_INCOME_CAPITALIZATION_PARAM_NAME, element);
+            if (Boolean.TRUE.equals(enableIncomeCapitalization)) {
+                baseDataValidator.reset().parameter(LoanProductConstants.ENABLE_INCOME_CAPITALIZATION_PARAM_NAME).failWithCode(
+                        "supported.only.for.progressive.loan.income.capitalization",
+                        "Income capitalization is only supported for Progressive loans");
+            }
+        }
+    }
+
     private Integer defaultToZeroIfNull(Integer value) {
         return value != null ? value : 0;
     }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java
index c3fe4c728f..4c436216c1 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java
@@ -45,6 +45,8 @@ import org.apache.fineract.portfolio.common.domain.DaysInYearCustomStrategyType;
 import org.apache.fineract.portfolio.common.service.CommonEnumerations;
 import org.apache.fineract.portfolio.delinquency.data.DelinquencyBucketData;
 import org.apache.fineract.portfolio.delinquency.service.DelinquencyReadPlatformService;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanChargeOffBehaviour;
 import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleProcessingType;
 import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleType;
@@ -288,8 +290,11 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
                     + "lp.allow_variabe_installments as isVariableIntallmentsAllowed, " + "lvi.minimum_gap as minimumGap, "
                     + "lvi.maximum_gap as maximumGap, dbuc.id as delinquencyBucketId, dbuc.name as delinquencyBucketName, "
                     + "lp.can_use_for_topup as canUseForTopup, lp.is_equal_amortization as isEqualAmortization, lp.loan_schedule_type as loanScheduleType, lp.loan_schedule_processing_type as loanScheduleProcessingType, lp.supported_interest_refund_types as supportedInterestRefundTypes, "
-                    + "lp.charge_off_behaviour as chargeOffBehaviour" + " from m_product_loan lp "
-                    + " left join m_fund f on f.id = lp.fund_id "
+                    + "lp.charge_off_behaviour as chargeOffBehaviour, " //
+                    + "lp.enable_income_capitalization as enableIncomeCapitalization, " //
+                    + "lp.capitalized_income_calculation_type as capitalizedIncomeCalculationType, " //
+                    + "lp.capitalized_income_strategy as capitalizedIncomeStrategy " //
+                    + " from m_product_loan lp " + " left join m_fund f on f.id = lp.fund_id "
                     + " left join m_product_loan_recalculation_details lpr on lpr.product_id=lp.id "
                     + " left join m_product_loan_guarantee_details lpg on lpg.loan_product_id=lp.id "
                     + " left join m_product_loan_configurable_attributes lca on lca.loan_product_id = lp.id "
@@ -552,6 +557,11 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
             final String chargeOffBehaviourStr = rs.getString("chargeOffBehaviour");
             final LoanChargeOffBehaviour loanChargeOffBehaviour = LoanChargeOffBehaviour.valueOf(chargeOffBehaviourStr);
             final boolean interestRecognitionOnDisbursementDate = rs.getBoolean("interestRecognitionOnDisbursementDate");
+            final boolean enableIncomeCapitalization = rs.getBoolean("enableIncomeCapitalization");
+            final StringEnumOptionData capitalizedIncomeCalculationType = LoanCapitalizedIncomeCalculationType
+                    .getStringEnumOptionData(rs.getString("capitalizedIncomeCalculationType"));
+            final StringEnumOptionData capitalizedIncomeStrategy = LoanCapitalizedIncomeStrategy
+                    .getStringEnumOptionData(rs.getString("capitalizedIncomeStrategy"));
 
             return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
                     numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
@@ -576,7 +586,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
                     enableInstallmentLevelDelinquency, loanScheduleType.asEnumOptionData(), loanScheduleProcessingType.asEnumOptionData(),
                     fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes,
                     loanChargeOffBehaviour.getValueAsStringEnumOptionData(), interestRecognitionOnDisbursementDate,
-                    daysInYearCustomStrategy);
+                    daysInYearCustomStrategy, enableIncomeCapitalization, capitalizedIncomeCalculationType, capitalizedIncomeStrategy);
         }
     }
 
diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml
index 2f294c33ce..09a9f0e42e 100644
--- a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml
+++ b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml
@@ -189,4 +189,5 @@
     <include file="parts/0168_transaction_summary_with_asset_owner_report_add_active_intermediate_filtering.xml" relativeToChangelogFile="true" />
     <include file="parts/0169_add_missing_permissions.xml" relativeToChangelogFile="true" />
     <include file="parts/0170_days_in_year_custom_strategy.xml" relativeToChangelogFile="true"/>
+    <include file="parts/0171_loan_capitalized_income.xml" relativeToChangelogFile="true"/>
 </databaseChangeLog>
diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0171_loan_capitalized_income.xml b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0171_loan_capitalized_income.xml
new file mode 100644
index 0000000000..3ac0cf5a20
--- /dev/null
+++ b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0171_loan_capitalized_income.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements. See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership. The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License. You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied. See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
+                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                   xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd">
+    <changeSet author="fineract" id="1">
+        <addColumn tableName="m_loan">
+            <column name="enable_income_capitalization" type="boolean" defaultValueBoolean="false">
+                <constraints nullable="false"/>
+            </column>
+            <column name="capitalized_income_calculation_type" type="VARCHAR(100)">
+                <constraints nullable="true"/>
+            </column>
+            <column name="capitalized_income_strategy" type="VARCHAR(100)">
+                <constraints nullable="true"/>
+            </column>
+        </addColumn>
+        <addColumn tableName="m_product_loan">
+            <column name="enable_income_capitalization" type="boolean" defaultValueBoolean="false">
+                <constraints nullable="false"/>
+            </column>
+            <column name="capitalized_income_calculation_type" type="VARCHAR(100)">
+                <constraints nullable="true"/>
+            </column>
+            <column name="capitalized_income_strategy" type="VARCHAR(100)">
+                <constraints nullable="true"/>
+            </column>
+        </addColumn>
+    </changeSet>
+</databaseChangeLog>
diff --git a/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/DefaultScheduledDateGeneratorTest.java b/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/DefaultScheduledDateGeneratorTest.java
index a7574fd5f2..d0d83caa6c 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/DefaultScheduledDateGeneratorTest.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/DefaultScheduledDateGeneratorTest.java
@@ -98,7 +98,8 @@ public class DefaultScheduledDateGeneratorTest {
                 Money.of(fromApplicationCurrency(dollarCurrency), ZERO), false, null, EMPTY_LIST, BigDecimal.valueOf(36_000L), null,
                 DaysInMonthType.ACTUAL, DaysInYearType.ACTUAL, false, null, null, null, null, null, ZERO, null, NONE, null, ZERO,
                 EMPTY_LIST, true, 0, false, holidayDetailDTO, false, false, false, null, false, false, null, false, DISBURSEMENT_DATE,
-                submittedOnDate, CUMULATIVE, LoanScheduleProcessingType.HORIZONTAL, null, false, null, null, false, null);
+                submittedOnDate, CUMULATIVE, LoanScheduleProcessingType.HORIZONTAL, null, false, null, null, false, null, false, null,
+                null);
 
         // when
         List<? extends LoanScheduleModelPeriod> result = underTest.generateRepaymentPeriods(mathContext, expectedDisbursementDate,
@@ -179,7 +180,7 @@ public class DefaultScheduledDateGeneratorTest {
                 EMPTY_LIST, BigDecimal.valueOf(36_000L), null, DaysInMonthType.ACTUAL, DaysInYearType.ACTUAL, false, null, null, null, null,
                 null, ZERO, null, NONE, null, ZERO, EMPTY_LIST, true, 0, false, holidayDetailDTO, false, false, false, null, false, false,
                 null, false, DISBURSEMENT_DATE, submittedOnDate, CUMULATIVE, LoanScheduleProcessingType.HORIZONTAL, null, false, null, null,
-                false, null);
+                false, null, false, null, null);
     }
 
     private HolidayDetailDTO createHolidayDTO() {
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanProductTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanProductTest.java
new file mode 100644
index 0000000000..ea49812563
--- /dev/null
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanProductTest.java
@@ -0,0 +1,147 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.integrationtests;
+
+import java.math.BigDecimal;
+import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
+import org.apache.fineract.client.models.GetLoansLoanIdResponse;
+import org.apache.fineract.client.models.PostClientsResponse;
+import org.apache.fineract.client.models.PostLoanProductsRequest;
+import org.apache.fineract.client.models.PostLoanProductsResponse;
+import org.apache.fineract.client.models.PutLoanProductsProductIdRequest;
+import org.apache.fineract.integrationtests.common.ClientHelper;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeCalculationType;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanCapitalizedIncomeStrategy;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class LoanProductTest extends BaseLoanIntegrationTest {
+
+    @Test
+    public void testIncomeCapitalizationEnabled() {
+        final PostClientsResponse client = clientHelper.createClient(ClientHelper.defaultClientCreationRequest());
+
+        final PostLoanProductsResponse loanProductsResponse = loanProductHelper
+                .createLoanProduct(create4IProgressive().enableIncomeCapitalization(true)
+                        .capitalizedIncomeCalculationType(PostLoanProductsRequest.CapitalizedIncomeCalculationTypeEnum.FLAT)
+                        .capitalizedIncomeStrategy(PostLoanProductsRequest.CapitalizedIncomeStrategyEnum.EQUAL_AMORTIZATION));
+
+        final GetLoanProductsProductIdResponse loanProductsProductIdResponse = loanProductHelper
+                .retrieveLoanProductById(loanProductsResponse.getResourceId());
+        Assertions.assertEquals(Boolean.TRUE, loanProductsProductIdResponse.getEnableIncomeCapitalization());
+        Assertions.assertNotNull(loanProductsProductIdResponse.getCapitalizedIncomeCalculationType());
+        Assertions.assertEquals(LoanCapitalizedIncomeCalculationType.FLAT.getCode(),
+                loanProductsProductIdResponse.getCapitalizedIncomeCalculationType().getCode());
+        Assertions.assertNotNull(loanProductsProductIdResponse.getCapitalizedIncomeStrategy());
+        Assertions.assertEquals(LoanCapitalizedIncomeStrategy.EQUAL_AMORTIZATION.getCode(),
+                loanProductsProductIdResponse.getCapitalizedIncomeStrategy().getCode());
+
+        runAt("20 December 2024", () -> {
+            Long loanId = applyAndApproveProgressiveLoan(client.getClientId(), loanProductsResponse.getResourceId(), "20 December 2024",
+                    430.0, 7.0, 6, null);
+
+            final GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
+            Assertions.assertEquals(Boolean.TRUE, loanDetails.getEnableIncomeCapitalization());
+            Assertions.assertNotNull(loanDetails.getCapitalizedIncomeCalculationType());
+            Assertions.assertEquals(LoanCapitalizedIncomeCalculationType.FLAT.getCode(),
+                    loanDetails.getCapitalizedIncomeCalculationType().getCode());
+            Assertions.assertNotNull(loanDetails.getCapitalizedIncomeStrategy());
+            Assertions.assertEquals(LoanCapitalizedIncomeStrategy.EQUAL_AMORTIZATION.getCode(),
+                    loanDetails.getCapitalizedIncomeStrategy().getCode());
+
+            Assertions.assertDoesNotThrow(() -> disburseLoan(loanId, BigDecimal.valueOf(430), "20 December 2024"));
+        });
+    }
+
+    @Test
+    public void testIncomeCapitalizationDisabled() {
+        final PostClientsResponse client = clientHelper.createClient(ClientHelper.defaultClientCreationRequest());
+
+        final PostLoanProductsResponse loanProductsResponse = loanProductHelper
+                .createLoanProduct(create4IProgressive().enableIncomeCapitalization(false)
+                        .capitalizedIncomeCalculationType(PostLoanProductsRequest.CapitalizedIncomeCalculationTypeEnum.FLAT)
+                        .capitalizedIncomeStrategy(PostLoanProductsRequest.CapitalizedIncomeStrategyEnum.EQUAL_AMORTIZATION));
+
+        final GetLoanProductsProductIdResponse loanProductsProductIdResponse = loanProductHelper
+                .retrieveLoanProductById(loanProductsResponse.getResourceId());
+        Assertions.assertEquals(Boolean.FALSE, loanProductsProductIdResponse.getEnableIncomeCapitalization());
+        Assertions.assertNotNull(loanProductsProductIdResponse.getCapitalizedIncomeCalculationType());
+        Assertions.assertEquals(LoanCapitalizedIncomeCalculationType.FLAT.getCode(),
+                loanProductsProductIdResponse.getCapitalizedIncomeCalculationType().getCode());
+        Assertions.assertNotNull(loanProductsProductIdResponse.getCapitalizedIncomeStrategy());
+        Assertions.assertEquals(LoanCapitalizedIncomeStrategy.EQUAL_AMORTIZATION.getCode(),
+                loanProductsProductIdResponse.getCapitalizedIncomeStrategy().getCode());
+
+        runAt("20 December 2024", () -> {
+            Long loanId = applyAndApproveProgressiveLoan(client.getClientId(), loanProductsResponse.getResourceId(), "20 December 2024",
+                    430.0, 7.0, 6, null);
+
+            final GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
+            Assertions.assertEquals(Boolean.FALSE, loanDetails.getEnableIncomeCapitalization());
+            Assertions.assertNotNull(loanDetails.getCapitalizedIncomeCalculationType());
+            Assertions.assertEquals(LoanCapitalizedIncomeCalculationType.FLAT.getCode(),
+                    loanDetails.getCapitalizedIncomeCalculationType().getCode());
+            Assertions.assertNotNull(loanDetails.getCapitalizedIncomeStrategy());
+            Assertions.assertEquals(LoanCapitalizedIncomeStrategy.EQUAL_AMORTIZATION.getCode(),
+                    loanDetails.getCapitalizedIncomeStrategy().getCode());
+
+            Assertions.assertDoesNotThrow(() -> disburseLoan(loanId, BigDecimal.valueOf(430), "20 December 2024"));
+        });
+    }
+
+    @Test
+    public void testIncomeCapitalizationUpdateProduct() {
+        final PostLoanProductsResponse loanProductsResponse = loanProductHelper
+                .createLoanProduct(create4IProgressive().enableIncomeCapitalization(true)
+                        .capitalizedIncomeCalculationType(PostLoanProductsRequest.CapitalizedIncomeCalculationTypeEnum.FLAT)
+                        .capitalizedIncomeStrategy(PostLoanProductsRequest.CapitalizedIncomeStrategyEnum.EQUAL_AMORTIZATION));
+
+        final GetLoanProductsProductIdResponse loanProductsProductIdResponse = loanProductHelper
+                .retrieveLoanProductById(loanProductsResponse.getResourceId());
+        Assertions.assertEquals(Boolean.TRUE, loanProductsProductIdResponse.getEnableIncomeCapitalization());
+        Assertions.assertNotNull(loanProductsProductIdResponse.getCapitalizedIncomeCalculationType());
+        Assertions.assertEquals(LoanCapitalizedIncomeCalculationType.FLAT.getCode(),
+                loanProductsProductIdResponse.getCapitalizedIncomeCalculationType().getCode());
+        Assertions.assertNotNull(loanProductsProductIdResponse.getCapitalizedIncomeStrategy());
+        Assertions.assertEquals(LoanCapitalizedIncomeStrategy.EQUAL_AMORTIZATION.getCode(),
+                loanProductsProductIdResponse.getCapitalizedIncomeStrategy().getCode());
+
+        loanProductHelper.updateLoanProductById(loanProductsResponse.getResourceId(),
+                new PutLoanProductsProductIdRequest().enableIncomeCapitalization(false));
+
+        final GetLoanProductsProductIdResponse updatedLoanProductsProductIdResponse = loanProductHelper
+                .retrieveLoanProductById(loanProductsResponse.getResourceId());
+        Assertions.assertEquals(Boolean.FALSE, updatedLoanProductsProductIdResponse.getEnableIncomeCapitalization());
+        Assertions.assertNotNull(updatedLoanProductsProductIdResponse.getCapitalizedIncomeCalculationType());
+        Assertions.assertEquals(LoanCapitalizedIncomeCalculationType.FLAT.getCode(),
+                updatedLoanProductsProductIdResponse.getCapitalizedIncomeCalculationType().getCode());
+        Assertions.assertNotNull(updatedLoanProductsProductIdResponse.getCapitalizedIncomeStrategy());
+        Assertions.assertEquals(LoanCapitalizedIncomeStrategy.EQUAL_AMORTIZATION.getCode(),
+                updatedLoanProductsProductIdResponse.getCapitalizedIncomeStrategy().getCode());
+    }
+
+    @Test
+    public void testIncomeCapitalizationCumulativeNotSupported() {
+        Assertions.assertThrows(RuntimeException.class,
+                () -> loanProductHelper.createLoanProduct(createOnePeriod30DaysPeriodicAccrualProduct(7.0).enableIncomeCapitalization(true)
+                        .capitalizedIncomeCalculationType(PostLoanProductsRequest.CapitalizedIncomeCalculationTypeEnum.FLAT)
+                        .capitalizedIncomeStrategy(PostLoanProductsRequest.CapitalizedIncomeStrategyEnum.EQUAL_AMORTIZATION)));
+    }
+
+}