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.module.endow.web.struts; 017 018 import java.io.ByteArrayOutputStream; 019 import java.io.IOException; 020 import java.util.ArrayList; 021 import java.util.HashMap; 022 import java.util.Iterator; 023 import java.util.List; 024 import java.util.Map; 025 import java.util.zip.ZipEntry; 026 import java.util.zip.ZipOutputStream; 027 028 import javax.servlet.http.HttpServletRequest; 029 import javax.servlet.http.HttpServletResponse; 030 031 import org.apache.commons.lang.StringUtils; 032 import org.apache.struts.action.ActionForm; 033 import org.apache.struts.action.ActionForward; 034 import org.apache.struts.action.ActionMapping; 035 import org.kuali.kfs.module.endow.EndowConstants; 036 import org.kuali.kfs.module.endow.report.service.AssetStatementReportService; 037 import org.kuali.kfs.module.endow.report.util.AssetStatementReportDataHolder; 038 import org.kuali.kfs.module.endow.report.util.AssetStatementReportPrint; 039 import org.kuali.kfs.module.endow.report.util.EndowmentReportHeaderDataHolder; 040 import org.kuali.kfs.sys.KFSConstants; 041 import org.kuali.kfs.sys.context.SpringContext; 042 import org.kuali.rice.kns.util.WebUtils; 043 044 public class AssetStatementAction extends EndowmentReportBaseAction { 045 046 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AssetStatementAction.class); 047 048 private final String ENDOWMENT_REPORT_NAME = "Endowment Asset Statement"; 049 private final String NON_ENDOWED_REPORT_NAME = "Non-Endowed Asset Statement"; 050 private final String REPORT_FILE_NAME = "AssetStatementReport.pdf"; 051 052 private final String RESPONSE_CONTENT_TYPE = "application/pdf"; 053 private final String ZIP_FILENAME = "AssetStatementReport.zip"; 054 055 private final String ENDOWMENT_DETAIL_FILENAME = "AssetStatementReport_EndowmentDetail.pdf"; 056 private final String ENDOWMENT_TOTAL_FILENAME = "AssetStatementReport_EndowmentTotal.pdf"; 057 private final String NON_ENDOWED_DETAIL_FILENAME = "AssetStatementReport_NonEndowedDetail.pdf"; 058 private final String NON_ENDOWED_TOTAL_FILENAME = "AssetStatementReport_NonEndowedTotal.pdf"; 059 060 public AssetStatementAction() { 061 super(); 062 } 063 064 /** 065 * Directs to the start page 066 * 067 * @param mapping 068 * @param form 069 * @param request 070 * @param response 071 * @return 072 * @throws Exception 073 */ 074 public ActionForward start(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 075 return mapping.findForward(KFSConstants.MAPPING_BASIC); 076 } 077 078 /** 079 * Clears the form when the "clear" button is pressed 080 * 081 * @param mapping 082 * @param form 083 * @param request 084 * @param response 085 * @return 086 * @throws Exception 087 */ 088 public ActionForward clear(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 089 AssetStatementForm transactionStatementForm = (AssetStatementForm) form; 090 transactionStatementForm.clear(); 091 return mapping.findForward(KFSConstants.MAPPING_BASIC); 092 } 093 094 /** 095 * Cancels the current page and goes to the start page 096 * 097 * @param mapping 098 * @param form 099 * @param request 100 * @param response 101 * @return 102 * @throws Exception 103 */ 104 public ActionForward cancel(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 105 return mapping.findForward(KFSConstants.MAPPING_BASIC); 106 } 107 108 /** 109 * Generates Transaction Statement in the PDF form 110 * 111 * @param mapping 112 * @param form 113 * @param request 114 * @param response 115 * @return 116 * @throws Exception 117 */ 118 public ActionForward print(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 119 120 // get all the value strings from the form 121 AssetStatementForm assetStatementForm = (AssetStatementForm) form; 122 String kemids = assetStatementForm.getKemid(); 123 String benefittingOrganziationCampuses = assetStatementForm.getBenefittingOrganziationCampus(); 124 String benefittingOrganziationCharts = assetStatementForm.getBenefittingOrganziationChart(); 125 String benefittingOrganziations = assetStatementForm.getBenefittingOrganziation(); 126 String typeCodes = assetStatementForm.getTypeCode(); 127 String purposeCodes = assetStatementForm.getPurposeCode(); 128 String combineGroupCodes = assetStatementForm.getCombineGroupCode(); 129 String monthEndDate = assetStatementForm.getMonthEndDate(); 130 String endowmentOption = assetStatementForm.getEndowmentOption(); 131 String reportOption = assetStatementForm.getReportOption(); 132 String listKemidsInHeader = assetStatementForm.getListKemidsInHeader(); 133 String closedIndicator = assetStatementForm.getClosedIndicator(); 134 String printFileOption = assetStatementForm.getPrintFileOption(); 135 String message = assetStatementForm.getMessage(); 136 137 List<AssetStatementReportDataHolder> endowmentAssetStatementReportDataHolders = null; 138 List<AssetStatementReportDataHolder> nonEndowedAssetStatementReportDataHolders = null; 139 140 /* 141 * Creates the report data based on the selected criteria. 142 * The criteria are selected as follows. 143 * 1. Kemid and the other criteria cannot be selected at the same time. 144 * 2. If none of them are selected, all kemids will be selected. 145 * 3. The other criteria other than kemid are "AND" combined. 146 * 4. All the criteria in the text input can be multiple by the use of wild card or the separator ('&' for kemid, ',' for the others) 147 */ 148 149 AssetStatementReportService assetStatementReportService = SpringContext.getBean(AssetStatementReportService.class); 150 151 if (StringUtils.isNotBlank(kemids)) { 152 153 if (( StringUtils.isNotBlank(benefittingOrganziationCampuses) 154 || StringUtils.isNotBlank(benefittingOrganziationCharts) 155 || StringUtils.isNotBlank(benefittingOrganziations) 156 || StringUtils.isNotBlank(typeCodes) 157 || StringUtils.isNotBlank(purposeCodes) 158 || StringUtils.isNotBlank(combineGroupCodes) )) { 159 160 // kemid and the other criteria cannot be selected at the same time 161 assetStatementForm.setMessage(ERROR_REPORT_KEMID_WITH_OTHER_CRITERIA); 162 return mapping.findForward(KFSConstants.MAPPING_BASIC); 163 164 } else { 165 // by kemid only 166 List<String> kemidList = parseValueString(kemids, KEMID_SEPERATOR); 167 if (KFSConstants.ParameterValues.YES.equalsIgnoreCase(endowmentOption)) { 168 endowmentAssetStatementReportDataHolders = assetStatementReportService.getAssetStatementReportsByKemidByIds(kemidList, monthEndDate, endowmentOption, reportOption, closedIndicator); 169 } 170 else if (KFSConstants.ParameterValues.NO.equalsIgnoreCase(endowmentOption)) { 171 nonEndowedAssetStatementReportDataHolders = assetStatementReportService.getAssetStatementReportsByKemidByIds(kemidList, monthEndDate, endowmentOption, reportOption, closedIndicator); 172 } 173 else { 174 endowmentAssetStatementReportDataHolders = assetStatementReportService.getAssetStatementReportsByKemidByIds(kemidList, monthEndDate, KFSConstants.ParameterValues.YES, reportOption, closedIndicator); 175 nonEndowedAssetStatementReportDataHolders = assetStatementReportService.getAssetStatementReportsByKemidByIds(kemidList, monthEndDate, KFSConstants.ParameterValues.NO, reportOption, closedIndicator); 176 } 177 } 178 } 179 else { 180 if (( StringUtils.isBlank(benefittingOrganziationCampuses) 181 && StringUtils.isBlank(benefittingOrganziationCharts) 182 && StringUtils.isBlank(benefittingOrganziations) 183 && StringUtils.isBlank(typeCodes) 184 && StringUtils.isBlank(purposeCodes) 185 && StringUtils.isBlank(combineGroupCodes) )) { 186 187 // for all kemids 188 if (KFSConstants.ParameterValues.YES.equalsIgnoreCase(endowmentOption)) { 189 endowmentAssetStatementReportDataHolders = assetStatementReportService.getAssetStatementReportForAllKemids(monthEndDate, endowmentOption, reportOption, closedIndicator); 190 } else if (KFSConstants.ParameterValues.NO.equalsIgnoreCase(endowmentOption)) { 191 nonEndowedAssetStatementReportDataHolders = assetStatementReportService.getAssetStatementReportForAllKemids(monthEndDate, endowmentOption, reportOption, closedIndicator); 192 } else { 193 endowmentAssetStatementReportDataHolders = assetStatementReportService.getAssetStatementReportForAllKemids(monthEndDate, KFSConstants.ParameterValues.YES, reportOption, closedIndicator); 194 nonEndowedAssetStatementReportDataHolders = assetStatementReportService.getAssetStatementReportForAllKemids(monthEndDate, KFSConstants.ParameterValues.NO, reportOption, closedIndicator); 195 } 196 197 } 198 else { 199 // by other criteria 200 if (EndowConstants.EndowmentReport.BOTH.equalsIgnoreCase(endowmentOption)) { 201 endowmentAssetStatementReportDataHolders = assetStatementReportService.getAssetStatementReportsByOtherCriteria( 202 parseValueString(benefittingOrganziationCampuses, OTHER_CRITERIA_SEPERATOR), 203 parseValueString(benefittingOrganziationCharts, OTHER_CRITERIA_SEPERATOR), 204 parseValueString(benefittingOrganziations, OTHER_CRITERIA_SEPERATOR), 205 parseValueString(typeCodes, OTHER_CRITERIA_SEPERATOR), 206 parseValueString(purposeCodes, OTHER_CRITERIA_SEPERATOR), 207 parseValueString(combineGroupCodes, OTHER_CRITERIA_SEPERATOR), 208 monthEndDate, 209 KFSConstants.ParameterValues.YES, 210 reportOption, 211 closedIndicator); 212 213 nonEndowedAssetStatementReportDataHolders = assetStatementReportService.getAssetStatementReportsByOtherCriteria( 214 parseValueString(benefittingOrganziationCampuses, OTHER_CRITERIA_SEPERATOR), 215 parseValueString(benefittingOrganziationCharts, OTHER_CRITERIA_SEPERATOR), 216 parseValueString(benefittingOrganziations, OTHER_CRITERIA_SEPERATOR), 217 parseValueString(typeCodes, OTHER_CRITERIA_SEPERATOR), 218 parseValueString(purposeCodes, OTHER_CRITERIA_SEPERATOR), 219 parseValueString(combineGroupCodes, OTHER_CRITERIA_SEPERATOR), 220 monthEndDate, 221 KFSConstants.ParameterValues.NO, 222 reportOption, 223 closedIndicator); 224 } 225 else if (KFSConstants.ParameterValues.YES.equalsIgnoreCase(endowmentOption)) { 226 // either endowment or non-endowed 227 endowmentAssetStatementReportDataHolders = assetStatementReportService.getAssetStatementReportsByOtherCriteria( 228 parseValueString(benefittingOrganziationCampuses, OTHER_CRITERIA_SEPERATOR), 229 parseValueString(benefittingOrganziationCharts, OTHER_CRITERIA_SEPERATOR), 230 parseValueString(benefittingOrganziations, OTHER_CRITERIA_SEPERATOR), 231 parseValueString(typeCodes, OTHER_CRITERIA_SEPERATOR), 232 parseValueString(purposeCodes, OTHER_CRITERIA_SEPERATOR), 233 parseValueString(combineGroupCodes, OTHER_CRITERIA_SEPERATOR), 234 monthEndDate, 235 endowmentOption, 236 reportOption, 237 closedIndicator); 238 } 239 else if (KFSConstants.ParameterValues.NO.equalsIgnoreCase(endowmentOption)) { 240 // either endowment or non-endowed 241 nonEndowedAssetStatementReportDataHolders = assetStatementReportService.getAssetStatementReportsByOtherCriteria( 242 parseValueString(benefittingOrganziationCampuses, OTHER_CRITERIA_SEPERATOR), 243 parseValueString(benefittingOrganziationCharts, OTHER_CRITERIA_SEPERATOR), 244 parseValueString(benefittingOrganziations, OTHER_CRITERIA_SEPERATOR), 245 parseValueString(typeCodes, OTHER_CRITERIA_SEPERATOR), 246 parseValueString(purposeCodes, OTHER_CRITERIA_SEPERATOR), 247 parseValueString(combineGroupCodes, OTHER_CRITERIA_SEPERATOR), 248 monthEndDate, 249 endowmentOption, 250 reportOption, 251 closedIndicator); 252 } 253 } 254 } 255 256 // Check to see if there are something to print 257 if ((endowmentAssetStatementReportDataHolders != null && !endowmentAssetStatementReportDataHolders.isEmpty()) || 258 (nonEndowedAssetStatementReportDataHolders != null && !nonEndowedAssetStatementReportDataHolders.isEmpty())) { 259 EndowmentReportHeaderDataHolder reportHeaderDataHolderForEndowment = null; 260 EndowmentReportHeaderDataHolder reportHeaderDataHolderForNonEndowed = null; 261 262 if (endowmentAssetStatementReportDataHolders != null && !endowmentAssetStatementReportDataHolders.isEmpty()) { 263 264 // prepare the header sheet data 265 reportHeaderDataHolderForEndowment = assetStatementReportService.createReportHeaderSheetData( 266 getKemidsSelected(endowmentAssetStatementReportDataHolders), 267 parseValueString(benefittingOrganziationCampuses, OTHER_CRITERIA_SEPERATOR), 268 parseValueString(benefittingOrganziationCharts, OTHER_CRITERIA_SEPERATOR), 269 parseValueString(benefittingOrganziations, OTHER_CRITERIA_SEPERATOR), 270 parseValueString(typeCodes, OTHER_CRITERIA_SEPERATOR), 271 parseValueString(purposeCodes, OTHER_CRITERIA_SEPERATOR), 272 parseValueString(combineGroupCodes, OTHER_CRITERIA_SEPERATOR), 273 ENDOWMENT_REPORT_NAME, 274 endowmentOption, 275 reportOption); 276 } 277 if (nonEndowedAssetStatementReportDataHolders != null && !nonEndowedAssetStatementReportDataHolders.isEmpty()) { 278 279 // prepare the header sheet data 280 reportHeaderDataHolderForNonEndowed = assetStatementReportService.createReportHeaderSheetData( 281 getKemidsSelected(nonEndowedAssetStatementReportDataHolders), 282 parseValueString(benefittingOrganziationCampuses, OTHER_CRITERIA_SEPERATOR), 283 parseValueString(benefittingOrganziationCharts, OTHER_CRITERIA_SEPERATOR), 284 parseValueString(benefittingOrganziations, OTHER_CRITERIA_SEPERATOR), 285 parseValueString(typeCodes, OTHER_CRITERIA_SEPERATOR), 286 parseValueString(purposeCodes, OTHER_CRITERIA_SEPERATOR), 287 parseValueString(combineGroupCodes, OTHER_CRITERIA_SEPERATOR), 288 NON_ENDOWED_REPORT_NAME, 289 endowmentOption, 290 reportOption); 291 } 292 293 // generate the report in PDF 294 AssetStatementReportPrint assetStatementReportPrint = new AssetStatementReportPrint(); 295 296 if (printFileOption.equalsIgnoreCase(KFSConstants.ParameterValues.YES)) { 297 // consolidate all reports into one 298 ByteArrayOutputStream pdfStream = assetStatementReportPrint.printAssetStatementReport(reportHeaderDataHolderForEndowment, reportHeaderDataHolderForNonEndowed, endowmentAssetStatementReportDataHolders, nonEndowedAssetStatementReportDataHolders, endowmentOption, reportOption, listKemidsInHeader); 299 if (pdfStream != null) { 300 WebUtils.saveMimeOutputStreamAsFile(response, RESPONSE_CONTENT_TYPE, pdfStream, REPORT_FILE_NAME); 301 } 302 } 303 else { 304 // generate separate files 305 Map<String, ByteArrayOutputStream> pdfStreamMap = new HashMap<String, ByteArrayOutputStream>(); 306 ByteArrayOutputStream pdfStream = null; 307 308 if (endowmentAssetStatementReportDataHolders != null && !endowmentAssetStatementReportDataHolders.isEmpty()) { 309 if (reportOption.equalsIgnoreCase(EndowConstants.EndowmentReport.DETAIL)) { 310 pdfStream = assetStatementReportPrint.generateEndowmentDetailReport(endowmentAssetStatementReportDataHolders, reportHeaderDataHolderForEndowment, listKemidsInHeader); 311 if (pdfStream != null) { 312 pdfStreamMap.put(ENDOWMENT_DETAIL_FILENAME, pdfStream); 313 } 314 } else if (reportOption.equalsIgnoreCase(EndowConstants.EndowmentReport.TOTAL)) { 315 pdfStream = assetStatementReportPrint.generateEndowmentTotalReport(endowmentAssetStatementReportDataHolders, reportHeaderDataHolderForEndowment, listKemidsInHeader); 316 if (pdfStream != null) { 317 pdfStreamMap.put(ENDOWMENT_TOTAL_FILENAME, pdfStream); 318 } 319 } else { 320 pdfStream = assetStatementReportPrint.generateEndowmentDetailReport(endowmentAssetStatementReportDataHolders, reportHeaderDataHolderForEndowment, listKemidsInHeader); 321 if (pdfStream != null) { 322 pdfStreamMap.put(ENDOWMENT_DETAIL_FILENAME, pdfStream); 323 } 324 pdfStream = assetStatementReportPrint.generateEndowmentTotalReport(endowmentAssetStatementReportDataHolders, reportHeaderDataHolderForEndowment, listKemidsInHeader); 325 if (pdfStream != null) { 326 pdfStreamMap.put(ENDOWMENT_TOTAL_FILENAME, pdfStream); 327 } 328 } 329 } 330 if (nonEndowedAssetStatementReportDataHolders != null && !nonEndowedAssetStatementReportDataHolders.isEmpty()) { 331 if (reportOption.equalsIgnoreCase(EndowConstants.EndowmentReport.DETAIL)) { 332 pdfStream = assetStatementReportPrint.generateNonEndowedDetailReport(nonEndowedAssetStatementReportDataHolders, reportHeaderDataHolderForNonEndowed, listKemidsInHeader); 333 if (pdfStream != null) { 334 pdfStreamMap.put(NON_ENDOWED_DETAIL_FILENAME, pdfStream); 335 } 336 } else if (reportOption.equalsIgnoreCase(EndowConstants.EndowmentReport.TOTAL)) { 337 pdfStream = assetStatementReportPrint.generateNonEndowedTotalReport(nonEndowedAssetStatementReportDataHolders, reportHeaderDataHolderForNonEndowed, listKemidsInHeader); 338 if (pdfStream != null) { 339 pdfStreamMap.put(NON_ENDOWED_TOTAL_FILENAME, pdfStream); 340 } 341 } else { 342 pdfStream = assetStatementReportPrint.generateNonEndowedDetailReport(nonEndowedAssetStatementReportDataHolders, reportHeaderDataHolderForNonEndowed, listKemidsInHeader); 343 if (pdfStream != null) { 344 pdfStreamMap.put(NON_ENDOWED_DETAIL_FILENAME, pdfStream); 345 } 346 pdfStream = assetStatementReportPrint.generateNonEndowedTotalReport(nonEndowedAssetStatementReportDataHolders, reportHeaderDataHolderForNonEndowed, listKemidsInHeader); 347 if (pdfStream != null) { 348 pdfStreamMap.put(NON_ENDOWED_TOTAL_FILENAME, pdfStream); 349 } 350 } 351 } 352 353 // zip and send them 354 if (!pdfStreamMap.isEmpty()) { 355 saveMimeZipOutputStreamAsFile(response, RESPONSE_CONTENT_TYPE, pdfStreamMap, ZIP_FILENAME); 356 } 357 } 358 359 return null; 360 } 361 362 // No report was generated 363 if (StringUtils.isBlank(kemids)) { 364 assetStatementForm.setMessage("No data was found to generate report."); 365 } else { 366 assetStatementForm.setMessage("No data was found to generate report for " + kemids + "."); 367 } 368 369 return mapping.findForward(KFSConstants.MAPPING_BASIC); 370 } 371 372 /** 373 * Zip and output files that are not of type text/plain or text/html. 374 * 375 * @param response 376 * @param contentType 377 * @param byteArrayOutputStreams 378 * @param fileNames 379 * @param zipFileName 380 * @throws IOException 381 */ 382 public static void saveMimeZipOutputStreamAsFile(HttpServletResponse response, String contentType, Map<String, ByteArrayOutputStream> outputStreamMap, String zipFileName) throws IOException { 383 384 response.setContentType(contentType); 385 response.setHeader("Content-disposition", "attachment; filename=" + zipFileName); 386 response.setHeader("Expires", "0"); 387 response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0"); 388 response.setHeader("Pragma", "public"); 389 390 ZipOutputStream zout = new ZipOutputStream(response.getOutputStream()); 391 int totalSize = 0; 392 Iterator<String> fileNames = outputStreamMap.keySet().iterator(); 393 while (fileNames.hasNext()) { 394 String fileName = fileNames.next(); 395 ByteArrayOutputStream pdfStream = outputStreamMap.get(fileName); 396 totalSize += pdfStream.size(); 397 zout.putNextEntry(new ZipEntry(fileName)); 398 zout.write(pdfStream.toByteArray()); 399 zout.closeEntry(); 400 } 401 response.setContentLength(totalSize); 402 zout.flush(); 403 zout.close(); 404 } 405 406 /** 407 * Retrieves all the kemids used for the report 408 * 409 * @param transactionStatementReportDataHolder 410 * @return 411 */ 412 protected List<String> getKemidsSelected(List<AssetStatementReportDataHolder> transactionStatementReportDataHolder) { 413 414 List<String> kemids = new ArrayList<String>(); 415 for (AssetStatementReportDataHolder dataHolder : transactionStatementReportDataHolder) { 416 kemids.add(dataHolder.getKemid()); 417 } 418 419 return kemids; 420 } 421 }