blob: dc19626f97568450d508a47467a9ec70b1d8a825 [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.accounting.journalentry.service;
import static java.util.Objects.requireNonNull;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.accounting.common.AccountingEnumerations;
import org.apache.fineract.accounting.financialactivityaccount.domain.FinancialActivityAccount;
import org.apache.fineract.accounting.financialactivityaccount.domain.FinancialActivityAccountRepositoryWrapper;
import org.apache.fineract.accounting.glaccount.data.GLAccountData;
import org.apache.fineract.accounting.glaccount.domain.GLAccountType;
import org.apache.fineract.accounting.glaccount.service.GLAccountReadPlatformService;
import org.apache.fineract.accounting.journalentry.data.JournalEntryAssociationParametersData;
import org.apache.fineract.accounting.journalentry.data.JournalEntryData;
import org.apache.fineract.accounting.journalentry.data.OfficeOpeningBalancesData;
import org.apache.fineract.accounting.journalentry.data.TransactionDetailData;
import org.apache.fineract.accounting.journalentry.data.TransactionTypeEnumData;
import org.apache.fineract.accounting.journalentry.exception.JournalEntriesNotFoundException;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
import org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
import org.apache.fineract.infrastructure.core.service.DateUtils;
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.infrastructure.security.utils.ColumnValidator;
import org.apache.fineract.organisation.monetary.data.CurrencyData;
import org.apache.fineract.organisation.office.data.OfficeData;
import org.apache.fineract.organisation.office.service.OfficeReadPlatformService;
import org.apache.fineract.portfolio.account.PortfolioAccountType;
import org.apache.fineract.portfolio.loanaccount.data.LoanTransactionEnumData;
import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations;
import org.apache.fineract.portfolio.note.data.NoteData;
import org.apache.fineract.portfolio.paymentdetail.data.PaymentDetailData;
import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
import org.apache.fineract.portfolio.savings.data.SavingsAccountTransactionEnumData;
import org.apache.fineract.portfolio.savings.service.SavingsEnumerations;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.util.CollectionUtils;
@RequiredArgsConstructor
public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlatformService {
private final JdbcTemplate jdbcTemplate;
private final GLAccountReadPlatformService glAccountReadPlatformService;
private final OfficeReadPlatformService officeReadPlatformService;
private final ColumnValidator columnValidator;
private final FinancialActivityAccountRepositoryWrapper financialActivityAccountRepositoryWrapper;
private final PaginationHelper paginationHelper;
private final DatabaseSpecificSQLGenerator sqlGenerator;
private static final class GLJournalEntryMapper implements RowMapper<JournalEntryData> {
private final JournalEntryAssociationParametersData associationParametersData;
GLJournalEntryMapper(final JournalEntryAssociationParametersData associationParametersData) {
this.associationParametersData = Objects.requireNonNullElseGet(associationParametersData,
JournalEntryAssociationParametersData::new);
}
public String schema() {
StringBuilder sb = new StringBuilder();
sb.append(" journalEntry.id as id, glAccount.classification_enum as classification ,").append("journalEntry.transaction_id,")
.append(" glAccount.name as glAccountName, glAccount.gl_code as glAccountCode,glAccount.id as glAccountId, ")
.append(" journalEntry.office_id as officeId, office.name as officeName, journalEntry.ref_num as referenceNumber, ")
.append(" journalEntry.manual_entry as manualEntry,journalEntry.entry_date as transactionDate, ")
.append(" journalEntry.type_enum as entryType,journalEntry.amount as amount, journalEntry.transaction_id as transactionId,")
.append(" journalEntry.entity_type_enum as entityType, journalEntry.entity_id as entityId, creatingUser.id as createdByUserId, ")
.append(" creatingUser.username as createdByUserName, journalEntry.description as comments, ")
.append(" journalEntry.submitted_on_date as submittedOnDate, journalEntry.reversed as reversed, ")
.append(" journalEntry.currency_code as currencyCode, curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, ")
.append(" curr.display_symbol as currencyDisplaySymbol, curr.decimal_places as currencyDigits, curr.currency_multiplesof as inMultiplesOf ");
if (associationParametersData.isRunningBalanceRequired()) {
sb.append(" ,journalEntry.is_running_balance_calculated as runningBalanceComputed, ")
.append(" journalEntry.office_running_balance as officeRunningBalance, ")
.append(" journalEntry.organization_running_balance as organizationRunningBalance ");
}
if (associationParametersData.isTransactionDetailsRequired()) {
sb.append(" ,pd.receipt_number as receiptNumber, ").append(" pd.check_number as checkNumber, ")
.append(" pd.account_number as accountNumber, ").append(" pt.value as paymentTypeName, ")
.append(" pd.payment_type_id as paymentTypeId,").append(" pd.bank_number as bankNumber, ")
.append(" pd.routing_code as routingCode, ").append(" note.id as noteId, ")
.append(" note.note as transactionNote, ").append(" lt.transaction_type_enum as loanTransactionType, ")
.append(" st.transaction_type_enum as savingsTransactionType ");
}
sb.append(" from acc_gl_journal_entry as journalEntry ")
.append(" left join acc_gl_account as glAccount on glAccount.id = journalEntry.account_id")
.append(" left join m_office as office on office.id = journalEntry.office_id")
.append(" left join m_appuser as creatingUser on creatingUser.id = journalEntry.created_by ")
.append(" join m_currency curr on curr.code = journalEntry.currency_code ");
if (associationParametersData.isTransactionDetailsRequired()) {
sb.append(" left join m_loan_transaction as lt on journalEntry.loan_transaction_id = lt.id ")
.append(" left join m_savings_account_transaction as st on journalEntry.savings_transaction_id = st.id ")
.append(" left join m_payment_detail as pd on lt.payment_detail_id = pd.id or st.payment_detail_id = pd.id or journalEntry.payment_details_id = pd.id")
.append(" left join m_payment_type as pt on pt.id = pd.payment_type_id ")
.append(" left join m_note as note on lt.id = note.loan_transaction_id or st.id = note.savings_account_transaction_id ");
}
return sb.toString();
}
@Override
public JournalEntryData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
final Long id = rs.getLong("id");
final Long officeId = rs.getLong("officeId");
final String officeName = rs.getString("officeName");
final String glCode = rs.getString("glAccountCode");
final String glAccountName = rs.getString("glAccountName");
final Long glAccountId = rs.getLong("glAccountId");
final int accountTypeId = JdbcSupport.getInteger(rs, "classification");
final EnumOptionData accountType = AccountingEnumerations.gLAccountType(accountTypeId);
final LocalDate transactionDate = JdbcSupport.getLocalDate(rs, "transactionDate");
final Boolean manualEntry = rs.getBoolean("manualEntry");
final BigDecimal amount = rs.getBigDecimal("amount");
final int entryTypeId = JdbcSupport.getInteger(rs, "entryType");
final EnumOptionData entryType = AccountingEnumerations.journalEntryType(entryTypeId);
final String transactionId = rs.getString("transactionId");
final Integer entityTypeId = JdbcSupport.getInteger(rs, "entityType");
EnumOptionData entityType = null;
if (entityTypeId != null) {
entityType = AccountingEnumerations.portfolioProductType(entityTypeId);
}
final Long entityId = JdbcSupport.getLong(rs, "entityId");
final Long createdByUserId = rs.getLong("createdByUserId");
final LocalDate submittedOnDate = JdbcSupport.getLocalDate(rs, "submittedOnDate");
final String createdByUserName = rs.getString("createdByUserName");
final String comments = rs.getString("comments");
final Boolean reversed = rs.getBoolean("reversed");
final String referenceNumber = rs.getString("referenceNumber");
BigDecimal officeRunningBalance = null;
BigDecimal organizationRunningBalance = null;
Boolean runningBalanceComputed = null;
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);
if (associationParametersData.isRunningBalanceRequired()) {
officeRunningBalance = rs.getBigDecimal("officeRunningBalance");
organizationRunningBalance = rs.getBigDecimal("organizationRunningBalance");
runningBalanceComputed = rs.getBoolean("runningBalanceComputed");
}
TransactionDetailData transactionDetailData = null;
if (associationParametersData.isTransactionDetailsRequired()) {
PaymentDetailData paymentDetailData = null;
final Long paymentTypeId = JdbcSupport.getLong(rs, "paymentTypeId");
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);
}
NoteData noteData = null;
final Long noteId = JdbcSupport.getLong(rs, "noteId");
if (noteId != null) {
final String note = rs.getString("transactionNote");
noteData = new NoteData(noteId, null, null, null, null, null, null, null, note, null, null, null, null, null, null);
}
Long transaction = null;
if (entityType != null && transactionId != null) {
String numericPart = transactionId.replaceAll("[^\\d]", "");
if (!numericPart.isEmpty()) {
transaction = Long.parseLong(numericPart);
}
}
TransactionTypeEnumData transactionTypeEnumData = null;
if (PortfolioAccountType.fromInt(entityTypeId).isLoanAccount()) {
final LoanTransactionEnumData loanTransactionType = LoanEnumerations
.transactionType(JdbcSupport.getInteger(rs, "loanTransactionType"));
transactionTypeEnumData = new TransactionTypeEnumData(loanTransactionType.getId(), loanTransactionType.getCode(),
loanTransactionType.getValue());
} else if (PortfolioAccountType.fromInt(entityTypeId).isSavingsAccount()) {
final SavingsAccountTransactionEnumData savingsTransactionType = SavingsEnumerations
.transactionType(JdbcSupport.getInteger(rs, "savingsTransactionType"));
transactionTypeEnumData = new TransactionTypeEnumData(savingsTransactionType.getId(), savingsTransactionType.getCode(),
savingsTransactionType.getValue());
}
transactionDetailData = new TransactionDetailData(transaction, paymentDetailData, noteData, transactionTypeEnumData);
}
return new JournalEntryData(id, officeId, officeName, glAccountName, glAccountId, glCode, accountType, transactionDate,
entryType, amount, transactionId, manualEntry, entityType, entityId, createdByUserId, submittedOnDate,
createdByUserName, comments, reversed, referenceNumber, officeRunningBalance, organizationRunningBalance,
runningBalanceComputed, transactionDetailData, currency);
}
}
@Override
public Page<JournalEntryData> retrieveAll(final SearchParameters searchParameters, final Long glAccountId,
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);
final StringBuilder sqlBuilder = new StringBuilder(200);
sqlBuilder.append("select ").append(sqlGenerator.calcFoundRows()).append(" ");
sqlBuilder.append(rm.schema());
final Object[] objectArray = new Object[15];
int arrayPos = 0;
String whereClose = " where ";
if (StringUtils.isNotBlank(transactionId)) {
sqlBuilder.append(whereClose).append(" journalEntry.transaction_id = ?");
objectArray[arrayPos] = transactionId;
arrayPos = arrayPos + 1;
whereClose = " and ";
}
if (entityType != null && entityType != 0 && (onlyManualEntries == null)) {
sqlBuilder.append(whereClose).append(" journalEntry.entity_type_enum = ?");
objectArray[arrayPos] = entityType;
arrayPos = arrayPos + 1;
whereClose = " and ";
}
if (searchParameters.hasOfficeId()) {
sqlBuilder.append(whereClose).append(" journalEntry.office_id = ?");
objectArray[arrayPos] = searchParameters.getOfficeId();
arrayPos = arrayPos + 1;
whereClose = " and ";
}
if (searchParameters.hasCurrencyCode()) {
sqlBuilder.append(whereClose).append(" journalEntry.currency_code = ?");
objectArray[arrayPos] = searchParameters.getCurrencyCode();
arrayPos = arrayPos + 1;
whereClose = " and ";
}
if (glAccountId != null && glAccountId != 0) {
sqlBuilder.append(whereClose).append(" journalEntry.account_id = ?");
objectArray[arrayPos] = glAccountId;
arrayPos = arrayPos + 1;
whereClose = " and ";
}
if (fromDate != null || toDate != null) {
if (fromDate != null && toDate != null) {
sqlBuilder.append(whereClose).append(" journalEntry.entry_date between ? and ? ");
whereClose = " and ";
objectArray[arrayPos] = fromDate;
arrayPos = arrayPos + 1;
objectArray[arrayPos] = toDate;
arrayPos = arrayPos + 1;
} else if (fromDate != null) {
sqlBuilder.append(whereClose).append(" journalEntry.entry_date >= ? ");
whereClose = " and ";
objectArray[arrayPos] = fromDate;
arrayPos = arrayPos + 1;
} else {
sqlBuilder.append(whereClose).append(" journalEntry.entry_date <= ? ");
whereClose = " and ";
objectArray[arrayPos] = toDate;
arrayPos = arrayPos + 1;
}
}
if (submittedOnDateFrom != null || submittedOnDateTo != null) {
if (submittedOnDateFrom != null && submittedOnDateTo != null) {
sqlBuilder.append(whereClose).append(" journalEntry.submitted_on_date between ? and ? ");
whereClose = " and ";
objectArray[arrayPos] = submittedOnDateFrom;
arrayPos = arrayPos + 1;
objectArray[arrayPos] = submittedOnDateTo;
arrayPos = arrayPos + 1;
} else if (fromDate != null) {
sqlBuilder.append(whereClose).append(" journalEntry.submitted_on_date >= ? ");
whereClose = " and ";
objectArray[arrayPos] = submittedOnDateFrom;
arrayPos = arrayPos + 1;
} else {
sqlBuilder.append(whereClose).append(" journalEntry.submitted_on_date <= ? ");
whereClose = " and ";
objectArray[arrayPos] = submittedOnDateTo;
arrayPos = arrayPos + 1;
}
}
if (onlyManualEntries != null) {
if (onlyManualEntries) {
sqlBuilder.append(whereClose).append(" journalEntry.manual_entry = ?");
whereClose = " and ";
objectArray[arrayPos] = Boolean.TRUE;
arrayPos = arrayPos + 1;
}
}
if (searchParameters.hasLoanId()) {
sqlBuilder.append(whereClose)
.append(" journalEntry.loan_transaction_id in (select id from m_loan_transaction where loan_id = ?)");
objectArray[arrayPos] = searchParameters.getLoanId();
arrayPos = arrayPos + 1;
whereClose = " and ";
}
if (searchParameters.hasSavingsId()) {
sqlBuilder.append(whereClose).append(
" journalEntry.savings_transaction_id in (select id from m_savings_account_transaction where savings_account_id = ?)");
objectArray[arrayPos] = searchParameters.getSavingsId();
arrayPos = arrayPos + 1;
}
if (searchParameters.hasOrderBy()) {
sqlBuilder.append(" order by ").append(searchParameters.getOrderBy());
this.columnValidator.validateSqlInjection(sqlBuilder.toString(), searchParameters.getOrderBy());
if (searchParameters.hasSortOrder()) {
sqlBuilder.append(' ').append(searchParameters.getSortOrder());
this.columnValidator.validateSqlInjection(sqlBuilder.toString(), searchParameters.getOrderBy());
}
} else {
sqlBuilder.append(" order by journalEntry.entry_date, journalEntry.id");
}
if (searchParameters.hasLimit()) {
sqlBuilder.append(" ");
if (searchParameters.hasOffset()) {
sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset()));
} else {
sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit()));
}
}
final Object[] finalObjectArray = Arrays.copyOf(objectArray, arrayPos);
return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), finalObjectArray, rm);
}
@Override
public JournalEntryData retrieveGLJournalEntryById(final long glJournalEntryId,
JournalEntryAssociationParametersData associationParametersData) {
try {
final GLJournalEntryMapper rm = new GLJournalEntryMapper(associationParametersData);
// Programmatic query, disable sonar issue
final String sql = "select " + rm.schema() + " where journalEntry.id = ?";
return this.jdbcTemplate.queryForObject(sql, rm, glJournalEntryId); // NOSONAR
} catch (final EmptyResultDataAccessException e) {
throw new JournalEntriesNotFoundException(glJournalEntryId, e);
}
}
@Override
public OfficeOpeningBalancesData retrieveOfficeOpeningBalances(final Long officeId, String currencyCode) {
final FinancialActivityAccount financialActivityAccountId = this.financialActivityAccountRepositoryWrapper
.findByFinancialActivityTypeWithNotFoundDetection(300);
final Long contraId = financialActivityAccountId.getGlAccount().getId();
if (contraId == null) {
throw new GeneralPlatformDomainRuleException(
"error.msg.financial.activity.mapping.opening.balance.contra.account.cannot.be.null",
"office-opening-balances-contra-account value can not be null", "office-opening-balances-contra-account");
}
final JournalEntryAssociationParametersData associationParametersData = new JournalEntryAssociationParametersData();
final GLAccountData contraAccount = this.glAccountReadPlatformService.retrieveGLAccountById(contraId, associationParametersData);
if (!GLAccountType.fromInt(requireNonNull(requireNonNull(contraAccount.getType()).getId()).intValue()).isEquityType()) {
throw new GeneralPlatformDomainRuleException(
"error.msg.configuration.opening.balance.contra.account.value.is.invalid.account.type",
"Global configuration 'office-opening-balances-contra-account' value is not an equity type account", contraId);
}
final OfficeData officeData = this.officeReadPlatformService.retrieveOffice(officeId);
final List<JournalEntryData> allOpeningTransactions = populateAllTransactionsFromGLAccounts(contraId);
final String contraTransactionId = retrieveContraAccountTransactionId(officeId, contraId, currencyCode);
List<JournalEntryData> existingOpeningBalanceTransactions = new ArrayList<>();
if (StringUtils.isNotBlank(contraTransactionId)) {
existingOpeningBalanceTransactions = retrieveOfficeBalanceTransactions(officeId, contraTransactionId, currencyCode);
}
final List<JournalEntryData> transactions = populateOpeningBalances(existingOpeningBalanceTransactions, allOpeningTransactions);
final List<JournalEntryData> assetAccountOpeningBalances = new ArrayList<>();
final List<JournalEntryData> liabilityAccountOpeningBalances = new ArrayList<>();
final List<JournalEntryData> incomeAccountOpeningBalances = new ArrayList<>();
final List<JournalEntryData> equityAccountOpeningBalances = new ArrayList<>();
final List<JournalEntryData> expenseAccountOpeningBalances = new ArrayList<>();
for (final JournalEntryData journalEntryData : transactions) {
final GLAccountType type = GLAccountType.fromInt(journalEntryData.getGlAccountType().getId().intValue());
if (type.isAssetType()) {
assetAccountOpeningBalances.add(journalEntryData);
} else if (type.isLiabilityType()) {
liabilityAccountOpeningBalances.add(journalEntryData);
} else if (type.isEquityType()) {
equityAccountOpeningBalances.add(journalEntryData);
} else if (type.isIncomeType()) {
incomeAccountOpeningBalances.add(journalEntryData);
} else if (type.isExpenseType()) {
expenseAccountOpeningBalances.add(journalEntryData);
}
}
final LocalDate transactionDate = DateUtils.getBusinessLocalDate();
return OfficeOpeningBalancesData.createNew(officeId, officeData.getName(), transactionDate, contraAccount,
assetAccountOpeningBalances, liabilityAccountOpeningBalances, incomeAccountOpeningBalances, equityAccountOpeningBalances,
expenseAccountOpeningBalances);
}
private List<JournalEntryData> populateOpeningBalances(final List<JournalEntryData> existingOpeningBalanceTransactions,
final List<JournalEntryData> allOpeningTransactions) {
final List<JournalEntryData> allOpeningBalanceTransactions = new ArrayList<>(allOpeningTransactions.size());
for (final JournalEntryData newOpeningBalanceTransaction : allOpeningTransactions) {
boolean isNewTransactionAddedToCollection = false;
for (final JournalEntryData existingOpeningBalanceTransaction : existingOpeningBalanceTransactions) {
if (newOpeningBalanceTransaction.getGlAccountId().equals(existingOpeningBalanceTransaction.getGlAccountId())) {
allOpeningBalanceTransactions.add(existingOpeningBalanceTransaction);
isNewTransactionAddedToCollection = true;
break;
}
}
if (!isNewTransactionAddedToCollection) {
allOpeningBalanceTransactions.add(newOpeningBalanceTransaction);
}
}
return allOpeningBalanceTransactions;
}
private List<JournalEntryData> populateAllTransactionsFromGLAccounts(final Long contraId) {
final List<GLAccountData> glAccounts = this.glAccountReadPlatformService.retrieveAllEnabledDetailGLAccounts();
final List<JournalEntryData> openingBalanceTransactions = new ArrayList<>(glAccounts.size());
for (final GLAccountData glAccountData : glAccounts) {
if (!contraId.equals(glAccountData.getId())) {
final JournalEntryData openingBalanceTransaction = JournalEntryData.fromGLAccountData(glAccountData);
openingBalanceTransactions.add(openingBalanceTransaction);
}
}
return openingBalanceTransactions;
}
private List<JournalEntryData> retrieveOfficeBalanceTransactions(final Long officeId, final String transactionId,
final String currencyCode) {
final Long contraId = null;
return retrieveContraTransactions(officeId, contraId, transactionId, currencyCode).getPageItems();
}
private String retrieveContraAccountTransactionId(final Long officeId, final Long contraId, final String currencyCode) {
final String transactionId = "";
final Page<JournalEntryData> contraJournalEntries = retrieveContraTransactions(officeId, contraId, transactionId, currencyCode);
if (!CollectionUtils.isEmpty(contraJournalEntries.getPageItems())) {
final JournalEntryData contraTransaction = contraJournalEntries.getPageItems()
.get(contraJournalEntries.getPageItems().size() - 1);
return contraTransaction.getTransactionId();
}
return transactionId;
}
private Page<JournalEntryData> retrieveContraTransactions(final Long officeId, final Long contraId, final String transactionId,
final String currencyCode) {
final Integer entityType = null;
final Boolean onlyManualEntries = null;
final LocalDate fromDate = null;
final LocalDate toDate = null;
final LocalDate submittedOnDateFrom = null;
final LocalDate submittedOnDateTo = null;
final JournalEntryAssociationParametersData associationParametersData = null;
final SearchParameters searchParameters = SearchParameters.builder().orphansOnly(false).officeId(officeId).offset(0)
.orderBy("journalEntry.id").sortOrder("ASC").currencyCode(currencyCode).build();
return retrieveAll(searchParameters, contraId, onlyManualEntries, fromDate, toDate, submittedOnDateFrom, submittedOnDateTo,
transactionId, entityType, associationParametersData);
}
@Override
public Page<JournalEntryData> retrieveJournalEntriesByEntityId(String transactionId, Long entityId, Integer entityType) {
JournalEntryAssociationParametersData associationParametersData = new JournalEntryAssociationParametersData(true, true);
try {
final GLJournalEntryMapper rm = new GLJournalEntryMapper(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 };
return this.paginationHelper.fetchPage(this.jdbcTemplate, sql, data, rm);
} catch (final EmptyResultDataAccessException e) {
throw new JournalEntriesNotFoundException(entityId, e);
}
}
}