FINEREACT-2404: Improved extensibility and cleanup

This commit is contained in:
cucusenok
2025-11-07 10:19:40 +01:00
committed by Adam Saghy
parent d269cb983f
commit 9320dd1bd7
12 changed files with 72 additions and 45 deletions
@@ -79,11 +79,11 @@ public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlat
private final PaginationHelper paginationHelper;
private final DatabaseSpecificSQLGenerator sqlGenerator;
private static final class GLJournalEntryMapper implements RowMapper<JournalEntryData> {
protected static class GLJournalEntryMapper implements RowMapper<JournalEntryData> {
private final JournalEntryAssociationParametersData associationParametersData;
GLJournalEntryMapper(final JournalEntryAssociationParametersData associationParametersData) {
protected GLJournalEntryMapper(final JournalEntryAssociationParametersData associationParametersData) {
this.associationParametersData = Objects.requireNonNullElseGet(associationParametersData,
JournalEntryAssociationParametersData::new);
}
@@ -240,8 +240,7 @@ public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlat
final Boolean onlyManualEntries, final LocalDate fromDate, final LocalDate toDate, final LocalDate submittedOnDateFrom,
final LocalDate submittedOnDateTo, final String transactionId, final Integer entityType,
final JournalEntryAssociationParametersData associationParametersData) {
GLJournalEntryMapper rm = new GLJournalEntryMapper(associationParametersData);
GLJournalEntryMapper rm = getGlJournalEntryMapper(associationParametersData);
final StringBuilder sqlBuilder = new StringBuilder(200);
sqlBuilder.append("select ").append(sqlGenerator.calcFoundRows()).append(" ");
sqlBuilder.append(rm.schema());
@@ -383,12 +382,16 @@ public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlat
return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), finalObjectArray, rm);
}
protected GLJournalEntryMapper getGlJournalEntryMapper(JournalEntryAssociationParametersData associationParametersData) {
return new GLJournalEntryMapper(associationParametersData);
}
@Override
public JournalEntryData retrieveGLJournalEntryById(final long glJournalEntryId,
JournalEntryAssociationParametersData associationParametersData) {
try {
final GLJournalEntryMapper rm = new GLJournalEntryMapper(associationParametersData);
final GLJournalEntryMapper rm = getGlJournalEntryMapper(associationParametersData);
// Programmatic query, disable sonar issue
final String sql = "select " + rm.schema() + " where journalEntry.id = ?";
@@ -526,7 +529,7 @@ public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlat
public Page<JournalEntryData> retrieveJournalEntriesByEntityId(String transactionId, Long entityId, Integer entityType) {
JournalEntryAssociationParametersData associationParametersData = new JournalEntryAssociationParametersData(true, true);
try {
final GLJournalEntryMapper rm = new GLJournalEntryMapper(associationParametersData);
final GLJournalEntryMapper rm = getGlJournalEntryMapper(associationParametersData);
final String sql = "select " + rm.schema()
+ " where journalEntry.transaction_id = ? and journalEntry.entity_id = ? and journalEntry.entity_type_enum = ?";
Object[] data = { transactionId, entityId, entityType };
@@ -98,7 +98,7 @@ import org.springframework.stereotype.Component;
@Component("loanTransactionValidator")
@AllArgsConstructor
public final class LoanTransactionValidatorImpl implements LoanTransactionValidator {
public class LoanTransactionValidatorImpl implements LoanTransactionValidator {
private final FromJsonHelper fromApiJsonHelper;
private final LoanApplicationValidator fromApiJsonDeserializer;
@@ -245,7 +245,7 @@ public final class LoanTransactionValidatorImpl implements LoanTransactionValida
});
}
private void validateDisbursementWithPostDatedChecks(final String json, final Long loanId) {
protected void validateDisbursementWithPostDatedChecks(final String json, final Long loanId) {
final JsonElement jsonElement = this.fromApiJsonHelper.parse(json);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan.disbursement");
@@ -291,7 +291,7 @@ public final class LoanTransactionValidatorImpl implements LoanTransactionValida
}
}
private void validateDisbursementDateWithMeetingDate(final LocalDate actualDisbursementDate, final CalendarInstance calendarInstance,
protected void validateDisbursementDateWithMeetingDate(final LocalDate actualDisbursementDate, final CalendarInstance calendarInstance,
Boolean isSkipRepaymentOnFirstMonth, Integer numberOfDays) {
if (null != calendarInstance) {
final Calendar calendar = calendarInstance.getCalendar();
@@ -334,9 +334,7 @@ public final class LoanTransactionValidatorImpl implements LoanTransactionValida
throw new InvalidJsonException();
}
final Set<String> transactionParameters = new HashSet<>(Arrays.asList("transactionDate", "transactionAmount", "externalId", "note",
"locale", "dateFormat", "paymentTypeId", "accountNumber", "checkNumber", "routingCode", "receiptNumber", "bankNumber",
LoanApiConstants.REVERSAL_EXTERNAL_ID_PARAMNAME));
final Set<String> transactionParameters = getTransactionParametersForEdit();
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, transactionParameters);
@@ -363,6 +361,12 @@ public final class LoanTransactionValidatorImpl implements LoanTransactionValida
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
protected HashSet<String> getTransactionParametersForEdit() {
return new HashSet<>(Arrays.asList("transactionDate", "transactionAmount", "externalId", "note", "locale", "dateFormat",
"paymentTypeId", "accountNumber", "checkNumber", "routingCode", "receiptNumber", "bankNumber",
LoanApiConstants.REVERSAL_EXTERNAL_ID_PARAMNAME));
}
@Override
public void validateChargebackTransaction(final String json) {
@@ -405,8 +409,7 @@ public final class LoanTransactionValidatorImpl implements LoanTransactionValida
throw new InvalidJsonException();
}
final Set<String> disbursementParameters = new HashSet<>(
Arrays.asList("transactionDate", "note", "locale", "dateFormat", "writeoffReasonId", "externalId"));
final Set<String> disbursementParameters = getNoAmountTransactionParameters();
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, disbursementParameters);
@@ -427,6 +430,10 @@ public final class LoanTransactionValidatorImpl implements LoanTransactionValida
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
protected Set<String> getNoAmountTransactionParameters() {
return new HashSet<>(Arrays.asList("transactionDate", "note", "locale", "dateFormat", "writeoffReasonId", "externalId"));
}
@Override
public void validateChargeOffTransaction(final String json) {
if (StringUtils.isBlank(json)) {
@@ -659,7 +666,7 @@ public final class LoanTransactionValidatorImpl implements LoanTransactionValida
}
}
private void validateLoanHasNoLaterChargeRefundTransactionToReverseOrCreateATransaction(Loan loan, LocalDate transactionDate,
protected void validateLoanHasNoLaterChargeRefundTransactionToReverseOrCreateATransaction(Loan loan, LocalDate transactionDate,
String reversedOrCreated) {
for (LoanTransaction txn : loan.getLoanTransactions()) {
if (txn.isChargeRefund() && DateUtils.isBefore(transactionDate, txn.getTransactionDate())) {
@@ -671,7 +678,7 @@ public final class LoanTransactionValidatorImpl implements LoanTransactionValida
}
}
private void validateLoanDisbursementIsBeforeTransactionDate(final Loan loan, final LocalDate transactionDate) {
protected void validateLoanDisbursementIsBeforeTransactionDate(final Loan loan, final LocalDate transactionDate) {
if (DateUtils.isBefore(transactionDate, loan.getDisbursementDate())) {
final String errorMessage = "The transaction date cannot be before the loan disbursement date: "
+ loan.getDisbursementDate().toString();
@@ -680,14 +687,14 @@ public final class LoanTransactionValidatorImpl implements LoanTransactionValida
}
}
private void validateTransactionShouldNotBeInTheFuture(final LocalDate transactionDate) {
protected void validateTransactionShouldNotBeInTheFuture(final LocalDate transactionDate) {
if (DateUtils.isDateInTheFuture(transactionDate)) {
final String errorMessage = "The transaction date cannot be in the future.";
throw new InvalidLoanStateTransitionException("transaction", "cannot.be.a.future.date", errorMessage, transactionDate);
}
}
private void validateLoanHasCurrency(final Loan loan) {
protected void validateLoanHasCurrency(final Loan loan) {
MonetaryCurrency currency = loan.getCurrency();
final ApplicationCurrency defaultApplicationCurrency = this.applicationCurrencyRepository.findOneByCode(currency.getCode());
if (defaultApplicationCurrency == null) {
@@ -695,7 +702,7 @@ public final class LoanTransactionValidatorImpl implements LoanTransactionValida
}
}
private void validateClientOfficeJoiningDateIsBeforeTransactionDate(Loan loan, LocalDate transactionDate) {
protected void validateClientOfficeJoiningDateIsBeforeTransactionDate(Loan loan, LocalDate transactionDate) {
if (loan.getClient() != null && loan.getClient().getOfficeJoiningDate() != null) {
final LocalDate clientOfficeJoiningDate = loan.getClient().getOfficeJoiningDate();
if (DateUtils.isBefore(transactionDate, clientOfficeJoiningDate)) {
@@ -759,7 +766,7 @@ public final class LoanTransactionValidatorImpl implements LoanTransactionValida
}
}
private void validateTransactionAmountNotExceedThresholdForMultiDisburseLoan(Loan loan) {
protected void validateTransactionAmountNotExceedThresholdForMultiDisburseLoan(Loan loan) {
if (loan.getLoanProduct().isMultiDisburseLoan()) {
BigDecimal totalDisbursed = loan.getDisbursedAmount();
BigDecimal totalPrincipalAdjusted = loan.getSummary().getTotalPrincipalAdjustments();
@@ -830,7 +837,7 @@ public final class LoanTransactionValidatorImpl implements LoanTransactionValida
validateTransactionAmountNotExceedThresholdForMultiDisburseLoan(loan);
}
private void validateRepaymentTypeTransactionNotBeforeAChargeRefund(final Loan loan, final LoanTransactionType loanTransactionType,
protected void validateRepaymentTypeTransactionNotBeforeAChargeRefund(final Loan loan, final LoanTransactionType loanTransactionType,
final LocalDate transactionDate) {
if (loanTransactionType.isRepaymentType() && !loanTransactionType.isChargeRefund()) {
for (LoanTransaction txn : loan.getLoanTransactions()) {
@@ -931,7 +938,7 @@ public final class LoanTransactionValidatorImpl implements LoanTransactionValida
return totalCollateral;
}
private static @NonNull Set<String> getDisbursementParameters(boolean isAccountTransfer) {
protected @NonNull Set<String> getDisbursementParameters(boolean isAccountTransfer) {
Set<String> disbursementParameters;
if (isAccountTransfer) {
@@ -952,9 +959,7 @@ public final class LoanTransactionValidatorImpl implements LoanTransactionValida
throw new InvalidJsonException();
}
final Set<String> transactionParameters = new HashSet<>(Arrays.asList("transactionDate", "transactionAmount", "externalId", "note",
"locale", "dateFormat", "paymentTypeId", "accountNumber", "checkNumber", "routingCode", "receiptNumber", "bankNumber",
"loanId", "numberOfRepayments", "interestRefundCalculation"));
final Set<String> transactionParameters = getRepaymentParameters();
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, transactionParameters);
@@ -976,6 +981,12 @@ public final class LoanTransactionValidatorImpl implements LoanTransactionValida
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
protected Set<String> getRepaymentParameters() {
return new HashSet<>(Arrays.asList("transactionDate", "transactionAmount", "externalId", "note", "locale", "dateFormat",
"paymentTypeId", "accountNumber", "checkNumber", "routingCode", "receiptNumber", "bankNumber", "loanId",
"numberOfRepayments", "interestRefundCalculation"));
}
@Override
public void validatePaymentDetails(final DataValidatorBuilder baseDataValidator, final JsonElement element) {
// Validate all string payment detail fields for max length
@@ -188,7 +188,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
private final ConfigurationDomainService configurationDomainService;
private final AccountDetailsReadPlatformService accountDetailsReadPlatformService;
private final ColumnValidator columnValidator;
private final DatabaseSpecificSQLGenerator sqlGenerator;
protected final DatabaseSpecificSQLGenerator sqlGenerator;
private final DelinquencyReadPlatformService delinquencyReadPlatformService;
private final LoanTransactionRepository loanTransactionRepository;
private final LoanChargePaidByReadService loanChargePaidByReadService;
@@ -300,7 +300,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
try {
this.context.authenticatedUser();
final LoanTransactionsMapper rm = new LoanTransactionsMapper(sqlGenerator);
final LoanTransactionsMapper rm = createLoanTransactionsMapper();
// retrieve all loan transactions that are not invalid and have not
// been 'contra'ed by another transaction
@@ -332,6 +332,10 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
}
}
protected LoanTransactionsMapper createLoanTransactionsMapper() {
return new LoanTransactionsMapper(sqlGenerator);
}
@Override
public Page<LoanAccountData> retrieveAll(final SearchParameters searchParameters) {
@@ -704,7 +708,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
public LoanTransactionData retrieveLoanTransaction(final Long loanId, final Long transactionId) {
this.context.authenticatedUser();
try {
final LoanTransactionsMapper rm = new LoanTransactionsMapper(sqlGenerator);
final LoanTransactionsMapper rm = createLoanTransactionsMapper();
final String sql = "select " + rm.loanPaymentsSchema() + " where l.id = ? and tr.id = ? ";
LoanTransactionData loanTransactionData = this.jdbcTemplate.queryForObject(sql, rm, loanId, transactionId); // NOSONAR
loanTransactionData.setTransactionRelations(
@@ -1702,11 +1706,11 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
}
private static final class LoanTransactionsMapper implements RowMapper<LoanTransactionData> {
protected static class LoanTransactionsMapper implements RowMapper<LoanTransactionData> {
private final DatabaseSpecificSQLGenerator sqlGenerator;
LoanTransactionsMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
protected LoanTransactionsMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
this.sqlGenerator = sqlGenerator;
}
@@ -1680,7 +1680,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
loan.getTopupLoanDetails().setTopupAmount(amount);
}
private void disburseLoanToSavings(final Loan loan, final JsonCommand command, final Money amount, final PaymentDetail paymentDetail) {
protected Long disburseLoanToSavings(final Loan loan, final JsonCommand command, final Money amount,
final PaymentDetail paymentDetail) {
final LocalDate transactionDate = command.localDateValueOfParameterNamed("actualDisbursementDate");
final ExternalId txnExternalId = externalIdFactory.createFromCommand(command, LoanApiConstants.externalIdParameterName);
@@ -1699,7 +1700,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
PortfolioAccountType.SAVINGS, loan.getId(), portfolioAccountData.getId(), "Loan Disbursement", locale, fmt, paymentDetail,
LoanTransactionType.DISBURSEMENT.getValue(), null, null, null, AccountTransferType.ACCOUNT_TRANSFER.getValue(), null, null,
txnExternalId, loan, null, fromSavingsAccount, isRegularTransaction, isExceptionForBalanceCheck);
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
return this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
}
@Transactional
@@ -91,7 +91,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
// mappers
private final SavingsAccountTransactionTemplateMapper transactionTemplateMapper;
private final SavingsAccountTransactionsMapper transactionsMapper;
protected SavingsAccountTransactionsMapper transactionsMapper;
private final SavingsAccountTransactionsForBatchMapper savingsAccountTransactionsForBatchMapper;
private final SavingAccountMapper savingAccountMapper;
private final SavingAccountMapperForInterestPosting savingAccountMapperForInterestPosting;
@@ -1088,7 +1088,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
* return this.jdbcTemplate.query(sql, this.annualFeeMapper, new Object[] {}); }
*/
public static final class SavingsAccountTransactionsMapper implements RowMapper<SavingsAccountTransactionData> {
public static class SavingsAccountTransactionsMapper implements RowMapper<SavingsAccountTransactionData> {
private static final String SELECT = buildSelect();
private static final String FROM = buildFrom();
@@ -1096,7 +1096,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
public SavingsAccountTransactionsMapper() {}
private static String buildSelect() {
protected static String buildSelect() {
return "tr.id as transactionId, tr.transaction_type_enum as transactionType, "
+ "tr.transaction_date as transactionDate, tr.amount as transactionAmount, "
+ "tr.release_id_of_hold_amount as releaseTransactionId, tr.reason_for_block as reasonForBlock, "
@@ -1116,7 +1116,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
+ "curr.display_symbol as currencyDisplaySymbol, pt.value as paymentTypeName, " + "tr.is_manual as postInterestAsOn ";
}
private static String buildFrom() {
protected static String buildFrom() {
return " FROM m_savings_account_transaction tr join m_savings_account sa on tr.savings_account_id = sa.id "
+ "join m_currency curr on curr.code = sa.currency_code "
+ "left join m_account_transfer_transaction fromtran on fromtran.from_savings_transaction_id = tr.id "
@@ -70,6 +70,7 @@ public class SavingsAccountTransactionsSearchServiceImpl implements SavingsAccou
private final DataTableValidator dataTableValidator;
private final JdbcTemplate jdbcTemplate;
private final SearchUtil searchUtil;
protected SavingsAccountReadPlatformServiceImpl.SavingsAccountTransactionsMapper tm = new SavingsAccountReadPlatformServiceImpl.SavingsAccountTransactionsMapper();
@Override
public Page<SavingsAccountTransactionData> searchTransactions(@NonNull Long savingsId,
@@ -111,7 +112,6 @@ public class SavingsAccountTransactionsSearchServiceImpl implements SavingsAccou
ArrayList<Object> params = new ArrayList<>();
searchUtil.buildQueryCondition(columnFilters, where, params, alias, headersByName, null, null, null, false, sqlGenerator);
SavingsAccountReadPlatformServiceImpl.SavingsAccountTransactionsMapper tm = new SavingsAccountReadPlatformServiceImpl.SavingsAccountTransactionsMapper();
Object[] args = params.toArray();
String countQuery = "SELECT COUNT(*) " + tm.from() + where;