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 }