blob: ec42c7630b2db7d275c21b04f2237c776aca0e2d [file] [log] [blame]
/**
* 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.client.service;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDate;
import java.util.Collection;
import lombok.RequiredArgsConstructor;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.infrastructure.core.domain.ExternalId;
import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
import org.apache.fineract.infrastructure.core.service.Page;
import org.apache.fineract.infrastructure.core.service.PaginationHelper;
import org.apache.fineract.infrastructure.core.service.SearchParameters;
import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
import org.apache.fineract.organisation.monetary.data.CurrencyData;
import org.apache.fineract.portfolio.client.data.ClientTransactionData;
import org.apache.fineract.portfolio.client.domain.ClientEnumerations;
import org.apache.fineract.portfolio.client.domain.ClientTransaction;
import org.apache.fineract.portfolio.client.domain.ClientTransactionRepository;
import org.apache.fineract.portfolio.client.domain.ClientTransactionType;
import org.apache.fineract.portfolio.client.exception.ClientTransactionNotFoundException;
import org.apache.fineract.portfolio.paymentdetail.data.PaymentDetailData;
import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class ClientTransactionReadPlatformServiceImpl implements ClientTransactionReadPlatformService {
private final JdbcTemplate jdbcTemplate;
private final DatabaseSpecificSQLGenerator sqlGenerator;
private final ClientTransactionMapper clientTransactionMapper = new ClientTransactionMapper();
private final PaginationHelper paginationHelper;
private final ClientTransactionRepository clientTransactionRepository;
private static final class ClientTransactionMapper implements RowMapper<ClientTransactionData> {
private final String schemaSql;
ClientTransactionMapper() {
final StringBuilder sqlBuilder = new StringBuilder(400);
sqlBuilder.append("tr.id as transactionId, tr.transaction_type_enum as transactionType, ");
sqlBuilder.append("tr.transaction_date as transactionDate, tr.amount as transactionAmount, ");
sqlBuilder.append("tr.submitted_on_date as submittedOnDate, tr.is_reversed as reversed, ");
sqlBuilder.append("tr.external_id as externalId, o.name as officeName, o.id as officeId, ");
sqlBuilder.append("c.id as clientId, c.account_no as accountNo, ccpb.client_charge_id as clientChargeId, ");
sqlBuilder.append("pd.payment_type_id as paymentType,pd.account_number as accountNumber,pd.check_number as checkNumber, ");
sqlBuilder.append("pd.receipt_number as receiptNumber, pd.bank_number as bankNumber,pd.routing_code as routingCode, ");
sqlBuilder.append(
"tr.currency_code as currencyCode, curr.decimal_places as currencyDigits, curr.currency_multiplesof as inMultiplesOf, ");
sqlBuilder.append("curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, ");
sqlBuilder.append("curr.display_symbol as currencyDisplaySymbol, ");
sqlBuilder.append("pt.value as paymentTypeName ");
sqlBuilder.append("from m_client c ");
sqlBuilder.append("join m_client_transaction tr on tr.client_id = c.id ");
sqlBuilder.append("join m_currency curr on curr.code = tr.currency_code ");
sqlBuilder.append("left join m_payment_detail pd on tr.payment_detail_id = pd.id ");
sqlBuilder.append("left join m_payment_type pt on pd.payment_type_id = pt.id ");
sqlBuilder.append("left join m_office o on o.id = tr.office_id ");
sqlBuilder.append("left join m_client_charge_paid_by ccpb on ccpb.client_transaction_id = tr.id ");
this.schemaSql = sqlBuilder.toString();
}
public String schema() {
return this.schemaSql;
}
@Override
public ClientTransactionData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
final Long id = rs.getLong("transactionId");
final Long officeId = rs.getLong("officeId");
final String officeName = rs.getString("officeName");
final String externalId = rs.getString("externalId");
final int transactionTypeInt = JdbcSupport.getInteger(rs, "transactionType");
final EnumOptionData transactionType = ClientEnumerations.clientTransactionType(transactionTypeInt);
final LocalDate date = JdbcSupport.getLocalDate(rs, "transactionDate");
final LocalDate submittedOnDate = JdbcSupport.getLocalDate(rs, "submittedOnDate");
final BigDecimal amount = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "transactionAmount");
final boolean reversed = rs.getBoolean("reversed");
PaymentDetailData paymentDetailData = null;
if (ClientTransactionType.fromInt(transactionType.getId().intValue()).equals(ClientTransactionType.PAY_CHARGE)) {
final Long paymentTypeId = JdbcSupport.getLong(rs, "paymentType");
if (paymentTypeId != null) {
final String typeName = rs.getString("paymentTypeName");
final PaymentTypeData paymentType = PaymentTypeData.instance(paymentTypeId, typeName);
final String accountNumber = rs.getString("accountNumber");
final String checkNumber = rs.getString("checkNumber");
final String routingCode = rs.getString("routingCode");
final String receiptNumber = rs.getString("receiptNumber");
final String bankNumber = rs.getString("bankNumber");
paymentDetailData = new PaymentDetailData(id, paymentType, accountNumber, checkNumber, routingCode, receiptNumber,
bankNumber);
}
}
final String currencyCode = rs.getString("currencyCode");
final String currencyName = rs.getString("currencyName");
final String currencyNameCode = rs.getString("currencyNameCode");
final String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
final Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits");
final Integer inMultiplesOf = JdbcSupport.getInteger(rs, "inMultiplesOf");
final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDigits, inMultiplesOf, currencyDisplaySymbol,
currencyNameCode);
return ClientTransactionData.create(id, officeId, officeName, transactionType, date, currency, paymentDetailData, amount,
externalId, submittedOnDate, reversed);
}
}
@Override
public Page<ClientTransactionData> retrieveAllTransactions(Long clientId, SearchParameters searchParameters) {
Object[] parameters = new Object[1];
final StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ").append(this.clientTransactionMapper.schema())
.append(" where c.id = ? ");
parameters[0] = clientId;
sqlBuilder.append(" order by tr.transaction_date DESC, tr.submitted_on_date DESC, tr.id DESC ");
// apply limit and offsets
if (searchParameters.hasLimit()) {
sqlBuilder.append(" ");
if (searchParameters.hasOffset()) {
sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset()));
} else {
sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit()));
}
}
return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), parameters, this.clientTransactionMapper);
}
@Override
public Collection<ClientTransactionData> retrieveAllTransactions(Long clientId, Long chargeId) {
Object[] parameters = new Object[1];
String sql = "select " + this.clientTransactionMapper.schema() + " where c.id = ? ";
if (chargeId != null) {
parameters = new Object[2];
parameters[1] = chargeId;
sql = sql + " and ccpb.client_charge_id = ?";
}
parameters[0] = clientId;
sql = sql + " order by tr.transaction_date DESC, tr.submitted_on_date DESC, tr.id DESC";
return this.jdbcTemplate.query(sql, this.clientTransactionMapper, parameters); // NOSONAR
}
@Override
public ClientTransactionData retrieveTransaction(Long clientId, Long transactionId) {
try {
final String sql = "select " + this.clientTransactionMapper.schema() + " where c.id = ? and tr.id= ?";
return this.jdbcTemplate.queryForObject(sql, this.clientTransactionMapper, clientId, transactionId); // NOSONAR
} catch (final EmptyResultDataAccessException e) {
throw new ClientTransactionNotFoundException(clientId, transactionId, e);
}
}
@Override
public ClientTransaction retrieveTransactionByExternalId(ExternalId transactionExternalId) {
return clientTransactionRepository.findByExternalId(transactionExternalId);
}
}