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.cam.report;
017
018 import java.io.File;
019 import java.io.FileOutputStream;
020 import java.text.SimpleDateFormat;
021 import java.util.Date;
022 import java.util.List;
023
024 import org.kuali.kfs.module.cam.CamsConstants;
025 import org.kuali.kfs.module.cam.CamsKeyConstants;
026 import org.kuali.kfs.sys.KFSConstants;
027 import org.kuali.kfs.sys.context.SpringContext;
028 import org.kuali.rice.kns.service.DateTimeService;
029 import org.kuali.rice.kns.service.KualiConfigurationService;
030
031 import com.lowagie.text.Cell;
032 import com.lowagie.text.Chunk;
033 import com.lowagie.text.Document;
034 import com.lowagie.text.DocumentException;
035 import com.lowagie.text.Element;
036 import com.lowagie.text.ExceptionConverter;
037 import com.lowagie.text.Font;
038 import com.lowagie.text.FontFactory;
039 import com.lowagie.text.Paragraph;
040 import com.lowagie.text.Phrase;
041 import com.lowagie.text.Rectangle;
042 import com.lowagie.text.Table;
043 import com.lowagie.text.pdf.PdfPCell;
044 import com.lowagie.text.pdf.PdfPTable;
045 import com.lowagie.text.pdf.PdfPageEventHelper;
046 import com.lowagie.text.pdf.PdfWriter;
047
048 public class DepreciationReport {
049
050
051 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DepreciationReport.class);
052 private int pageNumber = 0;
053 private int line = 0;
054 private int linesPerPage = 28;
055 private Document document;
056 private PdfWriter writer;
057
058 /**
059 * This method creates the report file and invokes the methods that write the data
060 *
061 * @param reportLog
062 * @param errorMsg
063 */
064 public void generateReport(List<String[]> reportLog, String errorMsg, String sDepreciationDate) {
065 try {
066 DateTimeService dateTimeService = SpringContext.getBean(DateTimeService.class);
067 LOG.debug("createReport() started");
068 this.document = new Document();
069
070 String destinationDirectory = SpringContext.getBean(KualiConfigurationService.class).getPropertyString(KFSConstants.REPORTS_DIRECTORY_KEY);
071
072 SimpleDateFormat sdf = new SimpleDateFormat(CamsConstants.DateFormats.YEAR_MONTH_DAY_NO_DELIMITER + "_" + CamsConstants.DateFormats.MILITARY_TIME_NO_DELIMITER);
073
074 String filename = destinationDirectory + File.separator + "cam" + File.separator + CamsConstants.Report.FILE_PREFIX + "_" + CamsConstants.Depreciation.REPORT_FILE_NAME + "_" + sdf.format(dateTimeService.getCurrentDate()) + "." + CamsConstants.Report.REPORT_EXTENSION;
075
076 Font headerFont = FontFactory.getFont(FontFactory.HELVETICA, 12, Font.NORMAL);
077
078 PageHelper helper = new PageHelper();
079 helper.runDate = dateTimeService.getCurrentDate();
080 helper.headerFont = headerFont;
081 helper.title = CamsConstants.Depreciation.DEPRECIATION_REPORT_TITLE;
082
083 writer = PdfWriter.getInstance(this.document, new FileOutputStream(filename));
084 writer.setPageEvent(helper);
085
086 this.document.open();
087
088 // Generate body of document.
089 this.generateReportLogBody(reportLog);
090 this.generateReportErrorLog(errorMsg);
091
092 }
093 catch (Exception e) {
094 throw new RuntimeException("DepreciationReport.generateReport(List<String[]> reportLog, List<String> errorLog) - Error on report generation: " + e.getMessage());
095 }
096 finally {
097 if ((this.document != null) && this.document.isOpen()) {
098 this.document.close();
099 }
100 }
101 }
102
103 /**
104 * This method adds the log lines into the report
105 *
106 * @param reportLog
107 */
108 private void generateReportLogBody(List<String[]> reportLog) {
109 try {
110 Font font = FontFactory.getFont(FontFactory.HELVETICA, 9, Font.NORMAL);
111 int columnwidths[];
112 columnwidths = new int[] { 40, 15 };
113
114 Table aTable = new Table(2, linesPerPage);
115 int rowsWritten = 0;
116 for (String[] columns : reportLog) {
117 if (pageNumber == 0 || line >= linesPerPage) {
118 if (pageNumber > 0) {
119 this.document.add(aTable);
120 }
121 int elementsLeft = reportLog.size() - rowsWritten;
122 int rowsNeeded = (elementsLeft >= linesPerPage ? linesPerPage : elementsLeft);
123 this.document.newPage();
124
125 this.generateColumnHeaders();
126
127 aTable = new Table(2, rowsNeeded); // 12 columns, 11 rows.
128
129 aTable.setAutoFillEmptyCells(true);
130 aTable.setPadding(3);
131 aTable.setWidths(columnwidths);
132 aTable.setWidth(100);
133 aTable.setBorder(Rectangle.NO_BORDER);
134
135 line = 0;
136 pageNumber++;
137 }
138 rowsWritten++;
139
140 Cell cell;
141 cell = new Cell(new Phrase(columns[0], font));
142 cell.setHorizontalAlignment(Element.ALIGN_LEFT);
143 cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
144 aTable.addCell(cell);
145
146 cell = new Cell(new Phrase(columns[1], font));
147 cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
148 cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
149 aTable.addCell(cell);
150 line++;
151 }
152 this.document.add(aTable);
153 }
154 catch (DocumentException de) {
155 throw new RuntimeException("DepreciationReport.generateReportLogBody(List<String[]> reportLog) - error: " + de.getMessage());
156 }
157 }
158
159 /**
160 * This method adds any error to the report
161 *
162 * @param errorMsg
163 */
164 private void generateReportErrorLog(String errorMsg) {
165 try {
166 Font font = FontFactory.getFont(FontFactory.HELVETICA, 9, Font.NORMAL);
167 Paragraph p1 = new Paragraph();
168
169 int rowsWritten = 0;
170 if (!errorMsg.equals("")) {
171 this.generateErrorColumnHeaders();
172
173 p1 = new Paragraph(new Chunk(errorMsg, font));
174 this.document.add(p1);
175 line++;
176 }
177 }
178 catch (Exception de) {
179 throw new RuntimeException("DepreciationReport.generateReportErrorLog(List<String> reportLog) - Report Generation Failed: " + de.getMessage());
180 }
181 }
182
183 /**
184 * This method creates a report group for the error message on the report
185 *
186 * @throws DocumentException
187 */
188 private void generateErrorColumnHeaders() throws DocumentException {
189 try {
190 int headerwidths[] = { 60 };
191
192 Table aTable = new Table(1, 1); // 2 columns, 1 rows.
193
194 aTable.setAutoFillEmptyCells(true);
195 aTable.setPadding(3);
196 aTable.setWidths(headerwidths);
197 aTable.setWidth(100);
198
199 Cell cell;
200
201 Font font = FontFactory.getFont(FontFactory.HELVETICA, 9, Font.NORMAL);
202
203 cell = new Cell(new Phrase("Error(s)", font));
204 cell.setHorizontalAlignment(Element.ALIGN_CENTER);
205 cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
206 cell.setGrayFill(0.9f);
207 aTable.addCell(cell);
208
209 this.document.add(aTable);
210
211 }
212 catch (Exception e) {
213 throw new RuntimeException("DepreciationReport.generateErrorColumnHeaders() - Error: " + e.getMessage());
214 }
215 }
216
217 /**
218 * This method inserts the depreciation date on the report
219 *
220 * @param sDepreciationDate private void generateDepreciationDateLabel(String sDepreciationDate) { try { int headerwidths[] = {
221 * 100 }; Table aTable = new Table(1, 1); // 1 columns, 1 rows. aTable.setAutoFillEmptyCells(true); aTable.setPadding(3);
222 * aTable.setWidths(headerwidths); aTable.setWidth(100); aTable.setBorder(0); Cell cell; Font font =
223 * FontFactory.getFont(FontFactory.HELVETICA, 11, Font.NORMAL); cell = new Cell(new Phrase("Depreciation Date:
224 * "+sDepreciationDate, font)); cell.setHorizontalAlignment(Element.ALIGN_CENTER);
225 * cell.setVerticalAlignment(Element.ALIGN_CENTER); cell.setBorder(0); aTable.addCell(cell); this.document.add(aTable); }
226 * catch (Exception e) { throw new RuntimeException("DepreciationReport.generateDepreciationDateLabel() - Error: " +
227 * e.getMessage()); } }
228 */
229
230 /**
231 * This method creates the headers for the report statistics
232 */
233 private void generateColumnHeaders() {
234 try {
235 int headerwidths[] = { 40, 15 };
236
237 Table aTable = new Table(2, 1); // 2 columns, 1 rows.
238
239 aTable.setAutoFillEmptyCells(true);
240 aTable.setPadding(3);
241 aTable.setWidths(headerwidths);
242 aTable.setWidth(100);
243
244 Cell cell;
245
246 Font font = FontFactory.getFont(FontFactory.HELVETICA, 9, Font.NORMAL);
247
248 cell = new Cell(new Phrase(SpringContext.getBean(KualiConfigurationService.class).getPropertyString(CamsKeyConstants.Depreciation.MSG_REPORT_DEPRECIATION_HEADING1), font));
249 cell.setHorizontalAlignment(Element.ALIGN_CENTER);
250 cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
251 cell.setGrayFill(0.9f);
252 aTable.addCell(cell);
253
254 cell = new Cell(new Phrase(SpringContext.getBean(KualiConfigurationService.class).getPropertyString(CamsKeyConstants.Depreciation.MSG_REPORT_DEPRECIATION_HEADING2), font));
255 cell.setHorizontalAlignment(Element.ALIGN_CENTER);
256 cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
257 cell.setGrayFill(0.9f);
258 aTable.addCell(cell);
259 this.document.add(aTable);
260
261 }
262 catch (Exception e) {
263 throw new RuntimeException("DepreciationReport.generateColumnHeaders() - Error: " + e.getMessage());
264 }
265 }
266
267
268 /**
269 * An inner class to help set up the PDF that is written
270 */
271 class PageHelper extends PdfPageEventHelper {
272 public Date runDate;
273 public Font headerFont;
274 public String title;
275
276 /**
277 * Writes the footer on the last page
278 *
279 * @see com.lowagie.text.pdf.PdfPageEventHelper#onEndPage(com.lowagie.text.pdf.PdfWriter, com.lowagie.text.Document)
280 */
281 public void onEndPage(PdfWriter writer, Document document) {
282 try {
283 Font titleFont = FontFactory.getFont(FontFactory.HELVETICA, 12, Font.NORMAL);
284 Font font = FontFactory.getFont(FontFactory.HELVETICA, 8, Font.NORMAL);
285
286 Rectangle page = document.getPageSize();
287 PdfPTable head = new PdfPTable(3);
288
289 int[] widths = { 15, 70, 15 };
290 head.setWidths(widths);
291
292 SimpleDateFormat sdf = new SimpleDateFormat(CamsConstants.DateFormats.MONTH_DAY_YEAR + " " + CamsConstants.DateFormats.MILITARY_TIME);
293
294 PdfPCell cell = new PdfPCell(new Phrase(sdf.format(runDate), font));
295 cell.setBorder(Rectangle.NO_BORDER);
296 head.addCell(cell);
297
298 cell = new PdfPCell(new Phrase(title, titleFont));
299 cell.setBorder(Rectangle.NO_BORDER);
300 cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
301 head.addCell(cell);
302
303 cell = new PdfPCell(new Phrase("Page: " + new Integer(writer.getPageNumber()), font));
304 cell.setBorder(Rectangle.NO_BORDER);
305 cell.setHorizontalAlignment(PdfPCell.ALIGN_RIGHT);
306 head.addCell(cell);
307
308 head.setTotalWidth(page.width() - document.leftMargin() - document.rightMargin());
309 head.writeSelectedRows(0, -1, document.leftMargin(), page.height() - document.topMargin() + head.getTotalHeight(), writer.getDirectContent());
310 }
311 catch (Exception e) {
312 throw new ExceptionConverter(e);
313 }
314 }
315 }
316 }