001/* 002 * Copyright 2006 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 */ 016package org.kuali.ole.gl.report; 017 018import java.io.FileNotFoundException; 019import java.io.FileOutputStream; 020import java.text.DecimalFormat; 021import java.text.SimpleDateFormat; 022import java.util.ArrayList; 023import java.util.Collections; 024import java.util.Date; 025import java.util.Iterator; 026import java.util.List; 027import java.util.Map; 028 029import org.kuali.ole.gl.businessobject.Transaction; 030import org.kuali.ole.sys.Message; 031import org.kuali.ole.sys.context.SpringContext; 032import org.kuali.rice.core.api.datetime.DateTimeService; 033 034import com.lowagie.text.Document; 035import com.lowagie.text.DocumentException; 036import com.lowagie.text.ExceptionConverter; 037import com.lowagie.text.Font; 038import com.lowagie.text.FontFactory; 039import com.lowagie.text.PageSize; 040import com.lowagie.text.Phrase; 041import com.lowagie.text.Rectangle; 042import com.lowagie.text.pdf.PdfPCell; 043import com.lowagie.text.pdf.PdfPTable; 044import com.lowagie.text.pdf.PdfPageEventHelper; 045import com.lowagie.text.pdf.PdfWriter; 046 047/** 048 * This class represents the functionality related to the generating the Transaction Report. The transaction report 049 * shows the primary key from transactions and a list of messages for each one. 050 * 051 */ 052public class TransactionReport { 053 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(TransactionReport.class); 054 055 static public class PageHelper extends PdfPageEventHelper { 056 public Date runDate; 057 public Font headerFont; 058 public String title; 059 060 /** 061 * Generates the end page for this transaction report 062 * 063 * @see com.lowagie.text.pdf.PdfPageEventHelper#onEndPage(com.lowagie.text.pdf.PdfWriter, com.lowagie.text.Document) 064 */ 065 public void onEndPage(PdfWriter writer, Document document) { 066 try { 067 Rectangle page = document.getPageSize(); 068 PdfPTable head = new PdfPTable(3); 069 SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); 070 PdfPCell cell = new PdfPCell(new Phrase(sdf.format(runDate), headerFont)); 071 cell.setBorder(Rectangle.NO_BORDER); 072 head.addCell(cell); 073 074 cell = new PdfPCell(new Phrase(title, headerFont)); 075 cell.setBorder(Rectangle.NO_BORDER); 076 cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER); 077 head.addCell(cell); 078 079 cell = new PdfPCell(new Phrase("Page: " + new Integer(writer.getPageNumber()), headerFont)); 080 cell.setBorder(Rectangle.NO_BORDER); 081 cell.setHorizontalAlignment(PdfPCell.ALIGN_RIGHT); 082 head.addCell(cell); 083 084 head.setTotalWidth(page.width() - document.leftMargin() - document.rightMargin()); 085 head.writeSelectedRows(0, -1, document.leftMargin(), page.height() - document.topMargin() + head.getTotalHeight(), writer.getDirectContent()); 086 } 087 catch (Exception e) { 088 throw new ExceptionConverter(e); 089 } 090 } 091 } 092 093 public TransactionReport() { 094 super(); 095 } 096 097 098 /** 099 * 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}