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

arnold 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 937bfe529c FINERACT-2326: Improve `LoanTransactionData` DTO structure
937bfe529c is described below

commit 937bfe529cfa3dff07bda50b81140ec3cf918a3f
Author: Adam Saghy <[email protected]>
AuthorDate: Fri Aug 29 18:00:26 2025 +0200

    FINERACT-2326: Improve `LoanTransactionData` DTO structure
---
 .../loanaccount/data/LoanTransactionData.java      | 347 +++--------------
 .../loanaccount/mapper/LoanTransactionMapper.java  |  16 +-
 .../loanaccount/data/LoanTransactionDataTest.java  | 428 +++++++++++++++++++++
 .../mapper/LoanTransactionMapperTest.java          | 148 +++++++
 .../service/LoanReadPlatformServiceImpl.java       | 101 ++---
 ...justTransactionBusinessEventSerializerTest.java |  14 +-
 6 files changed, 703 insertions(+), 351 deletions(-)

diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTransactionData.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTransactionData.java
index 9f9968f414..0e669052f1 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTransactionData.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTransactionData.java
@@ -24,6 +24,9 @@ import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.util.Collection;
 import java.util.List;
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
 import lombok.Getter;
 import lombok.Setter;
 import org.apache.fineract.infrastructure.codes.data.CodeValueData;
@@ -32,12 +35,13 @@ import 
org.apache.fineract.organisation.monetary.data.CurrencyData;
 import org.apache.fineract.portfolio.account.data.AccountTransferData;
 import org.apache.fineract.portfolio.paymentdetail.data.PaymentDetailData;
 import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
-import org.springframework.integration.annotation.Default;
 
 /**
  * Immutable data object representing a loan transaction.
  */
 @Getter
+@Builder(builderClassName = "Builder")
+@AllArgsConstructor(access = AccessLevel.PUBLIC)
 public class LoanTransactionData implements Serializable {
 
     @Serial
@@ -73,6 +77,7 @@ public class LoanTransactionData implements Serializable {
     private final LocalDate possibleNextRepaymentDate;
     private final BigDecimal availableDisbursementAmountWithOverApplied;
 
+    @Setter
     private Collection<LoanChargePaidByData> loanChargePaidByList;
 
     // templates
@@ -104,334 +109,74 @@ public class LoanTransactionData implements Serializable 
{
     private final ExternalId reversalExternalId;
     private LocalDate reversedOnDate;
 
+    @Setter
     private List<LoanTransactionRelationData> transactionRelations;
 
     private Collection<CodeValueData> chargeOffReasonOptions = null;
 
     public static LoanTransactionData importInstance(BigDecimal 
repaymentAmount, LocalDate lastRepaymentDate, Long repaymentTypeId,
             Integer rowIndex, String locale, String dateFormat) {
-        return new LoanTransactionData(repaymentAmount, lastRepaymentDate, 
repaymentTypeId, rowIndex, locale, dateFormat);
-    }
-
-    private LoanTransactionData(BigDecimal transactionAmount, LocalDate 
transactionDate, Long paymentTypeId, Integer rowIndex,
-            String locale, String dateFormat) {
-        this.transactionAmount = transactionAmount;
-        this.transactionDate = transactionDate;
-        this.paymentTypeId = paymentTypeId;
-        this.rowIndex = rowIndex;
-        this.dateFormat = dateFormat;
-        this.locale = locale;
-        this.amount = null;
-        this.netDisbursalAmount = null;
-        this.date = null;
-        this.type = null;
-        this.id = null;
-        this.loanId = null;
-        this.externalLoanId = ExternalId.empty();
-        this.officeId = null;
-        this.officeName = null;
-        this.currency = null;
-        this.paymentDetailData = null;
-        this.principalPortion = null;
-        this.interestPortion = null;
-        this.feeChargesPortion = null;
-        this.penaltyChargesPortion = null;
-        this.overpaymentPortion = null;
-        this.unrecognizedIncomePortion = null;
-        this.externalId = ExternalId.empty();
-        this.transfer = null;
-        this.fixedEmiAmount = null;
-        this.outstandingLoanBalance = null;
-        this.submittedOnDate = null;
-        this.manuallyReversed = false;
-        this.possibleNextRepaymentDate = null;
-        this.paymentTypeOptions = null;
-        this.writeOffReasonOptions = null;
-        this.reversalExternalId = ExternalId.empty();
-        this.availableDisbursementAmountWithOverApplied = null;
+        return 
LoanTransactionData.builder().transactionAmount(repaymentAmount).transactionDate(lastRepaymentDate)
+                
.paymentTypeId(repaymentTypeId).rowIndex(rowIndex).locale(locale).dateFormat(dateFormat).externalLoanId(ExternalId.empty())
+                
.externalId(ExternalId.empty()).reversalExternalId(ExternalId.empty()).manuallyReversed(false).build();
     }
 
     public static LoanTransactionData importInstance(BigDecimal 
repaymentAmount, LocalDate repaymentDate, Long repaymentTypeId,
             String accountNumber, Integer checkNumber, Integer routingCode, 
Integer receiptNumber, Integer bankNumber, Long loanAccountId,
             String transactionType, Integer rowIndex, String locale, String 
dateFormat) {
-        return new LoanTransactionData(repaymentAmount, repaymentDate, 
repaymentTypeId, accountNumber, checkNumber, routingCode,
-                receiptNumber, bankNumber, loanAccountId, "", rowIndex, 
locale, dateFormat);
-    }
-
-    private LoanTransactionData(BigDecimal transactionAmount, LocalDate 
transactionDate, Long paymentTypeId, String accountNumber,
-            Integer checkNumber, Integer routingCode, Integer receiptNumber, 
Integer bankNumber, Long accountId, String transactionType,
-            Integer rowIndex, String locale, String dateFormat) {
-        this.transactionAmount = transactionAmount;
-        this.transactionDate = transactionDate;
-        this.paymentTypeId = paymentTypeId;
-        this.accountNumber = accountNumber;
-        this.checkNumber = checkNumber;
-        this.routingCode = routingCode;
-        this.receiptNumber = receiptNumber;
-        this.bankNumber = bankNumber;
-        this.accountId = accountId;
-        this.transactionType = transactionType;
-        this.rowIndex = rowIndex;
-        this.dateFormat = dateFormat;
-        this.locale = locale;
-        this.id = null;
-        this.loanId = null;
-        this.externalLoanId = ExternalId.empty();
-        this.officeId = null;
-        this.officeName = null;
-        this.type = null;
-        this.date = null;
-        this.currency = null;
-        this.paymentDetailData = null;
-        this.amount = null;
-        this.netDisbursalAmount = null;
-        this.principalPortion = null;
-        this.interestPortion = null;
-        this.feeChargesPortion = null;
-        this.penaltyChargesPortion = null;
-        this.overpaymentPortion = null;
-        this.unrecognizedIncomePortion = null;
-        this.externalId = ExternalId.empty();
-        this.transfer = null;
-        this.fixedEmiAmount = null;
-        this.outstandingLoanBalance = null;
-        this.submittedOnDate = null;
-        this.manuallyReversed = false;
-        this.possibleNextRepaymentDate = null;
-        this.paymentTypeOptions = null;
-        this.writeOffReasonOptions = null;
-        this.reversalExternalId = ExternalId.empty();
-        this.availableDisbursementAmountWithOverApplied = null;
+        return 
LoanTransactionData.builder().transactionAmount(repaymentAmount).transactionDate(repaymentDate)
+                
.paymentTypeId(repaymentTypeId).accountNumber(accountNumber).checkNumber(checkNumber).routingCode(routingCode)
+                
.receiptNumber(receiptNumber).bankNumber(bankNumber).accountId(loanAccountId).transactionType(transactionType)
+                
.rowIndex(rowIndex).locale(locale).dateFormat(dateFormat).externalLoanId(ExternalId.empty()).externalId(ExternalId.empty())
+                
.reversalExternalId(ExternalId.empty()).manuallyReversed(false).build();
     }
 
     public static LoanTransactionData templateOnTop(final LoanTransactionData 
loanTransactionData,
             final Collection<PaymentTypeData> paymentTypeOptions) {
-        return new LoanTransactionData(loanTransactionData.id, 
loanTransactionData.officeId, loanTransactionData.officeName,
-                loanTransactionData.type, 
loanTransactionData.paymentDetailData, loanTransactionData.currency, 
loanTransactionData.date,
-                loanTransactionData.amount, 
loanTransactionData.netDisbursalAmount, loanTransactionData.principalPortion,
-                loanTransactionData.interestPortion, 
loanTransactionData.feeChargesPortion, 
loanTransactionData.penaltyChargesPortion,
-                loanTransactionData.overpaymentPortion, 
loanTransactionData.unrecognizedIncomePortion, paymentTypeOptions,
-                loanTransactionData.externalId, loanTransactionData.transfer, 
loanTransactionData.fixedEmiAmount,
-                loanTransactionData.outstandingLoanBalance, 
loanTransactionData.manuallyReversed, loanTransactionData.loanId,
-                loanTransactionData.externalLoanId);
+        return 
builder().id(loanTransactionData.id).officeId(loanTransactionData.officeId).officeName(loanTransactionData.officeName)
+                
.type(loanTransactionData.type).paymentDetailData(loanTransactionData.paymentDetailData)
+                
.currency(loanTransactionData.currency).date(loanTransactionData.date).amount(loanTransactionData.amount)
+                
.netDisbursalAmount(loanTransactionData.netDisbursalAmount).principalPortion(loanTransactionData.principalPortion)
+                
.interestPortion(loanTransactionData.interestPortion).feeChargesPortion(loanTransactionData.feeChargesPortion)
+                
.penaltyChargesPortion(loanTransactionData.penaltyChargesPortion).overpaymentPortion(loanTransactionData.overpaymentPortion)
+                
.unrecognizedIncomePortion(loanTransactionData.unrecognizedIncomePortion).paymentTypeOptions(paymentTypeOptions)
+                
.externalId(loanTransactionData.externalId).transfer(loanTransactionData.transfer)
+                
.fixedEmiAmount(loanTransactionData.fixedEmiAmount).outstandingLoanBalance(loanTransactionData.outstandingLoanBalance)
+                
.manuallyReversed(loanTransactionData.manuallyReversed).loanId(loanTransactionData.loanId)
+                .externalLoanId(loanTransactionData.externalLoanId).build();
     }
 
     public static LoanTransactionData templateOnTop(final LoanTransactionData 
loanTransactionData, final LoanTransactionEnumData typeOf) {
-        return new LoanTransactionData(loanTransactionData.id, 
loanTransactionData.officeId, loanTransactionData.officeName, typeOf,
-                loanTransactionData.paymentDetailData, 
loanTransactionData.currency, loanTransactionData.date, 
loanTransactionData.amount,
-                loanTransactionData.netDisbursalAmount, 
loanTransactionData.principalPortion, loanTransactionData.interestPortion,
-                loanTransactionData.feeChargesPortion, 
loanTransactionData.penaltyChargesPortion, 
loanTransactionData.overpaymentPortion,
-                loanTransactionData.unrecognizedIncomePortion, 
loanTransactionData.paymentTypeOptions, loanTransactionData.externalId,
-                loanTransactionData.transfer, 
loanTransactionData.fixedEmiAmount, loanTransactionData.outstandingLoanBalance,
-                loanTransactionData.manuallyReversed, 
loanTransactionData.loanId, loanTransactionData.externalLoanId);
-    }
-
-    @Default // Default constructor for mapper
-    public LoanTransactionData(final Long id, final Long officeId, final 
String officeName, final LoanTransactionEnumData transactionType,
-            final PaymentDetailData paymentDetailData, final CurrencyData 
currency, final LocalDate date, final BigDecimal amount,
-            final BigDecimal netDisbursalAmount, final BigDecimal 
principalPortion, final BigDecimal interestPortion,
-            final BigDecimal feeChargesPortion, final BigDecimal 
penaltyChargesPortion, final BigDecimal overpaymentPortion,
-            final ExternalId externalId, final AccountTransferData transfer, 
BigDecimal fixedEmiAmount, BigDecimal outstandingLoanBalance,
-            final BigDecimal unrecognizedIncomePortion, final boolean 
manuallyReversed, Long loanId, ExternalId externalLoanId) {
-        this(id, officeId, officeName, transactionType, paymentDetailData, 
currency, date, amount, netDisbursalAmount, principalPortion,
-                interestPortion, feeChargesPortion, penaltyChargesPortion, 
overpaymentPortion, unrecognizedIncomePortion, null, externalId,
-                transfer, fixedEmiAmount, outstandingLoanBalance, 
manuallyReversed, loanId, externalLoanId);
-    }
-
-    public LoanTransactionData(final Long id, final Long officeId, final 
String officeName, final LoanTransactionEnumData transactionType,
-            final PaymentDetailData paymentDetailData, final CurrencyData 
currency, final LocalDate date, final BigDecimal amount,
-            final BigDecimal netDisbursalAmount, final BigDecimal 
principalPortion, final BigDecimal interestPortion,
-            final BigDecimal feeChargesPortion, final BigDecimal 
penaltyChargesPortion, final BigDecimal overpaymentPortion,
-            BigDecimal unrecognizedIncomePortion, final 
Collection<PaymentTypeData> paymentTypeOptions, final ExternalId externalId,
-            final AccountTransferData transfer, final BigDecimal 
fixedEmiAmount, BigDecimal outstandingLoanBalance,
-            boolean manuallyReversed, Long loanId, ExternalId externalLoanId) {
-        this(id, externalLoanId, officeId, officeName, transactionType, 
paymentDetailData, currency, date, amount, netDisbursalAmount,
-                principalPortion, interestPortion, feeChargesPortion, 
penaltyChargesPortion, overpaymentPortion, unrecognizedIncomePortion,
-                paymentTypeOptions, externalId, transfer, fixedEmiAmount, 
outstandingLoanBalance, null, manuallyReversed,
-                ExternalId.empty(), null, loanId);
-    }
-
-    public LoanTransactionData(final Long id, final Long officeId, final 
String officeName, final LoanTransactionEnumData transactionType,
-            final PaymentDetailData paymentDetailData, final CurrencyData 
currency, final LocalDate date, final BigDecimal amount,
-            final BigDecimal netDisbursalAmount, final BigDecimal 
principalPortion, final BigDecimal interestPortion,
-            final BigDecimal feeChargesPortion, final BigDecimal 
penaltyChargesPortion, final BigDecimal overpaymentPortion,
-            final BigDecimal unrecognizedIncomePortion, final ExternalId 
externalId, final AccountTransferData transfer,
-            BigDecimal fixedEmiAmount, BigDecimal outstandingLoanBalance, 
LocalDate submittedOnDate, final boolean manuallyReversed,
-            final ExternalId reversalExternalId, final LocalDate 
reversedOnDate, Long loanId, ExternalId externalLoanId) {
-        this(id, externalLoanId, officeId, officeName, transactionType, 
paymentDetailData, currency, date, amount, netDisbursalAmount,
-                principalPortion, interestPortion, feeChargesPortion, 
penaltyChargesPortion, overpaymentPortion, unrecognizedIncomePortion,
-                null, externalId, transfer, fixedEmiAmount, 
outstandingLoanBalance, submittedOnDate, manuallyReversed, reversalExternalId,
-                reversedOnDate, loanId);
-    }
-
-    public LoanTransactionData(final Long id, final ExternalId externalLoanId, 
final Long officeId, final String officeName,
-            final LoanTransactionEnumData transactionType, final 
PaymentDetailData paymentDetailData, final CurrencyData currency,
-            final LocalDate date, final BigDecimal amount, final BigDecimal 
netDisbursalAmount, final BigDecimal principalPortion,
-            final BigDecimal interestPortion, final BigDecimal 
feeChargesPortion, final BigDecimal penaltyChargesPortion,
-            final BigDecimal overpaymentPortion, final BigDecimal 
unrecognizedIncomePortion,
-            final Collection<PaymentTypeData> paymentTypeOptions, final 
ExternalId externalId, final AccountTransferData transfer,
-            final BigDecimal fixedEmiAmount, BigDecimal 
outstandingLoanBalance, final LocalDate submittedOnDate,
-            final boolean manuallyReversed, final ExternalId 
reversalExternalId, final LocalDate reversedOnDate, Long loanId) {
-        this.id = id;
-        this.loanId = loanId;
-        this.externalLoanId = externalLoanId;
-        this.officeId = officeId;
-        this.officeName = officeName;
-        this.type = transactionType;
-        this.paymentDetailData = paymentDetailData;
-        this.currency = currency;
-        this.date = date;
-        this.amount = amount;
-        this.netDisbursalAmount = netDisbursalAmount;
-        this.principalPortion = principalPortion;
-        this.interestPortion = interestPortion;
-        this.feeChargesPortion = feeChargesPortion;
-        this.penaltyChargesPortion = penaltyChargesPortion;
-        this.unrecognizedIncomePortion = unrecognizedIncomePortion;
-        this.paymentTypeOptions = paymentTypeOptions;
-        this.externalId = externalId;
-        this.transfer = transfer;
-        this.overpaymentPortion = overpaymentPortion;
-        this.fixedEmiAmount = fixedEmiAmount;
-        this.outstandingLoanBalance = outstandingLoanBalance;
-        this.submittedOnDate = submittedOnDate;
-        this.manuallyReversed = manuallyReversed;
-        this.possibleNextRepaymentDate = null;
-        this.reversalExternalId = reversalExternalId;
-        this.reversedOnDate = reversedOnDate;
-        this.availableDisbursementAmountWithOverApplied = null;
-    }
-
-    public LoanTransactionData(Long id, LoanTransactionEnumData 
transactionType, LocalDate date, BigDecimal totalAmount,
-            BigDecimal netDisbursalAmount, BigDecimal principalPortion, 
BigDecimal interestPortion, BigDecimal feeChargesPortion,
-            BigDecimal penaltyChargesPortion, BigDecimal overpaymentPortion, 
BigDecimal unrecognizedIncomePortion,
-            BigDecimal outstandingLoanBalance, final boolean manuallyReversed, 
ExternalId externalId, Long loanId,
-            ExternalId externalLoanId) {
-        this(id, externalLoanId, null, null, transactionType, null, null, 
date, totalAmount, netDisbursalAmount, principalPortion,
-                interestPortion, feeChargesPortion, penaltyChargesPortion, 
overpaymentPortion, unrecognizedIncomePortion, null, externalId,
-                null, null, outstandingLoanBalance, null, manuallyReversed, 
ExternalId.empty(), null, loanId);
+        return 
builder().id(loanTransactionData.id).officeId(loanTransactionData.officeId).officeName(loanTransactionData.officeName)
+                
.type(typeOf).paymentDetailData(loanTransactionData.paymentDetailData).currency(loanTransactionData.currency)
+                
.date(loanTransactionData.date).amount(loanTransactionData.amount)
+                
.netDisbursalAmount(loanTransactionData.netDisbursalAmount).principalPortion(loanTransactionData.principalPortion)
+                
.interestPortion(loanTransactionData.interestPortion).feeChargesPortion(loanTransactionData.feeChargesPortion)
+                
.penaltyChargesPortion(loanTransactionData.penaltyChargesPortion).overpaymentPortion(loanTransactionData.overpaymentPortion)
+                
.unrecognizedIncomePortion(loanTransactionData.unrecognizedIncomePortion)
+                
.paymentTypeOptions(loanTransactionData.paymentTypeOptions).externalId(loanTransactionData.externalId)
+                
.transfer(loanTransactionData.transfer).fixedEmiAmount(loanTransactionData.fixedEmiAmount)
+                
.outstandingLoanBalance(loanTransactionData.outstandingLoanBalance).manuallyReversed(loanTransactionData.manuallyReversed)
+                
.loanId(loanTransactionData.loanId).externalLoanId(loanTransactionData.externalLoanId).build();
     }
 
     public static LoanTransactionData 
loanTransactionDataForCreditTemplate(final LoanTransactionEnumData 
transactionType,
             final LocalDate transactionDate, final BigDecimal 
transactionAmount, final Collection<PaymentTypeData> paymentOptions,
             final CurrencyData currency) {
-        final Long id = null;
-        final Long loanId = null;
-        final ExternalId externalLoanId = ExternalId.empty();
-        final ExternalId externalId = ExternalId.empty();
-        final Long officeId = null;
-        final String officeName = null;
-        final PaymentDetailData paymentDetailData = null;
-        final BigDecimal unrecognizedIncomePortion = null;
-        final BigDecimal principalPortion = null;
-        final BigDecimal interestPortion = null;
-        final BigDecimal feeChargesPortion = null;
-        final BigDecimal penaltyChargesPortion = null;
-        final BigDecimal overpaymentPortion = null;
-        final BigDecimal netDisbursalAmount = null;
-        final BigDecimal fixedEmiAmount = null;
-        final BigDecimal outstandingLoanBalance = null;
-        final AccountTransferData transfer = null;
-        final LocalDate submittedOnDate = null;
-        final LocalDate possibleNextRepaymentDate = null;
-        final boolean manuallyReversed = false;
-        final BigDecimal availableDisbursementAmountWithOverApplied = null;
-        return new LoanTransactionData(id, officeId, officeName, 
transactionType, paymentDetailData, currency, transactionDate,
-                transactionAmount, netDisbursalAmount, principalPortion, 
interestPortion, feeChargesPortion, penaltyChargesPortion,
-                overpaymentPortion, unrecognizedIncomePortion, paymentOptions, 
transfer, externalId, fixedEmiAmount, outstandingLoanBalance,
-                submittedOnDate, manuallyReversed, possibleNextRepaymentDate, 
loanId, externalLoanId,
-                availableDisbursementAmountWithOverApplied);
-
+        return 
builder().type(transactionType).date(transactionDate).amount(transactionAmount).paymentTypeOptions(paymentOptions)
+                
.currency(currency).externalLoanId(ExternalId.empty()).externalId(ExternalId.empty()).reversalExternalId(ExternalId.empty())
+                .manuallyReversed(false).build();
     }
 
     public static LoanTransactionData 
loanTransactionDataForDisbursalTemplate(final LoanTransactionEnumData 
transactionType,
             final LocalDate expectedDisbursedOnLocalDateForTemplate, final 
BigDecimal disburseAmountForTemplate,
-            final BigDecimal netDisbursalAmount, final 
Collection<PaymentTypeData> paymentOptions, final BigDecimal 
retriveLastEmiAmount,
+            final BigDecimal netDisbursalAmount, final 
Collection<PaymentTypeData> paymentOptions, final BigDecimal fixedEmiAmount,
             final LocalDate possibleNextRepaymentDate, final CurrencyData 
currency,
             final BigDecimal availableDisbursementAmountWithOverApplied) {
-        final Long id = null;
-        final Long loanId = null;
-        final ExternalId externalLoanId = ExternalId.empty();
-        final Long officeId = null;
-        final String officeName = null;
-        final PaymentDetailData paymentDetailData = null;
-        final BigDecimal unrecognizedIncomePortion = null;
-        final BigDecimal principalPortion = null;
-        final BigDecimal interestPortion = null;
-        final BigDecimal feeChargesPortion = null;
-        final BigDecimal penaltyChargesPortion = null;
-        final BigDecimal overpaymentPortion = null;
-        final ExternalId externalId = ExternalId.empty();
-        final BigDecimal outstandingLoanBalance = null;
-        final AccountTransferData transfer = null;
-        final LocalDate submittedOnDate = null;
-        final boolean manuallyReversed = false;
-        return new LoanTransactionData(id, officeId, officeName, 
transactionType, paymentDetailData, currency,
-                expectedDisbursedOnLocalDateForTemplate, 
disburseAmountForTemplate, netDisbursalAmount, principalPortion, 
interestPortion,
-                feeChargesPortion, penaltyChargesPortion, overpaymentPortion, 
unrecognizedIncomePortion, paymentOptions, transfer,
-                externalId, retriveLastEmiAmount, outstandingLoanBalance, 
submittedOnDate, manuallyReversed, possibleNextRepaymentDate,
-                loanId, externalLoanId, 
availableDisbursementAmountWithOverApplied);
-
-    }
-
-    private LoanTransactionData(Long id, final Long officeId, final String 
officeName, LoanTransactionEnumData transactionType,
-            final PaymentDetailData paymentDetailData, final CurrencyData 
currency, final LocalDate date, BigDecimal amount,
-            BigDecimal netDisbursalAmount, final BigDecimal principalPortion, 
final BigDecimal interestPortion,
-            final BigDecimal feeChargesPortion, final BigDecimal 
penaltyChargesPortion, final BigDecimal overpaymentPortion,
-            BigDecimal unrecognizedIncomePortion, Collection<PaymentTypeData> 
paymentOptions, final AccountTransferData transfer,
-            final ExternalId externalId, final BigDecimal fixedEmiAmount, 
BigDecimal outstandingLoanBalance,
-            final LocalDate submittedOnDate, final boolean manuallyReversed, 
final LocalDate possibleNextRepaymentDate, Long loanId,
-            ExternalId externalLoanId, final BigDecimal 
availableDisbursementAmountWithOverApplied) {
-        this.id = id;
-        this.loanId = loanId;
-        this.externalLoanId = externalLoanId;
-        this.officeId = officeId;
-        this.officeName = officeName;
-        this.type = transactionType;
-        this.paymentDetailData = paymentDetailData;
-        this.currency = currency;
-        this.date = date;
-        this.amount = amount;
-        this.netDisbursalAmount = netDisbursalAmount;
-        this.principalPortion = principalPortion;
-        this.interestPortion = interestPortion;
-        this.feeChargesPortion = feeChargesPortion;
-        this.penaltyChargesPortion = penaltyChargesPortion;
-        this.unrecognizedIncomePortion = unrecognizedIncomePortion;
-        this.paymentTypeOptions = paymentOptions;
-        this.externalId = externalId;
-        this.transfer = transfer;
-        this.overpaymentPortion = overpaymentPortion;
-        this.fixedEmiAmount = fixedEmiAmount;
-        this.outstandingLoanBalance = outstandingLoanBalance;
-        this.submittedOnDate = submittedOnDate;
-        this.manuallyReversed = manuallyReversed;
-        this.possibleNextRepaymentDate = possibleNextRepaymentDate;
-        this.reversalExternalId = ExternalId.empty();
-        this.availableDisbursementAmountWithOverApplied = 
availableDisbursementAmountWithOverApplied;
-    }
-
-    public boolean isNotDisbursement() {
-        return type.getId() == 1;
-    }
-
-    public void setWriteOffReasonOptions(Collection<CodeValueData> 
writeOffReasonOptions) {
-        this.writeOffReasonOptions = writeOffReasonOptions;
-    }
-
-    public void setChargeOffReasonOptions(Collection<CodeValueData> 
chargeOffReasonOptions) {
-        this.chargeOffReasonOptions = chargeOffReasonOptions;
-    }
-
-    public void setLoanChargePaidByList(Collection<LoanChargePaidByData> 
loanChargePaidByList) {
-        this.loanChargePaidByList = loanChargePaidByList;
-    }
-
-    public void setLoanTransactionRelations(List<LoanTransactionRelationData> 
transactionRelations) {
-        this.transactionRelations = transactionRelations;
-    }
-
-    public boolean supportTransactionRelations() {
-        return !type.isAccrual();
+        return 
builder().type(transactionType).date(expectedDisbursedOnLocalDateForTemplate).amount(disburseAmountForTemplate)
+                
.netDisbursalAmount(netDisbursalAmount).paymentTypeOptions(paymentOptions).fixedEmiAmount(fixedEmiAmount)
+                
.possibleNextRepaymentDate(possibleNextRepaymentDate).currency(currency)
+                
.availableDisbursementAmountWithOverApplied(availableDisbursementAmountWithOverApplied).externalLoanId(ExternalId.empty())
+                
.externalId(ExternalId.empty()).reversalExternalId(ExternalId.empty()).manuallyReversed(false).build();
     }
 }
diff --git 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/mapper/LoanTransactionMapper.java
 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/mapper/LoanTransactionMapper.java
index 97733c12af..be938e810d 100644
--- 
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/mapper/LoanTransactionMapper.java
+++ 
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/mapper/LoanTransactionMapper.java
@@ -46,8 +46,22 @@ public interface LoanTransactionMapper {
     @Mapping(target = "loanId", source = "loan.id")
     @Mapping(target = "externalLoanId", source = "loan.externalId")
     @Mapping(target = "netDisbursalAmount", source = "loan.netDisbursalAmount")
-    @Mapping(target = "transactionType", expression = 
"java(org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations.transactionType(loanTransaction.getTypeOf()))")
+    @Mapping(target = "transactionType", expression = 
"java(loanTransaction.getTypeOf().name())")
+    @Mapping(target = "type", expression = 
"java(org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations.transactionType(loanTransaction.getTypeOf()))")
     @Mapping(target = "paymentDetailData", expression = 
"java(loanTransaction.getPaymentDetail() != null ? 
loanTransaction.getPaymentDetail().toData() : null)")
     @Mapping(target = "currency", source = "loan.currency")
+    @Mapping(target = "possibleNextRepaymentDate", ignore = true)
+    @Mapping(target = "availableDisbursementAmountWithOverApplied", ignore = 
true)
+    @Mapping(target = "rowIndex", ignore = true)
+    @Mapping(target = "dateFormat", ignore = true)
+    @Mapping(target = "locale", ignore = true)
+    @Mapping(target = "paymentTypeId", ignore = true)
+    @Mapping(target = "accountNumber", ignore = true)
+    @Mapping(target = "checkNumber", ignore = true)
+    @Mapping(target = "routingCode", ignore = true)
+    @Mapping(target = "receiptNumber", ignore = true)
+    @Mapping(target = "bankNumber", ignore = true)
+    @Mapping(target = "accountId", ignore = true)
+    @Mapping(target = "transactionAmount", ignore = true)
     LoanTransactionData mapLoanTransaction(LoanTransaction loanTransaction);
 }
diff --git 
a/fineract-loan/src/test/java/org/apache/fineract/portfolio/loanaccount/data/LoanTransactionDataTest.java
 
b/fineract-loan/src/test/java/org/apache/fineract/portfolio/loanaccount/data/LoanTransactionDataTest.java
new file mode 100644
index 0000000000..9b690341f2
--- /dev/null
+++ 
b/fineract-loan/src/test/java/org/apache/fineract/portfolio/loanaccount/data/LoanTransactionDataTest.java
@@ -0,0 +1,428 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.portfolio.loanaccount.data;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.mockito.Mockito.mock;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.util.Collection;
+import java.util.List;
+import org.apache.fineract.infrastructure.codes.data.CodeValueData;
+import org.apache.fineract.infrastructure.core.domain.ExternalId;
+import org.apache.fineract.organisation.monetary.data.CurrencyData;
+import org.apache.fineract.portfolio.account.data.AccountTransferData;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType;
+import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations;
+import org.apache.fineract.portfolio.paymentdetail.data.PaymentDetailData;
+import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
+import org.junit.jupiter.api.Test;
+
+public class LoanTransactionDataTest {
+
+    @Test
+    public void testLoanTransactionDataBuilder() {
+        // Given
+        // Primitive and simple types
+        Long id = 1L;
+        Long officeId = 2L;
+        String officeName = "Test Office";
+        LocalDate date = LocalDate.of(2023, 1, 1);
+        BigDecimal amount = new BigDecimal("1000.50");
+        boolean manuallyReversed = true;
+        Long loanId = 10L;
+        String transactionType = "REPAYMENT";
+        Integer rowIndex = 1;
+        String dateFormat = "dd MMMM yyyy";
+        String locale = "en";
+        Long paymentTypeId = 1L;
+        String accountNumber = "AC123456";
+        Integer checkNumber = 2;
+        Integer routingCode = 3;
+        Integer receiptNumber = 4;
+        Integer bankNumber = 5;
+        Long accountId = 5L;
+        BigDecimal transactionAmount = new BigDecimal("1000.50");
+        Integer numberOfRepayments = 12;
+
+        // Complex types
+        LoanTransactionEnumData type = 
LoanEnumerations.transactionType(LoanTransactionType.REPAYMENT);
+        PaymentDetailData paymentDetailData = mock(PaymentDetailData.class);
+        CurrencyData currency = new CurrencyData("USD", "US Dollar", 2, 0, 
"$", "USD");
+        ExternalId externalId = ExternalId.generate();
+        ExternalId externalLoanId = ExternalId.generate();
+        ExternalId reversalExternalId = ExternalId.generate();
+
+        // Financial amounts
+        BigDecimal netDisbursalAmount = new BigDecimal("2000.00");
+        BigDecimal principalPortion = new BigDecimal("800.00");
+        BigDecimal interestPortion = new BigDecimal("100.00");
+        BigDecimal feeChargesPortion = new BigDecimal("50.25");
+        BigDecimal penaltyChargesPortion = new BigDecimal("50.25");
+        BigDecimal overpaymentPortion = new BigDecimal("100.00");
+        BigDecimal unrecognizedIncomePortion = BigDecimal.ZERO;
+        BigDecimal fixedEmiAmount = new BigDecimal("500.00");
+        BigDecimal availableDisbursementAmountWithOverApplied = new 
BigDecimal("1500.00");
+
+        // Dates
+        LocalDate possibleNextRepaymentDate = LocalDate.of(2023, 2, 1);
+        LocalDate reversedOnDate = LocalDate.of(2023, 1, 15);
+        LocalDate submittedOnDate = LocalDate.of(2023, 1, 1);
+
+        // Collections
+        List<LoanTransactionRelationData> transactionRelations = 
mock(List.class);
+        List<LoanChargePaidByData> loanChargePaidByList = mock(List.class);
+        List<LoanRepaymentScheduleInstallmentData> 
loanRepaymentScheduleInstallments = mock(List.class);
+        Collection<CodeValueData> writeOffReasonOptions = mock(List.class);
+        Collection<CodeValueData> chargeOffReasonOptions = mock(List.class);
+        Collection<PaymentTypeData> paymentTypeOptions = mock(List.class);
+        AccountTransferData transfer = mock(AccountTransferData.class);
+
+        // When
+        LoanTransactionData data = LoanTransactionData.builder()
+                // Simple fields
+                
.id(id).officeId(officeId).officeName(officeName).date(date).amount(amount).manuallyReversed(manuallyReversed)
+                
.loanId(loanId).transactionType(transactionType).rowIndex(rowIndex).dateFormat(dateFormat).locale(locale)
+                
.paymentTypeId(paymentTypeId).accountNumber(accountNumber).checkNumber(checkNumber).routingCode(routingCode)
+                
.receiptNumber(receiptNumber).bankNumber(bankNumber).accountId(accountId).transactionAmount(transactionAmount)
+                .numberOfRepayments(numberOfRepayments)
+                // Complex fields
+                
.type(type).paymentDetailData(paymentDetailData).currency(currency).externalId(externalId).externalLoanId(externalLoanId)
+                .reversalExternalId(reversalExternalId)
+                // Financial amounts
+                
.netDisbursalAmount(netDisbursalAmount).principalPortion(principalPortion).interestPortion(interestPortion)
+                
.feeChargesPortion(feeChargesPortion).penaltyChargesPortion(penaltyChargesPortion).overpaymentPortion(overpaymentPortion)
+                
.unrecognizedIncomePortion(unrecognizedIncomePortion).fixedEmiAmount(fixedEmiAmount)
+                
.availableDisbursementAmountWithOverApplied(availableDisbursementAmountWithOverApplied)
+                // Dates
+                
.possibleNextRepaymentDate(possibleNextRepaymentDate).reversedOnDate(reversedOnDate).submittedOnDate(submittedOnDate)
+                // Collections
+                
.transactionRelations(transactionRelations).loanChargePaidByList(loanChargePaidByList)
+                
.loanRepaymentScheduleInstallments(loanRepaymentScheduleInstallments).writeOffReasonOptions(writeOffReasonOptions)
+                
.chargeOffReasonOptions(chargeOffReasonOptions).paymentTypeOptions(paymentTypeOptions).transfer(transfer).build();
+
+        // Then - Simple fields
+        assertEquals(id, data.getId());
+        assertEquals(officeId, data.getOfficeId());
+        assertEquals(officeName, data.getOfficeName());
+        assertEquals(date, data.getDate());
+        assertEquals(amount, data.getAmount());
+        assertEquals(manuallyReversed, data.isManuallyReversed());
+        assertEquals(loanId, data.getLoanId());
+        assertEquals(transactionType, data.getTransactionType());
+        assertEquals(rowIndex, data.getRowIndex());
+        assertEquals(dateFormat, data.getDateFormat());
+        assertEquals(locale, data.getLocale());
+        assertEquals(paymentTypeId, data.getPaymentTypeId());
+        assertEquals(accountNumber, data.getAccountNumber());
+        assertEquals(checkNumber, data.getCheckNumber());
+        assertEquals(routingCode, data.getRoutingCode());
+        assertEquals(receiptNumber, data.getReceiptNumber());
+        assertEquals(bankNumber, data.getBankNumber());
+        assertEquals(accountId, data.getAccountId());
+        assertEquals(transactionAmount, data.getTransactionAmount());
+        assertEquals(numberOfRepayments, data.getNumberOfRepayments());
+
+        // Complex fields
+        assertEquals(type, data.getType());
+        assertEquals(paymentDetailData, data.getPaymentDetailData());
+        assertEquals(currency, data.getCurrency());
+        assertEquals(externalId, data.getExternalId());
+        assertEquals(externalLoanId, data.getExternalLoanId());
+        assertEquals(reversalExternalId, data.getReversalExternalId());
+
+        // Financial amounts
+        assertEquals(netDisbursalAmount, data.getNetDisbursalAmount());
+        assertEquals(principalPortion, data.getPrincipalPortion());
+        assertEquals(interestPortion, data.getInterestPortion());
+        assertEquals(feeChargesPortion, data.getFeeChargesPortion());
+        assertEquals(penaltyChargesPortion, data.getPenaltyChargesPortion());
+        assertEquals(overpaymentPortion, data.getOverpaymentPortion());
+        assertEquals(unrecognizedIncomePortion, 
data.getUnrecognizedIncomePortion());
+        assertEquals(fixedEmiAmount, data.getFixedEmiAmount());
+        assertEquals(availableDisbursementAmountWithOverApplied, 
data.getAvailableDisbursementAmountWithOverApplied());
+
+        // Dates
+        assertEquals(possibleNextRepaymentDate, 
data.getPossibleNextRepaymentDate());
+        assertEquals(reversedOnDate, data.getReversedOnDate());
+        assertEquals(submittedOnDate, data.getSubmittedOnDate());
+
+        // Collections
+        assertEquals(transactionRelations, data.getTransactionRelations());
+        assertEquals(loanChargePaidByList, data.getLoanChargePaidByList());
+        assertEquals(loanRepaymentScheduleInstallments, 
data.getLoanRepaymentScheduleInstallments());
+        assertEquals(writeOffReasonOptions, data.getWriteOffReasonOptions());
+        assertEquals(chargeOffReasonOptions, data.getChargeOffReasonOptions());
+        assertEquals(paymentTypeOptions, data.getPaymentTypeOptions());
+        assertEquals(transfer, data.getTransfer());
+    }
+
+    @Test
+    public void testImportInstanceSimple() {
+        // Given
+        BigDecimal repaymentAmount = new BigDecimal("1500.75");
+        LocalDate lastRepaymentDate = LocalDate.of(2023, 6, 15);
+        Long repaymentTypeId = 1L;
+        Integer rowIndex = 1;
+        String locale = "en";
+        String dateFormat = "dd MMMM yyyy";
+
+        // When
+        LoanTransactionData data = 
LoanTransactionData.importInstance(repaymentAmount, lastRepaymentDate, 
repaymentTypeId, rowIndex, locale,
+                dateFormat);
+
+        // Then
+        assertEquals(repaymentAmount, data.getTransactionAmount());
+        assertEquals(lastRepaymentDate, data.getTransactionDate());
+        assertEquals(repaymentTypeId, data.getPaymentTypeId());
+        assertEquals(rowIndex, data.getRowIndex());
+        assertEquals(locale, data.getLocale());
+        assertEquals(dateFormat, data.getDateFormat());
+        assertFalse(data.isManuallyReversed());
+        assertEquals(ExternalId.empty(), data.getExternalId());
+        assertEquals(ExternalId.empty(), data.getExternalLoanId());
+        assertEquals(ExternalId.empty(), data.getReversalExternalId());
+    }
+
+    @Test
+    public void testImportInstanceWithAllFields() {
+        // Given
+        BigDecimal repaymentAmount = new BigDecimal("2000.50");
+        LocalDate repaymentDate = LocalDate.of(2023, 7, 20);
+        Long repaymentTypeId = 2L;
+        String accountNumber = "ACC123";
+        Integer checkNumber = 1001;
+        Integer routingCode = 12345;
+        Integer receiptNumber = 5001;
+        Integer bankNumber = 10;
+        Long loanAccountId = 100L;
+        String transactionType = "REPAYMENT";
+        Integer rowIndex = 2;
+        String locale = "en";
+        String dateFormat = "dd MMMM yyyy";
+
+        // When
+        LoanTransactionData data = 
LoanTransactionData.importInstance(repaymentAmount, repaymentDate, 
repaymentTypeId, accountNumber,
+                checkNumber, routingCode, receiptNumber, bankNumber, 
loanAccountId, transactionType, rowIndex, locale, dateFormat);
+
+        // Then
+        assertEquals(repaymentAmount, data.getTransactionAmount());
+        assertEquals(repaymentDate, data.getTransactionDate());
+        assertEquals(repaymentTypeId, data.getPaymentTypeId());
+        assertEquals(accountNumber, data.getAccountNumber());
+        assertEquals(checkNumber, data.getCheckNumber());
+        assertEquals(routingCode, data.getRoutingCode());
+        assertEquals(receiptNumber, data.getReceiptNumber());
+        assertEquals(bankNumber, data.getBankNumber());
+        assertEquals(loanAccountId, data.getAccountId());
+        assertEquals(transactionType, data.getTransactionType());
+        assertEquals(rowIndex, data.getRowIndex());
+        assertEquals(locale, data.getLocale());
+        assertEquals(dateFormat, data.getDateFormat());
+        assertFalse(data.isManuallyReversed());
+        assertEquals(ExternalId.empty(), data.getExternalId());
+        assertEquals(ExternalId.empty(), data.getExternalLoanId());
+        assertEquals(ExternalId.empty(), data.getReversalExternalId());
+    }
+
+    @Test
+    public void testTemplateOnTopWithPaymentOptions() {
+        // Given
+        LoanTransactionData original = createSampleTransactionData();
+        Collection<PaymentTypeData> newPaymentOptions = mock(Collection.class);
+
+        // When
+        LoanTransactionData result = 
LoanTransactionData.templateOnTop(original, newPaymentOptions);
+
+        // Then
+        assertBasicFieldsCopied(original, result);
+        assertEquals(newPaymentOptions, result.getPaymentTypeOptions());
+    }
+
+    @Test
+    public void testTemplateOnTopWithTransactionType() {
+        // Given
+        LoanTransactionData original = createSampleTransactionData();
+        LoanTransactionEnumData newType = new LoanTransactionEnumData(2L, 
"code", "NEW_TYPE");
+
+        // When
+        LoanTransactionData result = 
LoanTransactionData.templateOnTop(original, newType);
+
+        // Then
+        assertBasicFieldsCopied(original, result);
+        assertEquals(newType, result.getType());
+    }
+
+    @Test
+    public void testLoanTransactionDataForCreditTemplate() {
+        // Given
+        LoanTransactionEnumData transactionType = new 
LoanTransactionEnumData(1L, "code", "CREDIT");
+        LocalDate transactionDate = LocalDate.of(2023, 8, 1);
+        BigDecimal transactionAmount = new BigDecimal("3000.00");
+        Collection<PaymentTypeData> paymentOptions = mock(Collection.class);
+        CurrencyData currency = new CurrencyData("USD", "US Dollar", 2, 0, 
"$", "USD");
+
+        // When
+        LoanTransactionData result = 
LoanTransactionData.loanTransactionDataForCreditTemplate(transactionType, 
transactionDate,
+                transactionAmount, paymentOptions, currency);
+
+        // Then
+        assertEquals(transactionType, result.getType());
+        assertEquals(transactionDate, result.getDate());
+        assertEquals(transactionAmount, result.getAmount());
+        assertEquals(paymentOptions, result.getPaymentTypeOptions());
+        assertEquals(currency, result.getCurrency());
+        assertFalse(result.isManuallyReversed());
+        assertEquals(ExternalId.empty(), result.getExternalId());
+        assertEquals(ExternalId.empty(), result.getExternalLoanId());
+        assertEquals(ExternalId.empty(), result.getReversalExternalId());
+    }
+
+    @Test
+    public void testLoanTransactionDataForDisbursalTemplate() {
+        // Given
+        LoanTransactionEnumData transactionType = new 
LoanTransactionEnumData(1L, "code", "DISBURSAL");
+        LocalDate expectedDisbursedOn = LocalDate.of(2023, 8, 1);
+        BigDecimal disburseAmount = new BigDecimal("5000.00");
+        BigDecimal netDisbursalAmount = new BigDecimal("4950.00");
+        Collection<PaymentTypeData> paymentOptions = mock(Collection.class);
+        BigDecimal fixedEmiAmount = new BigDecimal("500.00");
+        LocalDate possibleNextRepaymentDate = LocalDate.of(2023, 9, 1);
+        CurrencyData currency = new CurrencyData("USD", "US Dollar", 2, 0, 
"$", "USD");
+        BigDecimal availableDisbursementAmount = new BigDecimal("10000.00");
+
+        // When
+        LoanTransactionData result = 
LoanTransactionData.loanTransactionDataForDisbursalTemplate(transactionType, 
expectedDisbursedOn,
+                disburseAmount, netDisbursalAmount, paymentOptions, 
fixedEmiAmount, possibleNextRepaymentDate, currency,
+                availableDisbursementAmount);
+
+        // Then
+        assertEquals(transactionType, result.getType());
+        assertEquals(expectedDisbursedOn, result.getDate());
+        assertEquals(disburseAmount, result.getAmount());
+        assertEquals(netDisbursalAmount, result.getNetDisbursalAmount());
+        assertEquals(paymentOptions, result.getPaymentTypeOptions());
+        assertEquals(fixedEmiAmount, result.getFixedEmiAmount());
+        assertEquals(possibleNextRepaymentDate, 
result.getPossibleNextRepaymentDate());
+        assertEquals(currency, result.getCurrency());
+        assertEquals(availableDisbursementAmount, 
result.getAvailableDisbursementAmountWithOverApplied());
+        assertFalse(result.isManuallyReversed());
+        assertEquals(ExternalId.empty(), result.getExternalId());
+        assertEquals(ExternalId.empty(), result.getExternalLoanId());
+        assertEquals(ExternalId.empty(), result.getReversalExternalId());
+    }
+
+    @Test
+    public void testLoanTransactionDataWithNullValues() {
+        // When
+        LoanTransactionData data = LoanTransactionData.builder().build();
+
+        // Then - Simple fields
+        assertNull(data.getId());
+        assertNull(data.getOfficeId());
+        assertNull(data.getOfficeName());
+        assertNull(data.getDate());
+        assertNull(data.getAmount());
+        assertFalse(data.isManuallyReversed()); // Default boolean
+        assertNull(data.getLoanId());
+        assertNull(data.getTransactionType());
+        assertNull(data.getRowIndex());
+        assertNull(data.getDateFormat());
+        assertNull(data.getLocale());
+        assertNull(data.getPaymentTypeId());
+        assertNull(data.getAccountNumber());
+        assertNull(data.getCheckNumber());
+        assertNull(data.getRoutingCode());
+        assertNull(data.getReceiptNumber());
+        assertNull(data.getBankNumber());
+        assertNull(data.getAccountId());
+        assertNull(data.getTransactionAmount());
+        assertNull(data.getNumberOfRepayments());
+
+        // Complex fields
+        assertNull(data.getType());
+        assertNull(data.getPaymentDetailData());
+        assertNull(data.getCurrency());
+        assertNull(data.getExternalId());
+        assertNull(data.getExternalLoanId());
+        assertNull(data.getReversalExternalId());
+
+        // Financial amounts
+        assertNull(data.getNetDisbursalAmount());
+        assertNull(data.getPrincipalPortion());
+        assertNull(data.getInterestPortion());
+        assertNull(data.getFeeChargesPortion());
+        assertNull(data.getPenaltyChargesPortion());
+        assertNull(data.getOverpaymentPortion());
+        assertNull(data.getUnrecognizedIncomePortion());
+        assertNull(data.getFixedEmiAmount());
+        assertNull(data.getAvailableDisbursementAmountWithOverApplied());
+
+        // Dates
+        assertNull(data.getPossibleNextRepaymentDate());
+        assertNull(data.getReversedOnDate());
+        assertNull(data.getSubmittedOnDate());
+
+        // Collections
+        assertNull(data.getTransactionRelations());
+        assertNull(data.getLoanChargePaidByList());
+        assertNull(data.getLoanRepaymentScheduleInstallments());
+        assertNull(data.getWriteOffReasonOptions());
+        assertNull(data.getChargeOffReasonOptions());
+        assertNull(data.getPaymentTypeOptions());
+        assertNull(data.getTransfer());
+    }
+
+    // Helper methods
+    private LoanTransactionData createSampleTransactionData() {
+        return 
LoanTransactionData.builder().id(1L).officeId(1L).officeName("Test Office")
+                .type(new LoanTransactionEnumData(1L, "code", 
"REPAYMENT")).date(LocalDate.of(2023, 1, 1)).amount(new BigDecimal("1000.00"))
+                .currency(new CurrencyData("USD", "US Dollar", 2, 0, "$", 
"USD")).paymentDetailData(mock(PaymentDetailData.class))
+                
.externalId(ExternalId.generate()).externalLoanId(ExternalId.generate()).reversalExternalId(ExternalId.generate())
+                .manuallyReversed(false).loanId(1L).build();
+    }
+
+    private void assertBasicFieldsCopied(LoanTransactionData original, 
LoanTransactionData result) {
+        assertEquals(original.getId(), result.getId());
+        assertEquals(original.getOfficeId(), result.getOfficeId());
+        assertEquals(original.getOfficeName(), result.getOfficeName());
+        assertEquals(original.getPaymentDetailData(), 
result.getPaymentDetailData());
+        assertEquals(original.getCurrency(), result.getCurrency());
+        assertEquals(original.getDate(), result.getDate());
+        assertEquals(original.getAmount(), result.getAmount());
+        assertEquals(original.getNetDisbursalAmount(), 
result.getNetDisbursalAmount());
+        assertEquals(original.getPrincipalPortion(), 
result.getPrincipalPortion());
+        assertEquals(original.getInterestPortion(), 
result.getInterestPortion());
+        assertEquals(original.getFeeChargesPortion(), 
result.getFeeChargesPortion());
+        assertEquals(original.getPenaltyChargesPortion(), 
result.getPenaltyChargesPortion());
+        assertEquals(original.getOverpaymentPortion(), 
result.getOverpaymentPortion());
+        assertEquals(original.getUnrecognizedIncomePortion(), 
result.getUnrecognizedIncomePortion());
+        assertEquals(original.getExternalId(), result.getExternalId());
+        assertEquals(original.getTransfer(), result.getTransfer());
+        assertEquals(original.getFixedEmiAmount(), result.getFixedEmiAmount());
+        assertEquals(original.getOutstandingLoanBalance(), 
result.getOutstandingLoanBalance());
+        assertEquals(original.isManuallyReversed(), 
result.isManuallyReversed());
+        assertEquals(original.getLoanId(), result.getLoanId());
+        assertEquals(original.getExternalLoanId(), result.getExternalLoanId());
+    }
+
+}
diff --git 
a/fineract-loan/src/test/java/org/apache/fineract/portfolio/loanaccount/mapper/LoanTransactionMapperTest.java
 
b/fineract-loan/src/test/java/org/apache/fineract/portfolio/loanaccount/mapper/LoanTransactionMapperTest.java
new file mode 100644
index 0000000000..643fbb8add
--- /dev/null
+++ 
b/fineract-loan/src/test/java/org/apache/fineract/portfolio/loanaccount/mapper/LoanTransactionMapperTest.java
@@ -0,0 +1,148 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.portfolio.loanaccount.mapper;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import org.apache.fineract.infrastructure.core.domain.ExternalId;
+import org.apache.fineract.organisation.monetary.data.CurrencyData;
+import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
+import org.apache.fineract.organisation.monetary.mapper.CurrencyMapper;
+import org.apache.fineract.organisation.office.domain.Office;
+import org.apache.fineract.portfolio.loanaccount.data.LoanTransactionData;
+import org.apache.fineract.portfolio.loanaccount.domain.Loan;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType;
+import org.apache.fineract.portfolio.paymentdetail.data.PaymentDetailData;
+import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
+import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+@ExtendWith(MockitoExtension.class)
+public class LoanTransactionMapperTest {
+
+    @Mock
+    private CurrencyMapper currencyMapper;
+
+    @Mock
+    private LoanTransaction loanTransaction;
+
+    @Mock
+    private Loan loan;
+
+    @Mock
+    private PaymentDetail paymentDetail;
+
+    @InjectMocks
+    private LoanTransactionMapperImpl mapper;
+
+    @BeforeEach
+    void setUp() {
+        // Setup common mocks
+        when(loanTransaction.getLoan()).thenReturn(loan);
+        when(loan.getId()).thenReturn(1L);
+        when(loan.getCurrency()).thenReturn(new MonetaryCurrency("USD", 2, 0));
+        when(currencyMapper.map(any())).thenReturn(new CurrencyData("USD", "US 
Dollar", 2, 0, "$", "code"));
+    }
+
+    @Test
+    public void testMapLoanTransaction_MapsAllFieldsCorrectly() {
+        // Given
+        LocalDate transactionDate = LocalDate.now(ZoneId.of("UTC"));
+
+        // Setup transaction mocks
+        when(loanTransaction.getId()).thenReturn(1L);
+        
when(loanTransaction.getTypeOf()).thenReturn(LoanTransactionType.REPAYMENT);
+        when(loanTransaction.getTransactionDate()).thenReturn(transactionDate);
+        when(loanTransaction.getDateOf()).thenReturn(transactionDate);
+        when(loanTransaction.getAmount()).thenReturn(BigDecimal.valueOf(1000));
+        
when(loanTransaction.getPrincipalPortion()).thenReturn(BigDecimal.valueOf(800));
+        
when(loanTransaction.getInterestPortion()).thenReturn(BigDecimal.valueOf(100));
+        
when(loanTransaction.getFeeChargesPortion()).thenReturn(BigDecimal.valueOf(50));
+        
when(loanTransaction.getPenaltyChargesPortion()).thenReturn(BigDecimal.valueOf(50));
+        when(loanTransaction.getPaymentDetail()).thenReturn(paymentDetail);
+        
when(loanTransaction.getExternalId()).thenReturn(ExternalId.generate());
+        when(loanTransaction.isManuallyAdjustedOrReversed()).thenReturn(false);
+        when(loanTransaction.getOffice()).thenReturn(Office.headOffice("Test 
Office", LocalDate.of(2022, 2, 12), null));
+        
when(loanTransaction.getLoan().getNetDisbursalAmount()).thenReturn(BigDecimal.valueOf(2000));
+
+        // Setup payment detail mocks
+        when(paymentDetail.toData()).thenReturn(new PaymentDetailData(1L, 
PaymentTypeData.instance(1L, "Cash"), "accountNumber",
+                "checkNumber", "routingCode", "receiptNumber", "bankNumber"));
+
+        // When
+        LoanTransactionData result = 
mapper.mapLoanTransaction(loanTransaction);
+
+        // Then - Verify all mapped fields
+        assertNotNull(result);
+        assertEquals(1L, result.getId());
+        assertEquals(transactionDate, result.getDate());
+        assertEquals(BigDecimal.valueOf(1000), result.getAmount());
+        assertEquals(BigDecimal.valueOf(800), result.getPrincipalPortion());
+        assertEquals(BigDecimal.valueOf(100), result.getInterestPortion());
+        assertEquals(BigDecimal.valueOf(50), result.getFeeChargesPortion());
+        assertEquals(BigDecimal.valueOf(50), 
result.getPenaltyChargesPortion());
+        assertFalse(result.isManuallyReversed());
+        assertEquals("REPAYMENT", result.getTransactionType());
+        assertNotNull(result.getType());
+        assertNotNull(result.getPaymentDetailData());
+        assertNull(result.getOfficeId());
+        assertEquals("Test Office", result.getOfficeName());
+        assertEquals(1L, result.getLoanId());
+        assertEquals(loan.getExternalId(), result.getExternalLoanId());
+        assertEquals(BigDecimal.valueOf(2000), result.getNetDisbursalAmount());
+        assertNotNull(result.getCurrency());
+
+        // Verify ignored fields are null
+        assertNull(result.getNumberOfRepayments());
+        assertNull(result.getLoanRepaymentScheduleInstallments());
+        assertNull(result.getWriteOffReasonOptions());
+        assertNull(result.getChargeOffReasonOptions());
+        assertNull(result.getPaymentTypeOptions());
+        assertNull(result.getOverpaymentPortion());
+        assertNull(result.getTransfer());
+        assertNull(result.getFixedEmiAmount());
+        assertNull(result.getPossibleNextRepaymentDate());
+        assertNull(result.getAvailableDisbursementAmountWithOverApplied());
+        assertNull(result.getRowIndex());
+        assertNull(result.getDateFormat());
+        assertNull(result.getLocale());
+        assertNull(result.getPaymentTypeId());
+        assertNull(result.getAccountNumber());
+        assertNull(result.getCheckNumber());
+        assertNull(result.getRoutingCode());
+        assertNull(result.getReceiptNumber());
+        assertNull(result.getBankNumber());
+        assertNull(result.getAccountId());
+        assertNull(result.getTransactionAmount());
+    }
+}
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 2332a4782b..f9e609b251 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
@@ -316,7 +316,7 @@ public class LoanReadPlatformServiceImpl implements 
LoanReadPlatformService, Loa
             final List<LoanChargePaidByData> loanChargePaidByDatas = 
loanChargePaidByReadService
                     .fetchLoanChargesPaidByDataTransactionId(loanIds);
             for (LoanTransactionData loanTransaction : loanTransactionData) {
-                
loanTransaction.setLoanTransactionRelations(loanTransactionRelationDatas.stream().filter(
+                
loanTransaction.setTransactionRelations(loanTransactionRelationDatas.stream().filter(
                         loanTransactionRelationData -> 
loanTransactionRelationData.getFromLoanTransaction().equals(loanTransaction.getId()))
                         .toList());
                 
loanTransaction.setLoanChargePaidByList(loanChargePaidByDatas.stream()
@@ -580,11 +580,13 @@ public class LoanReadPlatformServiceImpl implements 
LoanReadPlatformService, Loa
         BigDecimal adjustedChargeAmount = adjustPrepayInstallmentCharge(loan, 
onDate);
         BigDecimal totalAdjusted = 
outstandingAmounts.getTotalOutstanding().getAmount().subtract(adjustedChargeAmount);
 
-        return new LoanTransactionData(null, null, null, transactionType, 
null, currencyData, earliestUnpaidInstallmentDate, totalAdjusted,
-                loan.getNetDisbursalAmount(), 
outstandingAmounts.principal().getAmount(), 
outstandingAmounts.interest().getAmount(),
-                
outstandingAmounts.feeCharges().getAmount().subtract(adjustedChargeAmount), 
outstandingAmounts.penaltyCharges().getAmount(),
-                null, unrecognizedIncomePortion, paymentOptions, 
ExternalId.empty(), null, null, outstandingLoanBalance, false, loanId,
-                loan.getExternalId());
+        return 
LoanTransactionData.builder().type(transactionType).currency(currencyData).date(earliestUnpaidInstallmentDate)
+                
.amount(totalAdjusted).netDisbursalAmount(loan.getNetDisbursalAmount())
+                
.principalPortion(outstandingAmounts.principal().getAmount()).interestPortion(outstandingAmounts.interest().getAmount())
+                
.feeChargesPortion(outstandingAmounts.feeCharges().getAmount().subtract(adjustedChargeAmount))
+                
.penaltyChargesPortion(outstandingAmounts.penaltyCharges().getAmount()).unrecognizedIncomePortion(unrecognizedIncomePortion)
+                
.paymentTypeOptions(paymentOptions).externalId(ExternalId.empty()).outstandingLoanBalance(outstandingLoanBalance)
+                
.manuallyReversed(false).loanId(loanId).externalLoanId(loan.getExternalId()).build();
     }
 
     private BigDecimal adjustPrepayInstallmentCharge(Loan loan, final 
LocalDate onDate) {
@@ -621,9 +623,10 @@ public class LoanReadPlatformServiceImpl implements 
LoanReadPlatformService, Loa
         final BigDecimal outstandingLoanBalance = null;
         final BigDecimal unrecognizedIncomePortion = null;
 
-        return new LoanTransactionData(null, null, null, transactionType, 
null, currencyData, waiveOfInterest.getTransactionDate(), amount,
-                loan.getNetDisbursalAmount(), null, null, null, null, null, 
ExternalId.empty(), null, null, outstandingLoanBalance,
-                unrecognizedIncomePortion, false, loanId, 
loan.getExternalId());
+        return 
LoanTransactionData.builder().type(transactionType).currency(currencyData).date(waiveOfInterest.getTransactionDate())
+                
.amount(amount).netDisbursalAmount(loan.getNetDisbursalAmount()).outstandingLoanBalance(outstandingLoanBalance)
+                
.unrecognizedIncomePortion(unrecognizedIncomePortion).externalId(ExternalId.empty()).manuallyReversed(false).loanId(loanId)
+                .externalLoanId(loan.getExternalId()).build();
     }
 
     @Override
@@ -633,9 +636,9 @@ public class LoanReadPlatformServiceImpl implements 
LoanReadPlatformService, Loa
         final BigDecimal outstandingLoanBalance = null;
         final LoanTransactionEnumData transactionType = 
LoanEnumerations.transactionType(LoanTransactionType.WRITEOFF);
         final BigDecimal unrecognizedIncomePortion = null;
-        return new LoanTransactionData(null, null, null, transactionType, 
null, null, DateUtils.getBusinessLocalDate(), null, null, null,
-                null, null, null, null, ExternalId.empty(), null, null, 
outstandingLoanBalance, unrecognizedIncomePortion, false, null,
-                null);
+        return 
LoanTransactionData.builder().type(transactionType).date(DateUtils.getBusinessLocalDate()).externalId(ExternalId.empty())
+                
.outstandingLoanBalance(outstandingLoanBalance).unrecognizedIncomePortion(unrecognizedIncomePortion).manuallyReversed(false)
+                .build();
 
     }
 
@@ -695,7 +698,7 @@ public class LoanReadPlatformServiceImpl implements 
LoanReadPlatformService, Loa
             final LoanTransactionsMapper rm = new 
LoanTransactionsMapper(sqlGenerator);
             final String sql = "select " + rm.loanPaymentsSchema() + " where 
l.id = ? and tr.id = ? ";
             LoanTransactionData loanTransactionData = 
this.jdbcTemplate.queryForObject(sql, rm, loanId, transactionId); // NOSONAR
-            loanTransactionData.setLoanTransactionRelations(
+            loanTransactionData.setTransactionRelations(
                     
loanTransactionRelationReadService.fetchLoanTransactionRelationDataFrom(loanTransactionData.getId()));
             return loanTransactionData;
         } catch (final EmptyResultDataAccessException e) {
@@ -1749,10 +1752,14 @@ public class LoanReadPlatformServiceImpl implements 
LoanReadPlatformService, Loa
                         toTransferDescription, toTransferReversed);
             }
 
-            return new LoanTransactionData(id, officeId, officeName, 
transactionType, paymentDetailData, currencyData, date, totalAmount,
-                    netDisbursalAmount, principalPortion, interestPortion, 
feeChargesPortion, penaltyChargesPortion, overPaymentPortion,
-                    unrecognizedIncomePortion, externalId, transfer, null, 
outstandingLoanBalance, submittedOnDate, manuallyReversed,
-                    reversalExternalId, reversedOnDate, loanId, 
externalLoanId);
+            return 
LoanTransactionData.builder().id(id).officeId(officeId).officeName(officeName).type(transactionType)
+                    
.paymentDetailData(paymentDetailData).currency(currencyData).date(date).amount(totalAmount)
+                    
.netDisbursalAmount(netDisbursalAmount).principalPortion(principalPortion).interestPortion(interestPortion)
+                    
.feeChargesPortion(feeChargesPortion).penaltyChargesPortion(penaltyChargesPortion)
+                    
.overpaymentPortion(overPaymentPortion).unrecognizedIncomePortion(unrecognizedIncomePortion).externalId(externalId)
+                    
.transfer(transfer).outstandingLoanBalance(outstandingLoanBalance).submittedOnDate(submittedOnDate)
+                    
.manuallyReversed(manuallyReversed).reversalExternalId(reversalExternalId).reversedOnDate(reversedOnDate).loanId(loanId)
+                    .externalLoanId(externalLoanId).build();
         }
     }
 
@@ -2007,9 +2014,10 @@ public class LoanReadPlatformServiceImpl implements 
LoanReadPlatformService, Loa
         final Collection<PaymentTypeData> paymentOptions = 
this.paymentTypeReadPlatformService.retrieveAllPaymentTypes();
         BigDecimal outstandingLoanBalance = null;
         final BigDecimal unrecognizedIncomePortion = null;
-        return new LoanTransactionData(null, null, null, transactionType, 
null, null, null, loan.getTotalWrittenOff(),
-                loan.getNetDisbursalAmount(), null, null, null, null, null, 
unrecognizedIncomePortion, paymentOptions, ExternalId.empty(),
-                null, null, outstandingLoanBalance, false, loanId, 
loan.getExternalId());
+        return 
LoanTransactionData.builder().type(transactionType).amount(loan.getTotalWrittenOff())
+                
.netDisbursalAmount(loan.getNetDisbursalAmount()).unrecognizedIncomePortion(unrecognizedIncomePortion)
+                
.paymentTypeOptions(paymentOptions).externalId(ExternalId.empty()).outstandingLoanBalance(outstandingLoanBalance)
+                
.manuallyReversed(false).loanId(loanId).externalLoanId(loan.getExternalId()).build();
 
     }
 
@@ -2021,10 +2029,10 @@ public class LoanReadPlatformServiceImpl implements 
LoanReadPlatformService, Loa
         final BigDecimal totalOutstanding = loan.getSummary() != null ? 
loan.getSummary().getTotalOutstanding() : null;
         final List<CodeValueData> writeOffReasonOptions = new ArrayList<>(
                 
this.codeValueReadPlatformService.retrieveCodeValuesByCode(LoanApiConstants.WRITEOFFREASONS));
-        LoanTransactionData loanTransactionData = new 
LoanTransactionData(null, null, null, transactionType, null, loan.getCurrency(),
-                DateUtils.getBusinessLocalDate(), totalOutstanding, 
loan.getNetDisbursalAmount(), null, null, null, null, null,
-                ExternalId.empty(), null, null, null, null, false, loanId, 
loan.getExternalId());
-        loanTransactionData.setWriteOffReasonOptions(writeOffReasonOptions);
+        LoanTransactionData loanTransactionData = 
LoanTransactionData.builder().type(transactionType).currency(loan.getCurrency())
+                
.date(DateUtils.getBusinessLocalDate()).amount(totalOutstanding).netDisbursalAmount(loan.getNetDisbursalAmount())
+                
.externalId(ExternalId.empty()).manuallyReversed(false).loanId(loanId).externalLoanId(loan.getExternalId())
+                .writeOffReasonOptions(writeOffReasonOptions).build();
         return loanTransactionData;
     }
 
@@ -2040,11 +2048,12 @@ public class LoanReadPlatformServiceImpl implements 
LoanReadPlatformService, Loa
         final BigDecimal totalPenaltyOutstanding = loan.getSummary() != null ? 
loan.getSummary().getPenaltyChargesOutstanding() : null;
         final List<CodeValueData> chargeOffReasonOptions = new ArrayList<>(
                 
this.codeValueReadPlatformService.retrieveCodeValuesByCode(LoanApiConstants.CHARGE_OFF_REASONS));
-        LoanTransactionData loanTransactionData = new 
LoanTransactionData(null, null, null, transactionType, null, loan.getCurrency(),
-                DateUtils.getBusinessLocalDate(), totalOutstanding, 
loan.getNetDisbursalAmount(), totalPrincipalOutstanding,
-                totalInterestOutstanding, totalFeeOutstanding, 
totalPenaltyOutstanding, null, ExternalId.empty(), null, null, null, null,
-                false, loanId, loan.getExternalId());
-        loanTransactionData.setChargeOffReasonOptions(chargeOffReasonOptions);
+        LoanTransactionData loanTransactionData = 
LoanTransactionData.builder().type(transactionType).currency(loan.getCurrency())
+                
.date(DateUtils.getBusinessLocalDate()).amount(totalOutstanding).netDisbursalAmount(loan.getNetDisbursalAmount())
+                
.principalPortion(totalPrincipalOutstanding).interestPortion(totalInterestOutstanding)
+                
.feeChargesPortion(totalFeeOutstanding).penaltyChargesPortion(totalPenaltyOutstanding).externalId(ExternalId.empty())
+                
.manuallyReversed(false).loanId(loanId).externalLoanId(loan.getExternalId()).chargeOffReasonOptions(chargeOffReasonOptions)
+                .build();
         return loanTransactionData;
     }
 
@@ -2216,9 +2225,9 @@ public class LoanReadPlatformServiceImpl implements 
LoanReadPlatformService, Loa
         final LocalDate currentDate = 
LocalDate.now(DateUtils.getDateTimeZoneOfTenant());
 
         final LoanTransactionEnumData transactionType = 
LoanEnumerations.transactionType(loanTransactionType);
-        return new LoanTransactionData(null, null, null, transactionType, 
null, currencyData, currentDate, transactionAmount, null,
-                netDisbursal, null, null, null, null, null, paymentOptions, 
ExternalId.empty(), null, null, null, false, loanId,
-                externalLoanId);
+        return 
LoanTransactionData.builder().type(transactionType).currency(currencyData).date(currentDate).amount(transactionAmount)
+                
.netDisbursalAmount(netDisbursal).paymentTypeOptions(paymentOptions).externalId(ExternalId.empty()).manuallyReversed(false)
+                .loanId(loanId).externalLoanId(externalLoanId).build();
     }
 
     @Override
@@ -2309,14 +2318,15 @@ public class LoanReadPlatformServiceImpl implements 
LoanReadPlatformService, Loa
 
         final Money outStandingAmount = 
loanRepaymentScheduleInstallment.getTotalOutstanding(currency);
 
-        return new LoanTransactionData(null, null, null, transactionType, 
null, currencyData, earliestUnpaidInstallmentDate,
-                outStandingAmount.getAmount(), loan.getNetDisbursalAmount(),
-                
loanRepaymentScheduleInstallment.getPrincipalOutstanding(currency).getAmount(),
-                
loanRepaymentScheduleInstallment.getInterestOutstanding(currency).getAmount(),
-                
loanRepaymentScheduleInstallment.getFeeChargesOutstanding(currency).getAmount(),
-                
loanRepaymentScheduleInstallment.getPenaltyChargesOutstanding(currency).getAmount(),
 null, unrecognizedIncomePortion,
-                paymentTypeOptions, ExternalId.empty(), null, null, 
outstandingLoanBalance, isManuallyReversed, loanId,
-                loan.getExternalId());
+        return 
LoanTransactionData.builder().type(transactionType).currency(currencyData).date(earliestUnpaidInstallmentDate)
+                
.amount(outStandingAmount.getAmount()).netDisbursalAmount(loan.getNetDisbursalAmount())
+                
.principalPortion(loanRepaymentScheduleInstallment.getPrincipalOutstanding(currency).getAmount())
+                
.interestPortion(loanRepaymentScheduleInstallment.getInterestOutstanding(currency).getAmount())
+                
.feeChargesPortion(loanRepaymentScheduleInstallment.getFeeChargesOutstanding(currency).getAmount())
+                
.penaltyChargesPortion(loanRepaymentScheduleInstallment.getPenaltyChargesOutstanding(currency).getAmount())
+                
.unrecognizedIncomePortion(unrecognizedIncomePortion).paymentTypeOptions(paymentTypeOptions).externalId(ExternalId.empty())
+                
.outstandingLoanBalance(outstandingLoanBalance).manuallyReversed(isManuallyReversed).loanId(loanId)
+                .externalLoanId(loan.getExternalId()).build();
     }
 
     private static final class CurrencyMapper implements 
RowMapper<CurrencyData> {
@@ -2395,10 +2405,13 @@ public class LoanReadPlatformServiceImpl implements 
LoanReadPlatformService, Loa
             boolean manuallyReversed = false;
             final PaymentDetailData paymentDetailData = null;
             final AccountTransferData transfer = null;
-            final BigDecimal fixedEmiAmount = null;
-            return new LoanTransactionData(id, officeId, officeName, 
transactionType, paymentDetailData, currencyData, date, totalDue,
-                    netDisbursalAmount, principalPortion, interestDue, feeDue, 
penaltyDue, overPaymentPortion, ExternalId.empty(), transfer,
-                    fixedEmiAmount, outstandingLoanBalance, 
unrecognizedIncomePortion, manuallyReversed, loanId, ExternalId.empty());
+            return 
LoanTransactionData.builder().id(id).officeId(officeId).officeName(officeName).type(transactionType)
+                    
.paymentDetailData(paymentDetailData).currency(currencyData).date(date).amount(totalDue)
+                    
.netDisbursalAmount(netDisbursalAmount).principalPortion(principalPortion).interestPortion(interestDue)
+                    
.feeChargesPortion(feeDue).penaltyChargesPortion(penaltyDue).overpaymentPortion(overPaymentPortion)
+                    
.externalId(ExternalId.empty()).transfer(transfer).outstandingLoanBalance(outstandingLoanBalance)
+                    
.unrecognizedIncomePortion(unrecognizedIncomePortion).manuallyReversed(manuallyReversed).loanId(loanId)
+                    .externalLoanId(ExternalId.empty()).build();
         }
 
     }
diff --git 
a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanAdjustTransactionBusinessEventSerializerTest.java
 
b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanAdjustTransactionBusinessEventSerializerTest.java
index 1bbe3f7cd5..e4e66c6ffa 100644
--- 
a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanAdjustTransactionBusinessEventSerializerTest.java
+++ 
b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanAdjustTransactionBusinessEventSerializerTest.java
@@ -137,11 +137,15 @@ public class 
LoanAdjustTransactionBusinessEventSerializerTest {
         String reversedLocalDate = 
reversedOnDate.format(DateTimeFormatter.ISO_DATE);
         LoanAdjustTransactionBusinessEvent businessEvent = new 
LoanAdjustTransactionBusinessEvent(loanAdjustTransactionBusinessEventData);
 
-        LoanTransactionData transactionToAdjustData = new 
LoanTransactionData(1L, 1L, "", LoanEnumerations.transactionType(2), null, null,
-                LocalDate.now(ZoneId.systemDefault()), 
BigDecimal.valueOf(0.0), BigDecimal.valueOf(0.0), BigDecimal.valueOf(0.0),
-                BigDecimal.valueOf(0.0), BigDecimal.valueOf(0.0), 
BigDecimal.valueOf(0.0), BigDecimal.valueOf(0.0), BigDecimal.valueOf(0.0),
-                new ExternalId("testExternalId"), null, null, 
BigDecimal.valueOf(0.0), LocalDate.now(ZoneId.systemDefault()).minusDays(4),
-                true, new ExternalId("testReversalExternalId"), 
reversedOnDate, 1L, new ExternalId("testExternalLoanId"));
+        LoanTransactionData transactionToAdjustData = 
LoanTransactionData.builder().id(1L).officeId(1L).officeName("")
+                
.type(LoanEnumerations.transactionType(2)).date(LocalDate.now(ZoneId.systemDefault())).amount(BigDecimal.valueOf(0.0))
+                
.netDisbursalAmount(BigDecimal.valueOf(0.0)).principalPortion(BigDecimal.valueOf(0.0))
+                
.interestPortion(BigDecimal.valueOf(0.0)).feeChargesPortion(BigDecimal.valueOf(0.0))
+                
.penaltyChargesPortion(BigDecimal.valueOf(0.0)).overpaymentPortion(BigDecimal.valueOf(0.0))
+                
.unrecognizedIncomePortion(BigDecimal.valueOf(0.0)).externalId(new 
ExternalId("testExternalId"))
+                
.outstandingLoanBalance(BigDecimal.valueOf(0.0)).submittedOnDate(LocalDate.now(ZoneId.systemDefault()).minusDays(4))
+                .manuallyReversed(true).reversalExternalId(new 
ExternalId("testReversalExternalId")).reversedOnDate(reversedOnDate)
+                .loanId(1L).externalLoanId(new 
ExternalId("testExternalLoanId")).build();
 
         when(service.retrieveLoanTransaction(anyLong(), 
anyLong())).thenReturn(transactionToAdjustData);
         
when(loanChargePaidByReadService.fetchLoanChargesPaidByDataTransactionId(anyLong())).thenReturn(new
 ArrayList<>());

Reply via email to