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    /*
017     * Created on Sep 6, 2005
018     *
019     */
020    package org.kuali.kfs.module.purap.pdf;
021    
022    import java.io.ByteArrayOutputStream;
023    import java.io.File;
024    import java.io.FileNotFoundException;
025    import java.io.FileOutputStream;
026    import java.sql.Date;
027    import java.text.SimpleDateFormat;
028    import java.util.ArrayList;
029    import java.util.Collection;
030    
031    import org.kuali.kfs.module.purap.PurapConstants;
032    import org.kuali.kfs.module.purap.businessobject.PurchaseOrderVendorQuote;
033    import org.kuali.kfs.module.purap.document.PurchaseOrderDocument;
034    import org.kuali.kfs.module.purap.util.PurApDateFormatUtils;
035    import org.kuali.kfs.sys.context.SpringContext;
036    import org.kuali.rice.kns.service.DateTimeService;
037    
038    import com.lowagie.text.Document;
039    import com.lowagie.text.DocumentException;
040    import com.lowagie.text.Element;
041    import com.lowagie.text.ExceptionConverter;
042    import com.lowagie.text.Font;
043    import com.lowagie.text.FontFactory;
044    import com.lowagie.text.PageSize;
045    import com.lowagie.text.Paragraph;
046    import com.lowagie.text.pdf.BaseFont;
047    import com.lowagie.text.pdf.PdfContentByte;
048    import com.lowagie.text.pdf.PdfPCell;
049    import com.lowagie.text.pdf.PdfPTable;
050    import com.lowagie.text.pdf.PdfPageEventHelper;
051    import com.lowagie.text.pdf.PdfTemplate;
052    import com.lowagie.text.pdf.PdfWriter;
053    
054    /**
055     * Base class to handle pdf for purchase order quote request documents.
056     * 
057     */
058    public class PurchaseOrderQuoteRequestsPdf extends PdfPageEventHelper {
059        private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PurchaseOrderQuoteRequestsPdf.class);
060    
061        public PdfTemplate tpl; // A template that will hold the total number of pages.
062        public PdfContentByte cb;
063        public PdfPTable headerTable;
064        public PurchaseOrderDocument po;
065        public BaseFont helv;
066    
067        Font titleFont = FontFactory.getFont("ARIAL", 14, 0);
068        Font cellTitleFont = FontFactory.getFont("ARIAL", 8, 0);
069        Font cellTextFont = FontFactory.getFont("ARIAL", 12, 0);
070    
071        public PurchaseOrderQuoteRequestsPdf() {
072            super();
073        }
074    
075        /**
076         * Overrides the method in PdfPageEventHelper from itext to initialize the template and font for purchase
077         * order quote request pdf documents.
078         * 
079         * @param writer    The PdfWriter for this document.
080         * @param document  The document.
081         * @see com.lowagie.text.pdf.PdfPageEventHelper#onOpenDocument(com.lowagie.text.pdf.PdfWriter, com.lowagie.text.Document)
082         */    
083        public void onOpenDocument(PdfWriter writer, Document document) {
084            LOG.debug("onOpenDocument() started.");
085            try {
086                // initialization of the template
087                tpl = writer.getDirectContent().createTemplate(100, 100);
088                // initialization of the font
089                helv = BaseFont.createFont("Helvetica", BaseFont.WINANSI, false);
090            }
091            catch (Exception e) {
092                throw new ExceptionConverter(e);
093            }
094        }
095    
096        /**
097         * Overrides the method in PdfPageEventHelper from itext to compose the footer and show the
098         * footer.
099         *
100         * @param writer    The PdfWriter for this document.
101         * @param document  The document.
102         * @see com.lowagie.text.pdf.PdfPageEventHelper#onEndPage(com.lowagie.text.pdf.PdfWriter, com.lowagie.text.Document)
103         */
104        public void onEndPage(PdfWriter writer, Document document) {
105            LOG.debug("onEndPage() started.");
106            PdfContentByte cb = writer.getDirectContent();
107            cb.saveState();
108            // compose the footer
109            String text = "Page " + writer.getPageNumber() + " of ";
110            float textSize = helv.getWidthPoint(text, 12);
111            float textBase = document.bottom() - 20;
112            cb.beginText();
113            cb.setFontAndSize(helv, 12);
114            // show the footer
115            float adjust = helv.getWidthPoint("0", 12);
116            cb.setTextMatrix(document.right() - textSize - adjust, textBase);
117            cb.showText(text);
118            cb.endText();
119            cb.addTemplate(tpl, document.right() - adjust, textBase);
120            cb.saveState();
121        }
122    
123    
124        /**
125         * Overrides the method in the PdfPageEventHelper from itext to put the total number of pages into the template.
126         * 
127         * @param writer    The PdfWriter for this document.
128         * @param document  The document.
129         * @see com.lowagie.text.pdf.PdfPageEventHelper#onCloseDocument(com.lowagie.text.pdf.PdfWriter, com.lowagie.text.Document)
130         */
131        public void onCloseDocument(PdfWriter writer, Document document) {
132            LOG.debug("onCloseDocument() started.");
133            tpl.beginText();
134            tpl.setFontAndSize(helv, 12);
135            tpl.setTextMatrix(0, 0);
136            tpl.showText("" + (writer.getPageNumber() - 1));
137            tpl.endText();
138        }
139    
140        /**
141         * Gets a PageEvents object.
142         * 
143         * @return a new PageEvents object
144         */
145        public PurchaseOrderPdf getPageEvents() {
146            LOG.debug("getPageEvents() started.");
147            return new PurchaseOrderPdf();
148        }
149    
150        /**
151         * Creates an instance of a new Document and set its margins.
152         * 
153         * @return    The created Document object.
154         */
155        private Document getDocument() throws DocumentException {
156            LOG.debug("getDocument() started");
157            Document document = new Document(PageSize.A4);
158            // Margins: 36pt = 0.5 inch, 72pt = 1 inch. Left, right, top, bottom.
159            document.setMargins(9, 9, 25, 36);
160            return document;
161        }
162    
163        /**
164         * Generates the purchase order quote request list pdf document based on the data in the given input parameters
165         * by creating a pdf writer using the given byteArrayOutputStream then calls the createPOQuoteRequestsListPdf to 
166         * write the pdf document into the writer.
167         * 
168         * @param po                     The PurchaseOrderDocument to be used to generate the pdf.
169         * @param byteArrayOutputStream  The ByteArrayOutputStream to print the pdf to.
170         * @param institutionName        The purchasing institution name.
171         * @return                       Collection of errors which are made of the messages from DocumentException.
172         */
173        public Collection generatePOQuoteRequestsListPdf(PurchaseOrderDocument po, ByteArrayOutputStream byteArrayOutputStream, String institutionName) {
174            LOG.debug("generatePOQuoteRequestsListPDF() started for po number " + po.getPurapDocumentIdentifier());
175    
176            Collection errors = new ArrayList();
177    
178            try {
179                Document doc = this.getDocument();
180                PdfWriter writer = PdfWriter.getInstance(doc, byteArrayOutputStream);
181                this.createPOQuoteRequestsListPdf(po, doc, writer, institutionName);
182            }
183            catch (DocumentException de) {
184                LOG.error(de.getMessage(), de);
185                errors.add(de.getMessage());
186            }
187            return errors;
188        }
189    
190        /**
191         * Invokes the createPOQuoteRequestsListPdf method to create a purchase order quote list request pdf document 
192         * and saves it into a file which name and location are specified in the input parameters.
193         * 
194         * @param po               The PurchaseOrderDocument to be used to generate the pdf.
195         * @param pdfFileLocation  The location to save the pdf file.
196         * @param pdfFilename      The name for the pdf file.
197         * @param institutionName  The purchasing institution name.
198         * @return                 Collection of errors which are made of the messages from DocumentException.    
199         */
200        public Collection savePOQuoteRequestsListPdf(PurchaseOrderDocument po, String pdfFileLocation, String pdfFilename, String institutionName) {
201            LOG.debug("savePOQuoteRequestsListPDF() started for po number " + po.getPurapDocumentIdentifier());
202    
203            Collection errors = new ArrayList();
204    
205            try {
206                Document doc = this.getDocument();
207                PdfWriter writer = PdfWriter.getInstance(doc, new FileOutputStream(pdfFileLocation + pdfFilename));
208                this.createPOQuoteRequestsListPdf(po, doc, writer, institutionName);
209            }
210            catch (DocumentException de) {
211                LOG.error(de.getMessage(), de);
212                errors.add(de.getMessage());
213            }
214            catch (FileNotFoundException f) {
215                LOG.error(f.getMessage(), f);
216                errors.add(f.getMessage());
217            }
218            return errors;
219        }
220    
221        /**
222         * Deletes an already created PDF.
223         * 
224         * @param pdfFileLocation  The location to save the pdf file.
225         * @param pdfFilename      The name for the pdf file.
226         */
227        public void deletePdf(String pdfFileLocation, String pdfFilename) {
228            LOG.debug("deletePdf() started for po pdf file: " + pdfFilename);
229    
230            File f = new File(pdfFileLocation + pdfFilename);
231            f.delete();
232        }
233    
234        /**
235         * Creates the pdf using given input parameters.
236         * 
237         * @param po        The PurchaseOrderDocument to be used to create the pdf.
238         * @param document  The pdf document whose margins have already been set.
239         * @param writer    The PdfWriter to write the pdf document into.
240         * @param instName  The purchasing institution name
241         * @throws DocumentException
242         */
243        private void createPOQuoteRequestsListPdf(PurchaseOrderDocument po, Document document, PdfWriter writer, String instName) throws DocumentException {
244            LOG.debug("createPOQuoteRequestsListPdf() started for po number " + po.getPurapDocumentIdentifier());
245    
246            // These have to be set because they are used by the onOpenDocument() method.
247            this.po = po;
248    
249            // Turn on the page events that handle the header and page numbers.
250            PurchaseOrderPdf events = new PurchaseOrderPdf().getPageEvents();
251            writer.setPageEvent(this); // Passing in "this" lets it know about the po, campusName, etc.
252    
253            document.open();
254    
255            PdfPCell cell;
256            Paragraph p = new Paragraph();
257    
258            float[] headerWidths = { 0.25f, 0.25f, 0.25f, 0.25f };
259            headerTable = new PdfPTable(headerWidths);
260            headerTable.setWidthPercentage(100);
261            headerTable.setHorizontalAlignment(Element.ALIGN_CENTER);
262    
263            headerTable.getDefaultCell().setBorderWidth(0);
264            headerTable.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);
265            headerTable.getDefaultCell().setVerticalAlignment(Element.ALIGN_CENTER);
266    
267            // New row
268            cell = new PdfPCell(new Paragraph(instName + "\nRequest for Quotation Vendor List\n\n", titleFont));
269            cell.setBorderWidth(0);
270            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
271            cell.setColspan(4);
272            headerTable.addCell(cell);
273    
274            // New row
275            cell = new PdfPCell(new Paragraph("PO Number: " + po.getPurapDocumentIdentifier(), cellTextFont));
276            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
277            cell.setBorderWidth(0);
278            headerTable.addCell(cell);
279    
280            cell = new PdfPCell(new Paragraph("Req. Number: " + po.getRequisitionIdentifier(), cellTextFont));
281            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
282            cell.setBorderWidth(0);
283            headerTable.addCell(cell);
284    
285            // Date format pattern: MM-dd-yyyy
286            SimpleDateFormat sdf = PurApDateFormatUtils.getSimpleDateFormat(PurapConstants.NamedDateFormats.KUALI_SIMPLE_DATE_FORMAT_2);
287            Date today = SpringContext.getBean(DateTimeService.class).getCurrentSqlDate();
288            cell = new PdfPCell(new Paragraph("Printed: " + sdf.format(today), cellTextFont));
289            cell.setBorderWidth(0);
290            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
291            headerTable.addCell(cell);
292    
293            if (po.getPurchaseOrderQuoteDueDate() != null) {
294                Date dueDate = po.getPurchaseOrderQuoteDueDate();
295                cell = new PdfPCell(new Paragraph("Due: " + sdf.format(dueDate) + "\n\n", cellTextFont));
296            }
297            else {
298                cell = new PdfPCell(new Paragraph("Due: N/A\n\n", cellTextFont));
299            }
300            cell.setBorderWidth(0);
301            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
302            headerTable.addCell(cell);
303    
304            document.add(headerTable);
305    
306            // ***** List table *****
307            LOG.debug("createPOQuoteRequestsListPdf() list table started.");
308            float[] listWidths = { 0.20f, 0.20f, 0.20f, 0.20f, 0.20f };
309            PdfPTable listTable = new PdfPTable(listWidths);
310            listTable.setWidthPercentage(100);
311            listTable.setHorizontalAlignment(Element.ALIGN_CENTER);
312    
313            cell = new PdfPCell(new Paragraph("Vendor Name", cellTextFont));
314            cell.setHorizontalAlignment(Element.ALIGN_LEFT);
315            cell.setBorderWidth(0);
316            listTable.addCell(cell);
317            cell = new PdfPCell(new Paragraph("City", cellTextFont));
318            cell.setHorizontalAlignment(Element.ALIGN_LEFT);
319            cell.setBorderWidth(0);
320            listTable.addCell(cell);
321            cell = new PdfPCell(new Paragraph("Attention", cellTextFont));
322            cell.setHorizontalAlignment(Element.ALIGN_LEFT);
323            cell.setBorderWidth(0);
324            listTable.addCell(cell);
325            cell = new PdfPCell(new Paragraph("Fax #", cellTextFont));
326            cell.setHorizontalAlignment(Element.ALIGN_LEFT);
327            cell.setBorderWidth(0);
328            listTable.addCell(cell);
329            cell = new PdfPCell(new Paragraph("Received", cellTextFont));
330            cell.setHorizontalAlignment(Element.ALIGN_LEFT);
331            cell.setBorderWidth(0);
332            listTable.addCell(cell);
333    
334            // The line under the headings.
335            cell = new PdfPCell(new Paragraph(" ", cellTitleFont));
336            cell.setFixedHeight(1);
337            cell.setColspan(5);
338            listTable.addCell(cell);
339    
340            for (PurchaseOrderVendorQuote poqv : po.getPurchaseOrderVendorQuotes()) {
341                cell = new PdfPCell(new Paragraph(poqv.getVendorName(), cellTextFont));
342                cell.setHorizontalAlignment(Element.ALIGN_LEFT);
343                cell.setBorderWidth(0);
344                listTable.addCell(cell);
345                if (poqv.getVendorStateCode() != null) {
346                    cell = new PdfPCell(new Paragraph(poqv.getVendorCityName() + ", " + poqv.getVendorStateCode(), cellTextFont));
347                }
348                else if (poqv.getVendorCountryCode() != null) {
349                    cell = new PdfPCell(new Paragraph(poqv.getVendorCityName() + ", " + poqv.getVendorCountryCode(), cellTextFont));
350                }
351                else {
352                    cell = new PdfPCell(new Paragraph(poqv.getVendorCityName(), cellTextFont));
353                }
354                cell.setHorizontalAlignment(Element.ALIGN_LEFT);
355                cell.setBorderWidth(0);
356                listTable.addCell(cell);
357                cell = new PdfPCell(new Paragraph(poqv.getVendorAttentionName(), cellTextFont));
358                cell.setHorizontalAlignment(Element.ALIGN_LEFT);
359                cell.setBorderWidth(0);
360                listTable.addCell(cell);
361                cell = new PdfPCell(new Paragraph(poqv.getVendorFaxNumber(), cellTextFont));
362                cell.setHorizontalAlignment(Element.ALIGN_LEFT);
363                cell.setBorderWidth(0);
364                listTable.addCell(cell);
365                cell = new PdfPCell(new Paragraph("__________", cellTextFont));
366                cell.setHorizontalAlignment(Element.ALIGN_LEFT);
367                cell.setBorderWidth(0);
368                listTable.addCell(cell);
369            }
370    
371            document.add(listTable);
372    
373            document.close();
374            LOG.debug("createPOQuoteRequestsListPdf()pdf document closed.");
375        } // End of createQuotePdf()
376    }