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.coa.service.impl;
017
018import java.sql.Date;
019import java.util.Collection;
020import java.util.HashMap;
021import java.util.Map;
022import java.util.Set;
023import java.util.TreeSet;
024
025import org.kuali.ole.coa.businessobject.AccountingPeriod;
026import org.kuali.ole.coa.service.AccountingPeriodService;
027import org.kuali.ole.sys.OLEConstants;
028import org.kuali.ole.sys.OLEPropertyConstants;
029import org.kuali.ole.sys.businessobject.UniversityDate;
030import org.kuali.rice.core.api.datetime.DateTimeService;
031import org.kuali.rice.krad.service.BusinessObjectService;
032import org.springframework.cache.annotation.CacheEvict;
033import org.springframework.cache.annotation.Cacheable;
034
035/**
036 * This service implementation is the default implementation of the AccountingPeriod service that is delivered with Kuali.
037 */
038public class AccountingPeriodServiceImpl implements AccountingPeriodService {
039    // member data
040    private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AccountingPeriodServiceImpl.class);
041    protected BusinessObjectService businessObjectService;
042    protected DateTimeService dateTimeService;
043
044    protected static final Set<String> _invalidPeriodCodes = new TreeSet<String>();
045
046    static {
047        _invalidPeriodCodes.add("13");
048        _invalidPeriodCodes.add("AB");
049        _invalidPeriodCodes.add("BB");
050        _invalidPeriodCodes.add("CB");
051    }
052
053    /**
054     * The default implementation.
055     * 
056     * @see org.kuali.ole.coa.service.AccountingPeriodService#getAllAccountingPeriods()
057     */
058    @Override
059    @Cacheable(value=AccountingPeriod.CACHE_NAME, key="'{getAllAccountingPeriods}'")
060    public Collection<AccountingPeriod> getAllAccountingPeriods() {
061        return businessObjectService.findAll(AccountingPeriod.class);
062    }
063
064    /**
065     * Implements by choosing only accounting periods that are active.
066     * 
067     * @see org.kuali.ole.coa.service.AccountingPeriodService#getOpenAccountingPeriods()
068     */
069    @Override
070    @Cacheable(value=AccountingPeriod.CACHE_NAME, key="'{getOpenAccountingPeriods}'")
071    public Collection<AccountingPeriod> getOpenAccountingPeriods() {
072        HashMap<String,Object> map = new HashMap<String,Object>();
073        map.put(OLEConstants.ACCOUNTING_PERIOD_ACTIVE_INDICATOR_FIELD, Boolean.TRUE);
074
075        return businessObjectService.findMatchingOrderBy(AccountingPeriod.class, map, OLEPropertyConstants.ACCTING_PERIOD_UNIV_FISCAL_PERIOD_END_DATE, true);
076    }
077
078    /**
079     * This method is a helper method to easily grab an accounting period by looking up it's period and fiscal year
080     * 
081     * @param periodCode
082     * @param fiscalYear
083     * @return an accounting period
084     */
085    @Override
086    @Cacheable(value=AccountingPeriod.CACHE_NAME, key="#p0+'-'+#p1")
087    public AccountingPeriod getByPeriod(String periodCode, Integer fiscalYear) {
088        // build up the hashmap to find the accounting period
089        HashMap<String,Object> keys = new HashMap<String,Object>();
090        keys.put( OLEPropertyConstants.UNIVERSITY_FISCAL_PERIOD_CODE, periodCode);
091        keys.put( OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR, fiscalYear);
092        AccountingPeriod acctPeriod = businessObjectService.findByPrimaryKey(AccountingPeriod.class, keys);
093        return acctPeriod;
094    }
095
096    /**
097     * This method allows for AccountingPeriod retrieval via String date.
098     * 
099     * @param String
100     */
101    @Override
102    public AccountingPeriod getByStringDate(String dateString) {
103        AccountingPeriod acctPeriod;
104        try {
105            acctPeriod = getByDate(dateTimeService.convertToSqlDate(dateString));
106        }
107        catch (Exception pe) {
108            LOG.error("AccountingPeriod getByStringDate unable to convert string " + dateString + " into date.", pe);
109            throw new RuntimeException("AccountingPeriod getByStringDate unable to convert string " + dateString + " into date.", pe);
110        }
111        return acctPeriod;
112    }
113
114    /**
115     * This method is a helper method to get the current period.
116     * 
117     * @see org.kuali.ole.coa.service.AccountingPeriodService#getByDate(java.sql.Date)
118     */
119    @Override
120    @Cacheable(value=AccountingPeriod.CACHE_NAME, key="'date='+#p0")
121    public AccountingPeriod getByDate(Date date) {
122        Map<String,Object> primaryKeys = new HashMap<String, Object>();
123        primaryKeys.put(OLEPropertyConstants.UNIVERSITY_DATE, date);
124        UniversityDate universityDate = businessObjectService.findByPrimaryKey(UniversityDate.class, primaryKeys);
125        primaryKeys.clear();
126        primaryKeys.put(OLEPropertyConstants.UNIVERSITY_FISCAL_YEAR, universityDate.getUniversityFiscalYear());
127        primaryKeys.put(OLEPropertyConstants.UNIVERSITY_FISCAL_PERIOD_CODE, universityDate.getUniversityFiscalAccountingPeriod());
128        return businessObjectService.findByPrimaryKey(AccountingPeriod.class, primaryKeys);
129    }
130
131    /**
132     * This checks to see if the period code is empty or invalid ("13", "AB", "BB", "CB")
133     * 
134     * @param period
135     * @return
136     */
137    protected boolean isInvalidPeriodCode(AccountingPeriod period) {
138        String periodCode = period.getUniversityFiscalPeriodCode();
139        if (periodCode == null) {
140            throw new IllegalArgumentException("invalid (null) universityFiscalPeriodCode (" + periodCode + ")for" + period);
141        }
142        return _invalidPeriodCodes.contains(periodCode);
143    }
144
145    /**
146     * @see org.kuali.ole.coa.service.AccountingPeriodService#compareAccountingPeriodsByDate(org.kuali.ole.coa.businessobject.AccountingPeriod,
147     *      org.kuali.ole.coa.businessobject.AccountingPeriod)
148     */
149    @Override
150    public int compareAccountingPeriodsByDate(AccountingPeriod tweedleDee, AccountingPeriod tweedleDum) {
151        // note the lack of defensive programming here. If you send a null accounting
152        // period...then chances are, you deserve the NPE that you receive
153        Date tweedleDeeClose = tweedleDee.getUniversityFiscalPeriodEndDate();
154        Date tweedleDumClose = tweedleDum.getUniversityFiscalPeriodEndDate();
155
156        return tweedleDeeClose.compareTo(tweedleDumClose);
157    }
158
159    @Override
160    @CacheEvict(value=AccountingPeriod.CACHE_NAME,allEntries=true)
161    public void clearCache() {
162        // nothing to do - annotation does it all
163    }
164
165    public void setBusinessObjectService(BusinessObjectService businessObjectService) {
166        this.businessObjectService = businessObjectService;
167    }
168    public void setDateTimeService(DateTimeService dateTimeService) {
169        this.dateTimeService = dateTimeService;
170    }
171
172
173}