| /** |
| * 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); |
| } |
| } |
| } |