This is an automated email from the ASF dual-hosted git repository.

adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git


The following commit(s) were added to refs/heads/develop by this push:
     new 18a55874ba FINERACT-2286: Make configurable the outstanding interest 
strategy during asset owner transfer
18a55874ba is described below

commit 18a55874ba769f34b3942a8b8f40728b237d9211
Author: Adam Saghy <[email protected]>
AuthorDate: Wed May 21 15:12:37 2025 +0200

    FINERACT-2286: Make configurable the outstanding interest strategy during 
asset owner transfer
---
 .../api/GlobalConfigurationConstants.java          |  1 +
 .../domain/ConfigurationDomainService.java         |  1 +
 .../test/helper/GlobalConfigurationHelper.java     |  6 ++
 .../test/messaging/event/EventCheckHelper.java     | 21 +++--
 .../AssetExternalizationStepDef.java               | 35 ++++++--
 .../features/AssetExternalization.feature          | 97 ++++++++++++++++++++++
 .../loan/LoanAccountOwnerTransferBusinessStep.java | 18 ++--
 .../fineract/investor/domain/AttributeKey.java     | 17 ++--
 .../ExternalAssetOwnerLoanProductAttribute.java    | 38 +++++++++
 .../domain/ExternalAssetOwnerTransferDetails.java  | 33 +++++++-
 .../investor/service/AccountingServiceImpl.java    |  4 +-
 ...wnerTransferOutstandingInterestCalculation.java | 69 +++++++++++++++
 .../LoanAccountOwnerTransferServiceImpl.java       | 17 ++--
 .../module/investor/module-changelog-master.xml    |  1 +
 ...wner_transfer_outstanding_interest_strategy.xml | 43 ++++++++++
 .../LoanAccountOwnerTransferBusinessStepTest.java  | 25 +++++-
 .../service/AccountingServiceImplTest.java         | 24 +++++-
 .../LoanAccountOwnerTransferServiceTest.java       | 27 +++++-
 .../loanaccount/data/LoanAccountData.java          | 22 +++--
 .../loanaccount/guarantor/data/IGuarantor.java     | 18 +---
 .../service/LoanReadPlatformService.java           |  0
 .../service/LoanSummaryDataProvider.java           |  0
 .../service/LoanSummaryProviderDelegate.java       |  0
 ...argeRepaymentScheduleProcessingWrapperTest.java |  6 ++
 .../domain/ConfigurationDomainServiceJpa.java      |  6 ++
 .../ConvertChargeDataToSpecificChargeData.java     | 15 ----
 .../loanaccount/guarantor/data/GuarantorData.java  |  3 +-
 .../common/GlobalConfigurationHelper.java          | 13 ++-
 28 files changed, 474 insertions(+), 86 deletions(-)

diff --git 
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/configuration/api/GlobalConfigurationConstants.java
 
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/configuration/api/GlobalConfigurationConstants.java
index 82d91b4989..3e6426a1d3 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/configuration/api/GlobalConfigurationConstants.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/configuration/api/GlobalConfigurationConstants.java
@@ -76,6 +76,7 @@ public final class GlobalConfigurationConstants {
     public static final String NEXT_PAYMENT_DUE_DATE = "next-payment-due-date";
     public static final String ENABLE_PAYMENT_HUB_INTEGRATION = 
"enable-payment-hub-integration";
     public static final String ENABLE_IMMEDIATE_CHARGE_ACCRUAL_POST_MATURITY = 
"enable-immediate-charge-accrual-post-maturity";
+    public static final String 
ASSET_OWNER_TRANSFER_OUTSTANDING_INTEREST_CALCULATION_STRATEGY = 
"outstanding-interest-calculation-strategy-for-external-asset-transfer";
 
     private GlobalConfigurationConstants() {}
 }
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainService.java
 
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainService.java
index e7482d16a1..7a138fb25f 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainService.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainService.java
@@ -145,4 +145,5 @@ public interface ConfigurationDomainService {
 
     boolean isImmediateChargeAccrualPostMaturityEnabled();
 
+    String getAssetOwnerTransferOustandingInterestStrategy();
 }
diff --git 
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/helper/GlobalConfigurationHelper.java
 
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/helper/GlobalConfigurationHelper.java
index 224b6d76e9..fefacea9e6 100644
--- 
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/helper/GlobalConfigurationHelper.java
+++ 
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/helper/GlobalConfigurationHelper.java
@@ -74,4 +74,10 @@ public class GlobalConfigurationHelper {
         boolean isEnabled = 
BooleanUtils.toBoolean(updatedConfiguration.body().getEnabled());
         assertThat(isEnabled).isEqualTo(true);
     }
+
+    public GlobalConfigurationPropertyData getGlobalConfiguration(String 
configKey) throws IOException {
+        Response<GlobalConfigurationPropertyData> configuration = 
globalConfigurationApi.retrieveOneByName(configKey).execute();
+        ErrorHelper.checkSuccessfulApiCall(configuration);
+        return configuration.body();
+    }
 }
diff --git 
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/messaging/event/EventCheckHelper.java
 
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/messaging/event/EventCheckHelper.java
index abf0c196e6..6f7f7397f2 100644
--- 
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/messaging/event/EventCheckHelper.java
+++ 
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/messaging/event/EventCheckHelper.java
@@ -41,6 +41,7 @@ import 
org.apache.fineract.client.models.GetClientsClientIdResponse;
 import org.apache.fineract.client.models.GetLoansLoanIdDelinquencyPausePeriod;
 import org.apache.fineract.client.models.GetLoansLoanIdResponse;
 import org.apache.fineract.client.models.GetLoansLoanIdTransactions;
+import org.apache.fineract.client.models.GlobalConfigurationPropertyData;
 import org.apache.fineract.client.models.PageExternalTransferData;
 import org.apache.fineract.client.models.PostClientsResponse;
 import org.apache.fineract.client.models.PostLoansLoanIdResponse;
@@ -53,6 +54,7 @@ import 
org.apache.fineract.test.data.AssetExternalizationTransferStatus;
 import org.apache.fineract.test.data.AssetExternalizationTransferStatusReason;
 import org.apache.fineract.test.data.TransactionType;
 import org.apache.fineract.test.helper.ErrorMessageHelper;
+import org.apache.fineract.test.helper.GlobalConfigurationHelper;
 import org.apache.fineract.test.messaging.EventAssertion;
 import 
org.apache.fineract.test.messaging.event.assetexternalization.LoanAccountSnapshotEvent;
 import 
org.apache.fineract.test.messaging.event.assetexternalization.LoanOwnershipTransferEvent;
@@ -90,15 +92,14 @@ public class EventCheckHelper {
 
     @Autowired
     private ClientApi clientApi;
-
     @Autowired
     private LoansApi loansApi;
-
     @Autowired
     private EventAssertion eventAssertion;
-
     @Autowired
     private ExternalAssetOwnersApi externalAssetOwnersApi;
+    @Autowired
+    private GlobalConfigurationHelper configurationHelper;
 
     public void clientEventCheck(Response<PostClientsResponse> 
clientCreationResponse) throws IOException {
         Response<GetClientsClientIdResponse> clientDetails = 
clientApi.retrieveOne11(clientCreationResponse.body().getClientId(), false)
@@ -412,14 +413,24 @@ public class EventCheckHelper {
         ExternalTransferData filtered = content.stream().filter(t -> 
transferId.equals(t.getTransferId())).reduce((first, second) -> second)
                 .orElseThrow(() -> new IllegalStateException("No element 
found"));
 
+        BigDecimal totalOutstandingBalanceAmountExpected = 
zeroConversion(filtered.getDetails().getTotalOutstanding());
+        BigDecimal outstandingInterestPortionExpected = 
zeroConversion(filtered.getDetails().getTotalInterestOutstanding());
+
+        GlobalConfigurationPropertyData outstandingInterestStrategy = 
configurationHelper
+                
.getGlobalConfiguration("outstanding-interest-calculation-strategy-for-external-asset-transfer");
+        if 
("PAYABLE_OUTSTANDING_INTEREST".equals(outstandingInterestStrategy.getStringValue()))
 {
+            Response<GetLoansLoanIdResponse> loanDetails = 
loansApi.retrieveLoan(loanId, false, "all", null, null).execute();
+            totalOutstandingBalanceAmountExpected = 
BigDecimal.valueOf(loanDetails.body().getSummary().getTotalOutstanding());
+            outstandingInterestPortionExpected = 
BigDecimal.valueOf(loanDetails.body().getSummary().getInterestOutstanding());
+        }
+
         String ownerExternalIdExpected = 
filtered.getStatus().getValue().equals("BUYBACK") ? null : 
filtered.getOwner().getExternalId();
         String settlementDateExpected = 
filtered.getStatus().getValue().equals("BUYBACK") ? null
                 : FORMATTER_EVENTS.format(filtered.getSettlementDate());
-        BigDecimal totalOutstandingBalanceAmountExpected = 
zeroConversion(filtered.getDetails().getTotalOutstanding());
         BigDecimal outstandingPrincipalPortionExpected = 
zeroConversion(filtered.getDetails().getTotalPrincipalOutstanding());
         BigDecimal outstandingFeePortionExpected = 
zeroConversion(filtered.getDetails().getTotalFeeChargesOutstanding());
         BigDecimal outstandingPenaltyPortionExpected = 
zeroConversion(filtered.getDetails().getTotalPenaltyChargesOutstanding());
-        BigDecimal outstandingInterestPortionExpected = 
zeroConversion(filtered.getDetails().getTotalInterestOutstanding());
+
         BigDecimal overPaymentPortionExpected = 
zeroConversion(filtered.getDetails().getTotalOverpaid());
 
         eventAssertion.assertEvent(LoanAccountSnapshotEvent.class, 
loanId).extractingData(LoanAccountDataV1::getId).isEqualTo(loanId)
diff --git 
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/assetexternalization/AssetExternalizationStepDef.java
 
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/assetexternalization/AssetExternalizationStepDef.java
index 82d597abcb..b9f9fea0d2 100644
--- 
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/assetexternalization/AssetExternalizationStepDef.java
+++ 
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/assetexternalization/AssetExternalizationStepDef.java
@@ -341,11 +341,6 @@ public class AssetExternalizationStepDef extends 
AbstractStepDef {
                 transferExternalId = 
testContext().get(TestContextKey.ASSET_EXTERNALIZATION_SALES_TRANSFER_EXTERNAL_ID_FROM_RESPONSE);
             }
 
-            expectedValues.add(ownerExternalIdStored);
-            expectedValues.add(loanId == null ? null : String.valueOf(loanId));
-            expectedValues.add(loanExternalId);
-            expectedValues.add(transferExternalId);
-
             List<List<String>> actualValuesList = content.stream().map(t -> {
                 List<String> actualValues = new ArrayList<>();
                 actualValues.add(t.getSettlementDate() == null ? null : 
FORMATTER.format(t.getSettlementDate()));
@@ -354,6 +349,31 @@ public class AssetExternalizationStepDef extends 
AbstractStepDef {
                 actualValues.add(t.getEffectiveFrom() == null ? null : 
FORMATTER.format(t.getEffectiveFrom()));
                 actualValues.add(t.getEffectiveTo() == null ? null : 
FORMATTER.format(t.getEffectiveTo()));
                 actualValues.add(transactionType);
+                if (expectedValues.size() > 6) {
+                    actualValues.add(
+                            t.getDetails() != null ? 
t.getDetails().getTotalOutstanding().setScale(2, 
RoundingMode.HALF_DOWN).toString()
+                                    : null);
+                }
+                if (expectedValues.size() > 7) {
+                    actualValues.add(t.getDetails() != null
+                            ? 
t.getDetails().getTotalPrincipalOutstanding().setScale(2, 
RoundingMode.HALF_DOWN).toString()
+                            : null);
+                }
+                if (expectedValues.size() > 8) {
+                    actualValues.add(t.getDetails() != null
+                            ? 
t.getDetails().getTotalInterestOutstanding().setScale(2, 
RoundingMode.HALF_DOWN).toString()
+                            : null);
+                }
+                if (expectedValues.size() > 9) {
+                    actualValues.add(t.getDetails() != null
+                            ? 
t.getDetails().getTotalFeeChargesOutstanding().setScale(2, 
RoundingMode.HALF_DOWN).toString()
+                            : null);
+                }
+                if (expectedValues.size() > 10) {
+                    actualValues.add(t.getDetails() != null
+                            ? 
t.getDetails().getTotalPenaltyChargesOutstanding().setScale(2, 
RoundingMode.HALF_DOWN).toString()
+                            : null);
+                }
                 actualValues.add(t.getOwner().getExternalId() == null ? null : 
t.getOwner().getExternalId());
                 actualValues.add(loanId == null ? null : 
String.valueOf(t.getLoan().getLoanId()));
                 actualValues.add(loanExternalId == null ? null : 
t.getLoan().getExternalId());
@@ -361,6 +381,11 @@ public class AssetExternalizationStepDef extends 
AbstractStepDef {
                 return actualValues;
             }).collect(Collectors.toList());
 
+            expectedValues.add(ownerExternalIdStored);
+            expectedValues.add(loanId == null ? null : String.valueOf(loanId));
+            expectedValues.add(loanExternalId);
+            expectedValues.add(transferExternalId);
+
             boolean containsExpectedValues = 
actualValuesList.stream().anyMatch(actualValues -> 
actualValues.equals(expectedValues));
 
             assertThat(numberOfElementsActual)
diff --git 
a/fineract-e2e-tests-runner/src/test/resources/features/AssetExternalization.feature
 
b/fineract-e2e-tests-runner/src/test/resources/features/AssetExternalization.feature
index 327c9333aa..c205844b61 100644
--- 
a/fineract-e2e-tests-runner/src/test/resources/features/AssetExternalization.feature
+++ 
b/fineract-e2e-tests-runner/src/test/resources/features/AssetExternalization.feature
@@ -1679,3 +1679,100 @@ Feature: Asset Externalization
       | INCOME        | 404000        | Interest Income         | CREDIT    | 
0.33    |
       | ASSET         | 112603        | Interest/Fee Receivable | DEBIT     | 
0.33    |
       | INCOME        | 404000        | Interest Income         | CREDIT    | 
0.33    |
+
+  @TestRailId:C3690 @AssetExternalizationJournalEntry
+  Scenario: Verify that Asset externalization SALES and BUYBACK has the 
correct Journal entries with PAYABLE_OUTSTANDING_INTEREST strategy
+    When Global config 
"outstanding-interest-calculation-strategy-for-external-asset-transfer" value 
set to "PAYABLE_OUTSTANDING_INTEREST"
+    When Admin sets the business date to "1 May 2023"
+    When Admin creates a client with random data
+    When Admin creates a fully customized loan with the following data:
+      | LoanProduct                                     | submitted on date | 
with Principal | ANNUAL interest rate % | interest type     | interest 
calculation period | amortization type  | loanTermFrequency | 
loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | 
numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | 
interest free period | Payment strategy            |
+      | LP2_ADV_PYMNT_INTEREST_DAILY_EMI_ACTUAL_ACTUAL | 01 May 2023       | 
1000           | 12                     | DECLINING_BALANCE | DAILY             
          | EQUAL_INSTALLMENTS | 6                 | MONTHS                | 1  
            | MONTHS                 | 6                  | 0                   
    | 0                      | 0                    | 
ADVANCED_PAYMENT_ALLOCATION |
+    And Admin successfully approves the loan on "1 May 2023" with "1000" 
amount and expected disbursement date on "1 May 2023"
+    When Admin successfully disburse the loan on "1 May 2023" with "1000" EUR 
transaction amount
+    Then Loan status will be "ACTIVE"
+    When Admin makes asset externalization request by Loan ID with unique 
ownerExternalId, system-generated transferExternalId and the following data:
+      | Transaction type | settlementDate | purchasePriceRatio |
+      | sale             | 2023-05-21     | 1                  |
+    Then Asset externalization response has the correct Loan ID, 
transferExternalId
+    Then Fetching Asset externalization details by loan id gives 
numberOfElements: 1 with correct ownerExternalId and the following data:
+      | settlementDate | purchasePriceRatio | status  | effectiveFrom | 
effectiveTo | Transaction type | totalOutstanding | totalPrincipalOutstanding | 
totalInterestOutstanding | totalFeeChargesOutstanding | 
totalPenaltyChargesOutstanding |
+      | 2023-05-21     | 1                  | PENDING | 2023-05-01    | 
9999-12-31  | SALE             |                  |                           | 
                         |                            |                         
       |
+    When Admin adds "LOAN_SNOOZE_FEE" due date charge with "10 May 2023" due 
date and 10 EUR transaction amount
+    When Admin sets the business date to "10 May 2023"
+    When Admin runs inline COB job for Loan
+    When Admin sets the business date to "22 May 2023"
+    When Admin runs inline COB job for Loan
+    Then LoanOwnershipTransferBusinessEvent is created
+    Then LoanAccountSnapshotBusinessEvent is created
+    Then Fetching Asset externalization details by loan id gives 
numberOfElements: 2 with correct ownerExternalId and the following data:
+      | settlementDate | purchasePriceRatio | status  | effectiveFrom | 
effectiveTo | Transaction type | totalOutstanding | totalPrincipalOutstanding | 
totalInterestOutstanding | totalFeeChargesOutstanding | 
totalPenaltyChargesOutstanding |
+      | 2023-05-21     | 1                  | PENDING | 2023-05-01    | 
2023-05-21  | SALE             |                  |                           | 
                         |                            |                         
       |
+      | 2023-05-21     | 1                  | ACTIVE  | 2023-05-22    | 
9999-12-31  | SALE             | 1016.58          | 1000.00                   | 
6.58                     | 10.00                      | 0.00                    
       |
+    Then The latest asset externalization transaction with "ACTIVE" status has 
the following TRANSFER Journal entries:
+      | glAccountType | glAccountCode | glAccountName           | entryType | 
amount  |
+      | ASSET         | 112601        | Loans Receivable        | CREDIT    | 
1000.00 |
+      | ASSET         | 112603        | Interest/Fee Receivable | CREDIT    | 
16.58   |
+      | ASSET         | 146000        | Asset transfer          | DEBIT     | 
1016.58 |
+      | ASSET         | 112601        | Loans Receivable        | DEBIT     | 
1000.00 |
+      | ASSET         | 112603        | Interest/Fee Receivable | DEBIT     | 
16.58   |
+      | ASSET         | 146000        | Asset transfer          | CREDIT    | 
1016.58 |
+    Then The asset external owner has the following OWNER Journal entries:
+      | glAccountType | glAccountCode | glAccountName           | entryType | 
amount  |
+      | ASSET         | 112601        | Loans Receivable        | DEBIT     | 
1000.00 |
+      | ASSET         | 112603        | Interest/Fee Receivable | DEBIT     | 
16.58   |
+    When Admin makes asset externalization request by Loan ID with unique 
ownerExternalId, system-generated transferExternalId and the following data:
+      | Transaction type | settlementDate | purchasePriceRatio |
+      | buyback          | 2023-05-30     |                    |
+    Then Fetching Asset externalization details by loan id gives 
numberOfElements: 3 with correct ownerExternalId and the following data:
+      | settlementDate | purchasePriceRatio | status  | effectiveFrom | 
effectiveTo | Transaction type | totalOutstanding | totalPrincipalOutstanding | 
totalInterestOutstanding | totalFeeChargesOutstanding | 
totalPenaltyChargesOutstanding |
+      | 2023-05-21     | 1                  | PENDING | 2023-05-01    | 
2023-05-21  | SALE             |                  |                           | 
                         |                            |                         
       |
+      | 2023-05-21     | 1                  | ACTIVE  | 2023-05-22    | 
9999-12-31  | SALE             | 1016.58          | 1000.00                   | 
6.58                     | 10.00                      | 0.00                    
       |
+      | 2023-05-30     | 1                  | BUYBACK | 2023-05-22    | 
9999-12-31  | BUYBACK          |                  |                           | 
                         |                            |                         
       |
+    When Admin adds "LOAN_NSF_FEE" due date charge with "25 May 2023" due date 
and 20 EUR transaction amount
+    When Admin sets the business date to "26 May 2023"
+    When Admin runs inline COB job for Loan
+    When Admin sets the business date to "31 May 2023"
+    When Admin runs inline COB job for Loan
+    Then LoanOwnershipTransferBusinessEvent is created
+    Then LoanAccountSnapshotBusinessEvent is created
+    Then Fetching Asset externalization details by loan id gives 
numberOfElements: 3 with correct ownerExternalId and the following data:
+      | settlementDate | purchasePriceRatio | status  | effectiveFrom | 
effectiveTo | Transaction type | totalOutstanding | totalPrincipalOutstanding | 
totalInterestOutstanding | totalFeeChargesOutstanding | 
totalPenaltyChargesOutstanding |
+      | 2023-05-21     | 1                  | PENDING | 2023-05-01    | 
2023-05-21  | SALE             |                  |                           | 
                         |                            |                         
       |
+      | 2023-05-21     | 1                  | ACTIVE  | 2023-05-22    | 
2023-05-30  | SALE             | 1016.58          | 1000.00                   | 
6.58                     | 10.00                      | 0.00                    
       |
+      | 2023-05-30     | 1                  | BUYBACK | 2023-05-22    | 
2023-05-30  | BUYBACK          | 1039.53          | 1000.00                   | 
9.53                     | 10.00                      | 20.00                   
       |
+    Then The latest asset externalization transaction with "BUYBACK" status 
has the following TRANSFER Journal entries:
+      | glAccountType | glAccountCode | glAccountName           | entryType | 
amount  |
+      | ASSET         | 112601        | Loans Receivable        | DEBIT     | 
1000.00 |
+      | ASSET         | 112603        | Interest/Fee Receivable | DEBIT     | 
39.53   |
+      | ASSET         | 146000        | Asset transfer          | CREDIT    | 
1039.53 |
+      | ASSET         | 112601        | Loans Receivable        | CREDIT    | 
1000.00 |
+      | ASSET         | 112603        | Interest/Fee Receivable | CREDIT    | 
39.53   |
+      | ASSET         | 146000        | Asset transfer          | DEBIT     | 
1039.53 |
+    Then The asset external owner has the following OWNER Journal entries:
+      | glAccountType | glAccountCode | glAccountName           | entryType | 
amount  |
+      | ASSET         | 112601        | Loans Receivable        | DEBIT     | 
1000.00 |
+      | ASSET         | 112603        | Interest/Fee Receivable | DEBIT     | 
16.58   |
+      | ASSET         | 112603        | Interest/Fee Receivable | DEBIT     | 
0.33    |
+      | INCOME        | 404000        | Interest Income         | CREDIT    | 
0.33    |
+      | ASSET         | 112603        | Interest/Fee Receivable | DEBIT     | 
0.33    |
+      | INCOME        | 404000        | Interest Income         | CREDIT    | 
0.33    |
+      | ASSET         | 112603        | Interest/Fee Receivable | DEBIT     | 
0.33    |
+      | INCOME        | 404000        | Interest Income         | CREDIT    | 
0.33    |
+      | ASSET         | 112603        | Interest/Fee Receivable | DEBIT     | 
0.33    |
+      | INCOME        | 404000        | Interest Income         | CREDIT    | 
0.33    |
+      | ASSET         | 112603        | Interest/Fee Receivable | DEBIT     | 
0.33    |
+      | INCOME        | 404000        | Interest Income         | CREDIT    | 
0.33    |
+      | ASSET         | 112603        | Interest/Fee Receivable | DEBIT     | 
0.33    |
+      | INCOME        | 404000        | Interest Income         | CREDIT    | 
0.33    |
+      | ASSET         | 112603        | Interest/Fee Receivable | DEBIT     | 
0.33    |
+      | INCOME        | 404000        | Interest Income         | CREDIT    | 
0.33    |
+      | ASSET         | 112603        | Interest/Fee Receivable | DEBIT     | 
0.33    |
+      | INCOME        | 404000        | Interest Income         | CREDIT    | 
0.33    |
+      | ASSET         | 112603        | Interest/Fee Receivable | DEBIT     | 
0.33    |
+      | INCOME        | 404000        | Interest Income         | CREDIT    | 
0.33    |
+      | ASSET         | 112603        | Interest/Fee Receivable | DEBIT     | 
0.33    |
+      | INCOME        | 404000        | Interest Income         | CREDIT    | 
0.33    |
+      | ASSET         | 112603        | Interest/Fee Receivable | DEBIT     | 
0.33    |
+      | INCOME        | 404000        | Interest Income         | CREDIT    | 
0.33    |
+    When Global config 
"outstanding-interest-calculation-strategy-for-external-asset-transfer" value 
set to "TOTAL_OUTSTANDING_INTEREST"
diff --git 
a/fineract-investor/src/main/java/org/apache/fineract/investor/cob/loan/LoanAccountOwnerTransferBusinessStep.java
 
b/fineract-investor/src/main/java/org/apache/fineract/investor/cob/loan/LoanAccountOwnerTransferBusinessStep.java
index 752501c9b6..3ba0963ee3 100644
--- 
a/fineract-investor/src/main/java/org/apache/fineract/investor/cob/loan/LoanAccountOwnerTransferBusinessStep.java
+++ 
b/fineract-investor/src/main/java/org/apache/fineract/investor/cob/loan/LoanAccountOwnerTransferBusinessStep.java
@@ -21,7 +21,6 @@ package org.apache.fineract.investor.cob.loan;
 import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.util.List;
-import java.util.Objects;
 import java.util.Optional;
 import java.util.stream.Stream;
 import lombok.RequiredArgsConstructor;
@@ -42,6 +41,7 @@ import 
org.apache.fineract.investor.domain.ExternalAssetOwnerTransferRepository;
 import org.apache.fineract.investor.domain.LoanOwnershipTransferBusinessEvent;
 import org.apache.fineract.investor.service.AccountingService;
 import org.apache.fineract.investor.service.DelayedSettlementAttributeService;
+import 
org.apache.fineract.investor.service.ExternalAssetOwnerTransferOutstandingInterestCalculation;
 import org.apache.fineract.investor.service.LoanTransferabilityService;
 import org.apache.fineract.portfolio.loanaccount.domain.Loan;
 import org.springframework.context.annotation.Conditional;
@@ -65,6 +65,7 @@ public class LoanAccountOwnerTransferBusinessStep implements 
LoanCOBBusinessStep
     private final BusinessEventNotifierService businessEventNotifierService;
     private final LoanTransferabilityService loanTransferabilityService;
     private final DelayedSettlementAttributeService 
delayedSettlementAttributeService;
+    private final ExternalAssetOwnerTransferOutstandingInterestCalculation 
externalAssetOwnerTransferOutstandingInterestCalculation;
 
     @Override
     public Loan execute(Loan loan) {
@@ -220,14 +221,13 @@ public class LoanAccountOwnerTransferBusinessStep 
implements LoanCOBBusinessStep
             ExternalAssetOwnerTransfer externalAssetOwnerTransfer) {
         ExternalAssetOwnerTransferDetails details = new 
ExternalAssetOwnerTransferDetails();
         details.setExternalAssetOwnerTransfer(externalAssetOwnerTransfer);
-        
details.setTotalOutstanding(Objects.requireNonNullElse(loan.getSummary().getTotalOutstanding(),
 BigDecimal.ZERO));
-        
details.setTotalPrincipalOutstanding(Objects.requireNonNullElse(loan.getSummary().getTotalPrincipalOutstanding(),
 BigDecimal.ZERO));
-        
details.setTotalInterestOutstanding(Objects.requireNonNullElse(loan.getSummary().getTotalInterestOutstanding(),
 BigDecimal.ZERO));
-        details.setTotalFeeChargesOutstanding(
-                
Objects.requireNonNullElse(loan.getSummary().getTotalFeeChargesOutstanding(), 
BigDecimal.ZERO));
-        details.setTotalPenaltyChargesOutstanding(
-                
Objects.requireNonNullElse(loan.getSummary().getTotalPenaltyChargesOutstanding(),
 BigDecimal.ZERO));
-        
details.setTotalOverpaid(Objects.requireNonNullElse(loan.getTotalOverpaid(), 
BigDecimal.ZERO));
+        
details.setTotalPrincipalOutstanding(loan.getSummary().getTotalPrincipalOutstanding());
+        // We have different strategies to calculate oustanding interest
+        final BigDecimal interestAmount = 
externalAssetOwnerTransferOutstandingInterestCalculation.calculateOutstandingInterest(loan);
+        details.setTotalInterestOutstanding(interestAmount);
+        
details.setTotalFeeChargesOutstanding(loan.getSummary().getTotalFeeChargesOutstanding());
+        
details.setTotalPenaltyChargesOutstanding(loan.getSummary().getTotalPenaltyChargesOutstanding());
+        details.setTotalOverpaid(loan.getTotalOverpaid());
         return details;
     }
 
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanSummaryProviderDelegate.java
 
b/fineract-investor/src/main/java/org/apache/fineract/investor/domain/AttributeKey.java
similarity index 54%
copy from 
fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanSummaryProviderDelegate.java
copy to 
fineract-investor/src/main/java/org/apache/fineract/investor/domain/AttributeKey.java
index 20f9663fce..f874eaf1f8 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanSummaryProviderDelegate.java
+++ 
b/fineract-investor/src/main/java/org/apache/fineract/investor/domain/AttributeKey.java
@@ -16,20 +16,13 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.portfolio.loanaccount.service;
+package org.apache.fineract.investor.domain;
 
-import java.util.List;
-import lombok.AllArgsConstructor;
-import org.springframework.stereotype.Component;
+public interface AttributeKey {
 
-@Component
-@AllArgsConstructor
-public class LoanSummaryProviderDelegate {
+    String getKey();
 
-    private final List<LoanSummaryDataProvider> loanSummaryDataProviders;
+    String getValue();
 
-    public LoanSummaryDataProvider resolveLoanSummaryDataProvider(String 
loanProcessingStrategyCode) {
-        return loanSummaryDataProviders.stream().filter(provider -> 
provider.accept(loanProcessingStrategyCode)).findAny()
-                .orElseThrow(() -> new IllegalArgumentException("No provider 
found for :" + loanProcessingStrategyCode));
-    }
+    String getDescription();
 }
diff --git 
a/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerLoanProductAttribute.java
 
b/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerLoanProductAttribute.java
new file mode 100644
index 0000000000..fb08c38209
--- /dev/null
+++ 
b/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerLoanProductAttribute.java
@@ -0,0 +1,38 @@
+/**
+ * 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.investor.domain;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+@RequiredArgsConstructor
+@Getter
+public class ExternalAssetOwnerLoanProductAttribute implements AttributeKey {
+
+    public static final ExternalAssetOwnerLoanProductAttribute 
TOTAL_OUTSTANDING_INTEREST_STRATEGY = new 
ExternalAssetOwnerLoanProductAttribute(
+            "OUTSTANDING_INTEREST_STRATEGY", "TOTAL_OUTSTANDING",
+            "During external owner transfer the total (due + not yet due + 
projected) interest participate");
+    public static final ExternalAssetOwnerLoanProductAttribute 
PAYABLE_OUTSTANDING_INTEREST_STRATEGY = new 
ExternalAssetOwnerLoanProductAttribute(
+            "OUTSTANDING_INTEREST_STRATEGY", "PAYABLE_OUTSTANDING",
+            "During external owner transfer the total (due + not yet due) 
interest participate");
+
+    private final String key;
+    private final String value;
+    private final String description;
+}
diff --git 
a/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerTransferDetails.java
 
b/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerTransferDetails.java
index da1d29727d..13ae8323fb 100644
--- 
a/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerTransferDetails.java
+++ 
b/fineract-investor/src/main/java/org/apache/fineract/investor/domain/ExternalAssetOwnerTransferDetails.java
@@ -25,18 +25,20 @@ import jakarta.persistence.JoinColumn;
 import jakarta.persistence.OneToOne;
 import jakarta.persistence.Table;
 import java.math.BigDecimal;
+import java.util.Objects;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
 import lombok.Setter;
 import 
org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
+import org.apache.fineract.infrastructure.core.service.MathUtil;
 
 @Getter
-@Setter
 @Table(name = "m_external_asset_owner_transfer_details")
 @NoArgsConstructor
 @Entity
 public class ExternalAssetOwnerTransferDetails extends 
AbstractAuditableWithUTCDateTimeCustom<Long> {
 
+    @Setter
     @OneToOne(cascade = CascadeType.ALL)
     @JoinColumn(name = "asset_owner_transfer_id", referencedColumnName = "id")
     private ExternalAssetOwnerTransfer externalAssetOwnerTransfer;
@@ -58,4 +60,33 @@ public class ExternalAssetOwnerTransferDetails extends 
AbstractAuditableWithUTCD
 
     @Column(name = "total_overpaid_derived", scale = 6, precision = 19, 
nullable = false)
     private BigDecimal totalOverpaid;
+
+    public void setTotalPrincipalOutstanding(BigDecimal 
totalPrincipalOutstanding) {
+        this.totalPrincipalOutstanding = 
Objects.requireNonNullElse(totalPrincipalOutstanding, BigDecimal.ZERO);
+        updateTotalOutstanding();
+    }
+
+    public void setTotalInterestOutstanding(BigDecimal 
totalInterestOutstanding) {
+        this.totalInterestOutstanding = 
Objects.requireNonNullElse(totalInterestOutstanding, BigDecimal.ZERO);
+        updateTotalOutstanding();
+    }
+
+    public void setTotalFeeChargesOutstanding(BigDecimal 
totalFeeChargesOutstanding) {
+        this.totalFeeChargesOutstanding = 
Objects.requireNonNullElse(totalFeeChargesOutstanding, BigDecimal.ZERO);
+        updateTotalOutstanding();
+    }
+
+    public void setTotalPenaltyChargesOutstanding(BigDecimal 
totalPenaltyChargesOutstanding) {
+        this.totalPenaltyChargesOutstanding = 
Objects.requireNonNullElse(totalPenaltyChargesOutstanding, BigDecimal.ZERO);
+        updateTotalOutstanding();
+    }
+
+    private void updateTotalOutstanding() {
+        this.totalOutstanding = MathUtil.add(getTotalPrincipalOutstanding(), 
getTotalInterestOutstanding(), getTotalFeeChargesOutstanding(),
+                getTotalPenaltyChargesOutstanding());
+    }
+
+    public void setTotalOverpaid(BigDecimal totalOverpaid) {
+        this.totalOverpaid = Objects.requireNonNullElse(totalOverpaid, 
BigDecimal.ZERO);
+    }
 }
diff --git 
a/fineract-investor/src/main/java/org/apache/fineract/investor/service/AccountingServiceImpl.java
 
b/fineract-investor/src/main/java/org/apache/fineract/investor/service/AccountingServiceImpl.java
index fe72d6182a..d60487a135 100644
--- 
a/fineract-investor/src/main/java/org/apache/fineract/investor/service/AccountingServiceImpl.java
+++ 
b/fineract-investor/src/main/java/org/apache/fineract/investor/service/AccountingServiceImpl.java
@@ -55,6 +55,7 @@ public class AccountingServiceImpl implements 
AccountingService {
     private final ExternalAssetOwnerTransferJournalEntryMappingRepository 
externalAssetOwnerTransferJournalEntryMappingRepository;
     private final ExternalAssetOwnerJournalEntryMappingRepository 
externalAssetOwnerJournalEntryMappingRepository;
     private final FinancialActivityAccountRepositoryWrapper 
financialActivityAccountRepository;
+    private final ExternalAssetOwnerTransferOutstandingInterestCalculation 
externalAssetOwnerTransferOutstandingInterestCalculation;
 
     @Override
     public void createJournalEntriesForSaleAssetTransfer(final Loan loan, 
final ExternalAssetOwnerTransfer transfer,
@@ -104,7 +105,8 @@ public class AccountingServiceImpl implements 
AccountingService {
         final Long transactionId = transfer.getId();
         final LocalDate transactionDate = transfer.getSettlementDate();
         final BigDecimal principalAmount = 
loan.getSummary().getTotalPrincipalOutstanding();
-        final BigDecimal interestAmount = 
loan.getSummary().getTotalInterestOutstanding();
+        // We have different strategies to calculate oustanding interest
+        final BigDecimal interestAmount = 
externalAssetOwnerTransferOutstandingInterestCalculation.calculateOutstandingInterest(loan);
         final BigDecimal feesAmount = 
loan.getSummary().getTotalFeeChargesOutstanding();
         final BigDecimal penaltiesAmount = 
loan.getSummary().getTotalPenaltyChargesOutstanding();
         final BigDecimal overPaymentAmount = loan.getTotalOverpaid();
diff --git 
a/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnerTransferOutstandingInterestCalculation.java
 
b/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnerTransferOutstandingInterestCalculation.java
new file mode 100644
index 0000000000..46422b88c8
--- /dev/null
+++ 
b/fineract-investor/src/main/java/org/apache/fineract/investor/service/ExternalAssetOwnerTransferOutstandingInterestCalculation.java
@@ -0,0 +1,69 @@
+/**
+ * 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.investor.service;
+
+import java.math.BigDecimal;
+import lombok.RequiredArgsConstructor;
+import 
org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
+import org.apache.fineract.infrastructure.core.service.DateUtils;
+import org.apache.fineract.infrastructure.core.service.MathUtil;
+import org.apache.fineract.investor.config.InvestorModuleIsEnabledCondition;
+import org.apache.fineract.organisation.monetary.domain.Money;
+import org.apache.fineract.portfolio.loanaccount.data.LoanAccountData;
+import org.apache.fineract.portfolio.loanaccount.domain.Loan;
+import 
org.apache.fineract.portfolio.loanaccount.service.LoanReadPlatformService;
+import 
org.apache.fineract.portfolio.loanaccount.service.LoanSummaryDataProvider;
+import 
org.apache.fineract.portfolio.loanaccount.service.LoanSummaryProviderDelegate;
+import org.springframework.context.annotation.Conditional;
+import org.springframework.stereotype.Component;
+
+@Component
+@RequiredArgsConstructor
+@Conditional(InvestorModuleIsEnabledCondition.class)
+public class ExternalAssetOwnerTransferOutstandingInterestCalculation {
+
+    private final LoanSummaryProviderDelegate loanSummaryDataProvider;
+    private final ConfigurationDomainService configurationDomainService;
+    private final LoanReadPlatformService loanReadPlatformService;
+
+    private LoanSummaryDataProvider fetchLoanSummaryDataProvider(Loan loan) {
+        return 
this.loanSummaryDataProvider.resolveLoanSummaryDataProvider(loan.getTransactionProcessingStrategyCode());
+    }
+
+    public BigDecimal calculateOutstandingInterest(Loan loan) {
+        String outstandingInterestCalculationStrategy = 
configurationDomainService.getAssetOwnerTransferOustandingInterestStrategy();
+        return switch (outstandingInterestCalculationStrategy) {
+            case "TOTAL_OUTSTANDING_INTEREST" -> 
loan.getSummary().getTotalInterestOutstanding();
+            case "PAYABLE_OUTSTANDING_INTEREST" -> {
+                LoanAccountData data = 
loanReadPlatformService.retrieveOne(loan.getId());
+                data = 
loanReadPlatformService.fetchRepaymentScheduleData(data);
+                Money duePayableAmount = loan
+                        .getRepaymentScheduleInstallments(i -> 
!i.getDueDate().isAfter(DateUtils.getBusinessLocalDate())).stream()
+                        .map(i -> 
i.getInterestOutstanding(loan.getCurrency())).reduce(Money.zero(loan.getCurrency()),
 MathUtil::plus);
+                BigDecimal notDuePayableAmount = 
fetchLoanSummaryDataProvider(loan)
+                        
.computeTotalUnpaidPayableNotDueInterestAmountOnActualPeriod(loan, 
data.getRepaymentSchedule().getPeriods(),
+                                DateUtils.getBusinessLocalDate(), 
loan.getCurrency().toData(), duePayableAmount.getAmount());
+
+                yield MathUtil.add(duePayableAmount.getAmount(), 
notDuePayableAmount);
+            }
+            default -> throw new UnsupportedOperationException(
+                    "Unknown outstanding interest calculation: " + 
outstandingInterestCalculationStrategy);
+        };
+    }
+}
diff --git 
a/fineract-investor/src/main/java/org/apache/fineract/investor/service/LoanAccountOwnerTransferServiceImpl.java
 
b/fineract-investor/src/main/java/org/apache/fineract/investor/service/LoanAccountOwnerTransferServiceImpl.java
index c638a06d8f..28876ff79e 100644
--- 
a/fineract-investor/src/main/java/org/apache/fineract/investor/service/LoanAccountOwnerTransferServiceImpl.java
+++ 
b/fineract-investor/src/main/java/org/apache/fineract/investor/service/LoanAccountOwnerTransferServiceImpl.java
@@ -35,7 +35,6 @@ import static 
org.apache.fineract.investor.data.ExternalTransferSubStatus.UNSOLD
 import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.util.List;
-import java.util.Objects;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.service.MathUtil;
@@ -63,6 +62,7 @@ public class LoanAccountOwnerTransferServiceImpl implements 
LoanAccountOwnerTran
     private final ExternalAssetOwnerTransferLoanMappingRepository 
externalAssetOwnerTransferLoanMappingRepository;
     private final AccountingService accountingService;
     private final BusinessEventNotifierService businessEventNotifierService;
+    private final ExternalAssetOwnerTransferOutstandingInterestCalculation 
externalAssetOwnerTransferOutstandingInterestCalculation;
 
     @Override
     public void handleLoanClosedOrOverpaid(Loan loan) {
@@ -166,14 +166,13 @@ public class LoanAccountOwnerTransferServiceImpl 
implements LoanAccountOwnerTran
             ExternalAssetOwnerTransfer externalAssetOwnerTransfer) {
         ExternalAssetOwnerTransferDetails details = new 
ExternalAssetOwnerTransferDetails();
         details.setExternalAssetOwnerTransfer(externalAssetOwnerTransfer);
-        
details.setTotalOutstanding(Objects.requireNonNullElse(loan.getSummary().getTotalOutstanding(),
 BigDecimal.ZERO));
-        
details.setTotalPrincipalOutstanding(Objects.requireNonNullElse(loan.getSummary().getTotalPrincipalOutstanding(),
 BigDecimal.ZERO));
-        
details.setTotalInterestOutstanding(Objects.requireNonNullElse(loan.getSummary().getTotalInterestOutstanding(),
 BigDecimal.ZERO));
-        details.setTotalFeeChargesOutstanding(
-                
Objects.requireNonNullElse(loan.getSummary().getTotalFeeChargesOutstanding(), 
BigDecimal.ZERO));
-        details.setTotalPenaltyChargesOutstanding(
-                
Objects.requireNonNullElse(loan.getSummary().getTotalPenaltyChargesOutstanding(),
 BigDecimal.ZERO));
-        
details.setTotalOverpaid(Objects.requireNonNullElse(loan.getTotalOverpaid(), 
BigDecimal.ZERO));
+        
details.setTotalPrincipalOutstanding(loan.getSummary().getTotalPrincipalOutstanding());
+        // We have different strategies to calculate oustanding interest
+        final BigDecimal interestAmount = 
externalAssetOwnerTransferOutstandingInterestCalculation.calculateOutstandingInterest(loan);
+        details.setTotalInterestOutstanding(interestAmount);
+        
details.setTotalFeeChargesOutstanding(loan.getSummary().getTotalFeeChargesOutstanding());
+        
details.setTotalPenaltyChargesOutstanding(loan.getSummary().getTotalPenaltyChargesOutstanding());
+        details.setTotalOverpaid(loan.getTotalOverpaid());
         return details;
     }
 
diff --git 
a/fineract-investor/src/main/resources/db/changelog/tenant/module/investor/module-changelog-master.xml
 
b/fineract-investor/src/main/resources/db/changelog/tenant/module/investor/module-changelog-master.xml
index b3e6f32eec..e96557908c 100644
--- 
a/fineract-investor/src/main/resources/db/changelog/tenant/module/investor/module-changelog-master.xml
+++ 
b/fineract-investor/src/main/resources/db/changelog/tenant/module/investor/module-changelog-master.xml
@@ -39,4 +39,5 @@
   <include relativeToChangelogFile="true" 
file="parts/0015_add_intermediary_sale_command.xml"/>
   <include relativeToChangelogFile="true" 
file="parts/0016_add_external_reference_id.xml"/>
   <include relativeToChangelogFile="true" 
file="parts/0017_add_external_asset_owner_loan_product_attr_index.xml"/>
+  <include relativeToChangelogFile="true" 
file="parts/0018_add_external_asset_owner_transfer_outstanding_interest_strategy.xml"/>
 </databaseChangeLog>
diff --git 
a/fineract-investor/src/main/resources/db/changelog/tenant/module/investor/parts/0018_add_external_asset_owner_transfer_outstanding_interest_strategy.xml
 
b/fineract-investor/src/main/resources/db/changelog/tenant/module/investor/parts/0018_add_external_asset_owner_transfer_outstanding_interest_strategy.xml
new file mode 100644
index 0000000000..7004b0636b
--- /dev/null
+++ 
b/fineract-investor/src/main/resources/db/changelog/tenant/module/investor/parts/0018_add_external_asset_owner_transfer_outstanding_interest_strategy.xml
@@ -0,0 +1,43 @@
+<?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
+                   
https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd";>
+
+    <changeSet author="fineract" id="1" context="postgresql">
+        <sql>
+            SELECT SETVAL('c_configuration_id_seq', COALESCE(MAX(id), 0)+1, 
false ) FROM c_configuration;
+        </sql>
+    </changeSet>
+    <changeSet author="fineract" id="2">
+        <insert tableName="c_configuration">
+            <column name="name" 
value="outstanding-interest-calculation-strategy-for-external-asset-transfer"/>
+            <column name="value"/>
+            <column name="date_value"/>
+            <column name="string_value" value="TOTAL_OUTSTANDING_INTEREST"/>
+            <column name="enabled" valueBoolean="true"/>
+            <column name="is_trap_door" valueBoolean="false"/>
+            <column name="description" value=" Available options: 
TOTAL_OUTSTANDING_INTEREST, PAYABLE_OUTSTANDING_INTEREST. Define whether total 
outstanding interest (due + not yet due + projected) or payable till transfer 
date ( due + not yet due) should be involved in the asset transfer."/>
+        </insert>
+    </changeSet>
+</databaseChangeLog>
diff --git 
a/fineract-investor/src/test/java/org/apache/fineract/investor/cob/loan/LoanAccountOwnerTransferBusinessStepTest.java
 
b/fineract-investor/src/test/java/org/apache/fineract/investor/cob/loan/LoanAccountOwnerTransferBusinessStepTest.java
index ed5fa3934c..39c5db4462 100644
--- 
a/fineract-investor/src/test/java/org/apache/fineract/investor/cob/loan/LoanAccountOwnerTransferBusinessStepTest.java
+++ 
b/fineract-investor/src/test/java/org/apache/fineract/investor/cob/loan/LoanAccountOwnerTransferBusinessStepTest.java
@@ -24,6 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mockStatic;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -31,6 +32,8 @@ import static org.mockito.Mockito.verifyNoInteractions;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
+import java.math.MathContext;
+import java.math.RoundingMode;
 import java.time.LocalDate;
 import java.time.ZoneId;
 import java.util.HashMap;
@@ -55,12 +58,16 @@ import 
org.apache.fineract.investor.domain.ExternalAssetOwnerTransferRepository;
 import org.apache.fineract.investor.domain.LoanOwnershipTransferBusinessEvent;
 import org.apache.fineract.investor.service.AccountingService;
 import org.apache.fineract.investor.service.DelayedSettlementAttributeService;
+import 
org.apache.fineract.investor.service.ExternalAssetOwnerTransferOutstandingInterestCalculation;
 import org.apache.fineract.investor.service.LoanTransferabilityService;
+import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
 import org.apache.fineract.portfolio.loanaccount.domain.Loan;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanSummary;
 import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
 import org.jetbrains.annotations.NotNull;
+import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -69,6 +76,7 @@ import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
+import org.mockito.MockedStatic;
 import org.mockito.Mockito;
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.springframework.data.domain.Sort;
@@ -80,6 +88,7 @@ public class LoanAccountOwnerTransferBusinessStepTest {
     public static final LocalDate FUTURE_DATE_9999_12_31 = LocalDate.of(9999, 
12, 31);
     private static final Long LOAN_PRODUCT_ID = 2L;
     private final LocalDate actualDate = LocalDate.now(ZoneId.systemDefault());
+    private static final MockedStatic<MoneyHelper> MONEY_HELPER = 
mockStatic(MoneyHelper.class);
 
     @Mock
     private ExternalAssetOwnerTransferRepository 
externalAssetOwnerTransferRepository;
@@ -99,8 +108,22 @@ public class LoanAccountOwnerTransferBusinessStepTest {
     @Mock
     private DelayedSettlementAttributeService 
delayedSettlementAttributeService;
 
+    @Mock
+    private ExternalAssetOwnerTransferOutstandingInterestCalculation 
externalAssetOwnerTransferOutstandingInterestCalculation;
+
     private LoanAccountOwnerTransferBusinessStep underTest;
 
+    @BeforeAll
+    public static void init() {
+        
MONEY_HELPER.when(MoneyHelper::getRoundingMode).thenReturn(RoundingMode.HALF_EVEN);
+        MONEY_HELPER.when(MoneyHelper::getMathContext).thenReturn(new 
MathContext(12, RoundingMode.HALF_EVEN));
+    }
+
+    @AfterAll
+    public static void destruct() {
+        MONEY_HELPER.close();
+    }
+
     @BeforeEach
     public void setUp() {
         ThreadLocalContextUtil.setTenant(new FineractPlatformTenant(1L, 
"default", "Default", "Asia/Kolkata", null));
@@ -108,7 +131,7 @@ public class LoanAccountOwnerTransferBusinessStepTest {
         ThreadLocalContextUtil.setBusinessDates(new 
HashMap<>(Map.of(BusinessDateType.BUSINESS_DATE, actualDate)));
         underTest = new 
LoanAccountOwnerTransferBusinessStep(externalAssetOwnerTransferRepository,
                 externalAssetOwnerTransferLoanMappingRepository, 
accountingService, businessEventNotifierService,
-                loanTransferabilityService, delayedSettlementAttributeService);
+                loanTransferabilityService, delayedSettlementAttributeService, 
externalAssetOwnerTransferOutstandingInterestCalculation);
     }
 
     @AfterEach
diff --git 
a/fineract-investor/src/test/java/org/apache/fineract/investor/service/AccountingServiceImplTest.java
 
b/fineract-investor/src/test/java/org/apache/fineract/investor/service/AccountingServiceImplTest.java
index 9e20c1e4ed..ad2d1816a5 100644
--- 
a/fineract-investor/src/test/java/org/apache/fineract/investor/service/AccountingServiceImplTest.java
+++ 
b/fineract-investor/src/test/java/org/apache/fineract/investor/service/AccountingServiceImplTest.java
@@ -27,11 +27,14 @@ import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.lenient;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import java.math.BigDecimal;
+import java.math.MathContext;
+import java.math.RoundingMode;
 import java.time.LocalDate;
 import java.util.HashMap;
 import java.util.List;
@@ -51,16 +54,20 @@ import 
org.apache.fineract.investor.domain.ExternalAssetOwnerJournalEntryMapping
 import org.apache.fineract.investor.domain.ExternalAssetOwnerTransfer;
 import 
org.apache.fineract.investor.domain.ExternalAssetOwnerTransferJournalEntryMapping;
 import 
org.apache.fineract.investor.domain.ExternalAssetOwnerTransferJournalEntryMappingRepository;
+import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
 import org.apache.fineract.organisation.office.domain.Office;
 import org.apache.fineract.portfolio.loanaccount.domain.Loan;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanSummary;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
+import org.mockito.MockedStatic;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 import org.mockito.junit.jupiter.MockitoExtension;
@@ -68,6 +75,19 @@ import org.mockito.junit.jupiter.MockitoExtension;
 @ExtendWith(MockitoExtension.class)
 class AccountingServiceImplTest {
 
+    private static final MockedStatic<MoneyHelper> MONEY_HELPER = 
mockStatic(MoneyHelper.class);
+
+    @BeforeAll
+    public static void init() {
+        
MONEY_HELPER.when(MoneyHelper::getRoundingMode).thenReturn(RoundingMode.HALF_EVEN);
+        MONEY_HELPER.when(MoneyHelper::getMathContext).thenReturn(new 
MathContext(12, RoundingMode.HALF_EVEN));
+    }
+
+    @AfterAll
+    public static void destruct() {
+        MONEY_HELPER.close();
+    }
+
     @BeforeEach
     public void setUp() {
         ThreadLocalContextUtil.setBusinessDates(new 
HashMap<>(Map.of(BUSINESS_DATE, LocalDate.of(2024, 9, 27))));
@@ -517,6 +537,9 @@ class AccountingServiceImplTest {
         @Mock
         private FinancialActivityAccountRepositoryWrapper 
financialActivityAccountRepository;
 
+        @Mock
+        private ExternalAssetOwnerTransferOutstandingInterestCalculation 
externalAssetOwnerTransferOutstandingInterestCalculation;
+
         @InjectMocks
         private AccountingServiceImpl testSubject;
 
@@ -540,7 +563,6 @@ class AccountingServiceImplTest {
 
             LoanSummary loanSummary = Mockito.mock(LoanSummary.class);
             
when(loanSummary.getTotalPrincipalOutstanding()).thenReturn(BigDecimal.ONE);
-            
when(loanSummary.getTotalInterestOutstanding()).thenReturn(BigDecimal.ONE);
             
when(loanSummary.getTotalFeeChargesOutstanding()).thenReturn(BigDecimal.ONE);
             
when(loanSummary.getTotalPenaltyChargesOutstanding()).thenReturn(BigDecimal.ONE);
             when(loan.getSummary()).thenReturn(loanSummary);
diff --git 
a/fineract-investor/src/test/java/org/apache/fineract/investor/service/LoanAccountOwnerTransferServiceTest.java
 
b/fineract-investor/src/test/java/org/apache/fineract/investor/service/LoanAccountOwnerTransferServiceTest.java
index 430ff33a9b..ac409b363e 100644
--- 
a/fineract-investor/src/test/java/org/apache/fineract/investor/service/LoanAccountOwnerTransferServiceTest.java
+++ 
b/fineract-investor/src/test/java/org/apache/fineract/investor/service/LoanAccountOwnerTransferServiceTest.java
@@ -23,11 +23,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mockStatic;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import static org.springframework.data.domain.Sort.Direction.ASC;
 
+import java.math.MathContext;
+import java.math.RoundingMode;
 import java.time.LocalDate;
 import java.time.ZoneId;
 import java.util.HashMap;
@@ -44,9 +47,12 @@ import 
org.apache.fineract.investor.domain.ExternalAssetOwnerTransfer;
 import 
org.apache.fineract.investor.domain.ExternalAssetOwnerTransferLoanMappingRepository;
 import 
org.apache.fineract.investor.domain.ExternalAssetOwnerTransferRepository;
 import org.apache.fineract.investor.domain.LoanOwnershipTransferBusinessEvent;
+import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
 import org.apache.fineract.portfolio.loanaccount.domain.Loan;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanSummary;
 import org.jetbrains.annotations.NotNull;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -54,7 +60,9 @@ import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
 import org.mockito.ArgumentCaptor;
+import org.mockito.InjectMocks;
 import org.mockito.Mock;
+import org.mockito.MockedStatic;
 import org.mockito.Mockito;
 import org.mockito.junit.jupiter.MockitoExtension;
 import org.springframework.data.domain.Sort;
@@ -63,6 +71,7 @@ import org.springframework.data.jpa.domain.Specification;
 @ExtendWith(MockitoExtension.class)
 public class LoanAccountOwnerTransferServiceTest {
 
+    private static final MockedStatic<MoneyHelper> MONEY_HELPER = 
mockStatic(MoneyHelper.class);
     @Mock
     private ExternalAssetOwnerTransferRepository 
externalAssetOwnerTransferRepository;
     @Mock
@@ -71,15 +80,27 @@ public class LoanAccountOwnerTransferServiceTest {
     private AccountingService accountingService;
     @Mock
     private BusinessEventNotifierService businessEventNotifierService;
+    @Mock
+    private ExternalAssetOwnerTransferOutstandingInterestCalculation 
externalAssetOwnerTransferOutstandingInterestCalculation;
 
-    private LoanAccountOwnerTransferService underTest;
+    @InjectMocks
+    private LoanAccountOwnerTransferServiceImpl underTest;
     private final LocalDate actualDate = LocalDate.now(ZoneId.systemDefault());
 
+    @BeforeAll
+    public static void init() {
+        
MONEY_HELPER.when(MoneyHelper::getRoundingMode).thenReturn(RoundingMode.HALF_EVEN);
+        MONEY_HELPER.when(MoneyHelper::getMathContext).thenReturn(new 
MathContext(12, RoundingMode.HALF_EVEN));
+    }
+
+    @AfterAll
+    public static void destruct() {
+        MONEY_HELPER.close();
+    }
+
     @BeforeEach
     public void setUp() {
         ThreadLocalContextUtil.setBusinessDates(new 
HashMap<>(Map.of(BUSINESS_DATE, actualDate)));
-        underTest = new 
LoanAccountOwnerTransferServiceImpl(externalAssetOwnerTransferRepository,
-                externalAssetOwnerTransferLoanMappingRepository, 
accountingService, businessEventNotifierService);
     }
 
     @Test
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java
similarity index 98%
rename from 
fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java
rename to 
fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java
index f2e4b2f355..333da377db 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java
@@ -42,14 +42,13 @@ import 
org.apache.fineract.portfolio.account.data.PortfolioAccountData;
 import 
org.apache.fineract.portfolio.accountdetails.data.LoanAccountSummaryData;
 import org.apache.fineract.portfolio.calendar.data.CalendarData;
 import org.apache.fineract.portfolio.charge.data.ChargeData;
-import 
org.apache.fineract.portfolio.charge.util.ConvertChargeDataToSpecificChargeData;
 import org.apache.fineract.portfolio.client.data.ClientData;
 import org.apache.fineract.portfolio.delinquency.data.DelinquencyRangeData;
 import org.apache.fineract.portfolio.floatingrates.data.InterestRatePeriodData;
 import org.apache.fineract.portfolio.fund.data.FundData;
 import org.apache.fineract.portfolio.group.data.GroupGeneralData;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus;
-import org.apache.fineract.portfolio.loanaccount.guarantor.data.GuarantorData;
+import org.apache.fineract.portfolio.loanaccount.guarantor.data.IGuarantor;
 import 
org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanScheduleData;
 import 
org.apache.fineract.portfolio.loanproduct.data.LoanProductBorrowerCycleVariationData;
 import org.apache.fineract.portfolio.loanproduct.data.LoanProductData;
@@ -146,7 +145,7 @@ public class LoanAccountData {
     private Collection<LoanTransactionData> transactions;
     private Collection<LoanChargeData> charges;
     private Collection<LoanCollateralManagementData> collateral;
-    private Collection<GuarantorData> guarantors;
+    private Collection<? extends IGuarantor> guarantors;
     private CalendarData meeting;
     private Collection<NoteData> notes;
     private Collection<DisbursementData> disbursementDetails;
@@ -356,7 +355,7 @@ public class LoanAccountData {
         final Collection<LoanChargeData> charges = new 
ArrayList<LoanChargeData>();
         for (final ChargeData charge : product.charges()) {
             if (!charge.isOverdueInstallmentCharge()) {
-                
charges.add(ConvertChargeDataToSpecificChargeData.toLoanChargeData(charge));
+                charges.add(toLoanChargeData(charge));
             }
         }
 
@@ -530,7 +529,7 @@ public class LoanAccountData {
      */
     public LoanAccountData associationsAndTemplate(final LoanScheduleData 
repaymentSchedule,
             final Collection<LoanTransactionData> transactions, final 
Collection<LoanChargeData> charges,
-            final Collection<LoanCollateralManagementData> collateral, final 
Collection<GuarantorData> guarantors,
+            final Collection<LoanCollateralManagementData> collateral, final 
Collection<? extends IGuarantor> guarantors,
             final CalendarData calendarData, final Collection<LoanProductData> 
productOptions,
             final Collection<EnumOptionData> termFrequencyTypeOptions, final 
Collection<EnumOptionData> repaymentFrequencyTypeOptions,
             final Collection<EnumOptionData> 
repaymentFrequencyNthDayTypeOptions,
@@ -680,4 +679,17 @@ public class LoanAccountData {
     public boolean isActive() {
         return LoanStatus.fromInt(getStatus().getId().intValue()).isActive();
     }
+
+    public static LoanChargeData toLoanChargeData(final ChargeData chargeData) 
{
+
+        BigDecimal percentage = null;
+        if (chargeData.getChargeCalculationType().getId() == 2) {
+            percentage = chargeData.getAmount();
+        }
+
+        return LoanChargeData.newLoanChargeDetails(chargeData.getId(), 
chargeData.getName(), chargeData.getCurrency(),
+                chargeData.getAmount(), percentage, 
chargeData.getChargeTimeType(), chargeData.getChargeCalculationType(),
+                chargeData.isPenalty(), chargeData.getChargePaymentMode(), 
chargeData.getMinCap(), chargeData.getMaxCap(),
+                ExternalId.empty());
+    }
 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanSummaryProviderDelegate.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/data/IGuarantor.java
similarity index 54%
copy from 
fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanSummaryProviderDelegate.java
copy to 
fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/data/IGuarantor.java
index 20f9663fce..cb1d911883 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanSummaryProviderDelegate.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/data/IGuarantor.java
@@ -16,20 +16,8 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.portfolio.loanaccount.service;
+package org.apache.fineract.portfolio.loanaccount.guarantor.data;
 
-import java.util.List;
-import lombok.AllArgsConstructor;
-import org.springframework.stereotype.Component;
+import java.io.Serializable;
 
-@Component
-@AllArgsConstructor
-public class LoanSummaryProviderDelegate {
-
-    private final List<LoanSummaryDataProvider> loanSummaryDataProviders;
-
-    public LoanSummaryDataProvider resolveLoanSummaryDataProvider(String 
loanProcessingStrategyCode) {
-        return loanSummaryDataProviders.stream().filter(provider -> 
provider.accept(loanProcessingStrategyCode)).findAny()
-                .orElseThrow(() -> new IllegalArgumentException("No provider 
found for :" + loanProcessingStrategyCode));
-    }
-}
+public interface IGuarantor extends Serializable {}
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java
similarity index 100%
rename from 
fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java
rename to 
fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanSummaryDataProvider.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanSummaryDataProvider.java
similarity index 100%
rename from 
fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanSummaryDataProvider.java
rename to 
fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanSummaryDataProvider.java
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanSummaryProviderDelegate.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanSummaryProviderDelegate.java
similarity index 100%
rename from 
fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanSummaryProviderDelegate.java
rename to 
fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanSummaryProviderDelegate.java
diff --git 
a/fineract-loan/src/test/java/org/apache/fineract/portfolio/loanaccount/domain/SingleLoanChargeRepaymentScheduleProcessingWrapperTest.java
 
b/fineract-loan/src/test/java/org/apache/fineract/portfolio/loanaccount/domain/SingleLoanChargeRepaymentScheduleProcessingWrapperTest.java
index b8e124e090..2e82031343 100644
--- 
a/fineract-loan/src/test/java/org/apache/fineract/portfolio/loanaccount/domain/SingleLoanChargeRepaymentScheduleProcessingWrapperTest.java
+++ 
b/fineract-loan/src/test/java/org/apache/fineract/portfolio/loanaccount/domain/SingleLoanChargeRepaymentScheduleProcessingWrapperTest.java
@@ -44,6 +44,7 @@ import 
org.apache.fineract.portfolio.charge.domain.ChargeCalculationType;
 import org.apache.fineract.portfolio.charge.domain.ChargePaymentMode;
 import org.apache.fineract.portfolio.charge.domain.ChargeTimeType;
 import org.jetbrains.annotations.NotNull;
+import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 import org.mockito.ArgumentCaptor;
@@ -69,6 +70,11 @@ public class 
SingleLoanChargeRepaymentScheduleProcessingWrapperTest {
         MONEY_HELPER.when(MoneyHelper::getMathContext).thenReturn(new 
MathContext(12, RoundingMode.HALF_EVEN));
     }
 
+    @AfterAll
+    public static void destruct() {
+        MONEY_HELPER.close();
+    }
+
     @Test
     public void testOnePeriodWithFeeCharge() {
         LocalDate disbursementDate = LocalDate.of(2023, 1, 1);
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java
index 2e8558184a..cc17cad248 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java
@@ -527,4 +527,10 @@ public class ConfigurationDomainServiceJpa implements 
ConfigurationDomainService
     public boolean isImmediateChargeAccrualPostMaturityEnabled() {
         return 
getGlobalConfigurationPropertyData(GlobalConfigurationConstants.ENABLE_IMMEDIATE_CHARGE_ACCRUAL_POST_MATURITY).isEnabled();
     }
+
+    @Override
+    public String getAssetOwnerTransferOustandingInterestStrategy() {
+        return getGlobalConfigurationPropertyData(
+                
GlobalConfigurationConstants.ASSET_OWNER_TRANSFER_OUTSTANDING_INTEREST_CALCULATION_STRATEGY).getStringValue();
+    }
 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/util/ConvertChargeDataToSpecificChargeData.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/util/ConvertChargeDataToSpecificChargeData.java
index 8f50d46c1f..ac2a6c2aa8 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/util/ConvertChargeDataToSpecificChargeData.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/util/ConvertChargeDataToSpecificChargeData.java
@@ -21,9 +21,7 @@ package org.apache.fineract.portfolio.charge.util;
 import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.util.Collection;
-import org.apache.fineract.infrastructure.core.domain.ExternalId;
 import org.apache.fineract.portfolio.charge.data.ChargeData;
-import org.apache.fineract.portfolio.loanaccount.data.LoanChargeData;
 import org.apache.fineract.portfolio.savings.data.SavingsAccountChargeData;
 import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountChargeData;
 
@@ -31,19 +29,6 @@ public final class ConvertChargeDataToSpecificChargeData {
 
     private ConvertChargeDataToSpecificChargeData() {}
 
-    public static LoanChargeData toLoanChargeData(final ChargeData chargeData) 
{
-
-        BigDecimal percentage = null;
-        if (chargeData.getChargeCalculationType().getId() == 2) {
-            percentage = chargeData.getAmount();
-        }
-
-        return LoanChargeData.newLoanChargeDetails(chargeData.getId(), 
chargeData.getName(), chargeData.getCurrency(),
-                chargeData.getAmount(), percentage, 
chargeData.getChargeTimeType(), chargeData.getChargeCalculationType(),
-                chargeData.isPenalty(), chargeData.getChargePaymentMode(), 
chargeData.getMinCap(), chargeData.getMaxCap(),
-                ExternalId.empty());
-    }
-
     public static SavingsAccountChargeData toSavingsAccountChargeData(final 
ChargeData chargeData) {
 
         final Long savingsChargeId = null;
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/data/GuarantorData.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/data/GuarantorData.java
index ea293c89f4..4bdd36bea3 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/data/GuarantorData.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/data/GuarantorData.java
@@ -19,7 +19,6 @@
 package org.apache.fineract.portfolio.loanaccount.guarantor.data;
 
 import java.io.Serial;
-import java.io.Serializable;
 import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.util.Collection;
@@ -34,7 +33,7 @@ import 
org.apache.fineract.portfolio.loanaccount.guarantor.domain.GuarantorType;
 import 
org.apache.fineract.portfolio.loanaccount.guarantor.service.GuarantorEnumerations;
 
 @Getter
-public class GuarantorData implements Serializable {
+public class GuarantorData implements IGuarantor {
 
     @Serial
     private static final long serialVersionUID = 1L;
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/GlobalConfigurationHelper.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/GlobalConfigurationHelper.java
index bc0e0f2970..e636d63460 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/GlobalConfigurationHelper.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/GlobalConfigurationHelper.java
@@ -105,8 +105,8 @@ public class GlobalConfigurationHelper {
         ArrayList<HashMap> expectedGlobalConfigurations = 
getAllDefaultGlobalConfigurations();
         GetGlobalConfigurationsResponse actualGlobalConfigurations = 
getAllGlobalConfigurations();
 
-        Assertions.assertEquals(56, expectedGlobalConfigurations.size());
-        Assertions.assertEquals(56, 
actualGlobalConfigurations.getGlobalConfiguration().size());
+        Assertions.assertEquals(57, expectedGlobalConfigurations.size());
+        Assertions.assertEquals(57, 
actualGlobalConfigurations.getGlobalConfiguration().size());
 
         for (int i = 0; i < expectedGlobalConfigurations.size(); i++) {
 
@@ -540,6 +540,15 @@ public class GlobalConfigurationHelper {
         enableImmediateChargeAccrualPostMaturity.put("trapDoor", false);
         defaults.add(enableImmediateChargeAccrualPostMaturity);
 
+        HashMap<String, Object> assetOwnerTransferInterestOutstandingStrategy 
= new HashMap<>();
+        assetOwnerTransferInterestOutstandingStrategy.put("name",
+                
GlobalConfigurationConstants.ASSET_OWNER_TRANSFER_OUTSTANDING_INTEREST_CALCULATION_STRATEGY);
+        assetOwnerTransferInterestOutstandingStrategy.put("value", 0L);
+        assetOwnerTransferInterestOutstandingStrategy.put("enabled", false);
+        assetOwnerTransferInterestOutstandingStrategy.put("trapDoor", false);
+        assetOwnerTransferInterestOutstandingStrategy.put("string_value", 
"TOTAL_OUTSTANDING_INTEREST");
+        defaults.add(assetOwnerTransferInterestOutstandingStrategy);
+
         return defaults;
     }
 

Reply via email to