001/*
002 * Copyright 2007 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.fp.document.dataaccess.impl;
017
018import java.util.ArrayList;
019import java.util.Calendar;
020import java.util.GregorianCalendar;
021import java.util.Iterator;
022import java.util.List;
023
024import org.apache.ojb.broker.query.Criteria;
025import org.apache.ojb.broker.query.QueryByCriteria;
026import org.apache.ojb.broker.query.QueryFactory;
027import org.kuali.ole.fp.businessobject.CashieringItemInProcess;
028import org.kuali.ole.fp.businessobject.CashieringTransaction;
029import org.kuali.ole.fp.businessobject.Check;
030import org.kuali.ole.fp.businessobject.CheckBase;
031import org.kuali.ole.fp.businessobject.CoinDetail;
032import org.kuali.ole.fp.businessobject.CurrencyDetail;
033import org.kuali.ole.fp.document.dataaccess.CashManagementDao;
034import org.kuali.ole.sys.OLEConstants;
035import org.kuali.ole.sys.util.TransactionalServiceUtils;
036import org.kuali.rice.core.framework.persistence.ojb.dao.PlatformAwareDaoBaseOjb;
037import org.springframework.dao.DataAccessException;
038
039public class CashManagementDaoOjb extends PlatformAwareDaoBaseOjb implements CashManagementDao {
040    private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(CashManagementDaoOjb.class);
041
042    public CashManagementDaoOjb() {
043        super();
044    }
045
046    /**
047     * @see org.kuali.ole.fp.document.dataaccess.CashManagementDao#findOpenItemsInProcessByCampusCode(java.lang.String)
048     */
049    public List<CashieringItemInProcess> findOpenItemsInProcessByCampusCode(String campusCode) throws DataAccessException {
050        List<CashieringItemInProcess> openItems = new ArrayList<CashieringItemInProcess>();
051        Criteria criteria = new Criteria();
052        criteria.addEqualTo("campusCode", campusCode);
053        criteria.addColumnIsNull("ITM_CLOSED_DT");
054
055        QueryByCriteria openItemsQuery = QueryFactory.newQuery(CashieringItemInProcess.class, criteria);
056        return new ArrayList<CashieringItemInProcess>( getPersistenceBrokerTemplate().getCollectionByQuery(openItemsQuery) );
057    }
058
059    /**
060     * @see org.kuali.ole.fp.document.dataaccess.CashManagementDao#findRecentlyClosedItemsInProcess(java.lang.String)
061     */
062    public List<CashieringItemInProcess> findRecentlyClosedItemsInProcess(String campusCode) {
063        List<CashieringItemInProcess> closedItems = new ArrayList<CashieringItemInProcess>();
064
065        Criteria criteria = new Criteria();
066        criteria.addEqualTo("campusCode", campusCode);
067        criteria.addColumnNotNull("ITM_CLOSED_DT");
068        Calendar thirtyDaysAgo = new GregorianCalendar();
069        thirtyDaysAgo.add(Calendar.DAY_OF_YEAR, -30);
070        criteria.addGreaterThan("itemClosedDate", new java.sql.Date(thirtyDaysAgo.getTimeInMillis()));
071
072        QueryByCriteria closedItemsQuery = QueryFactory.newQuery(CashieringItemInProcess.class, criteria);
073        Iterator iter = getPersistenceBrokerTemplate().getIteratorByQuery(closedItemsQuery);
074        while (iter.hasNext()) {
075            closedItems.add((CashieringItemInProcess) iter.next());
076        }
077        return closedItems;
078    }
079
080    /**
081     * @see org.kuali.ole.fp.document.dataaccess.CashManagementDao#findCoinDetailByCashieringStatus(java.lang.String,
082     *      java.lang.String, java.lang.String)
083     */
084    public CoinDetail findCoinDetailByCashieringStatus(String documentNumber, String documentTypeCode, String cashieringStatus) {
085        return (CoinDetail) retrieveCashDetail(documentNumber, documentTypeCode, cashieringStatus, CoinDetail.class);
086    }
087
088    /**
089     * @see org.kuali.ole.fp.document.dataaccess.CashManagementDao#findCurrencyDetailByCashieringStatus(java.lang.String,
090     *      java.lang.String, java.lang.String)
091     */
092    public CurrencyDetail findCurrencyDetailByCashieringStatus(String documentNumber, String documentTypeCode, String cashieringStatus) {
093        return (CurrencyDetail) retrieveCashDetail(documentNumber, documentTypeCode, cashieringStatus, CurrencyDetail.class);
094    }
095
096    /**
097     * This takes the primary keys for a cash or currency detail record and returns an OJB criteria for it
098     * 
099     * @param documentNumber document number to retrieve
100     * @param documentTypeCode type code of the document
101     * @param cashieringStatus the cashiering status
102     * @return a criteria, based on all of the given information
103     */
104    protected Criteria getCashDetailCriteria(String documentNumber, String documentTypeCode, String cashieringStatus) {
105        Criteria criteria = new Criteria();
106        criteria.addEqualTo("documentNumber", documentNumber);
107        criteria.addEqualTo("financialDocumentTypeCode", documentTypeCode);
108        criteria.addEqualTo("cashieringStatus", cashieringStatus);
109        return criteria;
110    }
111
112    /**
113     * This method retrieves a cash detail from the database
114     * 
115     * @param documentNumber the document number to retrieve from
116     * @param documentTypeCode the document type of the document the cash detail to look up is associated with
117     * @param cashieringStatus the cashiering status to look up from
118     * @param detailType the class of the cash detail type we want
119     * @return the cash detail type record
120     */
121    protected Object retrieveCashDetail(String documentNumber, String documentTypeCode, String cashieringStatus, Class detailType) {
122        QueryByCriteria cashDetailQuery = QueryFactory.newQuery(detailType, getCashDetailCriteria(documentNumber, documentTypeCode, cashieringStatus));
123        Iterator iter = getPersistenceBrokerTemplate().getIteratorByQuery(cashDetailQuery);
124        return (iter.hasNext() ? iter.next() : null);
125    }
126
127    /**
128     * @see org.kuali.ole.fp.document.dataaccess.CashManagementDao#selectCashieringChecksForDeposit(java.lang.String, java.lang.Integer)
129     */
130    public List<Check> selectCashieringChecksForDeposit(String documentNumber, Integer depositLineNumber) {
131        QueryByCriteria depositedChecksQuery = QueryFactory.newQuery(CheckBase.class, createDepositedCashieringCheckCriteria(documentNumber, depositLineNumber));
132        return putResultsIntoCheckList(getPersistenceBrokerTemplate().getIteratorByQuery(depositedChecksQuery));
133    }
134
135    /**
136     * This method creates a criteria to find the cashiering checks associated with a given deposit
137     * 
138     * @param documentNumber the document number the deposit is associated with
139     * @param depositLineNumber the line number of the deposit
140     * @return a criteria to find those checks
141     */
142    protected Criteria createDepositedCashieringCheckCriteria(String documentNumber, Integer depositLineNumber) {
143        Criteria criteria = getCashDetailCriteria(documentNumber, CashieringTransaction.DETAIL_DOCUMENT_TYPE, OLEConstants.CheckSources.CASH_MANAGEMENT);
144        criteria.addEqualTo("financialDocumentDepositLineNumber", depositLineNumber);
145        return criteria;
146    }
147
148    /**
149     * This method puts the check elements of an iterator into a list
150     * 
151     * @param iter an iterator with checks results in it
152     * @return a list of checks
153     */
154    protected List<Check> putResultsIntoCheckList(Iterator iter) {
155        List<Check> result = new ArrayList<Check>();
156        while (iter.hasNext()) {
157            result.add((Check) iter.next());
158        }
159        return result;
160    }
161
162    /**
163     * @see org.kuali.ole.fp.document.dataaccess.CashManagementDao#selectUndepositedCashieringChecks(java.lang.String)
164     */
165    public List<Check> selectUndepositedCashieringChecks(String documentNumber) {
166        QueryByCriteria undepositedChecksQuery = QueryFactory.newQuery(CheckBase.class, createUndepositedCashieringCheckCriteria(documentNumber));
167        return putResultsIntoCheckList(getPersistenceBrokerTemplate().getIteratorByQuery(undepositedChecksQuery));
168    }
169
170    /**
171     * This method creates the criteria to find undeposited cashiering checks
172     * 
173     * @param documentNumber the document number undeposited checks are associated with
174     * @return a criteria to find them
175     */
176    protected Criteria createUndepositedCashieringCheckCriteria(String documentNumber) {
177        Criteria criteria = getCashDetailCriteria(documentNumber, CashieringTransaction.DETAIL_DOCUMENT_TYPE, OLEConstants.CheckSources.CASH_MANAGEMENT);
178        criteria.addColumnIsNull("FDOC_DPST_LN_NBR");
179        return criteria;
180    }
181
182    /**
183     * @see org.kuali.ole.fp.document.dataaccess.CashManagementDao#selectDepositedCashieringChecks(java.lang.String)
184     */
185    public List<Check> selectDepositedCashieringChecks(String documentNumber) {
186        QueryByCriteria depositedChecksQuery = QueryFactory.newQuery(CheckBase.class, createDepositedCashieringCheckCriteria(documentNumber));
187        return putResultsIntoCheckList(getPersistenceBrokerTemplate().getIteratorByQuery(depositedChecksQuery));
188    }
189
190    /**
191     * This method creates the criteria to find deposited checks
192     * 
193     * @param documentNumber the CM document the checks are associated with
194     * @return a criteria to find deposited checks
195     */
196    protected Criteria createDepositedCashieringCheckCriteria(String documentNumber) {
197        Criteria criteria = getCashDetailCriteria(documentNumber, CashieringTransaction.DETAIL_DOCUMENT_TYPE, OLEConstants.CheckSources.CASH_MANAGEMENT);
198        criteria.addColumnNotNull("FDOC_DPST_LN_NBR");
199        return criteria;
200    }
201
202    /**
203     * This method retrieves all currency details associated with a cash management document
204     * 
205     * @param documentNumber the document number of the cash management document to get currency details for
206     * @return a list of currency details
207     */
208    public List<CurrencyDetail> getAllCurrencyDetails(String documentNumber) {
209        QueryByCriteria allCurrencyDetailsQuery = QueryFactory.newQuery(CurrencyDetail.class, getAllCashDetailCriteria(documentNumber));
210        List<CurrencyDetail> result = new ArrayList<CurrencyDetail>();
211        for (Iterator iter = getPersistenceBrokerTemplate().getIteratorByQuery(allCurrencyDetailsQuery); iter.hasNext();) {
212            result.add((CurrencyDetail) iter.next());
213        }
214        return result;
215    }
216
217    /**
218     * This method gets all coin details for a particular document number, irregardless of cashiering record source
219     * 
220     * @param documentNumber the document number to find cash details for
221     * @return hopefully, a bunch of coin details
222     */
223    public List<CoinDetail> getAllCoinDetails(String documentNumber) {
224        QueryByCriteria allCoinDetailsQuery = QueryFactory.newQuery(CoinDetail.class, getAllCashDetailCriteria(documentNumber));
225        List<CoinDetail> result = new ArrayList<CoinDetail>();
226        for (Iterator iter = getPersistenceBrokerTemplate().getIteratorByQuery(allCoinDetailsQuery); iter.hasNext();) {
227            result.add((CoinDetail) iter.next());
228        }
229        return result;
230    }
231
232    /**
233     * This method creates details for getting all of a certain cash detail, irregardless of cashiering record source
234     * 
235     * @param documentNumber the document number to get cash details for
236     * @return the criteria that will allow the retrieval of the right cash details
237     */
238    protected Criteria getAllCashDetailCriteria(String documentNumber) {
239        Criteria criteria = new Criteria();
240        criteria.addEqualTo("documentNumber", documentNumber);
241        criteria.addEqualTo("financialDocumentTypeCode", CashieringTransaction.DETAIL_DOCUMENT_TYPE);
242        return criteria;
243    }
244
245    /**
246     * @see org.kuali.ole.fp.document.dataaccess.CashManagementDao#selectNextAvailableCheckLineNumber(java.lang.String)
247     */
248    public Integer selectNextAvailableCheckLineNumber(String documentNumber) {
249        if (documentNumber != null) {
250            // select all cashiering checks associated with document
251            Criteria criteria = new Criteria();
252            criteria.addEqualTo("documentNumber", documentNumber);
253            criteria.addEqualTo("cashieringStatus", OLEConstants.CheckSources.CASH_MANAGEMENT);
254            criteria.addEqualTo("financialDocumentTypeCode", CashieringTransaction.DETAIL_DOCUMENT_TYPE);
255
256            QueryByCriteria cmChecksQuery = QueryFactory.newQuery(CheckBase.class, criteria);
257            cmChecksQuery.addOrderByDescending("sequenceId");
258            Iterator allChecksIter = getPersistenceBrokerTemplate().getIteratorByQuery(cmChecksQuery);
259            if (allChecksIter.hasNext()) {
260                return new Integer((((Check) TransactionalServiceUtils.retrieveFirstAndExhaustIterator(allChecksIter)).getSequenceId()).intValue() + 1);
261            }
262            else {
263                return new Integer(1);
264            }
265        }
266        else {
267            return null;
268        }
269    }
270
271}