001/*
002 * Copyright 2007-2008 The Kuali Foundation
003 * 
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * 
008 * http://www.opensource.org/licenses/ecl2.php
009 * 
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.ole.module.purap.pdf;
017
018import com.lowagie.text.*;
019import com.lowagie.text.pdf.BaseFont;
020import com.lowagie.text.pdf.PdfPCell;
021import com.lowagie.text.pdf.PdfPTable;
022import com.lowagie.text.pdf.PdfWriter;
023import org.apache.commons.lang.StringUtils;
024import org.apache.commons.logging.Log;
025import org.apache.commons.logging.LogFactory;
026import org.kuali.ole.module.purap.document.BulkReceivingDocument;
027import org.kuali.ole.sys.OLEConstants;
028
029import java.io.ByteArrayOutputStream;
030
031/**
032 * Base class to handle pdf for bulk receiving ticket.
033 */
034public class BulkReceivingPdf extends PurapPdf {
035
036    private static Log LOG = LogFactory.getLog(BulkReceivingPdf.class);
037    private BulkReceivingDocument blkRecDoc;
038
039    public BulkReceivingPdf() {
040        super();
041    }
042
043    /**
044     * Overrides the method in PdfPageEventHelper from itext to create and set the headerTable and set its logo image if
045     * there is a logoImage to be used, creates and sets the nestedHeaderTable and its content.
046     *
047     * @param writer   The PdfWriter for this document.
048     * @param document The document.
049     * @see com.lowagie.text.pdf.PdfPageEventHelper#onOpenDocument(com.lowagie.text.pdf.PdfWriter, com.lowagie.text.Document)
050     */
051    public void onOpenDocument(PdfWriter writer, Document document) {
052        try {
053
054            loadHeaderTable();
055
056            // initialization of the template
057            tpl = writer.getDirectContent().createTemplate(100, 100);
058
059            // initialization of the font
060            helv = BaseFont.createFont("Helvetica", BaseFont.WINANSI, false);
061
062        } catch (Exception e) {
063            throw new ExceptionConverter(e);
064        }
065    }
066
067    private void loadHeaderTable()
068            throws Exception {
069
070        float[] headerWidths = {0.20f, 0.80f};
071
072        headerTable = new PdfPTable(headerWidths);
073        headerTable.setWidthPercentage(100);
074        headerTable.setHorizontalAlignment(Element.ALIGN_CENTER);
075        headerTable.setSplitLate(false);
076        headerTable.getDefaultCell().setBorderWidth(0);
077        headerTable.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);
078        headerTable.getDefaultCell().setVerticalAlignment(Element.ALIGN_CENTER);
079
080        /**
081         * Logo display
082         */
083        if (StringUtils.isNotBlank(logoImage)) {
084            logo = Image.getInstance(logoImage);
085            logo.scalePercent(3, 3);
086            headerTable.addCell(new Phrase(new Chunk(logo, 0, 0)));
087        } else {
088            headerTable.addCell(new Phrase(new Chunk("")));
089        }
090
091        /**
092         * Nested table in tableHeader to display title and doc number
093         */
094        float[] nestedHeaderWidths = {0.70f, 0.30f};
095        nestedHeaderTable = new PdfPTable(nestedHeaderWidths);
096        nestedHeaderTable.setSplitLate(false);
097        PdfPCell cell;
098
099        /**
100         * Title
101         */
102        cell = new PdfPCell(new Paragraph("RECEIVING TICKET", ver_15_normal));
103        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
104        cell.setBorderWidth(0);
105        nestedHeaderTable.addCell(cell);
106
107        /**
108         * Doc Number
109         */
110        Paragraph p = new Paragraph();
111        p.add(new Chunk("Doc Number: ", ver_11_normal));
112        p.add(new Chunk(blkRecDoc.getDocumentNumber().toString(), cour_10_normal));
113        cell = new PdfPCell(p);
114        cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
115        cell.setBorderWidth(0);
116        nestedHeaderTable.addCell(cell);
117
118        // Add the nestedHeaderTable to the headerTable
119        cell = new PdfPCell(nestedHeaderTable);
120        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
121        cell.setBorderWidth(0);
122        headerTable.addCell(cell);
123    }
124
125    /**
126     * Gets a PageEvents object.
127     *
128     * @return a new PageEvents object
129     */
130    public BulkReceivingPdf getPageEvents() {
131        LOG.debug("getPageEvents() started.");
132        return new BulkReceivingPdf();
133    }
134
135    /**
136     * Generates the pdf document based on the data in the given BulkReceivingDocument
137     *
138     * @param blkRecDoc  The BulkReceivingDocument to be used to generate the pdf.
139     * @param byteStream The ByteArrayOutputStream where the pdf document will be written to.
140     */
141    public void generatePdf(BulkReceivingDocument blkRecDoc,
142                            ByteArrayOutputStream byteStream,
143                            String logoImage,
144                            String environment) {
145
146        if (LOG.isDebugEnabled()) {
147            LOG.debug("generatePdf() started for bulk receiving - " + blkRecDoc.getDocumentNumber());
148        }
149
150        Document document = null;
151
152        try {
153
154            document = this.getDocument(9, 9, 70, 36);
155            PdfWriter writer = PdfWriter.getInstance(document, byteStream);
156
157            //These have to be set because they are used by the onOpenDocument() and onStartPage() methods.
158            this.logoImage = logoImage;
159            this.blkRecDoc = blkRecDoc;
160            this.environment = environment;
161
162            // This turns on the page events that handle the header and page numbers.
163            BulkReceivingPdf events = new BulkReceivingPdf().getPageEvents();
164            writer.setPageEvent(this);
165
166            document.open();
167
168            document.add(createVendorAndDeliveryDetailsTable());
169            document.add(new Paragraph("\nAdditional Details\n  ", ver_8_bold));
170            document.add(createAdditionalDetailsTable());
171
172            document.close();
173
174        } catch (Exception de) {
175            throw new RuntimeException("Document Exception when trying to save a Bulk Receiving PDF", de);
176        } finally {
177            if (document != null && document.isOpen()) {
178                document.close();
179            }
180        }
181        if (LOG.isDebugEnabled()) {
182            LOG.debug("generatePdf() completed for bulk receiving - " + blkRecDoc.getDocumentNumber());
183        }
184    }
185
186    private PdfPTable createVendorAndDeliveryDetailsTable() {
187
188        PdfPCell cell;
189        Paragraph p = new Paragraph();
190
191        float[] infoWidths = {0.50f, 0.50f};
192        PdfPTable infoTable = new PdfPTable(infoWidths);
193
194        infoTable.setWidthPercentage(100);
195        infoTable.setHorizontalAlignment(Element.ALIGN_CENTER);
196        infoTable.setSplitLate(false);
197
198        infoTable.addCell(getPDFCell("Vendor", getFormattedVendorAddress()));
199        infoTable.addCell(getPDFCell("Delivery", getFormattedDeliveryAddress()));
200        infoTable.addCell(getPDFCell("Reference Number\n", blkRecDoc.getShipmentReferenceNumber()));
201
202        if (blkRecDoc.getCarrier() != null) {
203            infoTable.addCell(getPDFCell("Carrier\n", blkRecDoc.getCarrier().getCarrierDescription()));
204        } else {
205            infoTable.addCell(getPDFCell("Carrier\n", StringUtils.EMPTY));
206        }
207
208        infoTable.addCell(getPDFCell("Tracking/Pro Number\n", blkRecDoc.getTrackingNumber()));
209
210        if (blkRecDoc.getPurchaseOrderIdentifier() != null) {
211            infoTable.addCell(getPDFCell("PO\n", blkRecDoc.getPurchaseOrderIdentifier().toString()));
212        } else {
213            infoTable.addCell(getPDFCell("PO\n", StringUtils.EMPTY));
214        }
215
216        infoTable.addCell(getPDFCell("# of Pieces\n", "" + blkRecDoc.getNoOfCartons()));
217        infoTable.addCell(getPDFCell("Shipment Received Date\n", blkRecDoc.getShipmentReceivedDate().toString()));
218
219        if (blkRecDoc.getShipmentWeight() != null) {
220            infoTable.addCell(getPDFCell("Weight\n", blkRecDoc.getShipmentWeight().toString()));
221        } else {
222            infoTable.addCell(getPDFCell("Weight\n", StringUtils.EMPTY));
223        }
224
225        infoTable.addCell(getPDFCell("\n", StringUtils.EMPTY));
226
227        return infoTable;
228    }
229
230    private PdfPCell getPDFCell(String fieldTitle,
231                                String fieldValue) {
232
233        Paragraph p = new Paragraph();
234        p.add(new Chunk("  " + fieldTitle, ver_5_normal));
235
236        if (StringUtils.isNotEmpty(fieldValue)) {
237            p.add(new Chunk("     " + fieldValue, cour_10_normal));
238        } else {
239            p.add(new Chunk("  "));
240        }
241
242        PdfPCell cell = new PdfPCell(p);
243        cell.setHorizontalAlignment(Element.ALIGN_LEFT);
244
245        return cell;
246    }
247
248    private String getFormattedVendorAddress() {
249
250        StringBuffer vendorInfo = new StringBuffer();
251        vendorInfo.append("\n");
252
253        /**
254         * GoodsDeliveredVendorNumber will be null if it the doc is not for a specific PO 
255         */
256        if (blkRecDoc.getGoodsDeliveredVendorNumber() == null ||
257                blkRecDoc.getGoodsDeliveredVendorNumber().equals(blkRecDoc.getVendorNumber())) {
258
259            if (StringUtils.isNotBlank(blkRecDoc.getVendorName())) {
260                vendorInfo.append("     " + blkRecDoc.getVendorName() + "\n");
261            }
262
263            if (StringUtils.isNotBlank(blkRecDoc.getVendorLine1Address())) {
264                vendorInfo.append("     " + blkRecDoc.getVendorLine1Address() + "\n");
265            }
266
267            if (StringUtils.isNotBlank(blkRecDoc.getVendorLine2Address())) {
268                vendorInfo.append("     " + blkRecDoc.getVendorLine2Address() + "\n");
269            }
270
271            if (StringUtils.isNotBlank(blkRecDoc.getVendorCityName())) {
272                vendorInfo.append("     " + blkRecDoc.getVendorCityName());
273            }
274
275            if (StringUtils.isNotBlank(blkRecDoc.getVendorStateCode())) {
276                vendorInfo.append(", " + blkRecDoc.getVendorStateCode());
277            }
278
279            if (StringUtils.isNotBlank(blkRecDoc.getVendorAddressInternationalProvinceName())) {
280                vendorInfo.append(", " + blkRecDoc.getVendorAddressInternationalProvinceName());
281            }
282
283            if (StringUtils.isNotBlank(blkRecDoc.getVendorPostalCode())) {
284                vendorInfo.append(" " + blkRecDoc.getVendorPostalCode() + "\n");
285            } else {
286                vendorInfo.append("\n");
287            }
288
289            if (!OLEConstants.COUNTRY_CODE_UNITED_STATES.equalsIgnoreCase(blkRecDoc.getVendorCountryCode()) && blkRecDoc.getVendorCountry() != null) {
290                vendorInfo.append("     " + blkRecDoc.getVendorCountry().getName() + "\n\n");
291            } else {
292                vendorInfo.append("\n\n");
293            }
294
295        } else {
296
297            if (StringUtils.isNotBlank(blkRecDoc.getAlternateVendorDetail().getVendorName())) {
298                vendorInfo.append("     " + blkRecDoc.getAlternateVendorDetail().getVendorName() + "\n");
299            }
300
301            if (StringUtils.isNotBlank(blkRecDoc.getAlternateVendorDetail().getDefaultAddressLine1())) {
302                vendorInfo.append("     " + blkRecDoc.getAlternateVendorDetail().getDefaultAddressLine1() + "\n");
303            }
304
305            if (StringUtils.isNotBlank(blkRecDoc.getAlternateVendorDetail().getDefaultAddressLine2())) {
306                vendorInfo.append("     " + blkRecDoc.getAlternateVendorDetail().getDefaultAddressLine2() + "\n");
307            }
308
309            if (StringUtils.isNotBlank(blkRecDoc.getAlternateVendorDetail().getDefaultAddressCity())) {
310                vendorInfo.append("     " + blkRecDoc.getAlternateVendorDetail().getDefaultAddressCity());
311            }
312
313            if (StringUtils.isNotBlank(blkRecDoc.getAlternateVendorDetail().getDefaultAddressStateCode())) {
314                vendorInfo.append(", " + blkRecDoc.getAlternateVendorDetail().getDefaultAddressStateCode());
315            }
316
317            if (StringUtils.isNotBlank(blkRecDoc.getAlternateVendorDetail().getDefaultAddressInternationalProvince())) {
318                vendorInfo.append(", " + blkRecDoc.getAlternateVendorDetail().getDefaultAddressInternationalProvince());
319            }
320
321            if (StringUtils.isNotBlank(blkRecDoc.getAlternateVendorDetail().getDefaultAddressPostalCode())) {
322                vendorInfo.append(" " + blkRecDoc.getAlternateVendorDetail().getDefaultAddressPostalCode() + "\n");
323            } else {
324                vendorInfo.append("\n");
325            }
326
327            if (!OLEConstants.COUNTRY_CODE_UNITED_STATES.equalsIgnoreCase(blkRecDoc.getAlternateVendorDetail().getDefaultAddressCountryCode()) && blkRecDoc.getAlternateVendorDetail().getDefaultAddressCountryCode() != null) {
328                vendorInfo.append("     " + blkRecDoc.getAlternateVendorDetail().getDefaultAddressCountryCode() + "\n\n");
329            } else {
330                vendorInfo.append("\n\n");
331            }
332        }
333
334        return vendorInfo.toString();
335    }
336
337    private String getFormattedDeliveryAddress() {
338
339        StringBuffer shipToInfo = new StringBuffer();
340
341        shipToInfo.append("\n");
342
343        if (StringUtils.isNotBlank(blkRecDoc.getDeliveryToName())) {
344            shipToInfo.append("     " + StringUtils.defaultString(blkRecDoc.getDeliveryToName()) + "\n");
345        }
346
347        String deliveryBuildingName = blkRecDoc.getDeliveryBuildingName();
348
349        if (StringUtils.isNotBlank(blkRecDoc.getDeliveryBuildingRoomNumber())) {
350            if (StringUtils.isBlank(deliveryBuildingName)) {
351                shipToInfo.append("     Room #" + blkRecDoc.getDeliveryBuildingRoomNumber() + "\n");
352            } else {
353                shipToInfo.append("     " + deliveryBuildingName + " Room #" + blkRecDoc.getDeliveryBuildingRoomNumber() + "\n");
354            }
355        } else {
356            if (StringUtils.isNotBlank(deliveryBuildingName)) {
357                shipToInfo.append("     " + deliveryBuildingName + "\n");
358            }
359        }
360
361        shipToInfo.append("     " + blkRecDoc.getDeliveryBuildingLine1Address() + "\n");
362
363        if (StringUtils.isNotBlank(blkRecDoc.getDeliveryBuildingLine2Address())) {
364            shipToInfo.append("     " + blkRecDoc.getDeliveryBuildingLine2Address() + "\n");
365        }
366
367        shipToInfo.append("     " + blkRecDoc.getDeliveryCityName() + ", " +
368                blkRecDoc.getDeliveryStateCode() + " " +
369                blkRecDoc.getDeliveryPostalCode() + "\n\n");
370
371        return shipToInfo.toString();
372    }
373
374    private PdfPTable createAdditionalDetailsTable() {
375
376        float[] additionalInfoWidths = {0.25f, 0.75f};
377        PdfPTable additionalInfoTable = new PdfPTable(additionalInfoWidths);
378        additionalInfoTable.setWidthPercentage(100);
379        additionalInfoTable.setSplitLate(false);
380
381        Paragraph p = new Paragraph();
382        PdfPCell cell;
383
384        /**
385         * Notes to vendor
386         */
387        p.add(new Chunk("  Notes to Vendor  ", ver_5_normal));
388        cell = new PdfPCell(p);
389        cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
390        additionalInfoTable.addCell(cell);
391
392        p = new Paragraph();
393        p.add(new Chunk("  " + StringUtils.defaultString(blkRecDoc.getVendorNoteText()), cour_10_normal));
394
395        cell = new PdfPCell(p);
396        cell.setHorizontalAlignment(Element.ALIGN_LEFT);
397        additionalInfoTable.addCell(cell);
398
399        /**
400         * Delivery instructions
401         */
402        p = new Paragraph();
403        p.add(new Chunk("  Delivery instructions  ", ver_5_normal));
404        cell = new PdfPCell(p);
405        cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
406        additionalInfoTable.addCell(cell);
407
408        p = new Paragraph();
409        p.add(new Chunk("  " + StringUtils.defaultString(blkRecDoc.getDeliveryInstructionText()), cour_10_normal));
410
411        cell = new PdfPCell(p);
412        cell.setHorizontalAlignment(Element.ALIGN_LEFT);
413        additionalInfoTable.addCell(cell);
414
415        /**
416         * Additional Delivery instructions
417         */
418        p = new Paragraph();
419        p.add(new Chunk("  Additional Delivery instructions  ", ver_5_normal));
420        cell = new PdfPCell(p);
421        cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
422        additionalInfoTable.addCell(cell);
423
424        p = new Paragraph();
425        p.add(new Chunk("  " + StringUtils.defaultString(blkRecDoc.getDeliveryAdditionalInstructionText()), cour_10_normal));
426
427        cell = new PdfPCell(p);
428        cell.setHorizontalAlignment(Element.ALIGN_LEFT);
429        additionalInfoTable.addCell(cell);
430
431        updateRequestorInfo(blkRecDoc, additionalInfoTable);
432
433        String campusCode = blkRecDoc.getDeliveryCampusCode();
434
435        /**
436         * Dept Contact 
437         */
438        p = new Paragraph();
439        p.add(new Chunk("   Contact Name ", ver_5_normal));
440        cell = new PdfPCell(p);
441        cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
442        additionalInfoTable.addCell(cell);
443
444        p = new Paragraph();
445        p.add(new Chunk("  " + StringUtils.defaultString(blkRecDoc.getInstitutionContactName()), cour_10_normal));
446
447        cell = new PdfPCell(p);
448        cell.setHorizontalAlignment(Element.ALIGN_LEFT);
449        additionalInfoTable.addCell(cell);
450
451        /**
452         * Dept Contact Phone 
453         */
454        p = new Paragraph();
455        p.add(new Chunk("  Contact Phone  ", ver_5_normal));
456        cell = new PdfPCell(p);
457        cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
458        additionalInfoTable.addCell(cell);
459
460        p = new Paragraph();
461        p.add(new Chunk("  " + StringUtils.defaultString(blkRecDoc.getInstitutionContactPhoneNumber()), cour_10_normal));
462
463        cell = new PdfPCell(p);
464        cell.setHorizontalAlignment(Element.ALIGN_LEFT);
465        additionalInfoTable.addCell(cell);
466
467        /**
468         * Dept Contact email 
469         */
470        p = new Paragraph();
471        p.add(new Chunk("  Contact Email  ", ver_5_normal));
472        cell = new PdfPCell(p);
473        cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
474        additionalInfoTable.addCell(cell);
475
476        p = new Paragraph();
477        p.add(new Chunk("  " + StringUtils.defaultString(blkRecDoc.getInstitutionContactEmailAddress()), cour_10_normal));
478
479        cell = new PdfPCell(p);
480        cell.setHorizontalAlignment(Element.ALIGN_LEFT);
481        additionalInfoTable.addCell(cell);
482
483
484        /**
485         * Signature
486         */
487        p = new Paragraph();
488        p.add(new Chunk("  " + " Signature  ", ver_5_normal));
489        cell = new PdfPCell(p);
490        cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
491        additionalInfoTable.addCell(cell);
492
493        p = new Paragraph();
494        p.add(new Chunk("\n\n\n\n"));
495
496        cell = new PdfPCell(p);
497        cell.setHorizontalAlignment(Element.ALIGN_LEFT);
498        additionalInfoTable.addCell(cell);
499
500        /**
501         * Date
502         */
503        p = new Paragraph();
504        p.add(new Chunk("  " + " Date  ", ver_5_normal));
505        cell = new PdfPCell(p);
506        cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
507        additionalInfoTable.addCell(cell);
508
509        p = new Paragraph();
510        p.add(new Chunk("\n\n\n\n"));
511
512        cell = new PdfPCell(p);
513        cell.setHorizontalAlignment(Element.ALIGN_LEFT);
514        additionalInfoTable.addCell(cell);
515
516        return additionalInfoTable;
517    }
518
519    private void updateRequestorInfo(BulkReceivingDocument blkRecDoc,
520                                     PdfPTable additionalInfoTable) {
521        /**
522         * Requestor Name
523         */
524        Paragraph p = new Paragraph();
525        p.add(new Chunk("  Requestor Name  ", ver_5_normal));
526        PdfPCell cell = new PdfPCell(p);
527        cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
528        additionalInfoTable.addCell(cell);
529
530        p = new Paragraph();
531        p.add(new Chunk("  " + StringUtils.defaultString(blkRecDoc.getRequestorPersonName()), cour_10_normal));
532
533        cell = new PdfPCell(p);
534        cell.setHorizontalAlignment(Element.ALIGN_LEFT);
535        additionalInfoTable.addCell(cell);
536
537        /**
538         * Requestor Phone
539         */
540        p = new Paragraph();
541        p.add(new Chunk("  Requestor Phone  ", ver_5_normal));
542        cell = new PdfPCell(p);
543        cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
544        additionalInfoTable.addCell(cell);
545
546        p = new Paragraph();
547        p.add(new Chunk("  " + StringUtils.defaultString(blkRecDoc.getRequestorPersonPhoneNumber()), cour_10_normal));
548
549        cell = new PdfPCell(p);
550        cell.setHorizontalAlignment(Element.ALIGN_LEFT);
551        additionalInfoTable.addCell(cell);
552
553        /**
554         * Requestor Email
555         */
556        p = new Paragraph();
557        p.add(new Chunk("  Requestor Email  ", ver_5_normal));
558        cell = new PdfPCell(p);
559        cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
560        additionalInfoTable.addCell(cell);
561
562        p = new Paragraph();
563        p.add(new Chunk("  " + StringUtils.defaultString(blkRecDoc.getRequestorPersonEmailAddress()), cour_10_normal));
564        cell = new PdfPCell(p);
565        cell.setHorizontalAlignment(Element.ALIGN_LEFT);
566        additionalInfoTable.addCell(cell);
567    }
568}