001/* 002 * Copyright 2005 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 */ 016package org.kuali.ole.gl.dataaccess.impl; 017 018import java.util.ArrayList; 019import java.util.Arrays; 020import java.util.Collection; 021import java.util.HashMap; 022import java.util.Iterator; 023import java.util.List; 024import java.util.Map; 025 026import org.apache.commons.lang.StringUtils; 027import org.apache.ojb.broker.query.Criteria; 028import org.apache.ojb.broker.query.Query; 029import org.apache.ojb.broker.query.QueryByCriteria; 030import org.apache.ojb.broker.query.QueryFactory; 031import org.apache.ojb.broker.query.ReportQueryByCriteria; 032import org.kuali.ole.coa.businessobject.Account; 033import org.kuali.ole.gl.GeneralLedgerConstants; 034import org.kuali.ole.gl.OJBUtility; 035import org.kuali.ole.gl.businessobject.Balance; 036import org.kuali.ole.gl.businessobject.CashBalance; 037import org.kuali.ole.gl.businessobject.Transaction; 038import org.kuali.ole.gl.dataaccess.BalanceDao; 039import org.kuali.ole.gl.dataaccess.LedgerBalanceBalancingDao; 040import org.kuali.ole.sys.OLEConstants; 041import org.kuali.ole.sys.OLEPropertyConstants; 042import org.kuali.ole.sys.businessobject.SystemOptions; 043import org.kuali.rice.core.api.parameter.ParameterEvaluator; 044import org.kuali.rice.core.api.util.type.KualiDecimal; 045import org.kuali.rice.core.framework.persistence.ojb.dao.PlatformAwareDaoBaseOjb; 046 047/** 048 * An OJB implementation of BalanceDao 049 */ 050public class BalanceDaoOjb extends PlatformAwareDaoBaseOjb implements BalanceDao, LedgerBalanceBalancingDao { 051 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(BalanceDaoOjb.class); 052 053 /** 054 * Does a ReportQuery to summarize GL balance data 055 * 056 * @param universityFiscalYear the fiscal year of balances to search for 057 * @param balanceTypeCodes a list of balance type codes of balances to search for 058 * @return iterator of reported on java.lang.Object arrays with the report data 059 * @see org.kuali.ole.gl.dataaccess.BalanceDao#getGlSummary(int, java.util.List) 060 */ 061 public Iterator<Object[]> getGlSummary(int universityFiscalYear, Collection<String> balanceTypeCodes) { 062 LOG.debug("getGlSummary() started"); 063 064 Criteria c = new Criteria(); 065 c.addEqualTo(OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR, universityFiscalYear); 066 c.addIn(OLEPropertyConstants.BALANCE_TYPE_CODE, balanceTypeCodes); 067 068 String[] attributes = new String[] { "account.subFundGroup.fundGroupCode", "sum(accountLineAnnualBalanceAmount)", "sum(beginningBalanceLineAmount)", "sum(contractsGrantsBeginningBalanceAmount)", "sum(month1Amount)", "sum(month2Amount)", "sum(month3Amount)", "sum(month4Amount)", "sum(month5Amount)", "sum(month6Amount)", "sum(month7Amount)", "sum(month8Amount)", "sum(month9Amount)", "sum(month10Amount)", "sum(month11Amount)", "sum(month12Amount)", "sum(month13Amount)" }; 069 070 String[] groupby = new String[] { "account.subFundGroup.fundGroupCode" }; 071 072 ReportQueryByCriteria query = new ReportQueryByCriteria(Balance.class, c); 073 074 query.setAttributes(attributes); 075 query.addGroupBy(groupby); 076 query.addOrderByAscending("account.subFundGroup.fundGroupCode"); 077 078 return getPersistenceBrokerTemplate().getReportQueryIteratorByQuery(query); 079 } 080 081 /** 082 * Queries the database for all the balances for a given fiscal year 083 * 084 * @param year the university fiscal year of balances to return 085 * @return an iterator over all balances for a given fiscal year 086 * @see org.kuali.ole.gl.dataaccess.BalanceDao#findBalancesForFiscalYear(java.lang.Integer) 087 */ 088 public Iterator<Balance> findBalancesForFiscalYear(Integer year) { 089 LOG.debug("findBalancesForFiscalYear() started"); 090 091 Criteria c = new Criteria(); 092 c.addEqualTo(OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR, year); 093 094 QueryByCriteria query = QueryFactory.newQuery(Balance.class, c); 095 query.addOrderByAscending(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE); 096 query.addOrderByAscending(OLEPropertyConstants.ACCOUNT_NUMBER); 097 query.addOrderByAscending(OLEPropertyConstants.SUB_ACCOUNT_NUMBER); 098 query.addOrderByAscending(OLEPropertyConstants.OBJECT_CODE); 099 query.addOrderByAscending(OLEPropertyConstants.SUB_OBJECT_CODE); 100 query.addOrderByAscending(OLEPropertyConstants.BALANCE_TYPE_CODE); 101 query.addOrderByAscending(OLEPropertyConstants.OBJECT_TYPE_CODE); 102 103 return getPersistenceBrokerTemplate().getIteratorByQuery(query); 104 } 105 106 /** 107 * Using values from the transaction as keys, lookup the balance the transaction would affect were it posted 108 * 109 * @t a transaction to look up the related balance for 110 * @return a Balance that the given transaction would affect 111 * @see org.kuali.ole.gl.dataaccess.BalanceDao#getBalanceByTransaction(org.kuali.ole.gl.businessobject.Transaction) 112 */ 113 public Balance getBalanceByTransaction(Transaction t) { 114 LOG.debug("getBalanceByTransaction() started"); 115 116 Criteria crit = new Criteria(); 117 crit.addEqualTo(OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR, t.getUniversityFiscalYear()); 118 crit.addEqualTo(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, t.getChartOfAccountsCode()); 119 crit.addEqualTo(OLEPropertyConstants.ACCOUNT_NUMBER, t.getAccountNumber()); 120 crit.addEqualTo(OLEPropertyConstants.SUB_ACCOUNT_NUMBER, t.getSubAccountNumber()); 121 crit.addEqualTo(OLEPropertyConstants.OBJECT_CODE, t.getFinancialObjectCode()); 122 crit.addEqualTo(OLEPropertyConstants.SUB_OBJECT_CODE, t.getFinancialSubObjectCode()); 123 crit.addEqualTo(OLEPropertyConstants.BALANCE_TYPE_CODE, t.getFinancialBalanceTypeCode()); 124 crit.addEqualTo(OLEPropertyConstants.OBJECT_TYPE_CODE, t.getFinancialObjectTypeCode()); 125 126 QueryByCriteria qbc = QueryFactory.newQuery(Balance.class, crit); 127 return (Balance) getPersistenceBrokerTemplate().getObjectByQuery(qbc); 128 } 129 130 /** 131 * This method adds to the given criteria if the given collection is non-empty. It uses an EQUALS if there is exactly one 132 * element in the collection; otherwise, its uses an IN 133 * 134 * @param criteria - the criteria that might have a criterion appended 135 * @param name - name of the attribute 136 * @param collection - the collection to inspect 137 */ 138 protected void criteriaBuilder(Criteria criteria, String name, Collection collection) { 139 criteriaBuilderHelper(criteria, name, collection, false); 140 } 141 142 /** 143 * Similar to criteriaBuilder, this adds a negative criterion (NOT EQUALS, NOT IN) 144 * 145 * @param criteria - the criteria that might have a criterion appended 146 * @param name - name of the attribute 147 * @param collection - the collection to inspect 148 */ 149 protected void negatedCriteriaBuilder(Criteria criteria, String name, Collection collection) { 150 criteriaBuilderHelper(criteria, name, collection, true); 151 } 152 153 154 /** 155 * This method provides the implementation for the conveniences methods criteriaBuilder & negatedCriteriaBuilder 156 * 157 * @param criteria - the criteria that might have a criterion appended 158 * @param name - name of the attribute 159 * @param collection - the collection to inspect 160 * @param negate - the criterion will be negated (NOT EQUALS, NOT IN) when this is true 161 */ 162 protected void criteriaBuilderHelper(Criteria criteria, String name, Collection collection, boolean negate) { 163 if (collection != null) { 164 int size = collection.size(); 165 if (size == 1) { 166 if (negate) { 167 criteria.addNotEqualTo(name, collection.iterator().next()); 168 } 169 else { 170 criteria.addEqualTo(name, collection.iterator().next()); 171 } 172 } 173 if (size > 1) { 174 if (negate) { 175 criteria.addNotIn(name, collection); 176 } 177 else { 178 criteria.addIn(name, collection); 179 180 } 181 } 182 } 183 184 } 185 186 /** 187 * Build a query based on all the parameters, and return an Iterator of all Balances from the database that qualify 188 * 189 * @param account the account of balances to find 190 * @param fiscalYear the fiscal year of balances to find 191 * @param includedObjectCodes a Collection of object codes found balances should have one of 192 * @param excludedObjectCodes a Collection of object codes found balances should not have one of 193 * @param objectTypeCodes a Collection of object type codes found balances should have one of 194 * @param balanceTypeCodes a Collection of balance type codes found balances should have one of 195 * @return an Iterator of Balances 196 * @see org.kuali.ole.gl.dataaccess.BalanceDao#findBalances(org.kuali.ole.coa.businessobject.Account, java.lang.Integer, 197 * java.util.Collection, java.util.Collection, java.util.Collection, java.util.Collection) 198 */ 199 public Iterator<Balance> findBalances(Account account, Integer fiscalYear, Collection includedObjectCodes, Collection excludedObjectCodes, Collection objectTypeCodes, Collection balanceTypeCodes) { 200 LOG.debug("findBalances() started"); 201 202 Criteria criteria = new Criteria(); 203 204 criteria.addEqualTo(OLEPropertyConstants.ACCOUNT_NUMBER, account.getAccountNumber()); 205 criteria.addEqualTo(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, account.getChartOfAccountsCode()); 206 207 criteria.addEqualTo(OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR, fiscalYear); 208 209 criteriaBuilder(criteria, GeneralLedgerConstants.ColumnNames.OBJECT_TYPE_CODE, objectTypeCodes); 210 criteriaBuilder(criteria, GeneralLedgerConstants.ColumnNames.BALANCE_TYPE_CODE, balanceTypeCodes); 211 criteriaBuilder(criteria, GeneralLedgerConstants.ColumnNames.OBJECT_CODE, includedObjectCodes); 212 negatedCriteriaBuilder(criteria, GeneralLedgerConstants.ColumnNames.OBJECT_CODE, excludedObjectCodes); 213 214 ReportQueryByCriteria query = new ReportQueryByCriteria(Balance.class, criteria); 215 216 // returns an iterator of all matching balances 217 Iterator balances = getPersistenceBrokerTemplate().getIteratorByQuery(query); 218 return balances; 219 } 220 221 /** 222 * Using the given fieldValues as keys, return all cash balance records. The results will be limited to the system lookup 223 * results limit. 224 * 225 * @param fieldValues the input fields and values 226 * @param isConsolidated consolidation option is applied or not 227 * @return the records of cash balance entries 228 * @see org.kuali.ole.gl.dataaccess.BalanceDao#lookupCashBalance(Map, boolean, List) 229 */ 230 public Iterator<Balance> lookupCashBalance(Map fieldValues, boolean isConsolidated, Collection<String> encumbranceBalanceTypes) { 231 LOG.debug("findCashBalance() started"); 232 233 Query query = this.getCashBalanceQuery(fieldValues, isConsolidated, encumbranceBalanceTypes); 234 OJBUtility.limitResultSize(query); 235 return getPersistenceBrokerTemplate().getReportQueryIteratorByQuery(query); 236 } 237 238 /** 239 * Get the number of detailed cash balance records that would be returned, were we to do a query based on the given fieldValues 240 * 241 * @param fieldValues the input fields and values 242 * @param isConsolidated consolidation option is applied or not 243 * @return the size collection of cash balance entry groups 244 * @see org.kuali.ole.gl.dataaccess.BalanceDao#getDetailedCashBalanceRecordCount(Map, List) 245 */ 246 public Integer getDetailedCashBalanceRecordCount(Map fieldValues, Collection<String> encumbranceBalanceTypes) { 247 LOG.debug("getDetailedCashBalanceRecordCount() started"); 248 249 Query query = this.getCashBalanceQuery(fieldValues, false, encumbranceBalanceTypes); 250 return getPersistenceBrokerTemplate().getCount(query); 251 } 252 253 /** 254 * Given a map of keys, return all of the report data about qualifying cash balances 255 * 256 * @param fieldValues the input fields and values 257 * @return the size collection of cash balance entry groups 258 * @see org.kuali.ole.gl.dataaccess.BalanceDao#getConsolidatedCashBalanceRecordCount(Map, List) 259 */ 260 public int getConsolidatedCashBalanceRecordCount(Map fieldValues, Collection<String> encumbranceBalanceTypes) { 261 LOG.debug("getCashBalanceRecordCount() started"); 262 263 ReportQueryByCriteria query = this.getCashBalanceCountQuery(fieldValues, encumbranceBalanceTypes); 264 return getPersistenceBrokerTemplate().getCount(query); 265 } 266 267 /** 268 * Given a map of values, build a query out of those and find all the balances that qualify 269 * 270 * @param fieldValues a Map of fieldValues to use as keys in the query 271 * @param isConsolidated should the results be consolidated? 272 * @return an Iterator of Balances 273 * @see org.kuali.ole.gl.dataaccess.BalanceDao#findBalance(java.util.Map, boolean) 274 */ 275 public Iterator<Balance> findBalance(Map fieldValues, boolean isConsolidated, Collection<String> encumbranceBalanceTypes) { 276 LOG.debug("findBalance() started"); 277 278 Query query = this.getBalanceQuery(fieldValues, isConsolidated, encumbranceBalanceTypes); 279 OJBUtility.limitResultSize(query); 280 281 if (isConsolidated) { 282 return getPersistenceBrokerTemplate().getReportQueryIteratorByQuery(query); 283 } 284 return getPersistenceBrokerTemplate().getIteratorByQuery(query); 285 } 286 287 /** 288 * Given a Map of keys to use as a query, if we performed that query as a consolidated query... how many records would we get 289 * back? 290 * 291 * @param fieldValues a Map of values to use as keys to build the query 292 * @return an Iterator of counts... 293 * @see org.kuali.ole.gl.dataaccess.BalanceDao#getConsolidatedBalanceRecordCount(Map, List) 294 */ 295 public Iterator getConsolidatedBalanceRecordCount(Map fieldValues, Collection<String> encumbranceBalanceTypes) { 296 LOG.debug("getBalanceRecordCount() started"); 297 298 ReportQueryByCriteria query = this.getBalanceCountQuery(fieldValues, encumbranceBalanceTypes); 299 return getPersistenceBrokerTemplate().getReportQueryIteratorByQuery(query); 300 } 301 302 /** 303 * Builds a query for cash balances, based on the given field values 304 * 305 * @param fieldValues a map of keys to use when building the query 306 * @return an OJB ReportQuery to use as the query 307 */ 308 protected ReportQueryByCriteria getCashBalanceCountQuery(Map fieldValues, Collection<String> encumbranceBalanceTypes) { 309 Criteria criteria = buildCriteriaFromMap(fieldValues, new CashBalance(), encumbranceBalanceTypes); 310 criteria.addEqualTo(OLEPropertyConstants.BALANCE_TYPE_CODE, OLEConstants.BALANCE_TYPE_ACTUAL); 311 criteria.addEqualToField("chart.financialCashObjectCode", OLEPropertyConstants.OBJECT_CODE); 312 313 ReportQueryByCriteria query = QueryFactory.newReportQuery(CashBalance.class, criteria); 314 315 List groupByList = buildGroupByList(); 316 groupByList.remove(OLEPropertyConstants.SUB_ACCOUNT_NUMBER); 317 groupByList.remove(OLEPropertyConstants.SUB_OBJECT_CODE); 318 groupByList.remove(OLEPropertyConstants.OBJECT_TYPE_CODE); 319 320 // add the group criteria into the selection statement 321 String[] groupBy = (String[]) groupByList.toArray(new String[groupByList.size()]); 322 query.addGroupBy(groupBy); 323 324 return query; 325 } 326 327 /** 328 * build the query for cash balance search 329 * 330 * @param fieldValues Map of keys to use for the query 331 * @param isConsolidated should the results be consolidated? 332 * @return the OJB query to perform 333 */ 334 protected Query getCashBalanceQuery(Map fieldValues, boolean isConsolidated, Collection<String> encumbranceBalanceTypes) { 335 Criteria criteria = buildCriteriaFromMap(fieldValues, new CashBalance(), encumbranceBalanceTypes); 336 criteria.addEqualTo(OLEPropertyConstants.BALANCE_TYPE_CODE, OLEConstants.BALANCE_TYPE_ACTUAL); 337 criteria.addEqualToField("chart.financialCashObjectCode", OLEPropertyConstants.OBJECT_CODE); 338 339 ReportQueryByCriteria query = QueryFactory.newReportQuery(CashBalance.class, criteria); 340 List attributeList = buildAttributeList(false); 341 List groupByList = buildGroupByList(); 342 343 // if consolidated, then ignore the following fields 344 if (isConsolidated) { 345 attributeList.remove(OLEPropertyConstants.SUB_ACCOUNT_NUMBER); 346 groupByList.remove(OLEPropertyConstants.SUB_ACCOUNT_NUMBER); 347 attributeList.remove(OLEPropertyConstants.SUB_OBJECT_CODE); 348 groupByList.remove(OLEPropertyConstants.SUB_OBJECT_CODE); 349 attributeList.remove(OLEPropertyConstants.OBJECT_TYPE_CODE); 350 groupByList.remove(OLEPropertyConstants.OBJECT_TYPE_CODE); 351 } 352 353 // add the group criteria into the selection statement 354 String[] groupBy = (String[]) groupByList.toArray(new String[groupByList.size()]); 355 query.addGroupBy(groupBy); 356 357 // set the selection attributes 358 String[] attributes = (String[]) attributeList.toArray(new String[attributeList.size()]); 359 query.setAttributes(attributes); 360 361 return query; 362 } 363 364 /** 365 * build the query for balance search 366 * 367 * @param fieldValues Map of keys to use for the query 368 * @param isConsolidated should the results be consolidated? 369 * @return an OJB query to perform 370 */ 371 protected Query getBalanceQuery(Map fieldValues, boolean isConsolidated, Collection<String> encumbranceBalanceTypes) { 372 LOG.debug("getBalanceQuery(Map, boolean) started"); 373 374 Criteria criteria = buildCriteriaFromMap(fieldValues, new Balance(), encumbranceBalanceTypes); 375 ReportQueryByCriteria query = QueryFactory.newReportQuery(Balance.class, criteria); 376 377 // if consolidated, then ignore subaccount number and balance type code 378 if (isConsolidated) { 379 List attributeList = buildAttributeList(true); 380 List groupByList = buildGroupByList(); 381 382 // ignore subaccount number, sub object code and object type code 383 attributeList.remove(OLEPropertyConstants.SUB_ACCOUNT_NUMBER); 384 groupByList.remove(OLEPropertyConstants.SUB_ACCOUNT_NUMBER); 385 attributeList.remove(OLEPropertyConstants.SUB_OBJECT_CODE); 386 groupByList.remove(OLEPropertyConstants.SUB_OBJECT_CODE); 387 attributeList.remove(OLEPropertyConstants.OBJECT_TYPE_CODE); 388 groupByList.remove(OLEPropertyConstants.OBJECT_TYPE_CODE); 389 390 // set the selection attributes 391 String[] attributes = (String[]) attributeList.toArray(new String[attributeList.size()]); 392 query.setAttributes(attributes); 393 394 // add the group criteria into the selection statement 395 String[] groupBy = (String[]) groupByList.toArray(new String[groupByList.size()]); 396 query.addGroupBy(groupBy); 397 } 398 399 return query; 400 } 401 402 /** 403 * build the query for balance search 404 * 405 * @param fieldValues Map of keys to use for the query 406 * @return an OJB ReportQuery to perform 407 */ 408 protected ReportQueryByCriteria getBalanceCountQuery(Map fieldValues, Collection<String> encumbranceBalanceTypes) { 409 Criteria criteria = buildCriteriaFromMap(fieldValues, new Balance(), encumbranceBalanceTypes); 410 ReportQueryByCriteria query = QueryFactory.newReportQuery(Balance.class, criteria); 411 412 // set the selection attributes 413 query.setAttributes(new String[] { "count(*)" }); 414 415 List groupByList = buildGroupByList(); 416 groupByList.remove(OLEPropertyConstants.SUB_ACCOUNT_NUMBER); 417 groupByList.remove(OLEPropertyConstants.SUB_OBJECT_CODE); 418 groupByList.remove(OLEPropertyConstants.OBJECT_TYPE_CODE); 419 420 // add the group criteria into the selection statement 421 String[] groupBy = (String[]) groupByList.toArray(new String[groupByList.size()]); 422 query.addGroupBy(groupBy); 423 return query; 424 } 425 426 /** 427 * This method builds the query criteria based on the input field map 428 * 429 * @param fieldValues Map of keys to use for the query 430 * @param balance this really usen't used in the method 431 * @return a query criteria 432 */ 433 protected Criteria buildCriteriaFromMap(Map fieldValues, Balance balance, Collection<String> encumbranceBalanceTypes) { 434 Map localFieldValues = new HashMap(); 435 localFieldValues.putAll(fieldValues); 436 437 Criteria criteria = new Criteria(); 438 439 // handle encumbrance balance type 440 String propertyName = OLEPropertyConstants.BALANCE_TYPE_CODE; 441 if (localFieldValues.containsKey(propertyName)) { 442 String propertyValue = (String) localFieldValues.get(propertyName); 443 if (OLEConstants.AGGREGATE_ENCUMBRANCE_BALANCE_TYPE_CODE.equals(propertyValue)) { 444 localFieldValues.remove(OLEPropertyConstants.BALANCE_TYPE_CODE); 445 446 criteria.addIn(OLEPropertyConstants.BALANCE_TYPE_CODE, encumbranceBalanceTypes); 447 } 448 } 449 450 criteria.addAndCriteria(OJBUtility.buildCriteriaFromMap(localFieldValues, balance)); 451 return criteria; 452 } 453 454 /** 455 * This method builds the atrribute list used by balance searching 456 * 457 * @param isExtended should we add the attributes to sum each of the monthly totals? 458 * @return List an attribute list 459 */ 460 protected List<String> buildAttributeList(boolean isExtended) { 461 List attributeList = this.buildGroupByList(); 462 463 attributeList.add("sum(accountLineAnnualBalanceAmount)"); 464 attributeList.add("sum(beginningBalanceLineAmount)"); 465 attributeList.add("sum(contractsGrantsBeginningBalanceAmount)"); 466 467 // add the entended elements into the list 468 if (isExtended) { 469 attributeList.add("sum(month1Amount)"); 470 attributeList.add("sum(month2Amount)"); 471 attributeList.add("sum(month3Amount)"); 472 attributeList.add("sum(month4Amount)"); 473 attributeList.add("sum(month5Amount)"); 474 attributeList.add("sum(month6Amount)"); 475 attributeList.add("sum(month7Amount)"); 476 attributeList.add("sum(month8Amount)"); 477 attributeList.add("sum(month9Amount)"); 478 attributeList.add("sum(month10Amount)"); 479 attributeList.add("sum(month11Amount)"); 480 attributeList.add("sum(month12Amount)"); 481 attributeList.add("sum(month13Amount)"); 482 } 483 return attributeList; 484 } 485 486 /** 487 * This method builds group by attribute list used by balance searching 488 * 489 * @return List an group by attribute list 490 */ 491 protected List<String> buildGroupByList() { 492 List attributeList = new ArrayList(); 493 494 attributeList.add(OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR); 495 attributeList.add(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE); 496 attributeList.add(OLEPropertyConstants.ACCOUNT_NUMBER); 497 attributeList.add(OLEPropertyConstants.SUB_ACCOUNT_NUMBER); 498 attributeList.add(OLEPropertyConstants.BALANCE_TYPE_CODE); 499 attributeList.add(OLEPropertyConstants.OBJECT_CODE); 500 attributeList.add(OLEPropertyConstants.SUB_OBJECT_CODE); 501 attributeList.add(OLEPropertyConstants.OBJECT_TYPE_CODE); 502 503 return attributeList; 504 } 505 506 /** 507 * Since SubAccountNumber, SubObjectCode, and ObjectType are all part of the primary key of Balance, you're guaranteed to get 508 * one of those records when you call this method. Let's hope the right one. 509 * 510 * @param universityFiscalYear the fiscal year of the CB balance to return 511 * @param chartOfAccountsCode the chart of the accounts code of the CB balanes to return 512 * @param accountNumber the account number of the CB balance to return 513 * @param objectCode the object code of the CB balance to return 514 * @return the CB Balance record 515 * @see org.kuali.ole.gl.dataaccess.BalanceDao#getCurrentBudgetForObjectCode(java.lang.Integer, java.lang.String, 516 * java.lang.String, java.lang.String) 517 */ 518 public Balance getCurrentBudgetForObjectCode(Integer universityFiscalYear, String chartOfAccountsCode, String accountNumber, String objectCode) { 519 LOG.debug("getCurrentBudgetForObjectCode() started"); 520 521 Criteria crit = new Criteria(); 522 crit.addEqualTo(OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR, universityFiscalYear); 523 crit.addEqualTo(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, chartOfAccountsCode); 524 crit.addEqualTo(OLEPropertyConstants.ACCOUNT_NUMBER, accountNumber); 525 crit.addEqualTo(OLEPropertyConstants.OBJECT_CODE, objectCode); 526 crit.addEqualTo(OLEPropertyConstants.BALANCE_TYPE_CODE, OLEConstants.BALANCE_TYPE_CURRENT_BUDGET); 527 528 QueryByCriteria qbc = QueryFactory.newQuery(Balance.class, crit); 529 return (Balance) getPersistenceBrokerTemplate().getObjectByQuery(qbc); 530 } 531 532 /** 533 * Find all matching account balances. 534 * 535 * @param universityFiscalYear the university fiscal year of balances to return 536 * @param chartOfAccountsCode the chart of accounts code of balances to return 537 * @param accountNumber the account number of balances to return 538 * @return balances sorted by object code 539 */ 540 public Iterator<Balance> findAccountBalances(Integer universityFiscalYear, String chartOfAccountsCode, String accountNumber) { 541 LOG.debug("findAccountBalances() started"); 542 return this.findAccountBalances(universityFiscalYear, chartOfAccountsCode, accountNumber, OLEConstants.SF_TYPE_OBJECT); 543 } 544 545 /** 546 * Find all matching account balances. The Sufficient funds code is used to determine the sort of the results. 547 * 548 * @param universityFiscalYear the university fiscal year of balances to return 549 * @param chartOfAccountsCode the chart of accounts code of balances to return 550 * @param accountNumber the account number of balances to return 551 * @param sfCode the sufficient funds code, used to sort on 552 * @return an Iterator of balances 553 */ 554 public Iterator<Balance> findAccountBalances(Integer universityFiscalYear, String chartOfAccountsCode, String accountNumber, String sfCode) { 555 LOG.debug("findAccountBalances() started"); 556 557 Criteria crit = new Criteria(); 558 crit.addEqualTo(OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR, universityFiscalYear); 559 crit.addEqualTo(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, chartOfAccountsCode); 560 crit.addEqualTo(OLEPropertyConstants.ACCOUNT_NUMBER, accountNumber); 561 562 QueryByCriteria qbc = QueryFactory.newQuery(Balance.class, crit); 563 if (OLEConstants.SF_TYPE_OBJECT.equals(sfCode)) { 564 qbc.addOrderByAscending(OLEPropertyConstants.OBJECT_CODE); 565 } 566 else if (OLEConstants.SF_TYPE_LEVEL.equals(sfCode)) { 567 qbc.addOrderByAscending(GeneralLedgerConstants.BalanceInquiryDrillDowns.OBJECT_LEVEL_CODE); 568 } 569 else if (OLEConstants.SF_TYPE_CONSOLIDATION.equals(sfCode)) { 570 qbc.addOrderByAscending(GeneralLedgerConstants.BalanceInquiryDrillDowns.CONSOLIDATION_OBJECT_CODE); 571 } 572 return getPersistenceBrokerTemplate().getIteratorByQuery(qbc); 573 } 574 575 /** 576 * Purge the sufficient funds balance table by year/chart 577 * 578 * @param chart the chart of balances to purge 579 * @param year the university fiscal year of balances to purge 580 */ 581 public void purgeYearByChart(String chartOfAccountsCode, int year) { 582 LOG.debug("purgeYearByChart() started"); 583 584 Criteria criteria = new Criteria(); 585 criteria.addEqualTo(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, chartOfAccountsCode); 586 criteria.addLessThan(OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR, new Integer(year)); 587 588 getPersistenceBrokerTemplate().deleteByQuery(new QueryByCriteria(Balance.class, criteria)); 589 590 // This is required because if any deleted account balances are in the cache, deleteByQuery doesn't 591 // remove them from the cache so a future select will retrieve these deleted account balances from 592 // the cache and return them. Clearing the cache forces OJB to go to the database again. 593 getPersistenceBrokerTemplate().clearCache(); 594 } 595 596 /** 597 * Returns the count of balances for a given fiscal year; this method is used for year end job reporting 598 * 599 * @param year the university fiscal year to count balances for 600 * @return an int with the count of balances for that fiscal year 601 * @see org.kuali.ole.gl.dataaccess.BalanceDao#countBalancesForFiscalYear(java.lang.Integer) 602 */ 603 public int countBalancesForFiscalYear(Integer year) { 604 LOG.debug("countBalancesForFiscalYear() started"); 605 606 Criteria c = new Criteria(); 607 c.addEqualTo(OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR, year); 608 QueryByCriteria query = QueryFactory.newQuery(Balance.class, c); 609 610 return getPersistenceBrokerTemplate().getCount(query); 611 } 612 613 /** 614 * Finds all of the balances for the fiscal year that should be processed by nominal activity closing 615 * 616 * @param year the university fiscal year of balances to find 617 * @return an Iterator of Balances to process 618 * @see org.kuali.ole.gl.dataaccess.BalanceDao#findNominalActivityBalancesForFiscalYear(Integer, List, SystemOptions) 619 */ 620 public Iterator<Balance> findNominalActivityBalancesForFiscalYear(Integer year, Collection<String> nominalActivityObjectTypeCodes, SystemOptions currentYearOptions) { 621 LOG.debug("findNominalActivityBalancesForFiscalYear() started"); 622 623 Criteria c = new Criteria(); 624 c.addEqualTo(OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR, year); 625 c.addEqualTo(OLEPropertyConstants.BALANCE_TYPE_CODE, currentYearOptions.getActualFinancialBalanceTypeCd()); 626 c.addIn(OLEPropertyConstants.OBJECT_TYPE_CODE, nominalActivityObjectTypeCodes); 627 c.addNotEqualTo("accountLineAnnualBalanceAmount", KualiDecimal.ZERO); 628 629 QueryByCriteria query = QueryFactory.newQuery(Balance.class, c); 630 query.addOrderByAscending(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE); 631 query.addOrderByAscending(OLEPropertyConstants.ACCOUNT_NUMBER); 632 query.addOrderByAscending(OLEPropertyConstants.SUB_ACCOUNT_NUMBER); 633 query.addOrderByAscending(OLEPropertyConstants.OBJECT_CODE); 634 query.addOrderByAscending(OLEPropertyConstants.SUB_OBJECT_CODE); 635 query.addOrderByAscending(OLEPropertyConstants.BALANCE_TYPE_CODE); 636 query.addOrderByAscending(OLEPropertyConstants.OBJECT_TYPE_CODE); 637 638 return getPersistenceBrokerTemplate().getIteratorByQuery(query); 639 } 640 641 /** 642 * @see org.kuali.ole.gl.dataaccess.BalanceDao#findGeneralBalancesToForwardForFiscalYear(java.lang.Integer, java.util.List, 643 * java.lang.String[]) 644 */ 645 public Iterator<Balance> findGeneralBalancesToForwardForFiscalYear(Integer year, Collection<String> generalForwardBalanceObjectTypes, Collection<String> generalBalanceForwardBalanceTypes) { 646 647 Criteria c = new Criteria(); 648 c.addEqualTo(OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR, year); 649 c.addIn(OLEPropertyConstants.BALANCE_TYPE_CODE, generalBalanceForwardBalanceTypes); 650 c.addIn(OLEPropertyConstants.OBJECT_TYPE_CODE, generalForwardBalanceObjectTypes); 651 652 QueryByCriteria query = QueryFactory.newQuery(Balance.class, c); 653 query.addOrderByAscending(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE); 654 query.addOrderByAscending(OLEPropertyConstants.ACCOUNT_NUMBER); 655 query.addOrderByAscending(OLEPropertyConstants.SUB_ACCOUNT_NUMBER); 656 query.addOrderByAscending(OLEPropertyConstants.OBJECT_CODE); 657 query.addOrderByAscending(OLEPropertyConstants.SUB_OBJECT_CODE); 658 query.addOrderByAscending(OLEPropertyConstants.BALANCE_TYPE_CODE); 659 query.addOrderByAscending(OLEPropertyConstants.OBJECT_TYPE_CODE); 660 661 Iterator<Balance> balances = getPersistenceBrokerTemplate().getIteratorByQuery(query); 662 663 return balances; 664 } 665 666 /** 667 * @see org.kuali.ole.gl.dataaccess.BalanceDao#findCumulativeBalancesToForwardForFiscalYear(java.lang.Integer, java.util.List, 668 * java.util.List, java.lang.String[], java.lang.String[]) 669 */ 670 public Iterator<Balance> findCumulativeBalancesToForwardForFiscalYear(Integer year, Collection<String> cumulativeForwardBalanceObjectTypes, Collection<String> contractsAndGrantsDenotingValues, Collection<String> subFundGroupsForCumulativeBalanceForwarding, Collection<String> cumulativeBalanceForwardBalanceTypes, boolean fundGroupDenotesCGInd) { 671 Criteria c = new Criteria(); 672 c.addEqualTo(OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR, year); 673 c.addIn(OLEPropertyConstants.BALANCE_TYPE_CODE, cumulativeBalanceForwardBalanceTypes); 674 c.addIn(OLEPropertyConstants.OBJECT_TYPE_CODE, cumulativeForwardBalanceObjectTypes); 675 676 Criteria forCGCrit = new Criteria(); 677 if (fundGroupDenotesCGInd) { 678 for (String value : contractsAndGrantsDenotingValues) { 679 forCGCrit.addEqualTo("priorYearAccount.subFundGroup.fundGroupCode", value); 680 } 681 } 682 else { 683 for (String value : contractsAndGrantsDenotingValues) { 684 forCGCrit.addEqualTo("priorYearAccount.subFundGroupCode", value); 685 } 686 } 687 688 Criteria subFundGroupCrit = new Criteria(); 689 subFundGroupCrit.addIn("priorYearAccount.subFundGroupCode", subFundGroupsForCumulativeBalanceForwarding); 690 forCGCrit.addOrCriteria(subFundGroupCrit); 691 c.addAndCriteria(forCGCrit); 692 693 QueryByCriteria query = QueryFactory.newQuery(Balance.class, c); 694 query.addOrderByAscending(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE); 695 query.addOrderByAscending(OLEPropertyConstants.ACCOUNT_NUMBER); 696 query.addOrderByAscending(OLEPropertyConstants.SUB_ACCOUNT_NUMBER); 697 query.addOrderByAscending(OLEPropertyConstants.OBJECT_CODE); 698 query.addOrderByAscending(OLEPropertyConstants.SUB_OBJECT_CODE); 699 query.addOrderByAscending(OLEPropertyConstants.BALANCE_TYPE_CODE); 700 query.addOrderByAscending(OLEPropertyConstants.OBJECT_TYPE_CODE); 701 702 Iterator<Balance> balances = getPersistenceBrokerTemplate().getIteratorByQuery(query); 703 704 return balances; 705 } 706 707 /** 708 * Returns a list of balances to return for the Organization Reversion year end job to process 709 * 710 * @param the university fiscal year to find balances for 711 * @param endOfYear if true, use current year accounts, otherwise use prior year accounts 712 * @return an Iterator of Balances to process 713 * @see org.kuali.ole.gl.dataaccess.BalanceDao#findOrganizationReversionBalancesForFiscalYear(Integer, boolean, SystemOptions) 714 */ 715 public Iterator<Balance> findOrganizationReversionBalancesForFiscalYear(Integer year, boolean endOfYear, SystemOptions options, List<ParameterEvaluator> parameterEvaluators) { 716 LOG.debug("findOrganizationReversionBalancesForFiscalYear() started"); 717 Criteria c = new Criteria(); 718 c.addEqualTo(OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR, year); 719 720 for (ParameterEvaluator parameterEvaluator : parameterEvaluators) { 721 722 String currentRule = parameterEvaluator.getValue(); 723 if (endOfYear) { 724 currentRule = currentRule.replaceAll("account\\.", "priorYearAccount."); 725 } 726 if (StringUtils.isNotBlank(currentRule)) { 727 String propertyName = StringUtils.substringBefore(currentRule, "="); 728 List<String> ruleValues = Arrays.asList(StringUtils.substringAfter(currentRule, "=").split(";")); 729 if (propertyName != null && propertyName.length() > 0 && ruleValues.size() > 0 && !StringUtils.isBlank(ruleValues.get(0))) { 730 if (parameterEvaluator.constraintIsAllow()) { 731 c.addIn(propertyName, ruleValues); 732 } 733 else { 734 c.addNotIn(propertyName, ruleValues); 735 } 736 } 737 } 738 } 739 // we only ever calculate on CB, AC, and encumbrance types, so let's only select those 740 List organizationReversionBalancesToSelect = new ArrayList(); 741 organizationReversionBalancesToSelect.add(options.getActualFinancialBalanceTypeCd()); 742 organizationReversionBalancesToSelect.add(options.getFinObjTypeExpenditureexpCd()); 743 organizationReversionBalancesToSelect.add(options.getCostShareEncumbranceBalanceTypeCd()); 744 organizationReversionBalancesToSelect.add(options.getIntrnlEncumFinBalanceTypCd()); 745 organizationReversionBalancesToSelect.add(OLEConstants.BALANCE_TYPE_CURRENT_BUDGET); 746 c.addIn(OLEPropertyConstants.BALANCE_TYPE_CODE, organizationReversionBalancesToSelect); 747 QueryByCriteria query = QueryFactory.newQuery(Balance.class, c); 748 query.addOrderByAscending(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE); 749 query.addOrderByAscending(OLEPropertyConstants.ACCOUNT_NUMBER); 750 query.addOrderByAscending(OLEPropertyConstants.SUB_ACCOUNT_NUMBER); 751 query.addOrderByAscending(OLEPropertyConstants.OBJECT_CODE); 752 query.addOrderByAscending(OLEPropertyConstants.SUB_OBJECT_CODE); 753 query.addOrderByAscending(OLEPropertyConstants.BALANCE_TYPE_CODE); 754 query.addOrderByAscending(OLEPropertyConstants.OBJECT_TYPE_CODE); 755 756 return getPersistenceBrokerTemplate().getIteratorByQuery(query); 757 } 758 759 /** 760 * @see org.kuali.ole.gl.dataaccess.BalancingDao#findCountGreaterOrEqualThan(java.lang.Integer) 761 */ 762 public Integer findCountGreaterOrEqualThan(Integer year) { 763 Criteria criteria = new Criteria(); 764 criteria.addGreaterOrEqualThan(OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR, year); 765 766 ReportQueryByCriteria query = QueryFactory.newReportQuery(Balance.class, criteria); 767 768 return getPersistenceBrokerTemplate().getCount(query); 769 } 770 771}