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