FINERACT-2326: Improve LoanTransactionData DTO structure
This commit is contained in:
committed by
Arnold Gálovics
parent
d06eb618d0
commit
937bfe529c
+46
-301
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
+15
-1
@@ -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);
|
||||
}
|
||||
|
||||
+428
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
+148
@@ -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());
|
||||
}
|
||||
}
|
||||
+57
-44
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+9
-5
@@ -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<>());
|
||||
|
||||
Reference in New Issue
Block a user