/*
* The Kuali Financial System, a comprehensive financial management system for higher education.
*
* Copyright 2005-2014 The Kuali Foundation
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kuali.kfs.module.tem.pdf;
import static com.lowagie.text.Element.ALIGN_RIGHT;
import static com.lowagie.text.PageSize.LETTER;
import static com.lowagie.text.Rectangle.NO_BORDER;
import static java.awt.Color.BLACK;
import static org.kuali.kfs.module.tem.TemConstants.TravelReimbursementParameters.FAX_NUMBER;
import java.io.OutputStream;
import java.util.Collection;
import java.util.Map;
import org.kuali.kfs.module.tem.document.TravelReimbursementDocument;
import org.kuali.kfs.module.tem.report.util.BarcodeHelper;
import org.kuali.kfs.sys.context.SpringContext;
import org.kuali.rice.coreservice.framework.parameter.ParameterService;
import com.lowagie.text.BadElementException;
import com.lowagie.text.Cell;
import com.lowagie.text.Chunk;
import com.lowagie.text.Document;
import com.lowagie.text.Font;
import com.lowagie.text.FontFactory;
import com.lowagie.text.Image;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Phrase;
import com.lowagie.text.Table;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfWriter;
/**
* Class representing a PDF Coversheet of the {@link TravelReimbursementDocument}.
*/
public class Coversheet implements PdfStream {
private static final int ALIGNMENT_MARK_HEIGHT = 8;
private static final int ALIGNMENT_MARK_WIDTH = 10;
private static final int ALIGNMENT_MARGIN = 5;
private static final int TOP_MARGIN = 50;
private String initiatorName;
private String initiatorPrincipalName;
private String initiatorPhone;
private String initiatorEmail;
private String travelerName;
private String travelerPrincipalName;
private String travelerPhone;
private String travelerEmail;
private String instructions;
private String mailTo;
private String date;
private String tripId;
private String destination;
private String documentNumber;
private Collection<Map<String, String>> expenses;
/**
* Sets the initiatorName attribute
*
* @param initiatorName is the String initiatorName value
*/
public void setInitiatorName(final String initiatorName) {
this.initiatorName = initiatorName;
}
/**
* Gets the initiatorName attribute
*
* @return String value of initiatorName
*/
public String getInitiatorName() {
if (initiatorName == null) {
return "";
}
return this.initiatorName;
}
/**
* Sets the initiatorPrincipalName attribute
*
* @param initiatorPrincipalName is the String initiatorPrincipalName value
*/
public void setInitiatorPrincipalName(final String initiatorPrincipalName) {
this.initiatorPrincipalName = initiatorPrincipalName;
}
/**
* Gets the initiatorPrincipalName attribute
*
* @return String value of initiatorPrincipalName
*/
public String getInitiatorPrincipalName() {
if (initiatorPrincipalName == null) {
return "";
}
return this.initiatorPrincipalName;
}
/**
* Sets the initiatorPhone attribute
*
* @param initiatorPhone is the String initiatorPhone value
*/
public void setInitiatorPhone(final String initiatorPhone) {
this.initiatorPhone = initiatorPhone;
}
/**
* Gets the initiatorPhone attribute
*
* @return String value of initiatorPhone
*/
public String getInitiatorPhone() {
if (initiatorPhone == null) {
return "";
}
return this.initiatorPhone;
}
/**
* Sets the initiatorEmail attribute
*
* @param initiatorEmail is the String initiatorEmail value
*/
public void setInitiatorEmail(final String initiatorEmail) {
this.initiatorEmail = initiatorEmail;
}
/**
* Gets the initiatorEmail attribute
*
* @return String value of initiatorEmail
*/
public String getInitiatorEmail() {
if (initiatorEmail == null) {
return "";
}
return this.initiatorEmail;
}
/**
* Sets the travelerName attribute
*
* @param travelerName is the String travelerName value
*/
public void setTravelerName(final String travelerName) {
this.travelerName = travelerName;
}
/**
* Gets the travelerName attribute
*
* @return String value of travelerName
*/
public String getTravelerName() {
if (travelerName == null) {
return "";
}
return this.travelerName;
}
/**
* Sets the travelerPrincipalName attribute
*
* @param travelerPrincipalName is the String travelerPrincipalName value
*/
public void setTravelerPrincipalName(final String travelerPrincipalName) {
this.travelerPrincipalName = travelerPrincipalName;
}
/**
* Gets the travelerPrincipalName attribute
*
* @return String value of travelerPrincipalName
*/
public String getTravelerPrincipalName() {
if (travelerPrincipalName == null) {
return "";
}
return this.travelerPrincipalName;
}
/**
* Sets the travelerPhone attribute
*
* @param travelerPhone is the String travelerPhone value
*/
public void setTravelerPhone(final String travelerPhone) {
this.travelerPhone = travelerPhone;
}
/**
* Gets the travelerPhone attribute
*
* @return String value of travelerPhone
*/
public String getTravelerPhone() {
if (travelerPhone == null) {
return "";
}
return this.travelerPhone;
}
/**
* Sets the travelerEmail attribute
*
* @param travelerEmail is the String travelerEmail value
*/
public void setTravelerEmail(final String travelerEmail) {
this.travelerEmail = travelerEmail;
}
/**
* Gets the travelerEmail attribute
*
* @return String value of travelerEmail
*/
public String getTravelerEmail() {
if (travelerEmail == null) {
return "";
}
return this.travelerEmail;
}
/**
* Sets the instructions attribute
*
* @param instructions is the String instructions value
*/
public void setInstructions(final String instructions) {
this.instructions = instructions;
}
/**
* Gets the instructions attribute
*
* @return String value of instructions
*/
public String getInstructions() {
if (instructions == null) {
return "";
}
return this.instructions;
}
/**
* Sets the date attribute
*
* @param date is the String date value
*/
public void setDate(final String date) {
this.date = date;
}
/**
* Gets the date attribute
*
* @return String value of date
*/
public String getDate() {
if (date == null) {
return "";
}
return this.date;
}
/**
* Sets the mailTo attribute
*
* @param mailTo is the String mailTo value
*/
public void setMailTo(final String mailTo) {
this.mailTo = mailTo;
}
/**
* Gets the mailTo attribute
*
* @return String value of mailTo
*/
public String getMailTo() {
if (mailTo == null) {
return "";
}
return this.mailTo;
}
/**
* Sets the destination attribute
*
* @param destination is the String destination value
*/
public void setDestination(final String destination) {
this.destination = destination;
}
/**
* Gets the destination attribute
*
* @return String value of destination
*/
public String getDestination() {
if (destination == null) {
return "";
}
return this.destination;
}
/**
* Sets the tripId attribute
*
* @param tripId is the String tripId value
*/
public void setTripId(final String tripId) {
this.tripId = tripId;
}
/**
* Gets the tripId attribute
*
* @return String value of tripId
*/
public String getTripId() {
if (tripId == null) {
return "";
}
return this.tripId;
}
/**
* Sets the documentNumber attribute
*
* @param documentNumber is the String documentNumber value
*/
public void setDocumentNumber(final String documentNumber) {
this.documentNumber = documentNumber;
}
/**
* Gets the documentNumber attribute
*
* @return String value of documentNumber
*/
public String getDocumentNumber() {
return this.documentNumber;
}
/**
* Creates instructions section of the coverpage
*
* @returns a {@link Paragraph} for the PDF
*/
protected Paragraph getInstructionsParagraph() {
final Font headerFont = FontFactory.getFont(FontFactory.HELVETICA, 12, Font.BOLD);
final Font normalFont = FontFactory.getFont(FontFactory.HELVETICA, 12, Font.NORMAL);
final Paragraph retval = new Paragraph();
retval.add(new Chunk("Instructions", headerFont));
retval.add(Chunk.NEWLINE);
retval.add(new Phrase(getInstructions(), normalFont));
return retval;
}
/**
* Creates mailTo section for the coversheet. The MailTo section is where the coversheet will be mailed.
*
* @returns a {@link Paragraph} for the PDF
*/
protected Paragraph getMailtoParagraph() {
final Font headerFont = FontFactory.getFont(FontFactory.HELVETICA, 12, Font.BOLD);
final Font normalFont = FontFactory.getFont(FontFactory.HELVETICA, 12, Font.NORMAL);
final Paragraph retval = new Paragraph();
retval.add(new Chunk("Mail coversheet to:", headerFont));
retval.add(Chunk.NEWLINE);
retval.add(new Phrase(getMailTo(), normalFont));
return retval;
}
/**
* Information about the person that initiated the {@link TravelReimbursementDocument}
*/
protected Cell getInitiatorInfo() throws BadElementException {
final StringBuilder strBuilder = new StringBuilder();
strBuilder.append(getInitiatorName()).append("\n")
.append(getInitiatorPrincipalName()).append("\n")
.append(getInitiatorPhone()).append("\n")
.append(getInitiatorEmail()).append("\n");
final Cell retval = getBorderlessCell(strBuilder.toString());
return retval;
}
/**
* Information about the traveler described in the trip for the {@link TravelReimbursementDocument}
*
*/
protected Cell getTravelerInfo() throws BadElementException {
final StringBuilder strBuilder = new StringBuilder();
strBuilder.append(getTravelerName()).append("\n")
.append(getTravelerPrincipalName()).append("\n")
.append(getTravelerPhone()).append("\n")
.append(getTravelerEmail()).append("\n");
final Cell retval = getBorderlessCell(strBuilder.toString());
return retval;
}
/**
* Get the PDF Table containing trip information like trip id, date, and destination
*
* @returns {@link Table} used for a PDF
*/
protected Table getTripInfo() throws BadElementException {
final Table retval = new Table(3);
retval.setWidth(100f);
retval.setBorder(NO_BORDER);
retval.addCell(getHeaderCell("Trip/Event ID"));
final Cell dateHeaderCell = getHeaderCell("Date");
retval.addCell(dateHeaderCell);
retval.addCell(getHeaderCell("Destination/Event Name"));
retval.endHeaders();
retval.addCell(getBorderlessCell(getTripId()));
final Cell dateCell = getBorderlessCell(getDate());
retval.addCell(dateCell);
retval.addCell(getBorderlessCell(getDestination()));
return retval;
}
/**
* Get the PDF Table with personal information about the initiator and traveler
*
* @returns {@link Table} used for a PDF
*/
protected Table getPersonalInfo() throws BadElementException {
final Table retval = new Table(2);
retval.setWidth(100f);
retval.setBorder(NO_BORDER);
retval.addCell(getHeaderCell("Traveler"));
final Cell initiatorHeaderCell = getHeaderCell("Request Submitted By");
retval.addCell(initiatorHeaderCell);
retval.endHeaders();
retval.addCell(getTravelerInfo());
final Cell initiatorCell = getInitiatorInfo();
retval.addCell(initiatorCell);
return retval;
}
public void setExpenses(final Collection<Map<String, String>> expenses) {
this.expenses = expenses;
}
public Table getExpenses() throws BadElementException {
final Table retval = new Table(3);
retval.setWidth(100f);
retval.setBorder(NO_BORDER);
retval.addCell(getHeaderCell("Expenses"));
retval.addCell(getHeaderCell("Amount"));
retval.addCell(getHeaderCell("Receipt Required?"));
retval.endHeaders();
for (final Map<String, String> expense : expenses) {
retval.addCell(getBorderlessCell(expense.get("expenseType")));
retval.addCell(getBorderlessCell(expense.get("amount")));
retval.addCell(getBorderlessCell(expense.get("receipt")));
}
return retval;
}
/**
* Helper method to create a Header Cell from text
*
* @returns {@link Cell} with the header flag set
*/
protected Cell getBorderlessCell(final String text) throws BadElementException {
final Font normalFont = FontFactory.getFont(FontFactory.HELVETICA, 12, Font.NORMAL);
final Cell retval = new Cell(new Chunk(text, normalFont));
retval.setBorder(NO_BORDER);
return retval;
}
/**
* Helper method to create a Header Cell from text
*
* @returns {@link Cell} with the header flag set
*/
protected Cell getHeaderCell(final String text) throws BadElementException {
final Font headerFont = FontFactory.getFont(FontFactory.HELVETICA, 12, Font.BOLD);
final Cell retval = new Cell(new Chunk(text, headerFont));
retval.setBorder(NO_BORDER);
retval.setHeader(true);
return retval;
}
protected void upperLeftAlignmentMark(final PdfContentByte cb) {
cb.saveState();
cb.rectangle(ALIGNMENT_MARGIN,
(LETTER.height() + TOP_MARGIN) - ALIGNMENT_MARK_HEIGHT - ALIGNMENT_MARGIN,
ALIGNMENT_MARK_WIDTH,
ALIGNMENT_MARK_HEIGHT);
cb.setColorFill(BLACK);
cb.fill();
cb.restoreState();
}
protected void lowerLeftAlignmentMark(final PdfContentByte cb) {
cb.saveState();
cb.rectangle(ALIGNMENT_MARGIN,
ALIGNMENT_MARGIN,
ALIGNMENT_MARK_WIDTH,
ALIGNMENT_MARK_HEIGHT);
cb.setColorFill(BLACK);
cb.fill();
cb.restoreState();
}
protected void lowerRightAlignmentMark(final PdfContentByte cb) {
cb.saveState();
cb.rectangle(LETTER.width() - (ALIGNMENT_MARGIN * 4) - ALIGNMENT_MARK_WIDTH,
ALIGNMENT_MARGIN,
ALIGNMENT_MARK_WIDTH,
ALIGNMENT_MARK_HEIGHT);
cb.setColorFill(BLACK);
cb.fill();
cb.restoreState();
}
protected void upperRightAlignmentMark(final PdfContentByte cb) {
cb.saveState();
cb.rectangle(LETTER.width() - (ALIGNMENT_MARGIN * 4) - ALIGNMENT_MARK_WIDTH,
(LETTER.height() + TOP_MARGIN) - ALIGNMENT_MARGIN - ALIGNMENT_MARK_HEIGHT,
ALIGNMENT_MARK_WIDTH,
ALIGNMENT_MARK_HEIGHT);
cb.setColorFill(BLACK);
cb.fill();
cb.restoreState();
}
protected void drawAlignmentMarks(final PdfContentByte cb) {
upperLeftAlignmentMark(cb);
lowerLeftAlignmentMark(cb);
upperRightAlignmentMark(cb);
lowerRightAlignmentMark(cb);
}
/**
* @see org.kuali.kfs.module.tem.pdf.PdfStream#print(java.io.OutputStream)
* @throws Exception
*/
@Override
public void print(final OutputStream stream) throws Exception {
final Font titleFont = FontFactory.getFont(FontFactory.HELVETICA, 20, Font.BOLD);
final Font headerFont = FontFactory.getFont(FontFactory.HELVETICA, 12, Font.BOLD);
final Font normalFont = FontFactory.getFont(FontFactory.HELVETICA, 12, Font.NORMAL);
final Document doc = new Document();
final PdfWriter writer = PdfWriter.getInstance(doc, stream);
doc.open();
if(getDocumentNumber()!=null){
Image image=Image.getInstance(new BarcodeHelper().generateBarcodeImage(getDocumentNumber()),null);
doc.add(image);
}
final Paragraph title = new Paragraph("TEM Coversheet", titleFont);
doc.add(title);
final Paragraph faxNumber = new Paragraph("Fax this page to " + SpringContext.getBean(ParameterService.class).getParameterValueAsString(TravelReimbursementDocument.class, FAX_NUMBER), normalFont);
doc.add(faxNumber);
final Paragraph header = new Paragraph("", headerFont);
header.setAlignment(ALIGN_RIGHT);
header.add("Document Number: " + getDocumentNumber());
doc.add(header);
doc.add(getInstructionsParagraph());
doc.add(getMailtoParagraph());
doc.add(Chunk.NEWLINE);
doc.add(getTripInfo());
doc.add(Chunk.NEWLINE);
doc.add(getPersonalInfo());
doc.add(Chunk.NEWLINE);
doc.add(getExpenses());
drawAlignmentMarks(writer.getDirectContent());
doc.close();
writer.close();
}
}