View Javadoc
1   /*
2    * Copyright 2007 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.module.purap.pdf;
17  
18  import com.lowagie.text.*;
19  import com.lowagie.text.pdf.BaseFont;
20  import com.lowagie.text.pdf.PdfPCell;
21  import com.lowagie.text.pdf.PdfPTable;
22  import com.lowagie.text.pdf.PdfWriter;
23  import org.apache.commons.lang.ArrayUtils;
24  import org.apache.commons.lang.StringUtils;
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  import org.kuali.ole.module.purap.PurapConstants;
28  import org.kuali.ole.module.purap.businessobject.PurchaseOrderItem;
29  import org.kuali.ole.module.purap.businessobject.PurchaseOrderVendorStipulation;
30  import org.kuali.ole.module.purap.document.PurchaseOrderDocument;
31  import org.kuali.ole.module.purap.document.PurchaseOrderRetransmitDocument;
32  import org.kuali.ole.module.purap.exception.PurError;
33  import org.kuali.ole.module.purap.util.PurApDateFormatUtils;
34  import org.kuali.ole.select.businessobject.OleNoteType;
35  import org.kuali.ole.select.businessobject.OleNotes;
36  import org.kuali.ole.sys.OLEConstants;
37  import org.kuali.ole.sys.context.SpringContext;
38  import org.kuali.rice.core.api.util.RiceConstants;
39  import org.kuali.rice.core.api.util.type.KualiDecimal;
40  import org.kuali.rice.krad.service.BusinessObjectService;
41  
42  import java.io.ByteArrayOutputStream;
43  import java.io.FileNotFoundException;
44  import java.io.FileOutputStream;
45  import java.io.IOException;
46  import java.math.BigDecimal;
47  import java.text.NumberFormat;
48  import java.text.SimpleDateFormat;
49  import java.util.*;
50  import java.util.List;
51  
52  /**
53   * Base class to handle pdf for purchase order documents.
54   */
55  public class PurchaseOrderPdf extends PurapPdf {
56      private static Log LOG = LogFactory.getLog(PurchaseOrderPdf.class);
57  
58      /**
59       * headerTable pieces need to be public
60       */
61  
62      public PurchaseOrderPdf() {
63          super();
64      }
65  
66      /**
67       * Overrides the method in PdfPageEventHelper from itext to create and set the headerTable and set its logo image if
68       * there is a logoImage to be used, creates and sets the nestedHeaderTable and its content.
69       *
70       * @param writer   The PdfWriter for this document.
71       * @param document The document.
72       * @see com.lowagie.text.pdf.PdfPageEventHelper#onOpenDocument(com.lowagie.text.pdf.PdfWriter, com.lowagie.text.Document)
73       */
74      @Override
75      public void onOpenDocument(PdfWriter writer, Document document) {
76          if (LOG.isDebugEnabled()) {
77              LOG.debug("onOpenDocument() started. isRetransmit is " + isRetransmit);
78          }
79          try {
80              float[] headerWidths = {0.20f, 0.80f};
81              headerTable = new PdfPTable(headerWidths);
82              headerTable.setWidthPercentage(100);
83              headerTable.setHorizontalAlignment(Element.ALIGN_CENTER);
84              headerTable.setSplitLate(false);
85              headerTable.getDefaultCell().setBorderWidth(0);
86              headerTable.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);
87              headerTable.getDefaultCell().setVerticalAlignment(Element.ALIGN_CENTER);
88  
89              Image logo = null;
90              if (StringUtils.isNotBlank(logoImage)) {
91                  LOG.info(" Logo Image in open document :" + logoImage);
92                  try {
93                      logo = Image.getInstance(logoImage);
94                  } catch (FileNotFoundException e) {
95                      LOG.info("The logo image [" + logoImage + "] is not available.  Defaulting to the default image.");
96                  }
97              }
98  
99              if (logo == null) {
100                 // if we don't use images
101                 headerTable.addCell(new Phrase(new Chunk("")));
102             } else {
103                 logo.scalePercent(3, 3);
104                 headerTable.addCell(new Phrase(new Chunk(logo, 0, 0)));
105             }
106             // Nested table for titles, etc.
107             float[] nestedHeaderWidths = {0.70f, 0.30f};
108             nestedHeaderTable = new PdfPTable(nestedHeaderWidths);
109             nestedHeaderTable.setSplitLate(false);
110             PdfPCell cell;
111 
112             // New nestedHeaderTable row
113             cell = new PdfPCell(new Paragraph(po.getBillingName(), ver_15_normal));
114             cell.setHorizontalAlignment(Element.ALIGN_CENTER);
115             cell.setBorderWidth(0);
116             nestedHeaderTable.addCell(cell);
117             cell = new PdfPCell(new Paragraph(" ", ver_15_normal));
118             cell.setBorderWidth(0);
119             nestedHeaderTable.addCell(cell);
120             // New nestedHeaderTable row
121             if (isRetransmit) {
122                 cell = new PdfPCell(new Paragraph(po.getRetransmitHeader(), ver_15_normal));
123             } else {
124                 cell = new PdfPCell(new Paragraph("PURCHASE ORDER", ver_15_normal));
125             }
126             cell.setHorizontalAlignment(Element.ALIGN_CENTER);
127             cell.setBorderWidth(0);
128             nestedHeaderTable.addCell(cell);
129             Paragraph p = new Paragraph();
130             p.add(new Chunk("PO Number: ", ver_11_normal));
131             p.add(new Chunk(po.getPurapDocumentIdentifier().toString(), cour_7_normal));
132 
133             cell = new PdfPCell(p);
134             cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
135             cell.setBorderWidth(0);
136             nestedHeaderTable.addCell(cell);
137             if (!po.getPurchaseOrderAutomaticIndicator()) { // Contract manager name goes on non-APOs.
138                 // New nestedHeaderTable row, spans both columns
139                 p = new Paragraph();
140                 p.add(new Chunk("Contract Manager: ", ver_11_normal));
141                 p.add(new Chunk(po.getContractManager().getContractManagerName(), cour_7_normal));
142                 cell = new PdfPCell(p);
143                 cell.setColspan(2);
144                 cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
145                 cell.setBorderWidth(0);
146                 nestedHeaderTable.addCell(cell);
147             }
148             // Add the nestedHeaderTable to the headerTable
149             cell = new PdfPCell(nestedHeaderTable);
150             cell.setHorizontalAlignment(Element.ALIGN_CENTER);
151             cell.setBorderWidth(0);
152             headerTable.addCell(cell);
153 
154             // initialization of the template
155             tpl = writer.getDirectContent().createTemplate(100, 100);
156             // initialization of the font
157             helv = BaseFont.createFont("Helvetica", BaseFont.WINANSI, false);
158         } catch (Exception e) {
159             throw new ExceptionConverter(e);
160         }
161     }
162 
163     /**
164      * Gets a PageEvents object.
165      *
166      * @return a new PageEvents object
167      */
168     @Override
169     public PurchaseOrderPdf getPageEvents() {
170         LOG.debug("getPageEvents() started.");
171         return new PurchaseOrderPdf();
172     }
173 
174     /**
175      * Generates the pdf document based on the data in the given PurchaseOrderDocument, the pdf parameters,
176      * environment, retransmit items, creates a pdf writer using the given byteArrayOutputStream then
177      * write the pdf document into the writer.
178      *
179      * @param po                    The PurchaseOrderDocument to be used to generate the pdf.
180      * @param pdfParameters         The PurchaseOrderPdfParameters to be used to generate the pdf.
181      * @param byteArrayOutputStream The ByteArrayOutputStream where the pdf document will be written to.
182      * @param isRetransmit          The boolean to indicate whether this is for a retransmit purchase order document.
183      * @param environment           The current environment used (e.g. DEV if it is a development environment).
184      * @param retransmitItems       The items selected by the user to be retransmitted.
185      */
186     public void generatePdf(PurchaseOrderDocument po, PurchaseOrderTransmitParameters pdfParameters, ByteArrayOutputStream byteArrayOutputStream, boolean isRetransmit, String environment, List<PurchaseOrderItem> retransmitItems) {
187         if (LOG.isDebugEnabled()) {
188             LOG.debug("generatePdf() started for po number " + po.getPurapDocumentIdentifier());
189         }
190 
191         this.isRetransmit = isRetransmit;
192         String statusInquiryUrl = pdfParameters.getStatusInquiryUrl();
193         String campusName = pdfParameters.getCampusParameter().getCampus().getName();
194         String contractLanguage = pdfParameters.getContractLanguage();
195         String logoImage = pdfParameters.getLogoImage();
196         logoImage = getImageLocations(logoImage);
197         String directorSignatureImage = pdfParameters.getDirectorSignatureImage();
198         directorSignatureImage = getImageLocations(directorSignatureImage);
199         String directorName = pdfParameters.getCampusParameter().getCampusPurchasingDirectorName() != null ? pdfParameters.getCampusParameter().getCampusPurchasingDirectorName() : "";
200         String directorTitle = pdfParameters.getCampusParameter().getCampusPurchasingDirectorTitle() != null ? pdfParameters.getCampusParameter().getCampusPurchasingDirectorTitle() : "";
201         String contractManagerSignatureImage = pdfParameters.getContractManagerSignatureImage();
202         contractManagerSignatureImage = getImageLocations(contractManagerSignatureImage);
203 
204         if (LOG.isInfoEnabled()) {
205             LOG.info("PDF parameters" + "isRetransmit:" + this.isRetransmit + "statusInquiryUrl:" + statusInquiryUrl
206                     + "campusName:" + campusName + "contractLanguage:" + contractLanguage + "logoImage:" + logoImage
207                     + "directorSignatureImage:" + directorSignatureImage + "directorName:" + directorName
208                     + "directorTitle:" + directorTitle + "contractManagerSignatureImage:"
209                     + contractManagerSignatureImage + "isRetransmit" + isRetransmit + "retransmitItems:"
210                     + retransmitItems);
211         }
212         try {
213             Document doc = this.getDocument(9, 9, 70, 36);
214             PdfWriter writer = PdfWriter.getInstance(doc, byteArrayOutputStream);
215             this.createPdf(po, doc, writer, statusInquiryUrl, campusName, contractLanguage, logoImage, directorSignatureImage, directorName, directorTitle, contractManagerSignatureImage, isRetransmit, environment, retransmitItems);
216         } catch (DocumentException de) {
217             LOG.error("generatePdf() DocumentException: " + de.getMessage(), de);
218             throw new PurError("Document Exception when trying to save a Purchase Order PDF", de);
219         } catch (IOException i) {
220             LOG.error("generatePdf() IOException: " + i.getMessage(), i);
221             throw new PurError("IO Exception when trying to save a Purchase Order PDF", i);
222         } catch (Exception t) {
223             LOG.error("generatePdf() EXCEPTION: " + t.getMessage(), t);
224             throw new PurError("Unable to generate PDF for purchase order.  Please confirm that PDF service is running on OLE server.", t);
225         }
226     }
227 
228     /**
229      * Invokes the createPdf method to create a pdf document and saves it into a file
230      * which name and location are specified in the pdfParameters.
231      *
232      * @param po            The PurchaseOrderDocument to be used to create the pdf.
233      * @param pdfParameters The pdfParameters containing some of the parameters information needed by the pdf for example, the pdf file name and pdf file location, purchasing director name, etc.
234      * @param isRetransmit  The boolean to indicate whether this is for a retransmit purchase order document.
235      * @param environment   The current environment used (e.g. DEV if it is a development environment).
236      */
237     public void savePdf(PurchaseOrderDocument po, PurchaseOrderParameters pdfParameters, boolean isRetransmit, String environment) {
238         if (LOG.isDebugEnabled()) {
239             LOG.debug("savePdf() started for po number " + po.getPurapDocumentIdentifier());
240         }
241 
242         PurchaseOrderTransmitParameters pdfTransmitParameters = (PurchaseOrderTransmitParameters) pdfParameters;
243 
244         this.isRetransmit = isRetransmit;
245         String statusInquiryUrl = pdfTransmitParameters.getStatusInquiryUrl();
246         String campusName = pdfTransmitParameters.getCampusParameter().getCampus().getName();
247         String contractLanguage = pdfTransmitParameters.getContractLanguage();
248         String logoImage = pdfTransmitParameters.getLogoImage();
249         logoImage = getImageLocations(logoImage);
250         String directorSignatureImage = pdfTransmitParameters.getDirectorSignatureImage();
251         directorSignatureImage = getImageLocations(directorSignatureImage);
252         String directorName = pdfTransmitParameters.getCampusParameter().getCampusPurchasingDirectorName();
253         String directorTitle = pdfTransmitParameters.getCampusParameter().getCampusPurchasingDirectorTitle();
254         String contractManagerSignatureImage = pdfTransmitParameters.getContractManagerSignatureImage();
255         contractManagerSignatureImage = getImageLocations(contractManagerSignatureImage);
256         String pdfFileLocation = pdfTransmitParameters.getPdfFileLocation();
257         String pdfFileName = pdfTransmitParameters.getPdfFileName();
258 
259         try {
260             Document doc = this.getDocument(9, 9, 70, 36);
261             PdfWriter writer = PdfWriter.getInstance(doc, new FileOutputStream(pdfFileLocation + pdfFileName));
262             this.createPdf(po, doc, writer, statusInquiryUrl, campusName, contractLanguage, logoImage, directorSignatureImage, directorName, directorTitle, contractManagerSignatureImage, isRetransmit, environment);
263         } catch (DocumentException de) {
264             LOG.error("savePdf() DocumentException: " + de.getMessage(), de);
265             throw new PurError("Document Exception when trying to save a Purchase Order PDF", de);
266         } catch (FileNotFoundException f) {
267             LOG.error("savePdf() FileNotFoundException: " + f.getMessage(), f);
268             throw new PurError("FileNotFound Exception when trying to save a Purchase Order PDF", f);
269         } catch (IOException i) {
270             LOG.error("savePdf() IOException: " + i.getMessage(), i);
271             throw new PurError("IO Exception when trying to save a Purchase Order PDF", i);
272         } catch (Exception t) {
273             LOG.error("savePdf() EXCEPTION: " + t.getMessage(), t);
274             throw new PurError("Unable to generate PDF for purchase order.  Please confirm that PDF service is running on OLE server.", t);
275         }
276     }
277 
278     /**
279      * Creates the purchase order pdf, and pass in null as the retransmitItems List because it doesn't need retransmit.
280      *
281      * @param po                            The PurchaseOrderDocument to be used to create the pdf.
282      * @param document                      The pdf document whose margins have already been set.
283      * @param writer                        The PdfWriter to write the pdf document into.
284      * @param statusInquiryUrl              The status inquiry url to be displayed on the pdf document.
285      * @param campusName                    The campus name to be displayed on the pdf document.
286      * @param contractLanguage              The contract language to be displayed on the pdf document.
287      * @param logoImage                     The logo image file name to be displayed on the pdf document.
288      * @param directorSignatureImage        The director signature image to be displayed on the pdf document.
289      * @param directorName                  The director name to be displayed on the pdf document.
290      * @param directorTitle                 The director title to be displayed on the pdf document.
291      * @param contractManagerSignatureImage The contract manager signature image to be displayed on the pdf document.
292      * @param isRetransmit                  The boolean to indicate whether this is for a retransmit purchase order document.
293      * @param environment                   The current environment used (e.g. DEV if it is a development environment).
294      * @throws DocumentException
295      * @throws IOException
296      */
297     private void createPdf(PurchaseOrderDocument po, Document document, PdfWriter writer, String statusInquiryUrl, String campusName, String contractLanguage, String logoImage, String directorSignatureImage, String directorName, String directorTitle, String contractManagerSignatureImage, boolean isRetransmit, String environment) throws DocumentException, IOException {
298         createPdf(po, document, writer, statusInquiryUrl, campusName, contractLanguage, logoImage, directorSignatureImage, directorName, directorTitle, contractManagerSignatureImage, isRetransmit, environment, null);
299     }
300 
301     /**
302      * Create a PDF using the given input parameters.
303      *
304      * @param po                            The PurchaseOrderDocument to be used to create the pdf.
305      * @param document                      The pdf document whose margins have already been set.
306      * @param writer                        The PdfWriter to write the pdf document into.
307      * @param statusInquiryUrl              The status inquiry url to be displayed on the pdf document.
308      * @param campusName                    The campus name to be displayed on the pdf document.
309      * @param contractLanguage              The contract language to be displayed on the pdf document.
310      * @param logoImage                     The logo image file name to be displayed on the pdf document.
311      * @param directorSignatureImage        The director signature image to be displayed on the pdf document.
312      * @param directorName                  The director name to be displayed on the pdf document.
313      * @param directorTitle                 The director title to be displayed on the pdf document.
314      * @param contractManagerSignatureImage The contract manager signature image to be displayed on the pdf document.
315      * @param isRetransmit                  The boolean to indicate whether this is for a retransmit purchase order document.
316      * @param environment                   The current environment used (e.g. DEV if it is a development environment).
317      * @param retransmitItems               The items selected by the user to be retransmitted.
318      * @throws DocumentException
319      * @throws IOException
320      */
321     private void createPdf(PurchaseOrderDocument po, Document document, PdfWriter writer, String statusInquiryUrl, String campusName, String contractLanguage, String logoImage, String directorSignatureImage, String directorName, String directorTitle, String contractManagerSignatureImage, boolean isRetransmit, String environment, List<PurchaseOrderItem> retransmitItems) throws DocumentException, IOException {
322         if (LOG.isInfoEnabled()) {
323             LOG.info("Inside createPdf statement" + "PO:" + po + "Document:" + document + "PdfWriter:" + writer
324                     + "StatusInquiryUrl:" + statusInquiryUrl + "Campus Name:" + campusName + "Contract Language"
325                     + contractLanguage + "Logo Image:" + logoImage + "Director Signature Image:"
326                     + directorSignatureImage + "Director Name" + directorName + "Director Title:" + directorTitle
327                     + "Contract Manager Signature Image :" + contractManagerSignatureImage + "isRetransmit"
328                     + isRetransmit + "Environment" + environment + "retransmitItems" + retransmitItems);
329         }
330         if (LOG.isDebugEnabled()) {
331             LOG.debug("createPdf() started for po number " + po.getPurapDocumentIdentifier().toString());
332         }
333 
334         // These have to be set because they are used by the onOpenDocument() and onStartPage() methods.
335         this.campusName = campusName;
336         this.po = po;
337         this.logoImage = logoImage;
338         this.environment = environment;
339         // Code has been changed to get the locale dynamically
340         NumberFormat numberFormat = NumberFormat.getCurrencyInstance();
341         Collection errors = new ArrayList();
342 
343         // Date format pattern: MM-dd-yyyy
344         SimpleDateFormat sdf = new SimpleDateFormat(RiceConstants.SIMPLE_DATE_FORMAT_FOR_DATE, Locale.getDefault());
345 
346         // This turns on the page events that handle the header and page numbers.
347         PurchaseOrderPdf events = new PurchaseOrderPdf().getPageEvents();
348         writer.setPageEvent(this); // Passing in "this" lets it know about the po, campusName, etc.
349 
350         document.open();
351 
352         PdfPCell cell;
353         Paragraph p = new Paragraph();
354 
355         // ***** Info table (vendor, address info) *****
356         LOG.debug("createPdf() info table started.");
357         float[] infoWidths = {0.50f, 0.50f};
358         PdfPTable infoTable = new PdfPTable(infoWidths);
359 
360         infoTable.setWidthPercentage(100);
361         infoTable.setHorizontalAlignment(Element.ALIGN_CENTER);
362         infoTable.setSplitLate(false);
363 
364         StringBuffer vendorInfo = new StringBuffer();
365         vendorInfo.append("\n");
366         if (StringUtils.isNotBlank(po.getVendorName())) {
367             vendorInfo.append("     " + po.getVendorName() + "\n");
368         }
369         if (StringUtils.isNotBlank(po.getVendorAttentionName())) {
370             vendorInfo.append("     ATTN: " + po.getVendorAttentionName() + "\n");
371         }
372 
373         if (StringUtils.isNotBlank(po.getVendorLine1Address())) {
374             vendorInfo.append("     " + po.getVendorLine1Address() + "\n");
375         }
376         if (StringUtils.isNotBlank(po.getVendorLine2Address())) {
377             vendorInfo.append("     " + po.getVendorLine2Address() + "\n");
378         }
379         if (StringUtils.isNotBlank(po.getVendorCityName())) {
380             vendorInfo.append("     " + po.getVendorCityName());
381         }
382         if (StringUtils.isNotBlank(po.getVendorStateCode())) {
383             vendorInfo.append(", " + po.getVendorStateCode());
384         }
385         if (StringUtils.isNotBlank(po.getVendorAddressInternationalProvinceName())) {
386             vendorInfo.append(", " + po.getVendorAddressInternationalProvinceName());
387         }
388         if (StringUtils.isNotBlank(po.getVendorPostalCode())) {
389             vendorInfo.append(" " + po.getVendorPostalCode() + "\n");
390         } else {
391             vendorInfo.append("\n");
392         }
393         if (!OLEConstants.COUNTRY_CODE_UNITED_STATES.equalsIgnoreCase(po.getVendorCountryCode()) && po.getVendorCountry() != null) {
394             vendorInfo.append("     " + po.getVendorCountry().getName() + "\n\n");
395         } else {
396             vendorInfo.append("\n\n");
397         }
398         p = new Paragraph();
399         p.add(new Chunk(" Vendor", ver_5_normal));
400         p.add(new Chunk(vendorInfo.toString(), cour_7_normal));
401         cell = new PdfPCell(p);
402         cell.setHorizontalAlignment(Element.ALIGN_LEFT);
403         infoTable.addCell(cell);
404 
405         StringBuffer shipToInfo = new StringBuffer();
406         shipToInfo.append("\n");
407 
408         if (po.getAddressToVendorIndicator()) { // use receiving address
409             shipToInfo.append("     " + po.getReceivingName() + "\n");
410             shipToInfo.append("     " + po.getReceivingLine1Address() + "\n");
411             if (StringUtils.isNotBlank(po.getReceivingLine2Address())) {
412                 shipToInfo.append("     " + po.getReceivingLine2Address() + "\n");
413             }
414             shipToInfo.append("     " + po.getReceivingCityName() + ", " + po.getReceivingStateCode() + " " + po.getReceivingPostalCode() + "\n");
415             if (StringUtils.isNotBlank(po.getReceivingCountryCode()) && !OLEConstants.COUNTRY_CODE_UNITED_STATES.equalsIgnoreCase(po.getReceivingCountryCode())) {
416                 if (StringUtils.isNotBlank(po.getReceivingCountryName())) {
417                     shipToInfo.append("     " + po.getReceivingCountryName() + "\n");
418                 }
419             }
420         } else { // use delivery address
421             shipToInfo.append("     " + po.getDeliveryToName() + "\n");
422             // extra space needed below to separate other text going on same PDF line
423             String deliveryBuildingName = po.getDeliveryBuildingName() + " ";
424             if (po.isDeliveryBuildingOtherIndicator()) {
425                 deliveryBuildingName = "";
426             }
427             shipToInfo.append("     " + deliveryBuildingName + "Room #" + po.getDeliveryBuildingRoomNumber() + "\n");
428             shipToInfo.append("     " + po.getDeliveryBuildingLine1Address() + "\n");
429             if (StringUtils.isNotBlank(po.getDeliveryBuildingLine2Address())) {
430                 shipToInfo.append("     " + po.getDeliveryBuildingLine2Address() + "\n");
431             }
432             shipToInfo.append("     " + po.getDeliveryCityName() + ", " + po.getDeliveryStateCode() + " " + po.getDeliveryPostalCode() + "\n");
433             if (StringUtils.isNotBlank(po.getDeliveryCountryCode()) && !OLEConstants.COUNTRY_CODE_UNITED_STATES.equalsIgnoreCase(po.getDeliveryCountryCode())) {
434                 if (StringUtils.isNotBlank(po.getDeliveryCountryName())) {
435                     shipToInfo.append("     " + po.getDeliveryCountryName() + "\n");
436                 }
437             }
438         }
439         // display deliveryToPhoneNumber disregard of whether receiving or delivery address is used
440         if (StringUtils.isNotBlank(po.getDeliveryToPhoneNumber())) {
441             shipToInfo.append("     " + po.getDeliveryToPhoneNumber());
442         }
443         /*
444         // display deliveryToPhoneNumber based on the parameter indicator, disregard of whether receiving or delivery address is used
445         boolean displayDeliveryPhoneNumber = SpringContext.getBean(ParameterService.class).getIndicatorParameter(PurchaseOrderDocument.class, PurapParameterConstants.DISPLAY_DELIVERY_PHONE_NUMBER_ON_PDF_IND);
446         if (displayDeliveryPhoneNumber && StringUtils.isNotBlank(po.getDeliveryToPhoneNumber())) {
447             shipToInfo.append("     " + po.getDeliveryToPhoneNumber());
448         }
449         */
450 
451         p = new Paragraph();
452         p.add(new Chunk("  Shipping Address", ver_5_normal));
453         p.add(new Chunk(shipToInfo.toString(), cour_7_normal));
454         cell = new PdfPCell(p);
455         infoTable.addCell(cell);
456 
457         p = new Paragraph();
458         p.add(new Chunk("  Shipping Terms\n", ver_5_normal));
459         if (po.getVendorShippingPaymentTerms() != null && po.getVendorShippingTitle() != null) {
460             p.add(new Chunk("     " + po.getVendorShippingPaymentTerms().getVendorShippingPaymentTermsDescription(), cour_7_normal));
461             p.add(new Chunk(" - " + po.getVendorShippingTitle().getVendorShippingTitleDescription(), cour_7_normal));
462         } else if (po.getVendorShippingPaymentTerms() != null && po.getVendorShippingTitle() == null) {
463             p.add(new Chunk("     " + po.getVendorShippingPaymentTerms().getVendorShippingPaymentTermsDescription(), cour_7_normal));
464         } else if (po.getVendorShippingTitle() != null && po.getVendorShippingPaymentTerms() == null) {
465             p.add(new Chunk("     " + po.getVendorShippingTitle().getVendorShippingTitleDescription(), cour_7_normal));
466         }
467         cell = new PdfPCell(p);
468         cell.setHorizontalAlignment(Element.ALIGN_LEFT);
469         infoTable.addCell(cell);
470 
471         p = new Paragraph();
472         p.add(new Chunk("  Payment Terms\n", ver_5_normal));
473         if (po.getVendorPaymentTerms() != null) {
474             p.add(new Chunk("     " + po.getVendorPaymentTerms().getVendorPaymentTermsDescription(), cour_7_normal));
475         }
476         cell = new PdfPCell(p);
477         cell.setHorizontalAlignment(Element.ALIGN_LEFT);
478         infoTable.addCell(cell);
479 
480         p = new Paragraph();
481         p.add(new Chunk("  Delivery Required By\n", ver_5_normal));
482 
483         if (po.getDeliveryRequiredDate() != null && po.getDeliveryRequiredDateReason() != null) {
484             p.add(new Chunk("     " + sdf.format(po.getDeliveryRequiredDate()), cour_7_normal));
485             p.add(new Chunk(" - " + po.getDeliveryRequiredDateReason().getDeliveryRequiredDateReasonDescription(), cour_7_normal));
486         } else if (po.getDeliveryRequiredDate() != null && po.getDeliveryRequiredDateReason() == null) {
487             p.add(new Chunk("     " + sdf.format(po.getDeliveryRequiredDate()), cour_7_normal));
488         } else if (po.getDeliveryRequiredDate() == null && po.getDeliveryRequiredDateReason() != null) {
489             p.add(new Chunk("     " + po.getDeliveryRequiredDateReason().getDeliveryRequiredDateReasonDescription(), cour_7_normal));
490         }
491         cell = new PdfPCell(p);
492         cell.setHorizontalAlignment(Element.ALIGN_LEFT);
493         infoTable.addCell(cell);
494 
495         p = new Paragraph();
496         p.add(new Chunk("  ", ver_5_normal));
497         cell = new PdfPCell(p);
498         cell.setHorizontalAlignment(Element.ALIGN_LEFT);
499         infoTable.addCell(cell);
500 
501         // Nested table for Order Date, etc.
502         float[] nestedInfoWidths = {0.50f, 0.50f};
503         PdfPTable nestedInfoTable = new PdfPTable(nestedInfoWidths);
504         nestedInfoTable.setSplitLate(false);
505 
506         p = new Paragraph();
507         p.add(new Chunk("  Order Date\n", ver_5_normal));
508 
509         String orderDate = "";
510         if (po.getPurchaseOrderInitialOpenTimestamp() != null) {
511             orderDate = sdf.format(po.getPurchaseOrderInitialOpenTimestamp());
512         } else {
513             // This date isn't set until the first time this document is printed, so will be null the first time; use today's date.
514             orderDate = sdf.format(getDateTimeService().getCurrentSqlDate());
515         }
516 
517         p.add(new Chunk("     " + orderDate, cour_7_normal));
518         cell = new PdfPCell(p);
519         cell.setHorizontalAlignment(Element.ALIGN_LEFT);
520         nestedInfoTable.addCell(cell);
521 
522         p = new Paragraph();
523         p.add(new Chunk("  Customer #\n", ver_5_normal));
524         if (po.getVendorCustomerNumber() != null) {
525             p.add(new Chunk("     " + po.getVendorCustomerNumber(), cour_7_normal));
526         }
527         cell = new PdfPCell(p);
528         cell.setHorizontalAlignment(Element.ALIGN_LEFT);
529         nestedInfoTable.addCell(cell);
530 
531         p = new Paragraph();
532         p.add(new Chunk("  Delivery Instructions\n", ver_5_normal));
533         if (StringUtils.isNotBlank(po.getDeliveryInstructionText())) {
534             p.add(new Chunk("     " + po.getDeliveryInstructionText(), cour_7_normal));
535         }
536         cell = new PdfPCell(p);
537         cell.setHorizontalAlignment(Element.ALIGN_LEFT);
538         nestedInfoTable.addCell(cell);
539 
540         p = new Paragraph();
541         p.add(new Chunk("  Contract ID\n", ver_5_normal));
542         if (po.getVendorContract() != null) {
543             p.add(new Chunk(po.getVendorContract().getVendorContractName(), cour_7_normal));
544         }
545         cell = new PdfPCell(p);
546         cell.setHorizontalAlignment(Element.ALIGN_LEFT);
547         nestedInfoTable.addCell(cell);
548 
549         // Add the nestedInfoTable to the infoTable
550         cell = new PdfPCell(nestedInfoTable);
551         cell.setHorizontalAlignment(Element.ALIGN_CENTER);
552         infoTable.addCell(cell);
553 
554         StringBuffer billToInfo = new StringBuffer();
555         billToInfo.append("\n");
556         billToInfo.append("     " + po.getBillingName() + "\n");
557         billToInfo.append("     " + po.getBillingLine1Address() + "\n");
558         if (po.getBillingLine2Address() != null) {
559             billToInfo.append("     " + po.getBillingLine2Address() + "\n");
560         }
561         billToInfo.append("     " + po.getBillingCityName() + ", " + po.getBillingStateCode() + " " + po.getBillingPostalCode() + "\n");
562         if (po.getBillingPhoneNumber() != null) {
563             billToInfo.append("     " + po.getBillingPhoneNumber());
564         }
565         if (po.getBillingEmailAddress() != null) {
566             billToInfo.append("\n     " + po.getBillingEmailAddress());
567         }
568         p = new Paragraph();
569         p.add(new Chunk("  Billing Address", ver_5_normal));
570         p.add(new Chunk("     " + billToInfo.toString(), cour_7_normal));
571         p.add(new Chunk("\n Invoice status inquiry: " + statusInquiryUrl, ver_6_normal));
572         cell = new PdfPCell(p);
573         cell.setHorizontalAlignment(Element.ALIGN_LEFT);
574         infoTable.addCell(cell);
575 
576         document.add(infoTable);
577 
578         PdfPTable notesStipulationsTable = new PdfPTable(1);
579         notesStipulationsTable.setWidthPercentage(100);
580         notesStipulationsTable.setSplitLate(false);
581 
582         p = new Paragraph();
583         p.add(new Chunk("  Vendor Note(s)\n", ver_5_normal));
584         if (po.getVendorNoteText() != null) {
585             p.add(new Chunk("     " + po.getVendorNoteText() + "\n", cour_7_normal));
586         }
587 
588         PdfPCell tableCell = new PdfPCell(p);
589         tableCell.setHorizontalAlignment(Element.ALIGN_LEFT);
590         tableCell.setVerticalAlignment(Element.ALIGN_TOP);
591 
592         notesStipulationsTable.addCell(tableCell);
593 
594         p = new Paragraph();
595         p.add(new Chunk("  Vendor Stipulations and Information\n", ver_5_normal));
596         if ((po.getPurchaseOrderBeginDate() != null) && (po.getPurchaseOrderEndDate() != null)) {
597             p.add(new Chunk("     Order in effect from " + sdf.format(po.getPurchaseOrderBeginDate()) + " to " + sdf.format(po.getPurchaseOrderEndDate()) + ".\n", cour_7_normal));
598 
599         }
600         Collection<PurchaseOrderVendorStipulation> vendorStipulationsList = po.getPurchaseOrderVendorStipulations();
601         if (vendorStipulationsList.size() > 0) {
602             StringBuffer vendorStipulations = new StringBuffer();
603             for (PurchaseOrderVendorStipulation povs : vendorStipulationsList) {
604                 vendorStipulations.append("     " + povs.getVendorStipulationDescription() + "\n");
605             }
606             p.add(new Chunk("     " + vendorStipulations.toString(), cour_7_normal));
607         }
608 
609         tableCell = new PdfPCell(p);
610         tableCell.setHorizontalAlignment(Element.ALIGN_LEFT);
611         tableCell.setVerticalAlignment(Element.ALIGN_TOP);
612         notesStipulationsTable.addCell(tableCell);
613 
614         document.add(notesStipulationsTable);
615 
616         // ***** Items table *****
617         LOG.debug("createPdf() items table started.");
618 
619         float[] itemsWidths = {0.07f, 0.1f, 0.07f, 0.25f, 0.25f, 0.10f, 0.10f};
620 
621         if (!po.isUseTaxIndicator()) {
622             itemsWidths = ArrayUtils.add(itemsWidths, 0.14f);
623             itemsWidths = ArrayUtils.add(itemsWidths, 0.15f);
624         }
625 
626         PdfPTable itemsTable = new PdfPTable(itemsWidths.length);
627 
628         // itemsTable.setCellsFitPage(false); With this set to true a large cell will
629         // skip to the next page. The default Table behaviour seems to be what we want:
630         // start the large cell on the same page and continue it to the next.
631         itemsTable.setWidthPercentage(100);
632         itemsTable.setWidths(itemsWidths);
633         itemsTable.setSplitLate(false);
634 
635         tableCell = new PdfPCell(new Paragraph("Item\nNo.", ver_5_normal));
636         tableCell.setHorizontalAlignment(Element.ALIGN_CENTER);
637         itemsTable.addCell(tableCell);
638         tableCell = new PdfPCell(new Paragraph("Quantity", ver_5_normal));
639         tableCell.setHorizontalAlignment(Element.ALIGN_CENTER);
640         itemsTable.addCell(tableCell);
641         tableCell = new PdfPCell(new Paragraph("UOM", ver_5_normal));
642         tableCell.setHorizontalAlignment(Element.ALIGN_CENTER);
643         itemsTable.addCell(tableCell);
644         tableCell = new PdfPCell(new Paragraph("Description", ver_5_normal));
645         tableCell.setHorizontalAlignment(Element.ALIGN_CENTER);
646         itemsTable.addCell(tableCell);
647         tableCell = new PdfPCell(new Paragraph("Special Instructions", ver_5_normal));
648         tableCell.setHorizontalAlignment(Element.ALIGN_CENTER);
649         itemsTable.addCell(tableCell);
650         tableCell = new PdfPCell(new Paragraph("Unit Cost", ver_5_normal));
651         tableCell.setHorizontalAlignment(Element.ALIGN_CENTER);
652         itemsTable.addCell(tableCell);
653         tableCell = new PdfPCell(new Paragraph("Extended Cost", ver_5_normal));
654         tableCell.setHorizontalAlignment(Element.ALIGN_CENTER);
655         itemsTable.addCell(tableCell);
656 
657         if (!po.isUseTaxIndicator()) {
658             tableCell = new PdfPCell(new Paragraph("Tax Amount", ver_5_normal));
659             tableCell.setHorizontalAlignment(Element.ALIGN_CENTER);
660             itemsTable.addCell(tableCell);
661 
662             tableCell = new PdfPCell(new Paragraph("Total Amount", ver_5_normal));
663             tableCell.setHorizontalAlignment(Element.ALIGN_CENTER);
664             itemsTable.addCell(tableCell);
665         }
666 
667         Collection<PurchaseOrderItem> itemsList = new ArrayList();
668         if (isRetransmit) {
669             itemsList = retransmitItems;
670         } else {
671             itemsList = po.getItems();
672         }
673         for (PurchaseOrderItem poi : itemsList) {
674             if ((poi.getItemType() != null) && (poi.getItemType().isLineItemIndicator() || poi.getItemType().getItemTypeCode().equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_SHIP_AND_HAND_CODE) || poi.getItemType().getItemTypeCode().equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_FREIGHT_CODE) || poi.getItemType().getItemTypeCode().equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_ORDER_DISCOUNT_CODE) || poi.getItemType().getItemTypeCode().equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_TRADE_IN_CODE)) && lineItemDisplaysOnPdf(poi)) {
675                 boolean noteFlag  = true;
676                 String description = (poi.getItemCatalogNumber() != null) ? poi.getItemCatalogNumber().trim() + " - " : "";
677                 String vendorNotes = "";
678                 if (poi.getNotes().size() > 0) {
679                     for(OleNotes oleNotes : poi.getNotes()){
680                         String note = getNoteType(oleNotes.getNoteTypeId());
681                         if ((note != null && note.equals(OLEConstants.VENDOR_TYPE)) && noteFlag) {
682                             vendorNotes = oleNotes.getNote();
683                             noteFlag = false;
684                         }
685                     }
686                 }
687 
688                 description = description + ((poi.getItemDescription() != null) ? poi.getItemDescription().trim() : "");
689                 if (StringUtils.isNotBlank(description)) {
690                     if (poi.getItemType().getItemTypeCode().equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_ORDER_DISCOUNT_CODE) || poi.getItemType().getItemTypeCode().equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_TRADE_IN_CODE) || poi.getItemType().getItemTypeCode().equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_FREIGHT_CODE) || poi.getItemType().getItemTypeCode().equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_SHIP_AND_HAND_CODE)) {
691                         // If this is a full order discount or trade-in item, we add the item type description to the description.
692                         description = poi.getItemType().getItemTypeDescription() + " - " + description;
693                     }
694                 }
695 
696                 // Above the line item types items display the line number; other types don't.
697                 if (poi.getItemType().isLineItemIndicator()) {
698                     tableCell = new PdfPCell(new Paragraph(poi.getItemLineNumber().toString(), cour_7_normal));
699                 } else {
700                     tableCell = new PdfPCell(new Paragraph(" ", cour_7_normal));
701                 }
702                 tableCell.setHorizontalAlignment(Element.ALIGN_CENTER);
703                 itemsTable.addCell(tableCell);
704                 String quantity = (poi.getItemQuantity() != null) ? poi.getItemQuantity().toString() : " ";
705                 tableCell = new PdfPCell(new Paragraph(quantity, cour_7_normal));
706                 tableCell.setHorizontalAlignment(Element.ALIGN_CENTER);
707                 tableCell.setNoWrap(true);
708                 itemsTable.addCell(tableCell);
709                 tableCell = new PdfPCell(new Paragraph(poi.getItemUnitOfMeasureCode(), cour_7_normal));
710                 tableCell.setHorizontalAlignment(Element.ALIGN_CENTER);
711                 itemsTable.addCell(tableCell);
712 
713                 tableCell = new PdfPCell(new Paragraph(" " + description, cour_7_normal));
714                 tableCell.setHorizontalAlignment(Element.ALIGN_LEFT);
715                 itemsTable.addCell(tableCell);
716                 tableCell = new PdfPCell(new Paragraph(" " + vendorNotes, cour_7_normal));
717                 tableCell.setHorizontalAlignment(Element.ALIGN_LEFT);
718                 itemsTable.addCell(tableCell);
719                 String unitPrice = poi.getItemUnitPrice().setScale(2, BigDecimal.ROUND_HALF_UP).toString();
720                 tableCell = new PdfPCell(new Paragraph(unitPrice + " ", cour_7_normal));
721                 tableCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
722                 tableCell.setNoWrap(true);
723                 itemsTable.addCell(tableCell);
724                 tableCell = new PdfPCell(new Paragraph(numberFormat.format(poi.getExtendedPrice()) + " ", cour_7_normal));
725                 tableCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
726                 tableCell.setNoWrap(true);
727                 itemsTable.addCell(tableCell);
728 
729                 if (!po.isUseTaxIndicator()) {
730                     KualiDecimal taxAmount = poi.getItemTaxAmount();
731                     taxAmount = taxAmount == null ? KualiDecimal.ZERO : taxAmount;
732                     tableCell = new PdfPCell(new Paragraph(numberFormat.format(taxAmount) + " ", cour_7_normal));
733                     tableCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
734                     tableCell.setNoWrap(true);
735                     itemsTable.addCell(tableCell);
736 
737                     tableCell = new PdfPCell(new Paragraph(numberFormat.format(poi.getTotalAmount()) + " ", cour_7_normal));
738                     tableCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
739                     tableCell.setNoWrap(true);
740                     itemsTable.addCell(tableCell);
741                 }
742 
743             }
744         }
745         // Blank line before totals
746         itemsTable.addCell(" ");
747         itemsTable.addCell(" ");
748         itemsTable.addCell(" ");
749         itemsTable.addCell(" ");
750         itemsTable.addCell(" ");
751         itemsTable.addCell(" ");
752 
753         if (!po.isUseTaxIndicator()) {
754             itemsTable.addCell(" ");
755             itemsTable.addCell(" ");
756         }
757 
758         //Next Line
759         if (!po.isUseTaxIndicator()) {
760 
761             //Print Total Prior to Tax
762             itemsTable.addCell(" ");
763             itemsTable.addCell(" ");
764             itemsTable.addCell(" ");
765             itemsTable.addCell(" ");
766             itemsTable.addCell(" ");
767 
768             tableCell = new PdfPCell(new Paragraph("Total Prior to Tax: ", ver_10_normal));
769             tableCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
770             itemsTable.addCell(tableCell);
771             itemsTable.addCell(" ");
772             KualiDecimal totalDollarAmount = new KualiDecimal(BigDecimal.ZERO);
773             if (po instanceof PurchaseOrderRetransmitDocument) {
774                 totalDollarAmount = ((PurchaseOrderRetransmitDocument) po).getTotalPreTaxDollarAmountForRetransmit();
775             } else {
776                 totalDollarAmount = po.getTotalPreTaxDollarAmount();
777             }
778             tableCell = new PdfPCell(new Paragraph(numberFormat.format(totalDollarAmount) + " ", cour_7_normal));
779             tableCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
780             tableCell.setNoWrap(true);
781             itemsTable.addCell(tableCell);
782 
783             //Print Total Tax
784             itemsTable.addCell(" ");
785             itemsTable.addCell(" ");
786             itemsTable.addCell(" ");
787             itemsTable.addCell(" ");
788             itemsTable.addCell(" ");
789             itemsTable.addCell(" ");
790 
791             tableCell = new PdfPCell(new Paragraph("Total Tax: ", ver_10_normal));
792             tableCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
793             itemsTable.addCell(tableCell);
794             itemsTable.addCell(" ");
795             totalDollarAmount = new KualiDecimal(BigDecimal.ZERO);
796             if (po instanceof PurchaseOrderRetransmitDocument) {
797                 totalDollarAmount = ((PurchaseOrderRetransmitDocument) po).getTotalTaxDollarAmountForRetransmit();
798             } else {
799                 totalDollarAmount = po.getTotalTaxAmount();
800             }
801             tableCell = new PdfPCell(new Paragraph(numberFormat.format(totalDollarAmount) + " ", cour_7_normal));
802             tableCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
803             tableCell.setNoWrap(true);
804             itemsTable.addCell(tableCell);
805 
806         }
807 
808         // Totals line; first 5 cols empty
809         itemsTable.addCell(" ");
810         itemsTable.addCell(" ");
811         itemsTable.addCell(" ");
812         itemsTable.addCell(" ");
813 
814 
815         if (!po.isUseTaxIndicator()) {
816             itemsTable.addCell(" ");
817             itemsTable.addCell(" ");
818         }
819 
820         tableCell = new PdfPCell(new Paragraph("Total order amount: ", ver_10_normal));
821         tableCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
822         itemsTable.addCell(tableCell);
823         itemsTable.addCell(" ");
824         KualiDecimal totalDollarAmount = new KualiDecimal(BigDecimal.ZERO);
825         if (po instanceof PurchaseOrderRetransmitDocument) {
826             totalDollarAmount = ((PurchaseOrderRetransmitDocument) po).getTotalDollarAmountForRetransmit();
827         } else {
828             totalDollarAmount = po.getTotalDollarAmount();
829         }
830         tableCell = new PdfPCell(new Paragraph(numberFormat.format(totalDollarAmount) + " ", cour_7_normal));
831         tableCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
832         tableCell.setNoWrap(true);
833         itemsTable.addCell(tableCell);
834         // Blank line after totals
835         itemsTable.addCell(" ");
836         itemsTable.addCell(" ");
837         itemsTable.addCell(" ");
838         itemsTable.addCell(" ");
839         itemsTable.addCell(" ");
840         itemsTable.addCell(" ");
841 
842         if (!po.isUseTaxIndicator()) {
843             itemsTable.addCell(" ");
844             itemsTable.addCell(" ");
845         }
846 
847         document.add(itemsTable);
848 
849         // Contract language.
850         LOG.debug("createPdf() contract language started.");
851         document.add(new Paragraph(contractLanguage, ver_6_normal));
852         document.add(new Paragraph("\n", ver_6_normal));
853 
854         // ***** Signatures table *****
855         LOG.debug("createPdf() signatures table started.");
856         float[] signaturesWidths = {0.30f, 0.70f};
857         PdfPTable signaturesTable = new PdfPTable(signaturesWidths);
858         signaturesTable.setWidthPercentage(100);
859         signaturesTable.setHorizontalAlignment(Element.ALIGN_CENTER);
860         signaturesTable.setSplitLate(false);
861 
862         // Director signature and "for more info" line; only on APOs
863         if (po.getPurchaseOrderAutomaticIndicator()) {
864             // Empty cell.
865             cell = new PdfPCell(new Paragraph(" ", cour_7_normal));
866             cell.setBorderWidth(0);
867             signaturesTable.addCell(cell);
868 
869             //boolean displayRequestorEmail = true; //SpringContext.getBean(ParameterService.class).getIndicatorParameter(PurchaseOrderDocument.class, PurapParameterConstants.DISPLAY_REQUESTOR_EMAIL_ADDRESS_ON_PDF_IND);
870             if (StringUtils.isBlank(po.getInstitutionContactName()) || StringUtils.isBlank(po.getInstitutionContactPhoneNumber()) || StringUtils.isBlank(po.getInstitutionContactEmailAddress())) {
871                 //String emailAddress = displayRequestorEmail ? "  " + po.getRequestorPersonEmailAddress() : "";
872                 p = new Paragraph("For more information contact: " + po.getRequestorPersonName() + "  ", cour_7_normal);
873                 if(StringUtils.isNotBlank(po.getRequestorPersonPhoneNumber())) {
874                     p.add(po.getRequestorPersonPhoneNumber() + "  ");
875                 }
876                 if(StringUtils.isNotBlank(po.getRequestorPersonEmailAddress())) {
877                   p.add(po.getRequestorPersonEmailAddress());
878                 }
879             } else {
880                 //String emailAddress = displayRequestorEmail ? "  " + po.getInstitutionContactEmailAddress() : "";
881                 p = new Paragraph("For more information contact: " + po.getInstitutionContactName() + "  ", cour_7_normal);
882                 if(StringUtils.isNotBlank(po.getInstitutionContactPhoneNumber())) {
883                     p.add(po.getInstitutionContactPhoneNumber() + "  ");
884                 }
885                 if(StringUtils.isNotBlank(po.getInstitutionContactEmailAddress())) {
886                     p.add(po.getInstitutionContactEmailAddress());
887                 }
888             }
889             cell = new PdfPCell(p);
890             cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
891             cell.setVerticalAlignment(Element.ALIGN_CENTER);
892             cell.setBorderWidth(0);
893             signaturesTable.addCell(cell);
894 
895             Image directorSignature = null;
896             if (StringUtils.isNotBlank(directorSignatureImage)) {
897                 try {
898                     directorSignature = Image.getInstance(directorSignatureImage);
899                 } catch (FileNotFoundException e) {
900                     LOG.info("The director signature image [" + directorSignatureImage + "] is not available.  Defaulting to the default image.");
901                 }
902             }
903 
904             if (directorSignature == null) {
905                 // an empty cell if the contract manager signature image is not available.
906                 cell = new PdfPCell();
907             } else {
908                 directorSignature.scalePercent(30, 30);
909                 cell = new PdfPCell(directorSignature, false);
910             }
911 
912             cell.setHorizontalAlignment(Element.ALIGN_CENTER);
913             cell.setVerticalAlignment(Element.ALIGN_BOTTOM);
914             cell.setBorderWidth(0);
915             signaturesTable.addCell(cell);
916 
917             // Empty cell.
918             cell = new PdfPCell(new Paragraph(" ", cour_7_normal));
919             cell.setBorderWidth(0);
920             signaturesTable.addCell(cell);
921         }
922 
923         // Director name and title; on every pdf.
924         p = new Paragraph();
925         if (LOG.isDebugEnabled()) {
926             LOG.debug("createPdf() directorName parameter: " + directorName);
927         }
928         if (po.getPurchaseOrderAutomaticIndicator()) { // The signature is on the pdf; use small font.
929             p.add(new Chunk(directorName, ver_6_normal));
930         } else { // The signature isn't on the pdf; use larger font.
931             p.add(new Chunk(directorName, ver_10_normal));
932         }
933         p.add(new Chunk("\n" + directorTitle, ver_4_normal));
934         cell = new PdfPCell(p);
935         cell.setHorizontalAlignment(Element.ALIGN_CENTER);
936         cell.setVerticalAlignment(Element.ALIGN_TOP);
937         cell.setBorderWidth(0);
938         signaturesTable.addCell(cell);
939 
940         // Contract manager signature, name and phone; only on non-APOs
941         if (!po.getPurchaseOrderAutomaticIndicator()) {
942 
943             Image contractManagerSignature = null;
944             if (StringUtils.isNotBlank(contractManagerSignatureImage)) {
945                 try {
946                     contractManagerSignature = Image.getInstance(contractManagerSignatureImage);
947                 } catch (FileNotFoundException e) {
948                     LOG.info("The contract manager image [" + contractManagerSignatureImage + "] is not available.  Defaulting to the default image.");
949                 }
950             }
951 
952             if (contractManagerSignature == null) {
953                 // an empty cell if the contract manager signature image is not available.
954                 cell = new PdfPCell();
955             } else {
956                 contractManagerSignature.scalePercent(15, 15);
957                 cell = new PdfPCell(contractManagerSignature, false);
958             }
959             cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
960             cell.setVerticalAlignment(Element.ALIGN_BOTTOM);
961             cell.setBorderWidth(0);
962             signaturesTable.addCell(cell);
963 
964             // Empty cell.
965             cell = new PdfPCell(new Paragraph(" ", ver_10_normal));
966             cell.setBorderWidth(0);
967             signaturesTable.addCell(cell);
968 
969             cell = new PdfPCell(new Paragraph(po.getContractManager().getContractManagerName() + "  " + po.getContractManager().getContractManagerPhoneNumber(), cour_7_normal));
970             cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
971             cell.setVerticalAlignment(Element.ALIGN_TOP);
972             cell.setBorderWidth(0);
973             signaturesTable.addCell(cell);
974         } else { // Empty cell.
975             cell = new PdfPCell(new Paragraph(" ", ver_10_normal));
976             cell.setBorderWidth(0);
977             signaturesTable.addCell(cell);
978         }
979         document.add(signaturesTable);
980 
981         document.close();
982         LOG.debug("createPdf()pdf document closed.");
983     } // End of createPdf()
984 
985     /**
986      * Determines whether the item should be displayed on the pdf.
987      *
988      * @param poi The PurchaseOrderItem to be determined whether it should be displayed on the pdf.
989      * @return boolean true if it should be displayed on the pdf.
990      */
991     private boolean lineItemDisplaysOnPdf(PurchaseOrderItem poi) {
992         LOG.debug("lineItemDisplaysOnPdf() started");
993 
994         // Shipping, freight, full order discount and trade in items.
995         if ((poi.getItemType() != null) && (poi.getItemType().getItemTypeCode().equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_SHIP_AND_HAND_CODE) || poi.getItemType().getItemTypeCode().equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_FREIGHT_CODE) || poi.getItemType().getItemTypeCode().equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_ORDER_DISCOUNT_CODE) || poi.getItemType().getItemTypeCode().equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_TRADE_IN_CODE))) {
996 
997             // If the unit price is not null and either the unit price > 0 or the item type is full order discount or trade in,
998             // we'll display this line item on pdf.
999             if ((poi.getItemUnitPrice() != null) && ((poi.getItemUnitPrice().compareTo(zero.bigDecimalValue()) == 1) || (poi.getItemType().getItemTypeCode().equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_ORDER_DISCOUNT_CODE)) || (poi.getItemType().getItemTypeCode().equals(PurapConstants.ItemTypeCodes.ITEM_TYPE_TRADE_IN_CODE)))) {
1000                 if (LOG.isDebugEnabled()) {
1001                     LOG.debug("lineItemDisplaysOnPdf() Item type is " + poi.getItemType().getItemTypeCode() + ". Unit price is " + poi.getItemUnitPrice() + ". Display on pdf.");
1002                 }
1003                 return true;
1004             }
1005             if (LOG.isDebugEnabled()) {
1006                 LOG.debug("lineItemDisplaysOnPdf() Item type is " + poi.getItemType().getItemTypeCode() + ". Unit price is " + poi.getItemUnitPrice() + ". Don't display on pdf.");
1007             }
1008             return false;
1009         } else if ((poi.getItemType() != null) && poi.getItemType().isLineItemIndicator()) {
1010             if (poi.getItemQuantity() == null && poi.getItemUnitPrice() == null) {
1011                 if (LOG.isDebugEnabled()) {
1012                     LOG.debug("lineItemDisplaysOnPdf() Item type is " + poi.getItemType().getItemTypeCode() + " OrderQuantity and unit price are both null. Display on pdf.");
1013                 }
1014                 return true;
1015             }
1016             if ((poi.getItemType().isAmountBasedGeneralLedgerIndicator() && ((poi.getItemUnitPrice() != null) && (poi.getItemUnitPrice().compareTo(zero.bigDecimalValue()) >= 0))) || (((poi.getItemType().isQuantityBasedGeneralLedgerIndicator()) && (poi.getItemQuantity().isGreaterThan(zero))) && (poi.getItemUnitPrice() != null))) {
1017                 if (LOG.isDebugEnabled()) {
1018                     LOG.debug("lineItemDisplaysOnPdf() Item type is " + poi.getItemType().getItemTypeCode() + " OrderQuantity is " + poi.getItemQuantity() + ". Unit price is " + poi.getItemUnitPrice() + ". Display on pdf.");
1019                 }
1020                 return true;
1021             } else {
1022                 if (LOG.isDebugEnabled()) {
1023                     LOG.debug("lineItemDisplaysOnPdf() Item type is " + poi.getItemType().getItemTypeCode() + " and item order quantity is " + poi.getItemQuantity() + " and item unit price is " + poi.getItemUnitPrice() + ". Don't display on pdf.");
1024                 }
1025             }
1026         }
1027         return false;
1028     }
1029 
1030 
1031     public String getImageLocations(String existingLocation) {
1032         LOG.info("In Get Image Location");
1033         String filesPathAndName = getClass().getClassLoader().getResource("/").getPath();
1034         filesPathAndName = filesPathAndName.replace("WEB-INF/classes/", "static/images/");
1035         try {
1036             String[] imageNameList = existingLocation.split("/");
1037             LOG.info("File Name" + imageNameList[(imageNameList.length - 1)]);
1038             filesPathAndName = filesPathAndName + (imageNameList[(imageNameList.length - 1)]);
1039         } catch (Exception e) {
1040             LOG.info("Exception when getting the Image Location" + e.getMessage());
1041         }
1042         return filesPathAndName;
1043     }
1044 
1045     public String getNoteType(Integer noteTypeId) {
1046         Map criteriaMap = new HashMap();
1047         criteriaMap.put(OLEConstants.NOTE_ID, noteTypeId);
1048         OleNoteType oleNoteType = SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(OleNoteType.class, criteriaMap);
1049         if (oleNoteType != null) {
1050             return oleNoteType.getNoteType();
1051         }
1052         return "";
1053     }
1054 
1055 }