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.math.BigDecimal;
019import java.util.Iterator;
020
021import org.apache.ojb.broker.query.Criteria;
022import org.apache.ojb.broker.query.QueryByCriteria;
023import org.apache.ojb.broker.query.QueryFactory;
024import org.apache.ojb.broker.query.ReportQueryByCriteria;
025import org.kuali.ole.gl.businessobject.Entry;
026import org.kuali.ole.gl.businessobject.Transaction;
027import org.kuali.ole.gl.dataaccess.EntryDao;
028import org.kuali.ole.gl.dataaccess.LedgerEntryBalancingDao;
029import org.kuali.ole.sys.OLEConstants;
030import org.kuali.ole.sys.OLEPropertyConstants;
031import org.kuali.ole.sys.util.TransactionalServiceUtils;
032import org.kuali.rice.core.framework.persistence.ojb.dao.PlatformAwareDaoBaseOjb;
033import org.kuali.rice.krad.util.ObjectUtils;
034
035/**
036 * An OJB implementation of EntryDao
037 */
038public class EntryDaoOjb extends PlatformAwareDaoBaseOjb implements EntryDao, LedgerEntryBalancingDao {
039    private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(EntryDaoOjb.class);
040
041    private final static String UNIVERISITY_FISCAL_YEAR = "universityFiscalYear";
042    private final static String CHART_OF_ACCOUNTS_CODE = "chartOfAccountsCode";
043    private final static String ACCOUNT_NUMBER = "accountNumber";
044    private final static String SUB_ACCOUNT_NUMBER = "subAccountNumber";
045    private final static String FINANCIAL_OBJECT_CODE = "financialObjectCode";
046    private final static String FINANCIAL_SUB_OBJECT_CODE = "financialSubObjectCode";
047    private final static String FINANCIAL_BALANCE_TYPE_CODE = "financialBalanceTypeCode";
048    private final static String FINANCIAL_OBJECT_TYPE_CODE = "financialObjectTypeCode";
049    private final static String UNIVERISTY_FISCAL_PERIOD_CODE = "universityFiscalPeriodCode";
050    private final static String FINANCIAL_DOCUMENT_TYPE_CODE = "financialDocumentTypeCode";
051    private final static String FINANCIAL_SYSTEM_ORIGINATION_CODE = "financialSystemOriginationCode";
052    private final static String MAX_CONSTANT = "max(documentNumber)";
053
054
055    /**
056     * Constructs a EntryDaoOjb instance
057     */
058    public EntryDaoOjb() {
059        super();
060    }
061
062    /**
063     * Find the maximum transactionLedgerEntrySequenceNumber in the entry table for a specific transaction. This is used to make
064     * sure that rows added have a unique primary key.
065     * 
066     * @param t the transaction to check
067     * @return the max sequence number
068     */
069    public int getMaxSequenceNumber(Transaction t) {
070        LOG.debug("getSequenceNumber() ");
071
072        Criteria crit = new Criteria();
073        crit.addEqualTo(UNIVERISITY_FISCAL_YEAR, t.getUniversityFiscalYear());
074        crit.addEqualTo(CHART_OF_ACCOUNTS_CODE, t.getChartOfAccountsCode());
075        crit.addEqualTo(ACCOUNT_NUMBER, t.getAccountNumber());
076        crit.addEqualTo(SUB_ACCOUNT_NUMBER, t.getSubAccountNumber());
077        crit.addEqualTo(FINANCIAL_OBJECT_CODE, t.getFinancialObjectCode());
078        crit.addEqualTo(FINANCIAL_SUB_OBJECT_CODE, t.getFinancialSubObjectCode());
079        crit.addEqualTo(FINANCIAL_BALANCE_TYPE_CODE, t.getFinancialBalanceTypeCode());
080        crit.addEqualTo(FINANCIAL_OBJECT_TYPE_CODE, t.getFinancialObjectTypeCode());
081        crit.addEqualTo(UNIVERISTY_FISCAL_PERIOD_CODE, t.getUniversityFiscalPeriodCode());
082        crit.addEqualTo(FINANCIAL_DOCUMENT_TYPE_CODE, t.getFinancialDocumentTypeCode());
083        crit.addEqualTo(FINANCIAL_SYSTEM_ORIGINATION_CODE, t.getFinancialSystemOriginationCode());
084        crit.addEqualTo(OLEPropertyConstants.DOCUMENT_NUMBER, t.getDocumentNumber());
085
086        ReportQueryByCriteria q = QueryFactory.newReportQuery(Entry.class, crit);
087        q.setAttributes(new String[] { "max(transactionLedgerEntrySequenceNumber)" });
088
089        Iterator iter = getPersistenceBrokerTemplate().getReportQueryIteratorByQuery(q);
090        // would this work better? max = (BigDecimal) getPersistenceBrokerTemplate().getObjectByQuery(q);
091        BigDecimal max = null;
092        while (iter.hasNext()) {
093            Object[] data = (Object[]) iter.next();
094            max = (BigDecimal) data[0]; // Don't know why OJB returns a BigDecimal, but it does
095        }
096        if (max == null) {
097            return 0;
098        }
099        else {
100            return max.intValue();
101        }
102    }
103
104    /**
105     * Purge the entry table by chart/year
106     * 
107     * @param chart the chart of accounts code of entries to purge
108     * @param year the university fiscal year of entries to purge
109     */
110    public void purgeYearByChart(String chartOfAccountsCode, int year) {
111        LOG.debug("purgeYearByChart() started");
112
113        Criteria criteria = new Criteria();
114        criteria.addEqualTo(CHART_OF_ACCOUNTS_CODE, chartOfAccountsCode);
115        criteria.addLessThan(UNIVERISITY_FISCAL_YEAR, new Integer(year));
116
117        getPersistenceBrokerTemplate().deleteByQuery(new QueryByCriteria(Entry.class, criteria));
118
119        // This is required because if any deleted rows are in the cache, deleteByQuery doesn't
120        // remove them from the cache so a future select will retrieve these deleted account balances from
121        // the cache and return them. Clearing the cache forces OJB to go to the database again.
122        getPersistenceBrokerTemplate().clearCache();
123    }
124    
125    /**
126     * @see org.kuali.ole.gl.dataaccess.LedgerEntryBalancingDao#findEntryByGroup(java.lang.Integer, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
127     */
128    public Object[] findEntryByGroup(Integer universityFiscalYear, String chartOfAccountsCode, String financialObjectCode, String financialBalanceTypeCode, String universityFiscalPeriodCode, String transactionDebitCreditCode) {
129        Criteria criteria = new Criteria();
130        criteria.addEqualTo(OLEConstants.UNIVERSITY_FISCAL_YEAR_PROPERTY_NAME, universityFiscalYear);
131        criteria.addEqualTo(OLEConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME, chartOfAccountsCode);
132        criteria.addEqualTo(OLEConstants.FINANCIAL_OBJECT_CODE_PROPERTY_NAME, financialObjectCode);
133        criteria.addEqualTo(OLEConstants.FINANCIAL_BALANCE_TYPE_CODE_PROPERTY_NAME, financialBalanceTypeCode);
134        criteria.addEqualTo(OLEConstants.UNIVERSITY_FISCAL_PERIOD_CODE_PROPERTY_NAME, universityFiscalPeriodCode);
135        criteria.addEqualTo(OLEConstants.TRANSACTION_DEBIT_CREDIT_CODE, transactionDebitCreditCode);
136
137        ReportQueryByCriteria reportQuery = QueryFactory.newReportQuery(Entry.class, criteria);
138        reportQuery.setAttributes(new String[] { "count(*)", "sum(" + OLEConstants.TRANSACTION_LEDGER_ENTRY_AMOUNT + ")"});
139        reportQuery.addGroupBy(new String[] { OLEConstants.UNIVERSITY_FISCAL_YEAR_PROPERTY_NAME, OLEConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME, OLEConstants.FINANCIAL_OBJECT_CODE_PROPERTY_NAME, OLEConstants.FINANCIAL_BALANCE_TYPE_CODE_PROPERTY_NAME, OLEConstants.UNIVERSITY_FISCAL_PERIOD_CODE_PROPERTY_NAME, OLEConstants.TRANSACTION_DEBIT_CREDIT_CODE});
140        
141        Iterator<Object[]> iterator = getPersistenceBrokerTemplate().getReportQueryIteratorByQuery(reportQuery);
142        Object[] returnResult = TransactionalServiceUtils.retrieveFirstAndExhaustIterator(iterator);
143        
144        if (ObjectUtils.isNull(returnResult)) {
145            // Do nothing, we'll return null. Data wasn't found.
146        } else if (returnResult[0] instanceof BigDecimal) {
147            returnResult[0] = ((BigDecimal) returnResult[0]).intValue();
148        } else {
149            returnResult[0] = ((Long) returnResult[0]).intValue();
150        }
151        
152        return returnResult;
153    }
154    
155    /**
156     * @see org.kuali.ole.gl.dataaccess.LedgerEntryBalancingDao#findCountGreaterOrEqualThan(java.lang.Integer)
157     */
158    public Integer findCountGreaterOrEqualThan(Integer year) {
159        Criteria criteria = new Criteria();
160        criteria.addGreaterOrEqualThan(OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR, year);
161        
162        ReportQueryByCriteria query = QueryFactory.newReportQuery(Entry.class, criteria);
163        
164        return getPersistenceBrokerTemplate().getCount(query);
165    }
166}