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.sys.batch.dataaccess.impl;
017    
018    import java.sql.Date;
019    import java.util.Calendar;
020    import java.util.GregorianCalendar;
021    
022    import org.apache.log4j.Logger;
023    import org.apache.ojb.broker.query.Criteria;
024    import org.apache.ojb.broker.query.QueryByCriteria;
025    import org.kuali.kfs.sys.KFSPropertyConstants;
026    import org.kuali.kfs.sys.businessobject.SystemOptions;
027    import org.kuali.kfs.sys.businessobject.UniversityDate;
028    import org.kuali.rice.kns.service.BusinessObjectService;
029    
030    /**
031     * Performs custom fiscal year process for University Date records
032     */
033    public class UniversityDateFiscalYearMakerImpl extends FiscalYearMakerImpl {
034        private static Logger LOG = org.apache.log4j.Logger.getLogger(UniversityDateFiscalYearMakerImpl.class);
035    
036        private BusinessObjectService businessObjectService;
037    
038        /**
039         * @see org.kuali.kfs.coa.batch.dataaccess.impl.FiscalYearMakerHelperImpl#performCustomProcessing(java.lang.Integer)
040         */
041        @Override
042        public void performCustomProcessing(Integer baseFiscalYear, boolean firstCopyYear) {
043            int fiscalYearStartMonth = getFiscalYearStartMonth(baseFiscalYear);
044    
045            // determine start date year, if start month is not January the year will be one behind the fiscal year
046            int startDateYear = baseFiscalYear;
047            if (Calendar.JANUARY == fiscalYearStartMonth) {
048                startDateYear += 1;
049            }
050    
051            // start with first day of fiscal year and create records for each year up to end date
052            GregorianCalendar univPeriodDate = new GregorianCalendar(startDateYear, fiscalYearStartMonth, 1);
053    
054            // setup end date
055            GregorianCalendar enddate = new GregorianCalendar(univPeriodDate.get(Calendar.YEAR), univPeriodDate.get(Calendar.MONTH), univPeriodDate.get(Calendar.DAY_OF_MONTH));
056            enddate.add(Calendar.MONTH, 12);
057            enddate.add(Calendar.DAY_OF_MONTH, -1);
058    
059            // the fiscal year is always the year of the ending date of the fiscal year
060            Integer nextFiscalYear = (Integer) enddate.get(Calendar.YEAR);
061    
062            // get rid of any records already existing for next fiscal year
063            deleteNewYearRows(nextFiscalYear);
064    
065            // initialize the period variables
066            int period = 1;
067            String periodString = String.format("%02d", period);
068            int compareMonth = univPeriodDate.get(Calendar.MONTH);
069            int currentMonth = univPeriodDate.get(Calendar.MONTH);
070    
071            // loop through the dates until we are past end date
072            while (univPeriodDate.compareTo(enddate) <= 0) {
073                // if we hit period 13 something went wrong
074                if (period == 13) {
075                    LOG.error("Hit period 13 while creating university date records");
076                    throw new RuntimeException("Hit period 13 while creating university date records");
077                }
078                
079                // create the university date record
080                UniversityDate universityDate = new UniversityDate();
081                universityDate.setUniversityFiscalYear(nextFiscalYear);
082                universityDate.setUniversityDate(new Date(univPeriodDate.getTimeInMillis()));
083                universityDate.setUniversityFiscalAccountingPeriod(periodString);
084    
085                getPersistenceBrokerTemplate().store(universityDate);
086    
087                // add one to day for the next record
088                univPeriodDate.add(Calendar.DAY_OF_MONTH, 1);
089    
090                // does this kick us into a new month and therefore a new accounting period?
091                compareMonth = univPeriodDate.get(Calendar.MONTH);
092                if (currentMonth != compareMonth) {
093                    period = period + 1;
094                    periodString = String.format("%02d", period);
095                    currentMonth = compareMonth;
096                }
097            }
098        }
099    
100        /**
101         * Removes all UniversityDate records for the given fiscal year
102         * 
103         * @param requestYear year to delete records for
104         */
105        protected void deleteNewYearRows(Integer requestYear) {
106            Criteria criteriaID = new Criteria();
107            criteriaID.addEqualTo(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, requestYear);
108    
109            QueryByCriteria queryID = new QueryByCriteria(UniversityDate.class, criteriaID);
110            getPersistenceBrokerTemplate().deleteByQuery(queryID);
111    
112            getPersistenceBrokerTemplate().clearCache();
113            LOG.warn(String.format("\n rows for %d deleted", requestYear));
114        }
115    
116        /**
117         * Retrieves the system options record for the base fiscal year to determine the fiscal year start month
118         * 
119         * @param baseFiscalYear fiscal year to retrieve options record for
120         * @return int fiscal year start month (0 being Jan)
121         */
122        protected int getFiscalYearStartMonth(Integer baseFiscalYear) {
123            SystemOptions systemOptions = new SystemOptions();
124            systemOptions.setUniversityFiscalYear(baseFiscalYear);
125    
126            SystemOptions foundOptions = (SystemOptions) businessObjectService.retrieve(systemOptions);
127            if (foundOptions == null) {
128                LOG.error("Unable to retrieve system options record for fiscal year " + baseFiscalYear);
129                throw new RuntimeException("Unable to retrieve system options record for fiscal year " + baseFiscalYear);
130            }
131    
132            Integer fiscalYearStartMonth = Integer.parseInt(foundOptions.getUniversityFiscalYearStartMo());
133    
134            return fiscalYearStartMonth - 1;
135        }
136    
137        /**
138         * @see org.kuali.kfs.coa.batch.dataaccess.impl.FiscalYearMakerHelperImpl#doCustomProcessingOnly()
139         */
140        @Override
141        public boolean doCustomProcessingOnly() {
142            return true;
143        }
144    
145        /**
146         * Gets the businessObjectService attribute.
147         * 
148         * @return Returns the businessObjectService.
149         */
150        protected BusinessObjectService getBusinessObjectService() {
151            return businessObjectService;
152        }
153    
154        /**
155         * Sets the businessObjectService attribute value.
156         * 
157         * @param businessObjectService The businessObjectService to set.
158         */
159        public void setBusinessObjectService(BusinessObjectService businessObjectService) {
160            this.businessObjectService = businessObjectService;
161        }
162    
163    }