001    /*
002     * Copyright 2011 The Kuali Foundation.
003     * 
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     * 
008     * http://www.opensource.org/licenses/ecl2.php
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.kfs.gl.dataaccess.impl;
017    
018    import java.math.BigDecimal;
019    import java.util.ArrayList;
020    import java.util.List;
021    import java.util.Map;
022    
023    import org.kuali.kfs.gl.GeneralLedgerConstants;
024    import org.kuali.kfs.gl.dataaccess.AccountBalanceObjectDao;
025    import org.kuali.kfs.gl.service.AccountBalanceService;
026    import org.kuali.kfs.sys.KFSConstants;
027    import org.kuali.kfs.sys.businessobject.SystemOptions;
028    import org.kuali.kfs.sys.businessobject.UniversityDate;
029    import org.kuali.kfs.sys.context.SpringContext;
030    import org.kuali.kfs.sys.service.UniversityDateService;
031    import org.kuali.rice.kns.util.Guid;
032    import org.springframework.dao.IncorrectResultSizeDataAccessException;
033    import org.springframework.jdbc.support.rowset.SqlRowSet;
034    
035    /**
036     * Calculate Balance By Object Balance Inquiry Screen
037     */
038    public class AccountBalanceObjectDaoJdbc extends AccountBalanceDaoJdbcBase implements AccountBalanceObjectDao {
039        private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AccountBalanceObjectDaoJdbc.class);
040    
041        /**
042         * Returns a collection of report data for the account balance by object inquiry
043         * 
044         * @param universityFiscalYear the university fiscal year of reported on account balances
045         * @param chartOfAccountsCode the chart of accounts code of reported on account balances
046         * @param accountNumber the account number of reported on account balances
047         * @param financialObjectLevelCode the object level code of reported on account balances
048         * @param financialReportingSortCode the sort code for reported results
049         * @param isCostShareExcluded whether cost share account balances should be excluded from the query or not
050         * @param isConsolidated whether the results of the query should be consolidated
051         * @param pendingEntriesCode whether this query should account for no pending entries, approved pending entries, or all pending entries
052         * @return a List of Maps with the results of the query
053         * @see org.kuali.kfs.gl.dataaccess.AccountBalanceDao#findAccountBalanceByObject(java.lang.Integer, java.lang.String,
054         *      java.lang.String, java.lang.String, java.lang.String, boolean, boolean, int)
055         */
056        public List findAccountBalanceByObject(Integer universityFiscalYear, String chartOfAccountsCode, String accountNumber, String financialObjectLevelCode, String financialReportingSortCode, boolean isCostShareExcluded, boolean isConsolidated, int pendingEntriesCode) {
057            LOG.debug("findAccountBalanceByObject() started");
058    
059            SystemOptions options = optionsService.getOptions(universityFiscalYear);
060            List<Map<String, Object>> data = null;
061            String sessionId = new Guid().toString();
062            try {
063                // Delete any data for this session if it exists already
064                clearTempTable("FP_BAL_BY_OBJ_MT", "SESID", sessionId);
065                clearTempTable("FP_INTERIM1_OBJ_MT", "SESID", sessionId);
066    
067                // Add in all the data we need
068                getSimpleJdbcTemplate().update("INSERT INTO FP_INTERIM1_OBJ_MT (UNIV_FISCAL_YR, FIN_COA_CD, ACCOUNT_NBR, SUB_ACCT_NBR,FIN_OBJECT_CD, FIN_SUB_OBJ_CD, CURR_BDLN_BAL_AMT," 
069                        + " ACLN_ACTLS_BAL_AMT, ACLN_ENCUM_BAL_AMT, TIMESTAMP,SESID) " 
070                        + " SELECT a.UNIV_FISCAL_YR, a.FIN_COA_CD, a.ACCOUNT_NBR, a.SUB_ACCT_NBR," 
071                        + " a.FIN_OBJECT_CD, a.FIN_SUB_OBJ_CD, a.CURR_BDLN_BAL_AMT,a.ACLN_ACTLS_BAL_AMT, a.ACLN_ENCUM_BAL_AMT, a.TIMESTAMP, ?" 
072                        + " FROM GL_ACCT_BALANCES_T a, CA_OBJECT_CODE_T o WHERE a.univ_fiscal_yr = ? " 
073                        + " AND a.fin_coa_cd = ?" 
074                        + " AND a.account_nbr = ?" 
075                        + " AND a.univ_fiscal_yr = o.univ_fiscal_yr AND a.fin_coa_cd = o.fin_coa_cd AND a.fin_object_cd = o.fin_object_cd " 
076                        + "AND o.fin_obj_level_cd = ?", sessionId, universityFiscalYear, chartOfAccountsCode, accountNumber, financialObjectLevelCode);
077    
078                // Summarize pending entries into fp_interim1_level_mt if necessary
079                if ((pendingEntriesCode == AccountBalanceService.PENDING_ALL) || (pendingEntriesCode == AccountBalanceService.PENDING_APPROVED)) {
080                    if (getMatchingPendingEntriesByObject(options, universityFiscalYear, chartOfAccountsCode, accountNumber, financialObjectLevelCode, isCostShareExcluded, pendingEntriesCode, sessionId)) {
081                        summarizePendingEntriesByObject(options, sessionId);
082                    }
083                }
084    
085                // Delete what we don't need
086                if (isCostShareExcluded) {
087                    purgeCostShareEntries("FP_INTERIM1_OBJ_MT", "sesid", sessionId);
088                }
089    
090                // Summarize
091                if (isConsolidated) {
092                    getSimpleJdbcTemplate().update("INSERT INTO FP_BAL_BY_OBJ_MT (SUB_ACCT_NBR, FIN_OBJECT_CD, CURR_BDLN_BAL_AMT, ACLN_ACTLS_BAL_AMT, ACLN_ENCUM_BAL_AMT, FIN_REPORT_SORT_CD, " 
093                            + "SESID) SELECT  '*ALL*',fin_object_cd, SUM(curr_bdln_bal_amt),SUM(acln_actls_bal_amt), SUM(acln_encum_bal_amt)," 
094                            + "'B', ? " 
095                            + " FROM FP_INTERIM1_OBJ_MT WHERE FP_INTERIM1_OBJ_MT.SESID  = ?" 
096                            + " GROUP BY fin_object_cd", sessionId, sessionId);
097                }
098                else {
099                    getSimpleJdbcTemplate().update("INSERT INTO FP_BAL_BY_OBJ_MT (SUB_ACCT_NBR, FIN_OBJECT_CD, CURR_BDLN_BAL_AMT, ACLN_ACTLS_BAL_AMT, ACLN_ENCUM_BAL_AMT, FIN_REPORT_SORT_CD, " 
100                            + "SESID) SELECT  sub_acct_nbr, fin_object_cd, SUM(curr_bdln_bal_amt), SUM(acln_actls_bal_amt),SUM(acln_encum_bal_amt), " 
101                            + " 'B', ? " 
102                            + " FROM FP_INTERIM1_OBJ_MT WHERE FP_INTERIM1_OBJ_MT.SESID = ? " 
103                            + " GROUP BY sub_acct_nbr, fin_object_cd", sessionId, sessionId);
104                }
105    
106                // Here's the data
107                data = getSimpleJdbcTemplate().queryForList("select SUB_ACCT_NBR, FIN_OBJECT_CD, CURR_BDLN_BAL_AMT, ACLN_ACTLS_BAL_AMT, ACLN_ENCUM_BAL_AMT, FIN_REPORT_SORT_CD from FP_BAL_BY_OBJ_MT " 
108                        + " where SESID = ? " + " order by fin_object_cd", sessionId);
109            }
110            finally {
111                // Clean up everything
112                clearTempTable("FP_BAL_BY_OBJ_MT", "SESID", sessionId);
113                clearTempTable("FP_INTERIM1_OBJ_MT", "SESID", sessionId);
114                clearTempTable("GL_PENDING_ENTRY_MT", "SESID", sessionId);
115            }
116            return data;
117        }
118    
119        /**
120         * Summarizes all the pending ledger entries that would need to be reported on by this inquiry, 
121         * and saves all of that data to a temporary table
122         * 
123         * @param options a set of system options
124         * @param sessionId the unique web id of the currently inquiring user, used as a key for the temp table
125         */
126        protected void summarizePendingEntriesByObject(SystemOptions options, String sessionId) {
127            LOG.debug("summarizePendingEntriesByObject() started");
128    
129            try {
130    
131                String balanceStatementSql = "SELECT CURR_BDLN_BAL_AMT,ACLN_ACTLS_BAL_AMT,ACLN_ENCUM_BAL_AMT " 
132                        + "FROM FP_INTERIM1_OBJ_MT " 
133                        + "WHERE sesid = ? AND univ_fiscal_yr = ? AND fin_coa_cd = ? AND account_nbr = ? AND sub_acct_nbr = ?" 
134                        + " AND fin_object_cd = ? AND fin_sub_obj_cd = ?";
135    
136                String updateBalanceStatementSql = "UPDATE FP_INTERIM1_OBJ_MT " 
137                        + " SET curr_bdln_bal_amt = ?,acln_actls_bal_amt = ?,acln_encum_bal_amt = ? " 
138                        + " WHERE sesid = ? AND univ_fiscal_yr = ? AND fin_coa_cd = ? AND account_nbr = ? AND sub_acct_nbr = ?" 
139                        + " AND fin_object_cd = ? AND fin_sub_obj_cd = ?";
140    
141                String insertBalanceStatementSql = "INSERT INTO FP_INTERIM1_OBJ_MT (UNIV_FISCAL_YR, FIN_COA_CD, ACCOUNT_NBR, SUB_ACCT_NBR, FIN_OBJECT_CD, " 
142                        + "FIN_SUB_OBJ_CD, CURR_BDLN_BAL_AMT, ACLN_ACTLS_BAL_AMT, ACLN_ENCUM_BAL_AMT, TIMESTAMP, SESID) " 
143                        + "VALUES (?,?,?,?,?,?,?,?,?," + getDbPlatform().getCurTimeFunction() + ",?)";
144    
145                SqlRowSet pendingEntryRowSet = getJdbcTemplate().queryForRowSet("SELECT b.FIN_OFFST_GNRTN_CD,t.FIN_OBJTYP_DBCR_CD,e.* " 
146                        + "FROM GL_PENDING_ENTRY_MT e,CA_OBJ_TYPE_T t,CA_BALANCE_TYPE_T b " + "WHERE e.SESID = ?" 
147                        + " AND e.FIN_OBJ_TYP_CD = t.FIN_OBJ_TYP_CD AND e.fin_balance_typ_cd = b.fin_balance_typ_cd " 
148                        + "ORDER BY e.univ_fiscal_yr,e.account_nbr,e.sub_acct_nbr,e.fin_object_cd,e.fin_sub_obj_cd,e.fin_obj_typ_cd", new Object[] { sessionId });
149    
150    
151                int updateCount = 0;
152                int insertCount = 0;
153                while (pendingEntryRowSet.next()) {
154    
155                    Map<String, Object> balance = null;
156                    try {
157                        balance = getSimpleJdbcTemplate().queryForMap(balanceStatementSql, sessionId, pendingEntryRowSet.getInt(GeneralLedgerConstants.ColumnNames.UNIVERSITY_FISCAL_YEAR), pendingEntryRowSet.getString(GeneralLedgerConstants.ColumnNames.CHART_OF_ACCOUNTS_CODE), pendingEntryRowSet.getString(GeneralLedgerConstants.ColumnNames.ACCOUNT_NUMBER), pendingEntryRowSet.getString(GeneralLedgerConstants.ColumnNames.SUB_ACCOUNT_NUMBER), pendingEntryRowSet.getString(GeneralLedgerConstants.ColumnNames.OBJECT_CODE), pendingEntryRowSet.getString(GeneralLedgerConstants.ColumnNames.SUB_OBJECT_CODE));
158                    }
159                    catch (IncorrectResultSizeDataAccessException ex) {
160                        if (ex.getActualSize() != 0) {
161                            LOG.error("balance request sql returned more than one row, aborting", ex);
162                            throw ex;
163                        }
164                        // no rows returned - that's ok
165                    }
166    
167                    String balanceType = pendingEntryRowSet.getString(GeneralLedgerConstants.ColumnNames.BALANCE_TYPE_CODE);
168                    String debitCreditCode = pendingEntryRowSet.getString(GeneralLedgerConstants.ColumnNames.DEBIT_CREDIT_CODE);
169                    String objectTypeDebitCreditCode = pendingEntryRowSet.getString(GeneralLedgerConstants.ColumnNames.OBJECT_TYPE_DEBIT_CREDIT_CODE);
170                    String offsetGenerationCode = pendingEntryRowSet.getString(GeneralLedgerConstants.ColumnNames.OFFSET_GENERATION_CODE);
171    
172                    if (balance != null) {
173                        updateCount++;
174    
175                        BigDecimal budget = (BigDecimal) balance.get(GeneralLedgerConstants.ColumnNames.CURRENT_BDLN_BALANCE_AMOUNT);
176                        BigDecimal actual = (BigDecimal) balance.get(GeneralLedgerConstants.ColumnNames.ACCOUNTING_LINE_ACTUALS_BALANCE_AMOUNT);
177                        BigDecimal encumb = (BigDecimal) balance.get(GeneralLedgerConstants.ColumnNames.ACCOUNTING_LINE_ENCUMBRANCE_BALANCE_AMOUNT);
178    
179                        if (balanceType.equals(options.getBudgetCheckingBalanceTypeCd())) {
180                            budget = budget.add(pendingEntryRowSet.getBigDecimal(GeneralLedgerConstants.ColumnNames.TRANSACTION_LEDGER_ENTRY_AMOUNT));
181                        }
182                        else if (balanceType.equals(options.getActualFinancialBalanceTypeCd())) {
183                            if (debitCreditCode.equals(objectTypeDebitCreditCode) || (("N".equals(offsetGenerationCode) && KFSConstants.GL_BUDGET_CODE.equals(debitCreditCode)))) {
184                                actual = actual.add(pendingEntryRowSet.getBigDecimal(GeneralLedgerConstants.ColumnNames.TRANSACTION_LEDGER_ENTRY_AMOUNT));
185                            }
186                            else {
187                                actual = actual.subtract(pendingEntryRowSet.getBigDecimal(GeneralLedgerConstants.ColumnNames.TRANSACTION_LEDGER_ENTRY_AMOUNT));
188                            }
189                        }
190                        else if (balanceType.equals(options.getExtrnlEncumFinBalanceTypCd()) || balanceType.equals(options.getIntrnlEncumFinBalanceTypCd()) || balanceType.equals(options.getPreencumbranceFinBalTypeCd()) || "CE".equals(balanceType)) {
191                            if (debitCreditCode.equals(objectTypeDebitCreditCode) || (("N".equals(offsetGenerationCode) && KFSConstants.GL_BUDGET_CODE.equals(debitCreditCode)))) {
192                                encumb = encumb.add(pendingEntryRowSet.getBigDecimal(GeneralLedgerConstants.ColumnNames.TRANSACTION_LEDGER_ENTRY_AMOUNT));
193                            }
194                            else {
195                                encumb = encumb.subtract(pendingEntryRowSet.getBigDecimal(GeneralLedgerConstants.ColumnNames.TRANSACTION_LEDGER_ENTRY_AMOUNT));
196                            }
197                        }
198    
199                        // A balance exists, so we need to update it
200                        getSimpleJdbcTemplate().update(updateBalanceStatementSql, budget, actual, encumb, sessionId, pendingEntryRowSet.getInt(GeneralLedgerConstants.ColumnNames.UNIVERSITY_FISCAL_YEAR), pendingEntryRowSet.getString(GeneralLedgerConstants.ColumnNames.CHART_OF_ACCOUNTS_CODE), pendingEntryRowSet.getString(GeneralLedgerConstants.ColumnNames.ACCOUNT_NUMBER), pendingEntryRowSet.getString(GeneralLedgerConstants.ColumnNames.SUB_ACCOUNT_NUMBER), pendingEntryRowSet.getString(GeneralLedgerConstants.ColumnNames.OBJECT_CODE), pendingEntryRowSet.getString(GeneralLedgerConstants.ColumnNames.SUB_OBJECT_CODE));
201                    }
202                    else {
203                        insertCount++;
204    
205                        BigDecimal budget = new BigDecimal("0");
206                        BigDecimal actual = new BigDecimal("0");
207                        BigDecimal encumb = new BigDecimal("0");
208    
209                        if (balanceType.equals(options.getBudgetCheckingBalanceTypeCd())) {
210                            budget = pendingEntryRowSet.getBigDecimal(GeneralLedgerConstants.ColumnNames.TRANSACTION_LEDGER_ENTRY_AMOUNT);
211                        }
212                        else if (balanceType.equals(options.getActualFinancialBalanceTypeCd())) {
213                            if (debitCreditCode.equals(objectTypeDebitCreditCode) || (("N".equals(offsetGenerationCode) && KFSConstants.GL_BUDGET_CODE.equals(debitCreditCode)))) {
214                                actual = pendingEntryRowSet.getBigDecimal(GeneralLedgerConstants.ColumnNames.TRANSACTION_LEDGER_ENTRY_AMOUNT);
215                            }
216                            else {
217                                actual = pendingEntryRowSet.getBigDecimal(GeneralLedgerConstants.ColumnNames.TRANSACTION_LEDGER_ENTRY_AMOUNT).negate();
218                            }
219                        }
220                        else if (balanceType.equals(options.getExtrnlEncumFinBalanceTypCd()) || balanceType.equals(options.getIntrnlEncumFinBalanceTypCd()) || balanceType.equals(options.getPreencumbranceFinBalTypeCd()) || "CE".equals(balanceType)) {
221                            if (debitCreditCode.equals(objectTypeDebitCreditCode) || (("N".equals(offsetGenerationCode) && KFSConstants.GL_BUDGET_CODE.equals(debitCreditCode)))) {
222                                encumb = pendingEntryRowSet.getBigDecimal(GeneralLedgerConstants.ColumnNames.TRANSACTION_LEDGER_ENTRY_AMOUNT);
223                            }
224                            else {
225                                encumb = pendingEntryRowSet.getBigDecimal(GeneralLedgerConstants.ColumnNames.TRANSACTION_LEDGER_ENTRY_AMOUNT).negate();
226                            }
227                        }
228    
229                        // No balance exists, so we need to insert one
230                        getSimpleJdbcTemplate().update(insertBalanceStatementSql, pendingEntryRowSet.getInt(GeneralLedgerConstants.ColumnNames.UNIVERSITY_FISCAL_YEAR), pendingEntryRowSet.getString(GeneralLedgerConstants.ColumnNames.CHART_OF_ACCOUNTS_CODE), pendingEntryRowSet.getString(GeneralLedgerConstants.ColumnNames.ACCOUNT_NUMBER), pendingEntryRowSet.getString(GeneralLedgerConstants.ColumnNames.SUB_ACCOUNT_NUMBER), pendingEntryRowSet.getString(GeneralLedgerConstants.ColumnNames.OBJECT_CODE), pendingEntryRowSet.getString(GeneralLedgerConstants.ColumnNames.SUB_OBJECT_CODE), budget, actual, encumb, sessionId);
231                    }
232                }
233                LOG.info("summarizePendingEntriesByObject() INSERTS: " + insertCount);
234                LOG.info("summarizePendingEntriesByObject() UPDATES: " + updateCount);
235            }
236            catch (RuntimeException ex) {
237                LOG.error("summarizePendingEntriesByObject() Exception running sql", ex);
238                throw ex;
239            }
240        }
241    
242        /**
243         * Get any matching pending entries. Return true if there were some, false if not.
244         * 
245         * @param universityFiscalYear the university fiscal year of pending entries to summarize
246         * @param chartOfAccountsCode the chart of accounts code of pending entries to summarize
247         * @param accountNumber the account number of pending entries to summarize
248         * @param financialObjectLevelCode the object level code of pending entries to summarize
249         * @param pendingEntriesCode whether to summarize all, approved, or no pending entries
250         * @return true if any matching pending entries were found, false otherwise
251         */
252        protected boolean getMatchingPendingEntriesByObject(SystemOptions options, Integer universityFiscalYear, String chartOfAccountsCode, String accountNumber, String financialObjectLevelCode, boolean isCostShareExcluded, int pendingEntriesCode, String sessionId) {
253            LOG.debug("getMatchingPendingEntriesByObject() started");
254    
255            // If they have specified this year, we will get all the pending entries where the year is equal or the year is null
256            // (because most eDocs don't fill in the year field).
257            // If they have specified a previous year, we will get all the pending entries where the year is equal to their selection
258            // without the nulls (because we will post eDocs
259            // with blank years tonight most probably.
260    
261            UniversityDate today = SpringContext.getBean(UniversityDateService.class).getCurrentUniversityDate();
262    
263            clearTempTable("GL_PENDING_ENTRY_MT", "SESID", sessionId);
264    
265            List<Object> params = new ArrayList<Object>(20);
266    
267            String insertSql = "insert into GL_PENDING_ENTRY_MT (SESID, FS_ORIGIN_CD, FDOC_NBR, TRN_ENTR_SEQ_NBR, " 
268                    + "FIN_COA_CD, ACCOUNT_NBR, SUB_ACCT_NBR, FIN_OBJECT_CD, FIN_SUB_OBJ_CD, FIN_BALANCE_TYP_CD," 
269                    + "FIN_OBJ_TYP_CD, UNIV_FISCAL_YR, UNIV_FISCAL_PRD_CD, TRN_LDGR_ENTR_DESC, TRN_LDGR_ENTR_AMT, TRN_DEBIT_CRDT_CD," 
270                    + "TRANSACTION_DT, FDOC_TYP_CD, ORG_DOC_NBR, PROJECT_CD, ORG_REFERENCE_ID, FDOC_REF_TYP_CD, FS_REF_ORIGIN_CD,FDOC_REF_NBR, " 
271                    + "FDOC_REVERSAL_DT, TRN_ENCUM_UPDT_CD, FDOC_APPROVED_CD, ACCT_SF_FINOBJ_CD, TRN_ENTR_OFST_CD,TRNENTR_PROCESS_TM) ";
272    
273            String selectSql = "SELECT ?, p.FS_ORIGIN_CD, p.FDOC_NBR, p.TRN_ENTR_SEQ_NBR, p.FIN_COA_CD, p.ACCOUNT_NBR, " 
274                    + getDbPlatform().getIsNullFunction("p.SUB_ACCT_NBR", "'-----'") 
275                    + ", " 
276                    + " p.FIN_OBJECT_CD, " 
277                    + getDbPlatform().getIsNullFunction("p.FIN_SUB_OBJ_CD", "'---'") 
278                    + ", p.FIN_BALANCE_TYP_CD,p.FIN_OBJ_TYP_CD, p.UNIV_FISCAL_YR, " 
279                    + " p.UNIV_FISCAL_PRD_CD, p.TRN_LDGR_ENTR_DESC, p.TRN_LDGR_ENTR_AMT, p.TRN_DEBIT_CRDT_CD," 
280                    + "p.TRANSACTION_DT, p.FDOC_TYP_CD, p.ORG_DOC_NBR, PROJECT_CD, p.ORG_REFERENCE_ID, p.FDOC_REF_TYP_CD, p.FS_REF_ORIGIN_CD,p.FDOC_REF_NBR, p.FDOC_REVERSAL_DT, p.TRN_ENCUM_UPDT_CD, p.FDOC_APPROVED_CD, p.ACCT_SF_FINOBJ_CD, p.TRN_ENTR_OFST_CD,p.TRNENTR_PROCESS_TM " 
281                    + "FROM GL_PENDING_ENTRY_T p,CA_OBJECT_CODE_T o,KRNS_DOC_HDR_T d,FS_DOC_HEADER_T fd "
282                    + "WHERE o.FIN_COA_CD = p.FIN_COA_CD AND o.FIN_OBJECT_CD = p.FIN_OBJECT_CD AND o.FIN_OBJ_LEVEL_CD = ?" 
283                    + " AND p.fdoc_nbr = d.DOC_HDR_ID AND d.DOC_HDR_ID = fd.fdoc_nbr AND " 
284                    + " p.FIN_COA_CD = ?" 
285                    + " and p.account_nbr = ?" 
286                    + " and o.univ_fiscal_yr = ?";
287            params.add(sessionId);
288            params.add(financialObjectLevelCode);
289            params.add(chartOfAccountsCode);
290            params.add(accountNumber);
291            params.add(universityFiscalYear);
292    
293            if (pendingEntriesCode == AccountBalanceService.PENDING_ALL) {
294                selectSql = selectSql + " AND fd.fdoc_status_cd <> '" + KFSConstants.DocumentStatusCodes.DISAPPROVED + "' ";
295            }
296            else {
297                selectSql = selectSql + " AND fd.fdoc_status_cd = '" + KFSConstants.DocumentStatusCodes.APPROVED + "' ";
298            }
299            selectSql = selectSql + " AND fd.fdoc_status_cd <> '" + KFSConstants.DocumentStatusCodes.CANCELLED + "' ";
300            selectSql = selectSql + " AND p.FDOC_APPROVED_CD <> '" + KFSConstants.DocumentStatusCodes.CANCELLED + "' ";
301    
302            if (today.getUniversityFiscalYear().equals(universityFiscalYear)) {
303                selectSql = selectSql + "AND (p.univ_fiscal_yr is null OR p.univ_fiscal_yr = ? )";
304                params.add(universityFiscalYear);
305            }
306            else {
307                selectSql = selectSql + "AND p.univ_fiscal_yr = ?";
308                params.add(universityFiscalYear);
309            }
310    
311            getSimpleJdbcTemplate().update(insertSql + selectSql, params.toArray());
312    
313            if (isCostShareExcluded) {
314                purgeCostShareEntries("GL_PENDING_ENTRY_MT", "sesid", sessionId);
315            }
316    
317            if (!hasEntriesInPendingTable(sessionId)) {
318                return false;
319            }
320    
321            fixPendingEntryDisplay(options.getUniversityFiscalYear(), sessionId);
322    
323            return true;
324        }
325    }