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.module.ld.dataaccess.impl;
017    
018    import java.math.BigDecimal;
019    import java.util.ArrayList;
020    import java.util.Collection;
021    import java.util.Iterator;
022    import java.util.List;
023    import java.util.Map;
024    import java.util.Set;
025    
026    import org.apache.ojb.broker.query.Criteria;
027    import org.apache.ojb.broker.query.QueryByCriteria;
028    import org.apache.ojb.broker.query.QueryFactory;
029    import org.apache.ojb.broker.query.ReportQueryByCriteria;
030    import org.kuali.kfs.gl.OJBUtility;
031    import org.kuali.kfs.gl.dataaccess.LedgerEntryBalancingDao;
032    import org.kuali.kfs.module.ld.businessobject.LedgerEntry;
033    import org.kuali.kfs.module.ld.dataaccess.LaborLedgerEntryDao;
034    import org.kuali.kfs.module.ld.util.ConsolidationUtil;
035    import org.kuali.kfs.sys.KFSConstants;
036    import org.kuali.kfs.sys.KFSPropertyConstants;
037    import org.kuali.rice.kns.dao.impl.PlatformAwareDaoBaseOjb;
038    import org.kuali.rice.kns.util.ObjectUtils;
039    import org.kuali.rice.kns.util.TransactionalServiceUtils;
040    
041    /**
042     * This is the data access object for ledger entry.
043     * 
044     * @see org.kuali.kfs.module.ld.businessobject.LedgerEntry
045     */
046    public class LaborLedgerEntryDaoOjb extends PlatformAwareDaoBaseOjb implements LaborLedgerEntryDao, LedgerEntryBalancingDao {
047        private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(LaborLedgerEntryDaoOjb.class);
048    
049        /**
050         * @see org.kuali.kfs.module.ld.dataaccess.LaborLedgerEntryDao#getMaxSquenceNumber(org.kuali.kfs.module.ld.businessobject.LedgerEntry)
051         */
052        public Integer getMaxSquenceNumber(LedgerEntry ledgerEntry) {
053            Criteria criteria = new Criteria();
054    
055            criteria.addEqualTo(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, ledgerEntry.getUniversityFiscalYear());
056            criteria.addEqualTo(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, ledgerEntry.getChartOfAccountsCode());
057            criteria.addEqualTo(KFSPropertyConstants.ACCOUNT_NUMBER, ledgerEntry.getAccountNumber());
058            criteria.addEqualTo(KFSPropertyConstants.SUB_ACCOUNT_NUMBER, ledgerEntry.getSubAccountNumber());
059            criteria.addEqualTo(KFSPropertyConstants.FINANCIAL_OBJECT_CODE, ledgerEntry.getFinancialObjectCode());
060            criteria.addEqualTo(KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE, ledgerEntry.getFinancialSubObjectCode());
061            criteria.addEqualTo(KFSPropertyConstants.FINANCIAL_BALANCE_TYPE_CODE, ledgerEntry.getFinancialBalanceTypeCode());
062            criteria.addEqualTo(KFSPropertyConstants.FINANCIAL_OBJECT_TYPE_CODE, ledgerEntry.getFinancialObjectTypeCode());
063            criteria.addEqualTo(KFSPropertyConstants.UNIVERSITY_FISCAL_PERIOD_CODE, ledgerEntry.getUniversityFiscalPeriodCode());
064            criteria.addEqualTo(KFSPropertyConstants.FINANCIAL_DOCUMENT_TYPE_CODE, ledgerEntry.getFinancialDocumentTypeCode());
065            criteria.addEqualTo(KFSPropertyConstants.FINANCIAL_SYSTEM_ORIGINATION_CODE, ledgerEntry.getFinancialSystemOriginationCode());
066            criteria.addEqualTo(KFSPropertyConstants.DOCUMENT_NUMBER, ledgerEntry.getDocumentNumber());
067    
068            ReportQueryByCriteria query = QueryFactory.newReportQuery(this.getEntryClass(), criteria);
069            query.setAttributes(new String[] { "max(" + KFSPropertyConstants.TRANSACTION_ENTRY_SEQUENCE_NUMBER + ")" });
070    
071            Iterator iterator = getPersistenceBrokerTemplate().getReportQueryIteratorByQuery(query);
072            Integer maxSequenceNumber = Integer.valueOf(0);
073    
074            if (iterator.hasNext()) {
075                Object[] data = (Object[]) TransactionalServiceUtils.retrieveFirstAndExhaustIterator(iterator);
076                if (data[0] != null) {
077                    maxSequenceNumber = ((BigDecimal) data[0]).intValue();
078                }
079            }
080            return maxSequenceNumber;
081        }
082    
083        /**
084         * @see org.kuali.kfs.module.ld.dataaccess.LaborLedgerEntryDao#find(java.util.Map)
085         */
086        public Iterator<LedgerEntry> find(Map<String, String> fieldValues) {
087            Criteria criteria = OJBUtility.buildCriteriaFromMap(fieldValues, new LedgerEntry());
088    
089            QueryByCriteria query = QueryFactory.newQuery(this.getEntryClass(), criteria);
090            return getPersistenceBrokerTemplate().getIteratorByQuery(query);
091        }
092    
093        /**
094         * @see org.kuali.kfs.module.ld.dataaccess.LaborLedgerEntryDao#save(org.kuali.kfs.module.ld.businessobject.LedgerEntry)
095         */
096        public void save(LedgerEntry ledgerEntry) {
097            getPersistenceBrokerTemplate().store(ledgerEntry);
098        }
099    
100        /**
101         * @see org.kuali.kfs.module.ld.dataaccess.LaborLedgerEntryDao#findEmployeesWithPayType(java.util.Map, java.util.List, java.util.List)
102         */
103        public List<String> findEmployeesWithPayType(Map<Integer, Set<String>> payPeriods, List<String> balanceTypes, Map<String, Set<String>> earnCodePayGroupMap) {
104            Criteria criteria = this.buildPayTypeCriteria(payPeriods, balanceTypes, earnCodePayGroupMap);
105    
106            ReportQueryByCriteria query = QueryFactory.newReportQuery(this.getEntryClass(), criteria);
107            query.setAttributes(new String[] { KFSPropertyConstants.EMPLID });
108            query.setDistinct(true);
109    
110            Iterator<Object[]> employees = getPersistenceBrokerTemplate().getReportQueryIteratorByQuery(query);
111            List<String> employeeList = new ArrayList<String>();
112    
113            while (employees != null && employees.hasNext()) {
114                Object[] emplid = employees.next();
115                employeeList.add(emplid == null ? "" : emplid[0].toString());
116            }
117    
118            return employeeList;
119        }
120    
121        /**
122         * @see org.kuali.kfs.module.ld.dataaccess.LaborLedgerEntryDao#getLedgerEntriesForEmployeeWithPayType(java.lang.String, java.util.Map,
123         *      java.util.List, java.util.Map)
124         */
125        public Collection<LedgerEntry> getLedgerEntriesForEmployeeWithPayType(String emplid, Map<Integer, Set<String>> payPeriods, List<String> balanceTypes, Map<String, Set<String>> earnCodePayGroupMap) {
126            Criteria criteria = this.buildPayTypeCriteria(payPeriods, balanceTypes, earnCodePayGroupMap);
127            criteria.addEqualTo(KFSPropertyConstants.EMPLID, emplid);
128    
129            QueryByCriteria query = QueryFactory.newQuery(this.getEntryClass(), criteria);
130            return getPersistenceBrokerTemplate().getCollectionByQuery(query);
131        }
132    
133        /**
134         * @see org.kuali.kfs.module.ld.dataaccess.LaborLedgerEntryDao#isEmployeeWithPayType(java.lang.String, java.util.Map, java.util.List,
135         *      java.util.Map)
136         */
137        public boolean isEmployeeWithPayType(String emplid, Map<Integer, Set<String>> payPeriods, List<String> balanceTypes, Map<String, Set<String>> earnCodePayGroupMap) {
138            Criteria criteria = this.buildPayTypeCriteria(payPeriods, balanceTypes, earnCodePayGroupMap);
139            criteria.addEqualTo(KFSPropertyConstants.EMPLID, emplid);
140    
141            QueryByCriteria query = QueryFactory.newQuery(this.getEntryClass(), criteria);
142            return getPersistenceBrokerTemplate().getCount(query) > 0;
143        }
144    
145        /**
146         * @see org.kuali.kfs.module.ld.dataaccess.LaborLedgerEntryDao#deleteLedgerEntriesPriorToYear(java.lang.Integer, java.lang.String)
147         */
148        public void deleteLedgerEntriesPriorToYear(Integer fiscalYear, String chartOfAccountsCode) {
149            LOG.debug("deleteLedgerEntriesPriorToYear() started");
150    
151            Criteria criteria = new Criteria();
152            criteria.addLessThan(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, fiscalYear);
153            criteria.addEqualTo(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, chartOfAccountsCode);
154    
155            QueryByCriteria query = new QueryByCriteria(this.getEntryClass(), criteria);
156            getPersistenceBrokerTemplate().deleteByQuery(query);
157    
158        }
159    
160        /**
161         * @see org.kuali.kfs.gl.dataaccess.LedgerEntryBalancingDao#findEntryByGroup(java.lang.Integer, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
162         */
163        public Object[] findEntryByGroup(Integer universityFiscalYear, String chartOfAccountsCode, String financialObjectCode, String financialBalanceTypeCode, String universityFiscalPeriodCode, String transactionDebitCreditCode) {
164            Criteria criteria = new Criteria();
165            criteria.addEqualTo(KFSConstants.UNIVERSITY_FISCAL_YEAR_PROPERTY_NAME, universityFiscalYear);
166            criteria.addEqualTo(KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME, chartOfAccountsCode);
167            criteria.addEqualTo(KFSConstants.FINANCIAL_OBJECT_CODE_PROPERTY_NAME, financialObjectCode);
168            criteria.addEqualTo(KFSConstants.FINANCIAL_BALANCE_TYPE_CODE_PROPERTY_NAME, financialBalanceTypeCode);
169            criteria.addEqualTo(KFSConstants.UNIVERSITY_FISCAL_PERIOD_CODE_PROPERTY_NAME, universityFiscalPeriodCode);
170            criteria.addEqualTo(KFSConstants.TRANSACTION_DEBIT_CREDIT_CODE, transactionDebitCreditCode);
171    
172            ReportQueryByCriteria reportQuery = QueryFactory.newReportQuery(this.getEntryClass(), criteria);
173            reportQuery.setAttributes(new String[] { "count(*)", ConsolidationUtil.sum(KFSConstants.TRANSACTION_LEDGER_ENTRY_AMOUNT)});
174            reportQuery.addGroupBy(new String[] { KFSConstants.UNIVERSITY_FISCAL_YEAR_PROPERTY_NAME, KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME, KFSConstants.FINANCIAL_OBJECT_CODE_PROPERTY_NAME, KFSConstants.FINANCIAL_BALANCE_TYPE_CODE_PROPERTY_NAME, KFSConstants.UNIVERSITY_FISCAL_PERIOD_CODE_PROPERTY_NAME, KFSConstants.TRANSACTION_DEBIT_CREDIT_CODE});
175            
176            Iterator<Object[]> iterator = getPersistenceBrokerTemplate().getReportQueryIteratorByQuery(reportQuery);
177            Object[] returnResult = TransactionalServiceUtils.retrieveFirstAndExhaustIterator(iterator);
178            
179            if (ObjectUtils.isNull(returnResult)) {
180                // Do nothing, we'll return null. Data wasn't found.
181            } else if (returnResult[0] instanceof BigDecimal) {
182                returnResult[0] = ((BigDecimal) returnResult[0]).intValue();
183            }
184            else {
185                returnResult[0] = ((Long) returnResult[0]).intValue();
186            }
187            
188            return returnResult;
189        }
190        
191        // build the pay type criteria
192        protected Criteria buildPayTypeCriteria(Map<Integer, Set<String>> payPeriods, List<String> balanceTypes, Map<String, Set<String>> earnCodePayGroupMap) {
193            Criteria criteria = new Criteria();
194    
195            Criteria criteriaForPayPeriods = new Criteria();
196            for (Integer fiscalYear : payPeriods.keySet()) {
197                Criteria criteriaForFiscalYear = new Criteria();
198    
199                criteriaForFiscalYear.addEqualTo(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, fiscalYear);
200                criteriaForFiscalYear.addIn(KFSPropertyConstants.UNIVERSITY_FISCAL_PERIOD_CODE, payPeriods.get(fiscalYear));
201    
202                criteriaForPayPeriods.addOrCriteria(criteriaForFiscalYear);
203            }
204    
205            Criteria criteriaForBalanceTypes = new Criteria();
206            criteriaForBalanceTypes.addIn(KFSPropertyConstants.FINANCIAL_BALANCE_TYPE_CODE, balanceTypes);
207    
208            Criteria criteriaForEarnCodePayGroup = new Criteria();
209            for (String payGroup : earnCodePayGroupMap.keySet()) {
210                Criteria criteriaForEarnPay = new Criteria();
211    
212                criteriaForEarnPay.addEqualTo(KFSPropertyConstants.PAY_GROUP, payGroup);
213                criteriaForEarnPay.addIn(KFSPropertyConstants.EARN_CODE, earnCodePayGroupMap.get(payGroup));
214    
215                criteriaForEarnCodePayGroup.addOrCriteria(criteriaForEarnPay);
216            }
217    
218            criteria.addAndCriteria(criteriaForPayPeriods);
219            criteria.addAndCriteria(criteriaForBalanceTypes);
220            criteria.addAndCriteria(criteriaForEarnCodePayGroup);
221    
222            return criteria;
223        }
224    
225        /**
226         * @see org.kuali.kfs.gl.dataaccess.LedgerEntryBalancingDao#findCountGreaterOrEqualThan(java.lang.Integer)
227         */
228        public Integer findCountGreaterOrEqualThan(Integer year) {
229            Criteria criteria = new Criteria();
230            criteria.addGreaterOrEqualThan(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, year);
231            
232            ReportQueryByCriteria query = QueryFactory.newReportQuery(getEntryClass(), criteria);
233            
234            return getPersistenceBrokerTemplate().getCount(query);
235        }
236        
237        /**
238         * @return the Class type of the business object accessed and managed
239         */
240        protected Class getEntryClass() {
241            return LedgerEntry.class;
242        }
243    }