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 }