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 9320dd1bd7 FINEREACT-2404: Improved extensibility and cleanup
9320dd1bd7 is described below

commit 9320dd1bd7f330ee9e8481088a0fe3cbe94f4521
Author: cucusenok <BP-116: updated readme.md>
AuthorDate: Tue Nov 4 14:34:38 2025 +0400

    FINEREACT-2404: Improved extensibility and cleanup
---
 ...JournalEntryCommandFromApiJsonDeserializer.java |  8 +++-
 .../infrastructure/core/service/MDCWrapper.java    |  4 ++
 .../jobs/SendAsynchronousEventsTasklet.java        |  2 +-
 .../data/SavingsAccountTransactionData.java        |  4 +-
 .../fineract/test/messaging/store/EventStore.java  |  2 +-
 .../domain/LoanAccrualActivityRepository.java      |  4 +-
 .../JournalEntryReadPlatformServiceImpl.java       | 15 ++++---
 .../LoanTransactionValidatorImpl.java              | 49 +++++++++++++---------
 .../service/LoanReadPlatformServiceImpl.java       | 14 ++++---
 .../LoanWritePlatformServiceJpaRepositoryImpl.java |  5 ++-
 .../SavingsAccountReadPlatformServiceImpl.java     |  8 ++--
 ...avingsAccountTransactionsSearchServiceImpl.java |  2 +-
 12 files changed, 72 insertions(+), 45 deletions(-)

diff --git 
a/fineract-accounting/src/main/java/org/apache/fineract/accounting/journalentry/serialization/JournalEntryCommandFromApiJsonDeserializer.java
 
b/fineract-accounting/src/main/java/org/apache/fineract/accounting/journalentry/serialization/JournalEntryCommandFromApiJsonDeserializer.java
index 3acc08691d..21266f8a59 100644
--- 
a/fineract-accounting/src/main/java/org/apache/fineract/accounting/journalentry/serialization/JournalEntryCommandFromApiJsonDeserializer.java
+++ 
b/fineract-accounting/src/main/java/org/apache/fineract/accounting/journalentry/serialization/JournalEntryCommandFromApiJsonDeserializer.java
@@ -45,10 +45,14 @@ import org.springframework.stereotype.Component;
  */
 @Component
 @RequiredArgsConstructor
-public final class JournalEntryCommandFromApiJsonDeserializer extends 
AbstractFromApiJsonDeserializer<JournalEntryCommand> {
+public class JournalEntryCommandFromApiJsonDeserializer extends 
AbstractFromApiJsonDeserializer<JournalEntryCommand> {
 
     private final FromJsonHelper fromApiJsonHelper;
 
+    protected Set<String> getSupportedParameters() {
+        return JournalEntryJsonInputParams.getAllValues();
+    }
+
     @Override
     public JournalEntryCommand commandFromApiJson(final String json) {
         if (StringUtils.isBlank(json)) {
@@ -56,7 +60,7 @@ public final class JournalEntryCommandFromApiJsonDeserializer 
extends AbstractFr
         }
 
         final Type typeOfMap = new TypeToken<Map<String, Object>>() 
{}.getType();
-        final Set<String> supportedParameters = 
JournalEntryJsonInputParams.getAllValues();
+        final Set<String> supportedParameters = this.getSupportedParameters();
         this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, 
supportedParameters);
 
         final JsonElement element = this.fromApiJsonHelper.parse(json);
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/MDCWrapper.java
 
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/MDCWrapper.java
index 71ebe872ef..2f6dfde6ef 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/MDCWrapper.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/MDCWrapper.java
@@ -32,4 +32,8 @@ public class MDCWrapper {
     public void remove(String key) {
         MDC.remove(key);
     }
+
+    public String get(String key) {
+        return MDC.get(key);
+    }
 }
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/jobs/SendAsynchronousEventsTasklet.java
 
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/jobs/SendAsynchronousEventsTasklet.java
index b52bb661f8..474c2cd8d4 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/jobs/SendAsynchronousEventsTasklet.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/infrastructure/event/external/jobs/SendAsynchronousEventsTasklet.java
@@ -86,7 +86,7 @@ public class SendAsynchronousEventsTasklet implements Tasklet 
{
         return RepeatStatus.FINISHED;
     }
 
-    private boolean isDownstreamChannelEnabled() {
+    protected boolean isDownstreamChannelEnabled() {
         return 
fineractProperties.getEvents().getExternal().getProducer().getJms().isEnabled()
                 || 
fineractProperties.getEvents().getExternal().getProducer().getKafka().isEnabled();
     }
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionData.java
 
b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionData.java
index 76102db832..666a3ce9a8 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionData.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/portfolio/savings/data/SavingsAccountTransactionData.java
@@ -53,7 +53,7 @@ import org.springframework.util.CollectionUtils;
  */
 @Getter
 @JsonLocalDateArrayFormat
-public final class SavingsAccountTransactionData implements Serializable {
+public class SavingsAccountTransactionData implements Serializable {
 
     private Long id;
     private final SavingsAccountTransactionEnumData transactionType;
@@ -110,7 +110,7 @@ public final class SavingsAccountTransactionData implements 
Serializable {
     private Long accountCredit;
     private Long accountDebit;
 
-    private SavingsAccountTransactionData(final Long id, final 
SavingsAccountTransactionEnumData transactionType,
+    protected SavingsAccountTransactionData(final Long id, final 
SavingsAccountTransactionEnumData transactionType,
             final PaymentDetailData paymentDetailData, final Long savingsId, 
final String savingsAccountNo, final LocalDate transactionDate,
             final CurrencyData currency, final BigDecimal amount, final 
BigDecimal outstandingChargeAmount, final BigDecimal runningBalance,
             final boolean reversed, final AccountTransferData transfer, final 
Collection<PaymentTypeData> paymentTypeOptions,
diff --git 
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/messaging/store/EventStore.java
 
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/messaging/store/EventStore.java
index ef776e4dd8..5462d03f0c 100644
--- 
a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/messaging/store/EventStore.java
+++ 
b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/messaging/store/EventStore.java
@@ -68,7 +68,7 @@ public class EventStore {
         return receivedEvents;
     }
 
-    void receive(byte[] message) throws Exception {
+    public void receive(byte[] message) throws Exception {
         MessageV1 msgObject = 
MessageV1.fromByteBuffer(ByteBuffer.wrap(message));
         String type = msgObject.getType();
         String idempotencyKey = msgObject.getIdempotencyKey();
diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccrualActivityRepository.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccrualActivityRepository.java
index 07af9bb094..9b51288c69 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccrualActivityRepository.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccrualActivityRepository.java
@@ -20,11 +20,11 @@ package org.apache.fineract.portfolio.loanaccount.domain;
 
 import java.time.LocalDate;
 import java.util.Set;
+import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.Repository;
 import org.springframework.data.repository.query.Param;
 
-public interface LoanAccrualActivityRepository extends Repository<Loan, Long> {
+public interface LoanAccrualActivityRepository extends JpaRepository<Loan, 
Long> {
 
     @Query("select loan.id from Loan loan left join LoanTransaction lt on 
lt.loan = loan and lt.typeOf = :loanType and lt.reversed = false and lt.dateOf 
= :currentDate inner join LoanRepaymentScheduleInstallment rs on rs.loan = loan 
and rs.isDownPayment = false and rs.additional = false and rs.dueDate = 
:currentDate where 
loan.loanRepaymentScheduleDetail.enableAccrualActivityPosting = true and 
loan.loanStatus = :loanStatus and lt.id is null ")
     Set<Long> fetchLoanIdsForAccrualActivityPosting(@Param("currentDate") 
LocalDate currentDate,
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryReadPlatformServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryReadPlatformServiceImpl.java
index 68bf33aa25..0fde381cfb 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryReadPlatformServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryReadPlatformServiceImpl.java
@@ -79,11 +79,11 @@ public class JournalEntryReadPlatformServiceImpl implements 
JournalEntryReadPlat
     private final PaginationHelper paginationHelper;
     private final DatabaseSpecificSQLGenerator sqlGenerator;
 
-    private static final class GLJournalEntryMapper implements 
RowMapper<JournalEntryData> {
+    protected static class GLJournalEntryMapper implements 
RowMapper<JournalEntryData> {
 
         private final JournalEntryAssociationParametersData 
associationParametersData;
 
-        GLJournalEntryMapper(final JournalEntryAssociationParametersData 
associationParametersData) {
+        protected GLJournalEntryMapper(final 
JournalEntryAssociationParametersData associationParametersData) {
             this.associationParametersData = 
Objects.requireNonNullElseGet(associationParametersData,
                     JournalEntryAssociationParametersData::new);
         }
@@ -240,8 +240,7 @@ public class JournalEntryReadPlatformServiceImpl implements 
JournalEntryReadPlat
             final Boolean onlyManualEntries, final LocalDate fromDate, final 
LocalDate toDate, final LocalDate submittedOnDateFrom,
             final LocalDate submittedOnDateTo, final String transactionId, 
final Integer entityType,
             final JournalEntryAssociationParametersData 
associationParametersData) {
-
-        GLJournalEntryMapper rm = new 
GLJournalEntryMapper(associationParametersData);
+        GLJournalEntryMapper rm = 
getGlJournalEntryMapper(associationParametersData);
         final StringBuilder sqlBuilder = new StringBuilder(200);
         sqlBuilder.append("select 
").append(sqlGenerator.calcFoundRows()).append(" ");
         sqlBuilder.append(rm.schema());
@@ -383,12 +382,16 @@ public class JournalEntryReadPlatformServiceImpl 
implements JournalEntryReadPlat
         return this.paginationHelper.fetchPage(this.jdbcTemplate, 
sqlBuilder.toString(), finalObjectArray, rm);
     }
 
+    protected GLJournalEntryMapper 
getGlJournalEntryMapper(JournalEntryAssociationParametersData 
associationParametersData) {
+        return new GLJournalEntryMapper(associationParametersData);
+    }
+
     @Override
     public JournalEntryData retrieveGLJournalEntryById(final long 
glJournalEntryId,
             JournalEntryAssociationParametersData associationParametersData) {
         try {
 
-            final GLJournalEntryMapper rm = new 
GLJournalEntryMapper(associationParametersData);
+            final GLJournalEntryMapper rm = 
getGlJournalEntryMapper(associationParametersData);
             // Programmatic query, disable sonar issue
             final String sql = "select " + rm.schema() + " where 
journalEntry.id = ?";
 
@@ -526,7 +529,7 @@ public class JournalEntryReadPlatformServiceImpl implements 
JournalEntryReadPlat
     public Page<JournalEntryData> retrieveJournalEntriesByEntityId(String 
transactionId, Long entityId, Integer entityType) {
         JournalEntryAssociationParametersData associationParametersData = new 
JournalEntryAssociationParametersData(true, true);
         try {
-            final GLJournalEntryMapper rm = new 
GLJournalEntryMapper(associationParametersData);
+            final GLJournalEntryMapper rm = 
getGlJournalEntryMapper(associationParametersData);
             final String sql = "select " + rm.schema()
                     + " where journalEntry.transaction_id = ? and 
journalEntry.entity_id = ? and journalEntry.entity_type_enum = ?";
             Object[] data = { transactionId, entityId, entityType };
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanTransactionValidatorImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanTransactionValidatorImpl.java
index 42ff8fefcd..65c55ee8c4 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanTransactionValidatorImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanTransactionValidatorImpl.java
@@ -98,7 +98,7 @@ import org.springframework.stereotype.Component;
 
 @Component("loanTransactionValidator")
 @AllArgsConstructor
-public final class LoanTransactionValidatorImpl implements 
LoanTransactionValidator {
+public class LoanTransactionValidatorImpl implements LoanTransactionValidator {
 
     private final FromJsonHelper fromApiJsonHelper;
     private final LoanApplicationValidator fromApiJsonDeserializer;
@@ -245,7 +245,7 @@ public final class LoanTransactionValidatorImpl implements 
LoanTransactionValida
         });
     }
 
-    private void validateDisbursementWithPostDatedChecks(final String json, 
final Long loanId) {
+    protected void validateDisbursementWithPostDatedChecks(final String json, 
final Long loanId) {
         final JsonElement jsonElement = this.fromApiJsonHelper.parse(json);
         final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
         final DataValidatorBuilder baseDataValidator = new 
DataValidatorBuilder(dataValidationErrors).resource("loan.disbursement");
@@ -291,7 +291,7 @@ public final class LoanTransactionValidatorImpl implements 
LoanTransactionValida
         }
     }
 
-    private void validateDisbursementDateWithMeetingDate(final LocalDate 
actualDisbursementDate, final CalendarInstance calendarInstance,
+    protected void validateDisbursementDateWithMeetingDate(final LocalDate 
actualDisbursementDate, final CalendarInstance calendarInstance,
             Boolean isSkipRepaymentOnFirstMonth, Integer numberOfDays) {
         if (null != calendarInstance) {
             final Calendar calendar = calendarInstance.getCalendar();
@@ -334,9 +334,7 @@ public final class LoanTransactionValidatorImpl implements 
LoanTransactionValida
             throw new InvalidJsonException();
         }
 
-        final Set<String> transactionParameters = new 
HashSet<>(Arrays.asList("transactionDate", "transactionAmount", "externalId", 
"note",
-                "locale", "dateFormat", "paymentTypeId", "accountNumber", 
"checkNumber", "routingCode", "receiptNumber", "bankNumber",
-                LoanApiConstants.REVERSAL_EXTERNAL_ID_PARAMNAME));
+        final Set<String> transactionParameters = 
getTransactionParametersForEdit();
 
         final Type typeOfMap = new TypeToken<Map<String, Object>>() 
{}.getType();
         this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, 
transactionParameters);
@@ -363,6 +361,12 @@ public final class LoanTransactionValidatorImpl implements 
LoanTransactionValida
         throwExceptionIfValidationWarningsExist(dataValidationErrors);
     }
 
+    protected HashSet<String> getTransactionParametersForEdit() {
+        return new HashSet<>(Arrays.asList("transactionDate", 
"transactionAmount", "externalId", "note", "locale", "dateFormat",
+                "paymentTypeId", "accountNumber", "checkNumber", 
"routingCode", "receiptNumber", "bankNumber",
+                LoanApiConstants.REVERSAL_EXTERNAL_ID_PARAMNAME));
+    }
+
     @Override
     public void validateChargebackTransaction(final String json) {
 
@@ -405,8 +409,7 @@ public final class LoanTransactionValidatorImpl implements 
LoanTransactionValida
             throw new InvalidJsonException();
         }
 
-        final Set<String> disbursementParameters = new HashSet<>(
-                Arrays.asList("transactionDate", "note", "locale", 
"dateFormat", "writeoffReasonId", "externalId"));
+        final Set<String> disbursementParameters = 
getNoAmountTransactionParameters();
 
         final Type typeOfMap = new TypeToken<Map<String, Object>>() 
{}.getType();
         this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, 
disbursementParameters);
@@ -427,6 +430,10 @@ public final class LoanTransactionValidatorImpl implements 
LoanTransactionValida
         throwExceptionIfValidationWarningsExist(dataValidationErrors);
     }
 
+    protected Set<String> getNoAmountTransactionParameters() {
+        return new HashSet<>(Arrays.asList("transactionDate", "note", 
"locale", "dateFormat", "writeoffReasonId", "externalId"));
+    }
+
     @Override
     public void validateChargeOffTransaction(final String json) {
         if (StringUtils.isBlank(json)) {
@@ -659,7 +666,7 @@ public final class LoanTransactionValidatorImpl implements 
LoanTransactionValida
         }
     }
 
-    private void 
validateLoanHasNoLaterChargeRefundTransactionToReverseOrCreateATransaction(Loan 
loan, LocalDate transactionDate,
+    protected void 
validateLoanHasNoLaterChargeRefundTransactionToReverseOrCreateATransaction(Loan 
loan, LocalDate transactionDate,
             String reversedOrCreated) {
         for (LoanTransaction txn : loan.getLoanTransactions()) {
             if (txn.isChargeRefund() && DateUtils.isBefore(transactionDate, 
txn.getTransactionDate())) {
@@ -671,7 +678,7 @@ public final class LoanTransactionValidatorImpl implements 
LoanTransactionValida
         }
     }
 
-    private void validateLoanDisbursementIsBeforeTransactionDate(final Loan 
loan, final LocalDate transactionDate) {
+    protected void validateLoanDisbursementIsBeforeTransactionDate(final Loan 
loan, final LocalDate transactionDate) {
         if (DateUtils.isBefore(transactionDate, loan.getDisbursementDate())) {
             final String errorMessage = "The transaction date cannot be before 
the loan disbursement date: "
                     + loan.getDisbursementDate().toString();
@@ -680,14 +687,14 @@ public final class LoanTransactionValidatorImpl 
implements LoanTransactionValida
         }
     }
 
-    private void validateTransactionShouldNotBeInTheFuture(final LocalDate 
transactionDate) {
+    protected void validateTransactionShouldNotBeInTheFuture(final LocalDate 
transactionDate) {
         if (DateUtils.isDateInTheFuture(transactionDate)) {
             final String errorMessage = "The transaction date cannot be in the 
future.";
             throw new InvalidLoanStateTransitionException("transaction", 
"cannot.be.a.future.date", errorMessage, transactionDate);
         }
     }
 
-    private void validateLoanHasCurrency(final Loan loan) {
+    protected void validateLoanHasCurrency(final Loan loan) {
         MonetaryCurrency currency = loan.getCurrency();
         final ApplicationCurrency defaultApplicationCurrency = 
this.applicationCurrencyRepository.findOneByCode(currency.getCode());
         if (defaultApplicationCurrency == null) {
@@ -695,7 +702,7 @@ public final class LoanTransactionValidatorImpl implements 
LoanTransactionValida
         }
     }
 
-    private void validateClientOfficeJoiningDateIsBeforeTransactionDate(Loan 
loan, LocalDate transactionDate) {
+    protected void validateClientOfficeJoiningDateIsBeforeTransactionDate(Loan 
loan, LocalDate transactionDate) {
         if (loan.getClient() != null && 
loan.getClient().getOfficeJoiningDate() != null) {
             final LocalDate clientOfficeJoiningDate = 
loan.getClient().getOfficeJoiningDate();
             if (DateUtils.isBefore(transactionDate, clientOfficeJoiningDate)) {
@@ -759,7 +766,7 @@ public final class LoanTransactionValidatorImpl implements 
LoanTransactionValida
         }
     }
 
-    private void 
validateTransactionAmountNotExceedThresholdForMultiDisburseLoan(Loan loan) {
+    protected void 
validateTransactionAmountNotExceedThresholdForMultiDisburseLoan(Loan loan) {
         if (loan.getLoanProduct().isMultiDisburseLoan()) {
             BigDecimal totalDisbursed = loan.getDisbursedAmount();
             BigDecimal totalPrincipalAdjusted = 
loan.getSummary().getTotalPrincipalAdjustments();
@@ -830,7 +837,7 @@ public final class LoanTransactionValidatorImpl implements 
LoanTransactionValida
         validateTransactionAmountNotExceedThresholdForMultiDisburseLoan(loan);
     }
 
-    private void validateRepaymentTypeTransactionNotBeforeAChargeRefund(final 
Loan loan, final LoanTransactionType loanTransactionType,
+    protected void 
validateRepaymentTypeTransactionNotBeforeAChargeRefund(final Loan loan, final 
LoanTransactionType loanTransactionType,
             final LocalDate transactionDate) {
         if (loanTransactionType.isRepaymentType() && 
!loanTransactionType.isChargeRefund()) {
             for (LoanTransaction txn : loan.getLoanTransactions()) {
@@ -931,7 +938,7 @@ public final class LoanTransactionValidatorImpl implements 
LoanTransactionValida
         return totalCollateral;
     }
 
-    private static @NonNull Set<String> getDisbursementParameters(boolean 
isAccountTransfer) {
+    protected @NonNull Set<String> getDisbursementParameters(boolean 
isAccountTransfer) {
         Set<String> disbursementParameters;
 
         if (isAccountTransfer) {
@@ -952,9 +959,7 @@ public final class LoanTransactionValidatorImpl implements 
LoanTransactionValida
             throw new InvalidJsonException();
         }
 
-        final Set<String> transactionParameters = new 
HashSet<>(Arrays.asList("transactionDate", "transactionAmount", "externalId", 
"note",
-                "locale", "dateFormat", "paymentTypeId", "accountNumber", 
"checkNumber", "routingCode", "receiptNumber", "bankNumber",
-                "loanId", "numberOfRepayments", "interestRefundCalculation"));
+        final Set<String> transactionParameters = getRepaymentParameters();
 
         final Type typeOfMap = new TypeToken<Map<String, Object>>() 
{}.getType();
         this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, 
transactionParameters);
@@ -976,6 +981,12 @@ public final class LoanTransactionValidatorImpl implements 
LoanTransactionValida
         throwExceptionIfValidationWarningsExist(dataValidationErrors);
     }
 
+    protected Set<String> getRepaymentParameters() {
+        return new HashSet<>(Arrays.asList("transactionDate", 
"transactionAmount", "externalId", "note", "locale", "dateFormat",
+                "paymentTypeId", "accountNumber", "checkNumber", 
"routingCode", "receiptNumber", "bankNumber", "loanId",
+                "numberOfRepayments", "interestRefundCalculation"));
+    }
+
     @Override
     public void validatePaymentDetails(final DataValidatorBuilder 
baseDataValidator, final JsonElement element) {
         // Validate all string payment detail fields for max length
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 94e1cc8e7d..bc18d4bc55 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
@@ -188,7 +188,7 @@ public class LoanReadPlatformServiceImpl implements 
LoanReadPlatformService, Loa
     private final ConfigurationDomainService configurationDomainService;
     private final AccountDetailsReadPlatformService 
accountDetailsReadPlatformService;
     private final ColumnValidator columnValidator;
-    private final DatabaseSpecificSQLGenerator sqlGenerator;
+    protected final DatabaseSpecificSQLGenerator sqlGenerator;
     private final DelinquencyReadPlatformService 
delinquencyReadPlatformService;
     private final LoanTransactionRepository loanTransactionRepository;
     private final LoanChargePaidByReadService loanChargePaidByReadService;
@@ -300,7 +300,7 @@ public class LoanReadPlatformServiceImpl implements 
LoanReadPlatformService, Loa
         try {
             this.context.authenticatedUser();
 
-            final LoanTransactionsMapper rm = new 
LoanTransactionsMapper(sqlGenerator);
+            final LoanTransactionsMapper rm = createLoanTransactionsMapper();
 
             // retrieve all loan transactions that are not invalid and have not
             // been 'contra'ed by another transaction
@@ -332,6 +332,10 @@ public class LoanReadPlatformServiceImpl implements 
LoanReadPlatformService, Loa
         }
     }
 
+    protected LoanTransactionsMapper createLoanTransactionsMapper() {
+        return new LoanTransactionsMapper(sqlGenerator);
+    }
+
     @Override
     public Page<LoanAccountData> retrieveAll(final SearchParameters 
searchParameters) {
 
@@ -704,7 +708,7 @@ public class LoanReadPlatformServiceImpl implements 
LoanReadPlatformService, Loa
     public LoanTransactionData retrieveLoanTransaction(final Long loanId, 
final Long transactionId) {
         this.context.authenticatedUser();
         try {
-            final LoanTransactionsMapper rm = new 
LoanTransactionsMapper(sqlGenerator);
+            final LoanTransactionsMapper rm = createLoanTransactionsMapper();
             final String sql = "select " + rm.loanPaymentsSchema() + " where 
l.id = ? and tr.id = ? ";
             LoanTransactionData loanTransactionData = 
this.jdbcTemplate.queryForObject(sql, rm, loanId, transactionId); // NOSONAR
             loanTransactionData.setTransactionRelations(
@@ -1702,11 +1706,11 @@ public class LoanReadPlatformServiceImpl implements 
LoanReadPlatformService, Loa
 
     }
 
-    private static final class LoanTransactionsMapper implements 
RowMapper<LoanTransactionData> {
+    protected static class LoanTransactionsMapper implements 
RowMapper<LoanTransactionData> {
 
         private final DatabaseSpecificSQLGenerator sqlGenerator;
 
-        LoanTransactionsMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
+        protected LoanTransactionsMapper(DatabaseSpecificSQLGenerator 
sqlGenerator) {
             this.sqlGenerator = sqlGenerator;
         }
 
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java
index f8225d9686..41c8135c7e 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java
@@ -1680,7 +1680,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
         loan.getTopupLoanDetails().setTopupAmount(amount);
     }
 
-    private void disburseLoanToSavings(final Loan loan, final JsonCommand 
command, final Money amount, final PaymentDetail paymentDetail) {
+    protected Long disburseLoanToSavings(final Loan loan, final JsonCommand 
command, final Money amount,
+            final PaymentDetail paymentDetail) {
         final LocalDate transactionDate = 
command.localDateValueOfParameterNamed("actualDisbursementDate");
         final ExternalId txnExternalId = 
externalIdFactory.createFromCommand(command, 
LoanApiConstants.externalIdParameterName);
 
@@ -1699,7 +1700,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
                 PortfolioAccountType.SAVINGS, loan.getId(), 
portfolioAccountData.getId(), "Loan Disbursement", locale, fmt, paymentDetail,
                 LoanTransactionType.DISBURSEMENT.getValue(), null, null, null, 
AccountTransferType.ACCOUNT_TRANSFER.getValue(), null, null,
                 txnExternalId, loan, null, fromSavingsAccount, 
isRegularTransaction, isExceptionForBalanceCheck);
-        
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
+        return 
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
     }
 
     @Transactional
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java
index 96084d007b..922a0dcf17 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java
@@ -91,7 +91,7 @@ public class SavingsAccountReadPlatformServiceImpl implements 
SavingsAccountRead
 
     // mappers
     private final SavingsAccountTransactionTemplateMapper 
transactionTemplateMapper;
-    private final SavingsAccountTransactionsMapper transactionsMapper;
+    protected SavingsAccountTransactionsMapper transactionsMapper;
     private final SavingsAccountTransactionsForBatchMapper 
savingsAccountTransactionsForBatchMapper;
     private final SavingAccountMapper savingAccountMapper;
     private final SavingAccountMapperForInterestPosting 
savingAccountMapperForInterestPosting;
@@ -1088,7 +1088,7 @@ public class SavingsAccountReadPlatformServiceImpl 
implements SavingsAccountRead
      * return this.jdbcTemplate.query(sql, this.annualFeeMapper, new Object[] 
{}); }
      */
 
-    public static final class SavingsAccountTransactionsMapper implements 
RowMapper<SavingsAccountTransactionData> {
+    public static class SavingsAccountTransactionsMapper implements 
RowMapper<SavingsAccountTransactionData> {
 
         private static final String SELECT = buildSelect();
         private static final String FROM = buildFrom();
@@ -1096,7 +1096,7 @@ public class SavingsAccountReadPlatformServiceImpl 
implements SavingsAccountRead
 
         public SavingsAccountTransactionsMapper() {}
 
-        private static String buildSelect() {
+        protected static String buildSelect() {
             return "tr.id as transactionId, tr.transaction_type_enum as 
transactionType, "
                     + "tr.transaction_date as transactionDate, tr.amount as 
transactionAmount, "
                     + "tr.release_id_of_hold_amount as releaseTransactionId, 
tr.reason_for_block as reasonForBlock, "
@@ -1116,7 +1116,7 @@ public class SavingsAccountReadPlatformServiceImpl 
implements SavingsAccountRead
                     + "curr.display_symbol as currencyDisplaySymbol, pt.value 
as paymentTypeName, " + "tr.is_manual as postInterestAsOn ";
         }
 
-        private static String buildFrom() {
+        protected static String buildFrom() {
             return " FROM m_savings_account_transaction tr join 
m_savings_account sa on tr.savings_account_id = sa.id "
                     + "join m_currency curr on curr.code = sa.currency_code "
                     + "left join m_account_transfer_transaction fromtran on 
fromtran.from_savings_transaction_id = tr.id "
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/search/SavingsAccountTransactionsSearchServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/search/SavingsAccountTransactionsSearchServiceImpl.java
index e08aae8784..6b74576df8 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/search/SavingsAccountTransactionsSearchServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/search/SavingsAccountTransactionsSearchServiceImpl.java
@@ -70,6 +70,7 @@ public class SavingsAccountTransactionsSearchServiceImpl 
implements SavingsAccou
     private final DataTableValidator dataTableValidator;
     private final JdbcTemplate jdbcTemplate;
     private final SearchUtil searchUtil;
+    protected 
SavingsAccountReadPlatformServiceImpl.SavingsAccountTransactionsMapper tm = new 
SavingsAccountReadPlatformServiceImpl.SavingsAccountTransactionsMapper();
 
     @Override
     public Page<SavingsAccountTransactionData> searchTransactions(@NonNull 
Long savingsId,
@@ -111,7 +112,6 @@ public class SavingsAccountTransactionsSearchServiceImpl 
implements SavingsAccou
         ArrayList<Object> params = new ArrayList<>();
         searchUtil.buildQueryCondition(columnFilters, where, params, alias, 
headersByName, null, null, null, false, sqlGenerator);
 
-        SavingsAccountReadPlatformServiceImpl.SavingsAccountTransactionsMapper 
tm = new 
SavingsAccountReadPlatformServiceImpl.SavingsAccountTransactionsMapper();
         Object[] args = params.toArray();
 
         String countQuery = "SELECT COUNT(*) " + tm.from() + where;

Reply via email to