001: /*
002: * Copyright 2006 The Kuali Foundation.
003: *
004: * Licensed under the Educational Community License, Version 1.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/ecl1.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.module.gl.util;
017:
018: import java.io.FileOutputStream;
019: import java.text.DecimalFormat;
020: import java.text.SimpleDateFormat;
021: import java.util.Collections;
022: import java.util.Date;
023: import java.util.Iterator;
024: import java.util.List;
025: import java.util.Map;
026:
027: import org.kuali.module.gl.bo.Transaction;
028:
029: import com.lowagie.text.Document;
030: import com.lowagie.text.Font;
031: import com.lowagie.text.FontFactory;
032: import com.lowagie.text.PageSize;
033: import com.lowagie.text.Phrase;
034: import com.lowagie.text.Rectangle;
035: import com.lowagie.text.pdf.PdfPCell;
036: import com.lowagie.text.pdf.PdfPTable;
037: import com.lowagie.text.pdf.PdfWriter;
038:
039: /**
040: * This class generates the actual transaction report
041: */
042: public class TransactionReportGenerator {
043: private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger
044: .getLogger(TransactionReportGenerator.class);
045: public static final String PDF_FILE_EXTENSION = ".pdf";
046:
047: private Font headerFont = FontFactory.getFont(FontFactory.COURIER,
048: 8, Font.BOLD);
049: private Font textFont = FontFactory.getFont(FontFactory.COURIER, 8,
050: Font.NORMAL);
051: private Font totalFieldFont = FontFactory.getFont(
052: FontFactory.COURIER, 8, Font.BOLD);
053:
054: /**
055: * This method generates report based on the given summary
056: *
057: * @param reportSummary the summary information to be reported
058: * @param reportingDate the reporting date
059: * @param title the report title
060: * @param reportNamePrefix the prefix of the generated report file
061: * @param destinationDirectory the directory where the report is located
062: */
063: public void generateSummaryReport(List reportSummary,
064: Date reportingDate, String title, String reportNamePrefix,
065: String destinationDirectory) {
066: LOG.debug("generateSummaryReport() started");
067:
068: if (reportSummary != null) {
069: this .generatePDFReport(this
070: .buildSummaryTable(reportSummary), reportingDate,
071: title, reportNamePrefix, destinationDirectory);
072: }
073: }
074:
075: /**
076: * This method generates report based on the given error information
077: *
078: * @param reportErrors the error information to be reported
079: * @param reportingDate the reporting date
080: * @param title the report title
081: * @param reportNamePrefix the prefix of the generated report file
082: * @param destinationDirectory the directory where the report is located
083: */
084: public void generateErrorReport(Map reportErrors,
085: Date reportingDate, String title, String reportNamePrefix,
086: String destinationDirectory) {
087: LOG.debug("generateErrorReport() started");
088:
089: if (reportErrors != null) {
090: this .generatePDFReport(this .buildErrorTable(reportErrors),
091: reportingDate, title, reportNamePrefix,
092: destinationDirectory);
093: }
094: }
095:
096: /**
097: * Generate the PDF report with the given information
098: *
099: * @param pdfContents contents of PDF
100: * @param reportingDate date being reported on
101: * @param title title of report
102: * @param reportNamePrefix name of report prefix
103: * @param destinationDirectory directory report file will reside
104: */
105: private void generatePDFReport(PdfPTable pdfContents,
106: Date reportingDate, String title, String reportNamePrefix,
107: String destinationDirectory) {
108: Document document = new Document(PageSize.A4.rotate());
109:
110: PDFPageHelper pageHelper = new PDFPageHelper();
111: pageHelper.setRunDate(reportingDate);
112: pageHelper.setHeaderFont(headerFont);
113: pageHelper.setTitle(title);
114:
115: try {
116: String filename = destinationDirectory + "/"
117: + reportNamePrefix + "_";
118: SimpleDateFormat sdf = new SimpleDateFormat(
119: "yyyyMMdd_HHmmss");
120: filename = filename + sdf.format(reportingDate);
121: filename = filename + PDF_FILE_EXTENSION;
122:
123: PdfWriter writer = PdfWriter.getInstance(document,
124: new FileOutputStream(filename));
125: writer.setPageEvent(pageHelper);
126:
127: document.open();
128: document.add(pdfContents);
129: } catch (Exception de) {
130: LOG.error("generateReport() Error creating PDF report", de);
131: throw new RuntimeException("Report Generation Failed");
132: } finally {
133: this .closeDocument(document);
134: }
135: }
136:
137: /**
138: * Construct the summary table
139: *
140: * @param reportSummary list of report summaries
141: * @return PdfPTable summary table
142: */
143: private PdfPTable buildSummaryTable(List reportSummary) {
144:
145: float[] cellWidths = { 80, 20 };
146: PdfPTable summaryTable = new PdfPTable(cellWidths);
147: summaryTable.setWidthPercentage(40);
148:
149: PdfPCell cell = new PdfPCell(new Phrase("S T A T I S T I C S",
150: headerFont));
151: cell.setColspan(2);
152: cell.setBorder(Rectangle.NO_BORDER);
153: cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
154: summaryTable.addCell(cell);
155:
156: Collections.sort(reportSummary);
157: for (Iterator iter = reportSummary.iterator(); iter.hasNext();) {
158: Summary summary = (Summary) iter.next();
159: this .addRow(summaryTable, summary, textFont);
160: }
161: return summaryTable;
162: }
163:
164: /**
165: * Add a row with the given ledger entry into PDF table
166: *
167: * @param summaryTable table to add row to
168: * @param summary summary object
169: * @param textFont font for text
170: */
171: private void addRow(PdfPTable summaryTable, Summary summary,
172: Font textFont) {
173:
174: PdfPCell cell = new PdfPCell(new Phrase(summary
175: .getDescription(), textFont));
176: cell.setBorder(Rectangle.NO_BORDER);
177: summaryTable.addCell(cell);
178:
179: if ("".equals(summary.getDescription())) {
180: cell = new PdfPCell(new Phrase("", textFont));
181: cell.setBorder(Rectangle.NO_BORDER);
182: summaryTable.addCell(cell);
183: } else {
184: DecimalFormat nf = new DecimalFormat("###,###,###,##0");
185: cell = new PdfPCell(new Phrase(nf
186: .format(summary.getCount()), textFont));
187: cell.setBorder(Rectangle.NO_BORDER);
188: cell.setHorizontalAlignment(PdfPCell.ALIGN_RIGHT);
189: summaryTable.addCell(cell);
190: }
191: }
192:
193: /**
194: * Construct the error table
195: * @param reportErrors map containing error'd transactions
196: *
197: * @return PdfPTable error containing errors
198: */
199: private PdfPTable buildErrorTable(Map reportErrors) {
200:
201: float[] cellWidths = { 4, 3, 6, 5, 5, 4, 5, 5, 4, 5, 5, 9, 4,
202: 36 };
203: PdfPTable errorTable = new PdfPTable(cellWidths);
204: errorTable.setHeaderRows(2);
205: errorTable.setWidthPercentage(100);
206:
207: PdfPCell cell = new PdfPCell(new Phrase("W A R N I N G S",
208: headerFont));
209: cell.setColspan(14);
210: cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
211: errorTable.addCell(cell);
212:
213: if (reportErrors != null && reportErrors.size() > 0) {
214: this .addHeader(errorTable, headerFont);
215: for (Iterator errorIter = reportErrors.keySet().iterator(); errorIter
216: .hasNext();) {
217: Transaction transaction = (Transaction) errorIter
218: .next();
219: this .addRow(errorTable, reportErrors, transaction,
220: textFont);
221: }
222: } else {
223: cell = new PdfPCell(new Phrase("No errors occurred!",
224: headerFont));
225: cell.setColspan(14);
226: errorTable.addCell(cell);
227: }
228: return errorTable;
229: }
230:
231: /**
232: * Add a table header
233: *
234: * @param errorTable table containing errors
235: * @param headerFont font for header
236: */
237: private void addHeader(PdfPTable errorTable, Font headerFont) {
238:
239: PdfPCell cell = new PdfPCell(new Phrase("Year", headerFont));
240: errorTable.addCell(cell);
241: cell = new PdfPCell(new Phrase("COA", headerFont));
242: errorTable.addCell(cell);
243: cell = new PdfPCell(new Phrase("Account", headerFont));
244: errorTable.addCell(cell);
245: cell = new PdfPCell(new Phrase("Sacct", headerFont));
246: errorTable.addCell(cell);
247: cell = new PdfPCell(new Phrase("Obj", headerFont));
248: errorTable.addCell(cell);
249: cell = new PdfPCell(new Phrase("SObj", headerFont));
250: errorTable.addCell(cell);
251: cell = new PdfPCell(new Phrase("BalTyp", headerFont));
252: errorTable.addCell(cell);
253: cell = new PdfPCell(new Phrase("ObjTyp", headerFont));
254: errorTable.addCell(cell);
255: cell = new PdfPCell(new Phrase("Prd", headerFont));
256: errorTable.addCell(cell);
257: cell = new PdfPCell(new Phrase("DocType", headerFont));
258: errorTable.addCell(cell);
259: cell = new PdfPCell(new Phrase("Origin", headerFont));
260: errorTable.addCell(cell);
261: cell = new PdfPCell(new Phrase("DocNbr", headerFont));
262: errorTable.addCell(cell);
263: cell = new PdfPCell(new Phrase("Seq", headerFont));
264: errorTable.addCell(cell);
265: cell = new PdfPCell(new Phrase("Warning", headerFont));
266: errorTable.addCell(cell);
267: }
268:
269: /**
270: * Add a row with the given ledger entry into PDF table
271: *
272: * @param errorTable PdfPTable for report errors
273: * @param reportErrors map containing actual errors
274: * @param transaction transaction containing information for given row
275: * @param textFont font for text
276: */
277: private void addRow(PdfPTable errorTable, Map reportErrors,
278: Transaction transaction, Font textFont) {
279: PdfPCell cell = null;
280: boolean first = true;
281:
282: List errors = (List) reportErrors.get(transaction);
283: for (Iterator listIter = errors.iterator(); listIter.hasNext();) {
284: Object m = listIter.next();
285: String msg = m.toString();
286:
287: if (first) {
288: first = false;
289:
290: String fiscalYear = transaction
291: .getUniversityFiscalYear() == null ? "NULL"
292: : transaction.getUniversityFiscalYear()
293: .toString();
294: cell = new PdfPCell(new Phrase(fiscalYear, textFont));
295: errorTable.addCell(cell);
296:
297: cell = new PdfPCell(new Phrase(transaction
298: .getChartOfAccountsCode(), textFont));
299: errorTable.addCell(cell);
300: cell = new PdfPCell(new Phrase(transaction
301: .getAccountNumber(), textFont));
302: errorTable.addCell(cell);
303: cell = new PdfPCell(new Phrase(transaction
304: .getSubAccountNumber(), textFont));
305: errorTable.addCell(cell);
306: cell = new PdfPCell(new Phrase(transaction
307: .getFinancialObjectCode(), textFont));
308: errorTable.addCell(cell);
309: cell = new PdfPCell(new Phrase(transaction
310: .getFinancialSubObjectCode(), textFont));
311: errorTable.addCell(cell);
312: cell = new PdfPCell(new Phrase(transaction
313: .getFinancialBalanceTypeCode(), textFont));
314: errorTable.addCell(cell);
315: cell = new PdfPCell(new Phrase(transaction
316: .getFinancialObjectTypeCode(), textFont));
317: errorTable.addCell(cell);
318: cell = new PdfPCell(new Phrase(transaction
319: .getUniversityFiscalPeriodCode(), textFont));
320: errorTable.addCell(cell);
321: cell = new PdfPCell(new Phrase(transaction
322: .getFinancialDocumentTypeCode(), textFont));
323: errorTable.addCell(cell);
324: cell = new PdfPCell(new Phrase(transaction
325: .getFinancialSystemOriginationCode(), textFont));
326: errorTable.addCell(cell);
327: cell = new PdfPCell(new Phrase(transaction
328: .getDocumentNumber(), textFont));
329: errorTable.addCell(cell);
330:
331: String squenceNumber = transaction
332: .getUniversityFiscalYear() == null ? "NULL"
333: : transaction
334: .getTransactionLedgerEntrySequenceNumber()
335: .toString();
336: cell = new PdfPCell(new Phrase(squenceNumber, textFont));
337: errorTable.addCell(cell);
338: } else {
339: cell = new PdfPCell(new Phrase("", textFont));
340: cell.setColspan(13);
341: errorTable.addCell(cell);
342: }
343: cell = new PdfPCell(new Phrase(msg, textFont));
344: errorTable.addCell(cell);
345: }
346: }
347:
348: /**
349: * Close the document and release the resource
350: *
351: * @param document document to be closed
352: */
353: private void closeDocument(Document document) {
354: try {
355: if ((document != null) && document.isOpen()) {
356: document.close();
357: }
358: } catch (Throwable t) {
359: LOG.error("generateReport() Exception closing report", t);
360: }
361: }
362: }
|