View Javadoc
1   /*
2    * Copyright 2006 The Kuali Foundation
3    * 
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    * http://www.opensource.org/licenses/ecl2.php
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.ole.gl.report;
17  
18  import java.io.FileNotFoundException;
19  import java.io.FileOutputStream;
20  import java.text.DecimalFormat;
21  import java.text.SimpleDateFormat;
22  import java.util.ArrayList;
23  import java.util.Collections;
24  import java.util.Date;
25  import java.util.Iterator;
26  import java.util.List;
27  import java.util.Map;
28  
29  import org.kuali.ole.gl.businessobject.Transaction;
30  import org.kuali.ole.sys.Message;
31  import org.kuali.ole.sys.context.SpringContext;
32  import org.kuali.rice.core.api.datetime.DateTimeService;
33  
34  import com.lowagie.text.Document;
35  import com.lowagie.text.DocumentException;
36  import com.lowagie.text.ExceptionConverter;
37  import com.lowagie.text.Font;
38  import com.lowagie.text.FontFactory;
39  import com.lowagie.text.PageSize;
40  import com.lowagie.text.Phrase;
41  import com.lowagie.text.Rectangle;
42  import com.lowagie.text.pdf.PdfPCell;
43  import com.lowagie.text.pdf.PdfPTable;
44  import com.lowagie.text.pdf.PdfPageEventHelper;
45  import com.lowagie.text.pdf.PdfWriter;
46  
47  /**
48   * This class represents the functionality related to the generating the Transaction Report. The transaction report
49   * shows the primary key from transactions and a list of messages for each one.
50   * 
51   */
52  public class TransactionReport {
53      private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(TransactionReport.class);
54  
55      static public class PageHelper extends PdfPageEventHelper {
56          public Date runDate;
57          public Font headerFont;
58          public String title;
59  
60          /**
61           * Generates the end page for this transaction report
62           * 
63           * @see com.lowagie.text.pdf.PdfPageEventHelper#onEndPage(com.lowagie.text.pdf.PdfWriter, com.lowagie.text.Document)
64           */
65          public void onEndPage(PdfWriter writer, Document document) {
66              try {
67                  Rectangle page = document.getPageSize();
68                  PdfPTable head = new PdfPTable(3);
69                  SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
70                  PdfPCell cell = new PdfPCell(new Phrase(sdf.format(runDate), headerFont));
71                  cell.setBorder(Rectangle.NO_BORDER);
72                  head.addCell(cell);
73  
74                  cell = new PdfPCell(new Phrase(title, headerFont));
75                  cell.setBorder(Rectangle.NO_BORDER);
76                  cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
77                  head.addCell(cell);
78  
79                  cell = new PdfPCell(new Phrase("Page: " + new Integer(writer.getPageNumber()), headerFont));
80                  cell.setBorder(Rectangle.NO_BORDER);
81                  cell.setHorizontalAlignment(PdfPCell.ALIGN_RIGHT);
82                  head.addCell(cell);
83  
84                  head.setTotalWidth(page.width() - document.leftMargin() - document.rightMargin());
85                  head.writeSelectedRows(0, -1, document.leftMargin(), page.height() - document.topMargin() + head.getTotalHeight(), writer.getDirectContent());
86              }
87              catch (Exception e) {
88                  throw new ExceptionConverter(e);
89              }
90          }
91      }
92  
93      public TransactionReport() {
94          super();
95      }
96  
97  
98      /**
99       * Generates transaction report
100      * 
101      * @param reportErrors map containing transactions and the errors associated with each transaction
102      * @param reportSummary list of summary objects
103      * @param runDate date report is run
104      * @param title title of report
105      * @param fileprefix file prefix of report file
106      * @param destinationDirectory destination of where report file will reside
107      */
108     public void generateReport(Map<Transaction, List<Message>> reportErrors, List<Summary> reportSummary, Date runDate, String title, String fileprefix, String destinationDirectory) {
109         LOG.debug("generateReport() started");
110 
111         List transactions = new ArrayList();
112         if (reportErrors != null) {
113             transactions.addAll(reportErrors.keySet());
114         }
115         generateReport(transactions, reportErrors, reportSummary, runDate, title, fileprefix, destinationDirectory);
116     }
117 
118     /**
119      * Generates transaction report
120      * 
121      * @param errorSortedList list of error'd transactions
122      * @param reportErrors map containing transactions and the errors associated with each transaction
123      * @param reportSummary list of summary objects
124      * @param runDate date report is run
125      * @param title title of report
126      * @param fileprefix file prefix of report file
127      * @param destinationDirectory destination of where report file will reside
128      */
129     public void generateReport(List<Transaction> errorSortedList, Map<Transaction, List<Message>> reportErrors, List<Summary> reportSummary, Date runDate, String title, String fileprefix, String destinationDirectory) {
130         LOG.debug("generateReport() started");
131 
132         Font headerFont = FontFactory.getFont(FontFactory.COURIER, 8, Font.BOLD);
133         Font textFont = FontFactory.getFont(FontFactory.COURIER, 8, Font.NORMAL);
134 
135         Document document = new Document(PageSize.A4.rotate());
136 
137         PageHelper helper = new PageHelper();
138         helper.runDate = runDate;
139         helper.headerFont = headerFont;
140         helper.title = title;
141 
142         try {
143             DateTimeService dateTimeService = SpringContext.getBean(DateTimeService.class);
144             
145             String filename = destinationDirectory + "/" + fileprefix + "_";
146             filename = filename + dateTimeService.toDateTimeStringForFilename(runDate);
147             filename = filename + ".pdf";
148             PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
149             writer.setPageEvent(helper);
150 
151             document.open();
152             appendReport(document, headerFont, textFont, errorSortedList, reportErrors, reportSummary, runDate);
153         }
154         catch (DocumentException de) {
155             LOG.error("generateReport() Error creating PDF report", de);
156             throw new RuntimeException("Report Generation Failed: " + de.getMessage());
157         }
158         catch (FileNotFoundException fnfe) {
159             LOG.error("generateReport() Error writing PDF report", fnfe);
160             throw new RuntimeException("Report Generation Failed: Error writing to file " + fnfe.getMessage());
161         }
162         finally {
163             if ((document != null) && document.isOpen()) {
164                 document.close();
165             }
166         }
167     }
168 
169     /**
170      * Appends the scrubber totals/statistics and error report to the given (iText) document object.
171      * 
172      * @param document the PDF document
173      * @param headerFont font for header
174      * @param textFont font for report text
175      * @param errorSortedList list of error'd transactions
176      * @param reportErrors map containing transactions and the errors associated with each transaction
177      * @param reportSummary list of summary objects
178      * @param runDate date report was run
179      * @throws DocumentException
180      */
181     public void appendReport(Document document, Font headerFont, Font textFont, List<Transaction> errorSortedList, Map<Transaction, List<Message>> reportErrors, List<Summary> reportSummary, Date runDate) throws DocumentException {
182         // Sort what we get
183         Collections.sort(reportSummary);
184 
185         float[] summaryWidths = { 80, 20 };
186         PdfPTable summary = new PdfPTable(summaryWidths);
187         summary.setWidthPercentage(40);
188         PdfPCell cell = new PdfPCell(new Phrase("S T A T I S T I C S", headerFont));
189         cell.setColspan(2);
190         cell.setBorder(Rectangle.NO_BORDER);
191         cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
192         summary.addCell(cell);
193 
194         for (Iterator iter = reportSummary.iterator(); iter.hasNext();) {
195             Summary s = (Summary) iter.next();
196 
197             cell = new PdfPCell(new Phrase(s.getDescription(), textFont));
198             cell.setBorder(Rectangle.NO_BORDER);
199             summary.addCell(cell);
200 
201             if ("".equals(s.getDescription())) {
202                 cell = new PdfPCell(new Phrase("", textFont));
203                 cell.setBorder(Rectangle.NO_BORDER);
204                 summary.addCell(cell);
205             }
206             else {
207                 DecimalFormat nf = new DecimalFormat("###,###,###,##0");
208                 cell = new PdfPCell(new Phrase(nf.format(s.getCount()), textFont));
209                 cell.setBorder(Rectangle.NO_BORDER);
210                 cell.setHorizontalAlignment(PdfPCell.ALIGN_RIGHT);
211                 summary.addCell(cell);
212             }
213         }
214         cell = new PdfPCell(new Phrase(""));
215         cell.setColspan(2);
216         cell.setBorder(Rectangle.NO_BORDER);
217         summary.addCell(cell);
218 
219         document.add(summary);
220 
221         if (reportErrors != null && reportErrors.size() > 0) {
222             float[] warningWidths = { 4, 3, 6, 5, 5, 4, 5, 5, 4, 5, 5, 9, 4, 36 };
223             PdfPTable warnings = new PdfPTable(warningWidths);
224             warnings.setHeaderRows(2);
225             warnings.setWidthPercentage(100);
226             cell = new PdfPCell(new Phrase("W A R N I N G S", headerFont));
227             cell.setColspan(14);
228             cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
229             warnings.addCell(cell);
230 
231             // Add headers
232             cell = new PdfPCell(new Phrase("Year", headerFont));
233             warnings.addCell(cell);
234             cell = new PdfPCell(new Phrase("COA", headerFont));
235             warnings.addCell(cell);
236             cell = new PdfPCell(new Phrase("Account", headerFont));
237             warnings.addCell(cell);
238             cell = new PdfPCell(new Phrase("Sacct", headerFont));
239             warnings.addCell(cell);
240             cell = new PdfPCell(new Phrase("Obj", headerFont));
241             warnings.addCell(cell);
242             cell = new PdfPCell(new Phrase("SObj", headerFont));
243             warnings.addCell(cell);
244             cell = new PdfPCell(new Phrase("BalTyp", headerFont));
245             warnings.addCell(cell);
246             cell = new PdfPCell(new Phrase("ObjTyp", headerFont));
247             warnings.addCell(cell);
248             cell = new PdfPCell(new Phrase("Prd", headerFont));
249             warnings.addCell(cell);
250             cell = new PdfPCell(new Phrase("DocType", headerFont));
251             warnings.addCell(cell);
252             cell = new PdfPCell(new Phrase("Origin", headerFont));
253             warnings.addCell(cell);
254             cell = new PdfPCell(new Phrase("DocNbr", headerFont));
255             warnings.addCell(cell);
256             cell = new PdfPCell(new Phrase("Seq", headerFont));
257             warnings.addCell(cell);
258             cell = new PdfPCell(new Phrase("Warning", headerFont));
259             warnings.addCell(cell);
260 
261             for (Iterator errorIter = errorSortedList.iterator(); errorIter.hasNext();) {
262                 Transaction tran = (Transaction) errorIter.next();
263                 boolean first = true;
264 
265                 List errors = (List) reportErrors.get(tran);
266                 for (Iterator listIter = errors.iterator(); listIter.hasNext();) {
267                     String msg = null;
268                     Object m = listIter.next();
269                     if (m instanceof Message) {
270                         Message mm = (Message) m;
271                         msg = mm.getMessage();
272                     }
273                     else {
274                         if (m == null) {
275                             msg = "";
276                         }
277                         else {
278                             msg = m.toString();
279                         }
280                     }
281 
282                     if (first) {
283                         first = false;
284 
285                         if (tran.getUniversityFiscalYear() == null) {
286                             cell = new PdfPCell(new Phrase("NULL", textFont));
287                         }
288                         else {
289                             cell = new PdfPCell(new Phrase(tran.getUniversityFiscalYear().toString(), textFont));
290                         }
291                         warnings.addCell(cell);
292                         cell = new PdfPCell(new Phrase(tran.getChartOfAccountsCode(), textFont));
293                         warnings.addCell(cell);
294                         cell = new PdfPCell(new Phrase(tran.getAccountNumber(), textFont));
295                         warnings.addCell(cell);
296                         cell = new PdfPCell(new Phrase(tran.getSubAccountNumber(), textFont));
297                         warnings.addCell(cell);
298                         cell = new PdfPCell(new Phrase(tran.getFinancialObjectCode(), textFont));
299                         warnings.addCell(cell);
300                         cell = new PdfPCell(new Phrase(tran.getFinancialSubObjectCode(), textFont));
301                         warnings.addCell(cell);
302                         cell = new PdfPCell(new Phrase(tran.getFinancialBalanceTypeCode(), textFont));
303                         warnings.addCell(cell);
304                         cell = new PdfPCell(new Phrase(tran.getFinancialObjectTypeCode(), textFont));
305                         warnings.addCell(cell);
306                         cell = new PdfPCell(new Phrase(tran.getUniversityFiscalPeriodCode(), textFont));
307                         warnings.addCell(cell);
308                         cell = new PdfPCell(new Phrase(tran.getFinancialDocumentTypeCode(), textFont));
309                         warnings.addCell(cell);
310                         cell = new PdfPCell(new Phrase(tran.getFinancialSystemOriginationCode(), textFont));
311                         warnings.addCell(cell);
312                         cell = new PdfPCell(new Phrase(tran.getDocumentNumber(), textFont));
313                         warnings.addCell(cell);
314                         if (tran.getTransactionLedgerEntrySequenceNumber() == null) {
315                             cell = new PdfPCell(new Phrase("NULL", textFont));
316                         }
317                         else {
318                             cell = new PdfPCell(new Phrase(tran.getTransactionLedgerEntrySequenceNumber().toString(), textFont));
319                         }
320                         warnings.addCell(cell);
321                     }
322                     else {
323                         cell = new PdfPCell(new Phrase("", textFont));
324                         cell.setColspan(13);
325                         warnings.addCell(cell);
326                     }
327                     cell = new PdfPCell(new Phrase(msg, textFont));
328                     warnings.addCell(cell);
329                 }
330             }
331             document.add(warnings);
332         }
333     }
334 }