/*
* The Kuali Financial System, a comprehensive financial management system for higher education.
*
* Copyright 2005-2014 The Kuali Foundation
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kuali.kfs.gl.dataaccess.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.ojb.broker.query.Criteria;
import org.apache.ojb.broker.query.Query;
import org.apache.ojb.broker.query.QueryByCriteria;
import org.apache.ojb.broker.query.QueryFactory;
import org.apache.ojb.broker.query.ReportQueryByCriteria;
import org.kuali.kfs.coa.businessobject.BalanceType;
import org.kuali.kfs.coa.dataaccess.BalanceTypeDao;
import org.kuali.kfs.gl.GeneralLedgerConstants;
import org.kuali.kfs.gl.OJBUtility;
import org.kuali.kfs.gl.businessobject.Encumbrance;
import org.kuali.kfs.gl.businessobject.Transaction;
import org.kuali.kfs.gl.dataaccess.EncumbranceDao;
import org.kuali.kfs.sys.KFSPropertyConstants;
import org.kuali.kfs.sys.businessobject.SystemOptions;
import org.kuali.kfs.sys.context.SpringContext;
import org.kuali.kfs.sys.service.OptionsService;
import org.kuali.rice.core.framework.persistence.ojb.dao.PlatformAwareDaoBaseOjb;
/**
* An OJB implementation of the EncumbranceDao
*/
public class EncumbranceDaoOjb extends PlatformAwareDaoBaseOjb implements EncumbranceDao {
private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(EncumbranceDaoOjb.class);
protected BalanceTypeDao balanceTypeDao;
/**
* Returns an encumbrance that would be affected by the given transaction
*
* @param t the transaction to find the affected encumbrance for
* @return an Encumbrance that would be affected by the posting of the transaction, or null
* @see org.kuali.kfs.gl.dataaccess.EncumbranceDao#getEncumbranceByTransaction(org.kuali.kfs.gl.businessobject.Transaction)
*/
@Override
public Encumbrance getEncumbranceByTransaction(Transaction t) {
LOG.debug("getEncumbranceByTransaction() started");
Criteria crit = new Criteria();
crit.addEqualTo(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, t.getUniversityFiscalYear());
crit.addEqualTo(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, t.getChartOfAccountsCode());
crit.addEqualTo(KFSPropertyConstants.ACCOUNT_NUMBER, t.getAccountNumber());
crit.addEqualTo(KFSPropertyConstants.SUB_ACCOUNT_NUMBER, t.getSubAccountNumber());
crit.addEqualTo(KFSPropertyConstants.OBJECT_CODE, t.getFinancialObjectCode());
crit.addEqualTo(KFSPropertyConstants.SUB_OBJECT_CODE, t.getFinancialSubObjectCode());
crit.addEqualTo(KFSPropertyConstants.BALANCE_TYPE_CODE, t.getFinancialBalanceTypeCode());
crit.addEqualTo(KFSPropertyConstants.ENCUMBRANCE_DOCUMENT_TYPE_CODE, t.getFinancialDocumentTypeCode());
crit.addEqualTo(KFSPropertyConstants.ORIGIN_CODE, t.getFinancialSystemOriginationCode());
crit.addEqualTo(KFSPropertyConstants.DOCUMENT_NUMBER, t.getDocumentNumber());
QueryByCriteria qbc = QueryFactory.newQuery(Encumbrance.class, crit);
return (Encumbrance) getPersistenceBrokerTemplate().getObjectByQuery(qbc);
}
/**
* Returns an Iterator of all encumbrances that need to be closed for the fiscal year
*
* @param fiscalYear a fiscal year to find encumbrances for
* @return an Iterator of encumbrances to close
* @see org.kuali.kfs.gl.dataaccess.EncumbranceDao#getEncumbrancesToClose(java.lang.Integer)
*/
@Override
public Iterator getEncumbrancesToClose(Integer fiscalYear) {
Criteria criteria = new Criteria();
criteria.addEqualTo(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, fiscalYear);
QueryByCriteria query = new QueryByCriteria(Encumbrance.class, criteria);
query.addOrderByAscending(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE);
query.addOrderByAscending(KFSPropertyConstants.ACCOUNT_NUMBER);
query.addOrderByAscending(KFSPropertyConstants.SUB_ACCOUNT_NUMBER);
query.addOrderByAscending(KFSPropertyConstants.OBJECT_CODE);
query.addOrderByAscending(KFSPropertyConstants.SUB_OBJECT_CODE);
query.addOrderByAscending(KFSPropertyConstants.BALANCE_TYPE_CODE);
return getPersistenceBrokerTemplate().getIteratorByQuery(query);
}
/**
* Returns an Iterator of all encumbrances that need to be closed for the fiscal year and specified charts
*
* @param fiscalYear a fiscal year to find encumbrances for
* @param charts charts to find encumbrances for
* @return an Iterator of encumbrances to close
* @see org.kuali.kfs.gl.dataaccess.EncumbranceDao#getEncumbrancesToClose(java.lang.Integer, java.util.List)
*/
@Override
public Iterator getEncumbrancesToClose(Integer fiscalYear, List<String> charts) {
Criteria criteria = new Criteria();
criteria.addEqualTo(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, fiscalYear);
criteria.addIn(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, charts);
QueryByCriteria query = new QueryByCriteria(Encumbrance.class, criteria);
query.addOrderByAscending(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE);
query.addOrderByAscending(KFSPropertyConstants.ACCOUNT_NUMBER);
query.addOrderByAscending(KFSPropertyConstants.SUB_ACCOUNT_NUMBER);
query.addOrderByAscending(KFSPropertyConstants.OBJECT_CODE);
query.addOrderByAscending(KFSPropertyConstants.SUB_OBJECT_CODE);
query.addOrderByAscending(KFSPropertyConstants.BALANCE_TYPE_CODE);
return getPersistenceBrokerTemplate().getIteratorByQuery(query);
}
/**
* Purges the database of all those encumbrances with the given chart and year
*
* @param chartOfAccountsCode the chart of accounts code purged encumbrances will have
* @param year the university fiscal year purged encumbrances will have
* @see org.kuali.kfs.gl.dataaccess.EncumbranceDao#purgeYearByChart(java.lang.String, int)
*/
@Override
public void purgeYearByChart(String chartOfAccountsCode, int year) {
LOG.debug("purgeYearByChart() started");
Criteria criteria = new Criteria();
criteria.addEqualTo(KFSPropertyConstants.CHART, chartOfAccountsCode);
criteria.addLessThan(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, new Integer(year));
getPersistenceBrokerTemplate().deleteByQuery(new QueryByCriteria(Encumbrance.class, criteria));
// This is required because if any deleted account balances are in the cache, deleteByQuery
// doesn't
// remove them from the cache so a future select will retrieve these deleted account
// balances from
// the cache and return them. Clearing the cache forces OJB to go to the database again.
getPersistenceBrokerTemplate().clearCache();
}
/**
* fetch all encumbrance records from GL open encumbrance table
*
* @return an Iterator with all encumbrances currently in the database
* @see org.kuali.kfs.gl.dataaccess.EncumbranceDao#getAllEncumbrances()
*/
@Override
public Iterator getAllEncumbrances() {
Criteria criteria = new Criteria();
QueryByCriteria query = QueryFactory.newQuery(Encumbrance.class, criteria);
return getPersistenceBrokerTemplate().getIteratorByQuery(query);
}
/**
* group all encumbrances with/without the given document type code by fiscal year, chart, account, sub-account, object code,
* sub object code, and balance type code, and summarize the encumbrance amount and the encumbrance close amount.
*
* @param documentTypeCode the given document type code
* @param included indicate if all encumbrances with the given document type are included in the results or not
* @return an Iterator of arrays of java.lang.Objects holding summarization data about qualifying encumbrances
* @see org.kuali.kfs.gl.dataaccess.EncumbranceDao#getSummarizedEncumbrances(String, boolean)
*/
@Override
public Iterator getSummarizedEncumbrances(String documentTypeCode, boolean included) {
Criteria criteria = new Criteria();
if (included) {
criteria.addEqualTo(KFSPropertyConstants.ENCUMBRANCE_DOCUMENT_TYPE_CODE, documentTypeCode);
}
else {
criteria.addNotEqualTo(KFSPropertyConstants.ENCUMBRANCE_DOCUMENT_TYPE_CODE, documentTypeCode);
}
ReportQueryByCriteria query = QueryFactory.newReportQuery(Encumbrance.class, criteria);
// set the selection attributes
List attributeList = buildAttributeList();
String[] attributes = (String[]) attributeList.toArray(new String[attributeList.size()]);
query.setAttributes(attributes);
// add the group criteria into the selection statement
List groupByList = buildGroupByList();
String[] groupBy = (String[]) groupByList.toArray(new String[groupByList.size()]);
query.addGroupBy(groupBy);
return getPersistenceBrokerTemplate().getReportQueryIteratorByQuery(query);
}
/**
* Queries the database to find all open encumbrances that qualify by the given keys
*
* @param fieldValues the input fields and values
* @return a collection of open encumbrances
* @see org.kuali.kfs.gl.dataaccess.EncumbranceDao#findOpenEncumbrance(java.util.Map)
*/
@Override
public Iterator findOpenEncumbrance(Map fieldValues, boolean includeZeroEncumbrances) {
LOG.debug("findOpenEncumbrance() started");
Query query = this.getOpenEncumbranceQuery(fieldValues, includeZeroEncumbrances);
OJBUtility.limitResultSize(query);
return getPersistenceBrokerTemplate().getIteratorByQuery(query);
}
/**
* Builds query of open encumbrances that have the keys given in the map summarized by balance type codes
* where the sum(ACCOUNT_LINE_ENCUMBRANCE_AMOUNT - sum(ACCOUNT_LINE_ENCUMBRANCE_CLOSED_AMOUNT ) != 0
* and returns true if there are any results.
*
* @param fieldValues the input fields and values
* @param includeZeroEncumbrances
* @return true if there any open encumbrances when summarized by balance type
* @see org.kuali.kfs.gl.dataaccess.EncumbranceDao#hasSummarizedOpenEncumbranceRecords(java.util.Map)
*/
@Override
public boolean hasSummarizedOpenEncumbranceRecords(Map fieldValues, boolean includeZeroEncumbrances) {
LOG.debug("hasSummarizedOpenEncumbranceRecords() started");
// For PE - For all records on this account: sum (ACCOUNT_LINE_ENCUMBRANCE_AMOUNT ) - sum (ACCOUNT_LINE_ENCUMBRANCE_CLOSED_AMOUNT) <> 0
Criteria criteria = OJBUtility.buildCriteriaFromMap(fieldValues, new Encumbrance());
SystemOptions options = SpringContext.getBean(OptionsService.class).getCurrentYearOptions();
criteria.addIn(KFSPropertyConstants.BALANCE_TYPE_CODE, Arrays.asList(new String[] { options.getPreencumbranceFinBalTypeCd() }));
if (!includeZeroEncumbrances) {
Criteria nonZeroEncumbranceCriteria = new Criteria();
nonZeroEncumbranceCriteria.addNotEqualToField(KFSPropertyConstants.ACCOUNT_LINE_ENCUMBRANCE_AMOUNT, KFSPropertyConstants.ACCOUNT_LINE_ENCUMBRANCE_CLOSED_AMOUNT);
criteria.addAndCriteria(nonZeroEncumbranceCriteria);
}
ReportQueryByCriteria query = QueryFactory.newReportQuery(Encumbrance.class, criteria);
// set the selection attributes
query.setAttributes(new String[] {KFSPropertyConstants.BALANCE_TYPE_CODE,
"sum(" + GeneralLedgerConstants.ColumnNames.ACCOUNT_LINE_ENCUMBRANCE_AMOUNT + ") - sum(" + GeneralLedgerConstants.ColumnNames.ACCOUNT_LINE_ENCUMBRANCE_CLOSED_AMOUNT + ")"} );
// add the group criteria into the selection statement
query.addGroupBy(new String[] {KFSPropertyConstants.BALANCE_TYPE_CODE} );
// set the having clause
Criteria having = new Criteria ();
having.addNotEqualTo("sum(" + GeneralLedgerConstants.ColumnNames.ACCOUNT_LINE_ENCUMBRANCE_AMOUNT + ") - sum(" + GeneralLedgerConstants.ColumnNames.ACCOUNT_LINE_ENCUMBRANCE_CLOSED_AMOUNT + ")", new Integer (0));
query.setHavingCriteria(having);
Iterator searchResultsIterator = getPersistenceBrokerTemplate().getReportQueryIteratorByQuery(query);
// For EX & IE - For any record on this account: acln_encum_amt - acln_encum_cls_amt <> 0
Criteria criteria2 = OJBUtility.buildCriteriaFromMap(fieldValues, new Encumbrance());
criteria2.addIn(KFSPropertyConstants.BALANCE_TYPE_CODE, Arrays.asList(new String[] { options.getExtrnlEncumFinBalanceTypCd(), options.getIntrnlEncumFinBalanceTypCd() }));
if (!includeZeroEncumbrances) {
Criteria nonZeroEncumbranceCriteria = new Criteria();
nonZeroEncumbranceCriteria.addNotEqualToField(KFSPropertyConstants.ACCOUNT_LINE_ENCUMBRANCE_AMOUNT, KFSPropertyConstants.ACCOUNT_LINE_ENCUMBRANCE_CLOSED_AMOUNT);
criteria2.addAndCriteria(nonZeroEncumbranceCriteria);
}
ReportQueryByCriteria query2 = QueryFactory.newReportQuery(Encumbrance.class, criteria2);
// set the selection attributes
query2.setAttributes(new String[] {KFSPropertyConstants.BALANCE_TYPE_CODE,
GeneralLedgerConstants.ColumnNames.ACCOUNT_LINE_ENCUMBRANCE_AMOUNT + " - " + GeneralLedgerConstants.ColumnNames.ACCOUNT_LINE_ENCUMBRANCE_CLOSED_AMOUNT} );
Iterator searchResultsIterator2 = getPersistenceBrokerTemplate().getReportQueryIteratorByQuery(query2);
return searchResultsIterator.hasNext() || searchResultsIterator2.hasNext();
}
/**
* Counts the number of open encumbrances that have the keys given in the map
*
* @param fieldValues the input fields and values
* @return the number of the open encumbrances
* @see org.kuali.kfs.gl.dataaccess.EncumbranceDao#getOpenEncumbranceRecordCount(java.util.Map)
*/
@Override
public Integer getOpenEncumbranceRecordCount(Map fieldValues, boolean includeZeroEncumbrances) {
LOG.debug("getOpenEncumbranceRecordCount() started");
Query query = this.getOpenEncumbranceQuery(fieldValues, includeZeroEncumbrances);
return getPersistenceBrokerTemplate().getCount(query);
}
/**
* build the query for encumbrance search
*
* @param fieldValues a Map of values to use as keys for the query
* @param includeZeroEncumbrances should the query include encumbrances which have zeroed out?
* @return an OJB query
*/
protected Query getOpenEncumbranceQuery(Map fieldValues, boolean includeZeroEncumbrances) {
Criteria criteria = OJBUtility.buildCriteriaFromMap(fieldValues, new Encumbrance());
criteria.addIn(KFSPropertyConstants.BALANCE_TYPE_CODE, harvestCodesFromEncumbranceBalanceTypes());
if (!includeZeroEncumbrances) {
Criteria nonZeroEncumbranceCriteria = new Criteria();
nonZeroEncumbranceCriteria.addNotEqualToField(KFSPropertyConstants.ACCOUNT_LINE_ENCUMBRANCE_AMOUNT, KFSPropertyConstants.ACCOUNT_LINE_ENCUMBRANCE_CLOSED_AMOUNT);
criteria.addAndCriteria(nonZeroEncumbranceCriteria);
}
return QueryFactory.newQuery(Encumbrance.class, criteria);
}
/**
* @return returns only the codes from encumbrance balance types
*/
protected List<String> harvestCodesFromEncumbranceBalanceTypes() {
List<String> balanceTypeCodes = new ArrayList<String>();
Collection<BalanceType> encumbranceBalanceTypes = getBalanceTypeDao().getEncumbranceBalanceTypes();
for (BalanceType encumbranceBalanceType : encumbranceBalanceTypes) {
balanceTypeCodes.add(encumbranceBalanceType.getCode());
}
return balanceTypeCodes;
}
/**
* This method builds the atrribute list used by balance searching
*
* @return a List of encumbrance attributes that need to be summed
*/
protected List buildAttributeList() {
List attributeList = this.buildGroupByList();
attributeList.add("sum(" + KFSPropertyConstants.ACCOUNT_LINE_ENCUMBRANCE_AMOUNT + ")");
attributeList.add("sum(" + KFSPropertyConstants.ACCOUNT_LINE_ENCUMBRANCE_CLOSED_AMOUNT + ")");
return attributeList;
}
/**
* This method builds group by attribute list used by balance searching
*
* @return a List of encumbrance attributes to search on
*/
protected List buildGroupByList() {
List attributeList = new ArrayList();
attributeList.add(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR);
attributeList.add(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE);
attributeList.add(KFSPropertyConstants.ACCOUNT_NUMBER);
attributeList.add(KFSPropertyConstants.SUB_ACCOUNT_NUMBER);
attributeList.add(KFSPropertyConstants.OBJECT_CODE);
attributeList.add(KFSPropertyConstants.SUB_OBJECT_CODE);
attributeList.add(KFSPropertyConstants.BALANCE_TYPE_CODE);
return attributeList;
}
/**
* @see org.kuali.kfs.gl.dataaccess.EncumbranceDao#findCountGreaterOrEqualThan(java.lang.Integer)
*/
@Override
public Integer findCountGreaterOrEqualThan(Integer year) {
Criteria criteria = new Criteria();
criteria.addGreaterOrEqualThan(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, year);
ReportQueryByCriteria query = QueryFactory.newReportQuery(Encumbrance.class, criteria);
return getPersistenceBrokerTemplate().getCount(query);
}
/**
* @return the injected implementation of balance type dao
*/
public BalanceTypeDao getBalanceTypeDao() {
return balanceTypeDao;
}
/**
* Injects an implementation of BalanceTypeDao
* @param balanceTypeDao the implementation of BalanceTypeDao to inject
*/
public void setBalanceTypeDao(BalanceTypeDao balanceTypeDao) {
this.balanceTypeDao = balanceTypeDao;
}
}