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.gl.batch;
017
018 import java.io.File;
019 import java.text.SimpleDateFormat;
020 import java.util.ArrayList;
021 import java.util.Date;
022 import java.util.Iterator;
023 import java.util.List;
024
025 import org.apache.commons.io.filefilter.RegexFileFilter;
026 import org.kuali.kfs.gl.GeneralLedgerConstants;
027 import org.kuali.kfs.gl.batch.service.impl.OriginEntryFileIterator;
028 import org.kuali.kfs.gl.businessobject.GlSummary;
029 import org.kuali.kfs.gl.businessobject.OriginEntryInformation;
030 import org.kuali.kfs.gl.businessobject.Reversal;
031 import org.kuali.kfs.gl.report.PosterOutputSummaryReport;
032 import org.kuali.kfs.gl.service.BalanceService;
033 import org.kuali.kfs.gl.service.ReversalService;
034 import org.kuali.kfs.sys.FileUtil;
035 import org.kuali.kfs.sys.batch.AbstractWrappedBatchStep;
036 import org.kuali.kfs.sys.batch.service.WrappingBatchService;
037 import org.kuali.kfs.sys.batch.service.WrappedBatchExecutorService.CustomBatchExecutor;
038 import org.kuali.kfs.sys.businessobject.SystemOptions;
039 import org.kuali.kfs.sys.service.FiscalYearAwareReportWriterService;
040 import org.kuali.kfs.sys.service.OptionsService;
041 import org.kuali.kfs.sys.service.ReportWriterService;
042
043 /**
044 * A step to generate summary reports from a recent poster run
045 */
046 public class PosterSummaryReportStep extends AbstractWrappedBatchStep {
047 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PosterSummaryReportStep.class);
048 private static final String DATE_FORMAT = "MMdd";
049 private static final String BUD = "bud";
050 private static final String ACT = "act";
051 private static final String ENC = "enc";
052 private OptionsService optionsService;
053 private ReportWriterService posterOutputSummaryReportWriterService;
054 private FiscalYearAwareReportWriterService posterActualBalanceSummaryReportWriterService;
055 private FiscalYearAwareReportWriterService posterBudgetBalanceSummaryReportWriterService;
056 private FiscalYearAwareReportWriterService posterEncumbranceSummaryReportWriterService;
057 private ReversalService reversalService;
058 private BalanceService balanceService;
059 private String batchFileDirectoryName;
060
061 /**
062 * @see org.kuali.kfs.sys.batch.AbstractWrappedBatchStep#getCustomBatchExecutor()
063 */
064 @Override
065 protected CustomBatchExecutor getCustomBatchExecutor() {
066 return new CustomBatchExecutor() {
067 /**
068 * Runs the process that generates poster summary reports.
069 *
070 * @return true if the step completed successfully, false if otherwise
071 * @see org.kuali.kfs.sys.batch.Step#execute(java.lang.String)
072 */
073 public boolean execute() {
074 synchronized(this) { // why the synchronization?
075 final String CURRENT_YEAR_LOWER = getCurrentYearLowerParameter();
076 final String CURRENT_YEAR_UPPER = getCurrentYearUpperParameter();
077 final String CURRENT_AND_LAST_YEAR = getCurrentAndLastYearParameter();
078
079 SystemOptions currentYear = optionsService.getCurrentYearOptions();
080 SystemOptions nextYear = optionsService.getOptions(currentYear.getUniversityFiscalYear() + 1);
081 SystemOptions previousYear = optionsService.getOptions(currentYear.getUniversityFiscalYear() - 1);
082
083 Date runDate = getDateTimeService().getCurrentDate();
084 SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
085 String md = sdf.format(runDate);
086 generatePosterOutputReport(runDate);
087 if ((md.compareTo(CURRENT_YEAR_UPPER) > 0) || (md.compareTo(CURRENT_YEAR_LOWER) < 0)) {
088 // Current year
089 generateGlSummary(runDate, currentYear, BUD);
090 generateGlSummary(runDate, currentYear, ACT);
091 generateGlSummary(runDate, currentYear, ENC);
092 }
093 else if ((md.compareTo(CURRENT_AND_LAST_YEAR) > 0)) {
094 // Current year and Last year
095 generateGlSummary(runDate, currentYear, BUD);
096 generateGlSummary(runDate, previousYear, BUD);
097 generateGlSummary(runDate, currentYear, ACT);
098 generateGlSummary(runDate, previousYear, ACT);
099 generateGlSummary(runDate, currentYear, ENC);
100 generateGlSummary(runDate, previousYear, ENC);
101 }
102 else {
103 // Current year and next year
104 generateGlSummary(runDate, currentYear, BUD);
105 generateGlSummary(runDate, nextYear, BUD);
106 generateGlSummary(runDate, currentYear, ACT);
107 generateGlSummary(runDate, nextYear, ACT);
108 generateGlSummary(runDate, currentYear, ENC);
109 generateGlSummary(runDate, nextYear, ENC);
110 }
111 }
112 return true;
113 }
114 };
115 }
116
117 /**
118 * Generates reports about the output of a poster run.
119 *
120 * @param runDate the date the poster was run.
121 */
122 private void generatePosterOutputReport(Date runDate) {
123 PosterOutputSummaryReport posterOutputSummaryReport = new PosterOutputSummaryReport();
124
125 // summarize all the entries for the main poster
126 File mainPosterFile = FileUtil.getNewestFile(new File(batchFileDirectoryName), new RegexFileFilter((GeneralLedgerConstants.BatchFileSystem.POSTER_INPUT_FILE + "\\.[0-9_\\-]+\\" + GeneralLedgerConstants.BatchFileSystem.EXTENSION)));
127 if (mainPosterFile != null && mainPosterFile.exists()) {
128 OriginEntryFileIterator mainPosterIterator = new OriginEntryFileIterator(mainPosterFile);
129 while (mainPosterIterator.hasNext()) {
130 final OriginEntryInformation originEntry = mainPosterIterator.next();
131 posterOutputSummaryReport.summarize(originEntry);
132 }
133 } else {
134 LOG.warn("Could not Main Poster Input file with prefix "+GeneralLedgerConstants.BatchFileSystem.POSTER_INPUT_FILE+" for tabulation in the Poster Output Summary Report");
135 }
136
137 // summarize today's reversals
138 File reversalPosterFile = FileUtil.getNewestFile(new File(batchFileDirectoryName), new RegexFileFilter((GeneralLedgerConstants.BatchFileSystem.REVERSAL_POSTER_VALID_OUTPUT_FILE + "\\.[0-9_\\-]+\\" + GeneralLedgerConstants.BatchFileSystem.EXTENSION)));
139 if (reversalPosterFile != null && reversalPosterFile.exists()) {
140 OriginEntryFileIterator reversalOriginEntryIterator = new OriginEntryFileIterator(reversalPosterFile);
141 while (reversalOriginEntryIterator.hasNext()) {
142 final Reversal reversal = new Reversal (reversalOriginEntryIterator.next());
143 posterOutputSummaryReport.summarize(reversal);
144 }
145 } else {
146 LOG.warn("Could not Reversal Output file with prefix "+GeneralLedgerConstants.BatchFileSystem.REVERSAL_POSTER_VALID_OUTPUT_FILE+" for tabulation in the Poster Output Summary Report");
147 }
148
149 // summarize the icr poster
150 File icrPosterFile = FileUtil.getNewestFile(new File(batchFileDirectoryName), new RegexFileFilter(GeneralLedgerConstants.BatchFileSystem.ICR_POSTER_INPUT_FILE + "\\.[0-9_\\-]+\\" + GeneralLedgerConstants.BatchFileSystem.EXTENSION));
151 if (icrPosterFile != null && icrPosterFile.exists()) {
152 OriginEntryFileIterator icrIterator = new OriginEntryFileIterator(icrPosterFile);
153 while (icrIterator.hasNext()) {
154 final OriginEntryInformation originEntry = icrIterator.next();
155 posterOutputSummaryReport.summarize(originEntry);
156 }
157 } else {
158 LOG.warn("Could not Indirect Cost Recovery Poster Input file with prefix "+GeneralLedgerConstants.BatchFileSystem.ICR_POSTER_INPUT_FILE+" for tabulation in the Poster Output Summary Report");
159 }
160
161 posterOutputSummaryReport.writeReport(posterOutputSummaryReportWriterService);
162 }
163
164 /**
165 * Generates the GL Summary report
166 *
167 * @param runDate the run date of the poster service that should be reported
168 * @param options the options of the fiscal year the poster was run
169 * @param reportType the type of the report that should be generated
170 */
171 protected void generateGlSummary(Date runDate, SystemOptions year, String reportType) {
172 LOG.debug("generateGlSummary() started");
173
174 FiscalYearAwareReportWriterService fiscalYearAwareReportWriterService;
175
176 List<String> balanceTypeCodes = new ArrayList<String>();
177 if (ACT.equals(reportType)) {
178 fiscalYearAwareReportWriterService = posterActualBalanceSummaryReportWriterService;
179 balanceTypeCodes.add(year.getActualFinancialBalanceTypeCd());
180 }
181 else if (BUD.equals(reportType)) {
182 fiscalYearAwareReportWriterService = posterBudgetBalanceSummaryReportWriterService;
183 balanceTypeCodes.add(year.getBudgetCheckingBalanceTypeCd());
184 balanceTypeCodes.add(year.getBaseBudgetFinancialBalanceTypeCd());
185 balanceTypeCodes.add(year.getMonthlyBudgetFinancialBalanceTypeCd());
186 } else { // ENC
187 fiscalYearAwareReportWriterService = posterEncumbranceSummaryReportWriterService;
188 balanceTypeCodes.add(year.getExtrnlEncumFinBalanceTypCd());
189 balanceTypeCodes.add(year.getIntrnlEncumFinBalanceTypCd());
190 balanceTypeCodes.add(year.getPreencumbranceFinBalTypeCd());
191 balanceTypeCodes.add(year.getCostShareEncumbranceBalanceTypeCd());
192 }
193
194 List<GlSummary> balances = balanceService.getGlSummary(year.getUniversityFiscalYear(), balanceTypeCodes);
195
196 GlSummary totals = new GlSummary();
197 for(GlSummary balance : balances) {
198 totals.add(balance);
199 }
200 totals.setFundGroup("Total");
201
202 try {
203 fiscalYearAwareReportWriterService.setFiscalYear(year.getUniversityFiscalYear());
204 ((WrappingBatchService) fiscalYearAwareReportWriterService).initialize();
205
206 fiscalYearAwareReportWriterService.writeSubTitle("Balance Type of " + balanceTypeCodes + " for Fiscal Year " + year.getUniversityFiscalYearName());
207 fiscalYearAwareReportWriterService.writeNewLines(1);
208
209 fiscalYearAwareReportWriterService.writeTableRowSeparationLine(totals);
210 fiscalYearAwareReportWriterService.writeTable(balances, true, false);
211
212 fiscalYearAwareReportWriterService.writeTableRowSeparationLine(totals);
213 fiscalYearAwareReportWriterService.writeTableRow(totals);
214 } finally {
215 ((WrappingBatchService) fiscalYearAwareReportWriterService).destroy();
216 }
217 }
218
219 /**
220 * @return current year lower parameter for inner class
221 */
222 public String getCurrentYearLowerParameter() {
223 return getParameterService().getParameterValue(getClass(), GeneralLedgerConstants.GlSummaryReport.CURRENT_YEAR_LOWER);
224 }
225
226 /**
227 * @return current year upper parameter for inner class
228 */
229 public String getCurrentYearUpperParameter() {
230 return getParameterService().getParameterValue(PosterSummaryReportStep.this.getClass(), GeneralLedgerConstants.GlSummaryReport.CURRENT_YEAR_UPPER);
231 }
232
233 /**
234 * @return current and last year parameter for inner class
235 */
236 public String getCurrentAndLastYearParameter() {
237 return getParameterService().getParameterValue(PosterSummaryReportStep.this.getClass(), GeneralLedgerConstants.GlSummaryReport.CURRENT_AND_LAST_YEAR);
238 }
239
240 /**
241 * Sets the optionsService attribute, allowing the injection of an implementation of that service
242 *
243 * @param os the optionsService implementation to set
244 * @see org.kuali.kfs.sys.service.OptionsService
245 */
246 public void setOptionsService(OptionsService os) {
247 optionsService = os;
248 }
249
250 /**
251 * Gets the posterOutputSummaryReportWriterService attribute.
252 * @return Returns the posterOutputSummaryReportWriterService.
253 */
254 public ReportWriterService getPosterOutputSummaryReportWriterService() {
255 return posterOutputSummaryReportWriterService;
256 }
257
258 /**
259 * Sets the posterOutputSummaryReportWriterService attribute value.
260 * @param posterOutputSummaryReportWriterService The posterOutputSummaryReportWriterService to set.
261 */
262 public void setPosterOutputSummaryReportWriterService(ReportWriterService posterOutputSummaryReportWriterService) {
263 this.posterOutputSummaryReportWriterService = posterOutputSummaryReportWriterService;
264 }
265
266 /**
267 * Sets the posterActualBalanceSummaryReportWriterService attribute value.
268 * @param posterActualBalanceSummaryReportWriterService The posterActualBalanceSummaryReportWriterService to set.
269 */
270 public void setPosterActualBalanceSummaryReportWriterService(FiscalYearAwareReportWriterService posterActualBalanceSummaryReportWriterService) {
271 this.posterActualBalanceSummaryReportWriterService = posterActualBalanceSummaryReportWriterService;
272 }
273
274 /**
275 * Sets the posterBudgetBalanceSummaryReportWriterService attribute value.
276 * @param posterBudgetBalanceSummaryReportWriterService The posterBudgetBalanceSummaryReportWriterService to set.
277 */
278 public void setPosterBudgetBalanceSummaryReportWriterService(FiscalYearAwareReportWriterService posterBudgetBalanceSummaryReportWriterService) {
279 this.posterBudgetBalanceSummaryReportWriterService = posterBudgetBalanceSummaryReportWriterService;
280 }
281
282 /**
283 * Sets the posterEncumbranceSummaryReportWriterService attribute value.
284 * @param posterEncumbranceSummaryReportWriterService The posterEncumbranceSummaryReportWriterService to set.
285 */
286 public void setPosterEncumbranceSummaryReportWriterService(FiscalYearAwareReportWriterService posterEncumbranceSummaryReportWriterService) {
287 this.posterEncumbranceSummaryReportWriterService = posterEncumbranceSummaryReportWriterService;
288 }
289
290 /**
291 * Gets the reversalService attribute.
292 * @return Returns the reversalService.
293 */
294 public ReversalService getReversalService() {
295 return reversalService;
296 }
297
298 /**
299 * Sets the reversalService attribute value.
300 * @param reversalService The reversalService to set.
301 */
302 public void setReversalService(ReversalService reversalService) {
303 this.reversalService = reversalService;
304 }
305
306 /**
307 * Sets the balanceService attribute value.
308 * @param balanceService The balanceService to set.
309 */
310 public void setBalanceService(BalanceService balanceService) {
311 this.balanceService = balanceService;
312 }
313
314 /**
315 * Gets the batchFileDirectoryName attribute.
316 * @return Returns the batchFileDirectoryName.
317 */
318 public String getBatchFileDirectoryName() {
319 return batchFileDirectoryName;
320 }
321
322 /**
323 * Sets the batchFileDirectoryName attribute value.
324 * @param batchFileDirectoryName The batchFileDirectoryName to set.
325 */
326 public void setBatchFileDirectoryName(String batchFileDirectoryName) {
327 this.batchFileDirectoryName = batchFileDirectoryName;
328 }
329 }