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<>());