001 /* 002 * Copyright 2011 The Kuali Foundation. 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.kfs.fp.document.service.impl; 017 018 import java.io.File; 019 import java.io.IOException; 020 import java.io.OutputStream; 021 import java.util.HashMap; 022 import java.util.Iterator; 023 import java.util.List; 024 import java.util.Map; 025 026 import org.apache.commons.lang.StringUtils; 027 import org.kuali.kfs.fp.businessobject.DisbursementVoucherDocumentationLocation; 028 import org.kuali.kfs.fp.businessobject.PaymentReasonCode; 029 import org.kuali.kfs.fp.businessobject.options.PaymentMethodValuesFinder; 030 import org.kuali.kfs.fp.document.DisbursementVoucherConstants; 031 import org.kuali.kfs.fp.document.DisbursementVoucherDocument; 032 import org.kuali.kfs.fp.document.service.DisbursementVoucherCoverSheetService; 033 import org.kuali.rice.kns.bo.PersistableBusinessObject; 034 import org.kuali.rice.kns.lookup.keyvalues.KeyValuesFinder; 035 import org.kuali.rice.kns.service.BusinessObjectService; 036 import org.kuali.rice.kns.service.ParameterEvaluator; 037 import org.kuali.rice.kns.service.ParameterService; 038 import org.kuali.rice.kns.service.PersistenceStructureService; 039 import org.kuali.rice.core.util.KeyLabelPair; 040 import org.kuali.rice.kns.workflow.service.KualiWorkflowDocument; 041 042 import com.lowagie.text.DocumentException; 043 import com.lowagie.text.pdf.AcroFields; 044 import com.lowagie.text.pdf.PdfReader; 045 import com.lowagie.text.pdf.PdfStamper; 046 047 /** 048 * This is the default implementation of the DisbursementVoucherCoverSheetService interface. 049 */ 050 public class DisbursementVoucherCoverSheetServiceImpl implements DisbursementVoucherCoverSheetService { 051 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DisbursementVoucherCoverSheetServiceImpl.class); 052 053 private ParameterService parameterService; 054 private BusinessObjectService businessObjectService; 055 private PersistenceStructureService persistenceStructureService; 056 057 /** 058 * This method uses the values provided to build and populate a cover sheet associated with a given DisbursementVoucher. 059 * 060 * @param templateDirectory The directory where the cover sheet template can be found. 061 * @param templateName The name of the cover sheet template to be used to build the cover sheet. 062 * @param document The DisbursementVoucher the cover sheet will be populated from. 063 * @param outputStream The stream the cover sheet file will be written to. 064 * @see org.kuali.kfs.fp.document.service.DisbursementVoucherCoverSheetService#generateDisbursementVoucherCoverSheet(java.lang.String, 065 * java.lang.String, org.kuali.kfs.fp.document.DisbursementVoucherDocument, java.io.OutputStream) 066 */ 067 public void generateDisbursementVoucherCoverSheet(String templateDirectory, String templateName, DisbursementVoucherDocument document, OutputStream outputStream) throws DocumentException, IOException { 068 if (this.isCoverSheetPrintable(document)) { 069 String attachment = ""; 070 String handling = ""; 071 String alien = ""; 072 String lines = ""; 073 String bar = ""; 074 String rlines = ""; 075 076 String docNumber = document.getDocumentNumber(); 077 String initiator = document.getDocumentHeader().getWorkflowDocument().getInitiatorPrincipalId(); 078 String payee = document.getDvPayeeDetail().getDisbVchrPayeePersonName(); 079 080 String reason = ((PaymentReasonCode) retrieveObjectByKey(PaymentReasonCode.class, document.getDvPayeeDetail().getDisbVchrPaymentReasonCode())).getName(); 081 String check_total = document.getDisbVchrCheckTotalAmount().toString(); 082 083 String currency = getValueForKey(new PaymentMethodValuesFinder(), document.getDisbVchrPaymentMethodCode()); 084 085 String address = retrieveAddress(document.getDisbursementVoucherDocumentationLocationCode()); 086 087 // retrieve attachment label 088 if (document.isDisbVchrAttachmentCode()) { 089 attachment = parameterService.getParameterValue(DisbursementVoucherDocument.class, DisbursementVoucherConstants.DV_COVER_SHEET_TEMPLATE_ATTACHMENT_PARM_NM); 090 } 091 // retrieve handling label 092 if (document.isDisbVchrSpecialHandlingCode()) { 093 handling = parameterService.getParameterValue(DisbursementVoucherDocument.class, DisbursementVoucherConstants.DV_COVER_SHEET_TEMPLATE_HANDLING_PARM_NM); 094 } 095 // retrieve data for alien payment code 096 if (document.getDvPayeeDetail().isDisbVchrAlienPaymentCode()) { 097 String taxDocumentationLocationCode = parameterService.getParameterValue(DisbursementVoucherDocument.class, DisbursementVoucherConstants.TAX_DOCUMENTATION_LOCATION_CODE_PARM_NM); 098 099 address = retrieveAddress(taxDocumentationLocationCode); 100 alien = parameterService.getParameterValue(DisbursementVoucherDocument.class, DisbursementVoucherConstants.DV_COVER_SHEET_TEMPLATE_ALIEN_PARM_NM); 101 lines = parameterService.getParameterValue(DisbursementVoucherDocument.class, DisbursementVoucherConstants.DV_COVER_SHEET_TEMPLATE_LINES_PARM_NM); 102 } 103 104 // determine if non-employee travel payment reasons 105 String paymentReasonCode = document.getDvPayeeDetail().getDisbVchrPaymentReasonCode(); 106 ParameterEvaluator travelNonEmplPaymentReasonEvaluator = parameterService.getParameterEvaluator(DisbursementVoucherDocument.class, DisbursementVoucherConstants.NONEMPLOYEE_TRAVEL_PAY_REASONS_PARM_NM, paymentReasonCode); 107 boolean isTravelNonEmplPaymentReason = travelNonEmplPaymentReasonEvaluator.evaluationSucceeds(); 108 109 if (isTravelNonEmplPaymentReason) { 110 bar = parameterService.getParameterValue(DisbursementVoucherDocument.class, DisbursementVoucherConstants.DV_COVER_SHEET_TEMPLATE_BAR_PARM_NM); 111 rlines = parameterService.getParameterValue(DisbursementVoucherDocument.class, DisbursementVoucherConstants.DV_COVER_SHEET_TEMPLATE_RLINES_PARM_NM); 112 } 113 114 try { 115 PdfReader reader = new PdfReader(templateDirectory + templateName); 116 117 // populate form with document values 118 PdfStamper stamper = new PdfStamper(reader, outputStream); 119 120 AcroFields populatedCoverSheet = stamper.getAcroFields(); 121 populatedCoverSheet.setField("initiator", initiator); 122 populatedCoverSheet.setField("attachment", attachment); 123 populatedCoverSheet.setField("currency", currency); 124 populatedCoverSheet.setField("handling", handling); 125 populatedCoverSheet.setField("alien", alien); 126 populatedCoverSheet.setField("payee_name", payee); 127 populatedCoverSheet.setField("check_total", check_total); 128 populatedCoverSheet.setField("docNumber", docNumber); 129 populatedCoverSheet.setField("payment_reason", reason); 130 populatedCoverSheet.setField("destination_address", address); 131 populatedCoverSheet.setField("lines", lines); 132 populatedCoverSheet.setField("bar", bar); 133 populatedCoverSheet.setField("rlines", rlines); 134 135 stamper.setFormFlattening(true); 136 stamper.close(); 137 } 138 catch (DocumentException e) { 139 LOG.error("Error creating coversheet for: " + docNumber + ". ::" + e); 140 throw e; 141 } 142 catch (IOException e) { 143 LOG.error("Error creating coversheet for: " + docNumber + ". ::" + e); 144 throw e; 145 } 146 } 147 148 } 149 150 /** 151 * @see org.kuali.kfs.fp.document.service.DisbursementVoucherCoverSheetService#isCoverSheetPrintable(org.kuali.kfs.fp.document.DisbursementVoucherDocument) 152 */ 153 public boolean isCoverSheetPrintable(DisbursementVoucherDocument document) { 154 KualiWorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument(); 155 156 return !(workflowDocument.stateIsCanceled() || workflowDocument.stateIsInitiated() || workflowDocument.stateIsDisapproved() || workflowDocument.stateIsException() || workflowDocument.stateIsDisapproved() || workflowDocument.stateIsSaved()); 157 } 158 159 /** 160 * This method is used to retrieve business objects that have a single primary key field without hard-coding the key field name. 161 * 162 * @param clazz The class type that will be used to retrieve the primary key field names. 163 * @param keyValue The primary key value to be used to lookup the object by. 164 * @return An instance of a business object matching the class type and primary key value given. 165 */ 166 protected PersistableBusinessObject retrieveObjectByKey(Class clazz, String keyValue) { 167 List primaryKeyFields = persistenceStructureService.listPrimaryKeyFieldNames(clazz); 168 if (primaryKeyFields.size() != 1) { 169 throw new IllegalArgumentException("multi-part key found. expecting single key field for " + clazz.getName()); 170 } 171 Map primaryKeys = new HashMap(); 172 primaryKeys.put(primaryKeyFields.get(0), keyValue); 173 PersistableBusinessObject b = businessObjectService.findByPrimaryKey(clazz, primaryKeys); 174 175 return b; 176 } 177 178 /** 179 * This method is a helper method to retrieve values from a list based on a primary key provided. 180 * 181 * @param keyValuesFinder KeyValuesFinder that the value will be retrieved from. 182 * @param key The key to the value being retrieved. 183 * @return The value associated with the key provided, or empty string if no value is found. 184 */ 185 protected String getValueForKey(KeyValuesFinder keyValuesFinder, String key) { 186 for (Iterator i = keyValuesFinder.getKeyValues().iterator(); i.hasNext();) { 187 KeyLabelPair pair = (KeyLabelPair) i.next(); 188 if (StringUtils.equals((String) pair.getKey(), key)) { 189 return pair.getLabel(); 190 } 191 } 192 return ""; 193 } 194 195 /** 196 * This method contains logic to determine the address the cover sheet should be sent to. 197 * 198 * @param docLocCd A key used to retrieve the document location. 199 * @return The address the cover sheet will be sent to or empty string if no location is found. 200 */ 201 protected String retrieveAddress(String docLocCd) { 202 String address = ""; 203 try { 204 address = ((DisbursementVoucherDocumentationLocation) retrieveObjectByKey(DisbursementVoucherDocumentationLocation.class, docLocCd)).getDisbursementVoucherDocumentationLocationAddress(); 205 } 206 catch (NullPointerException e) { 207 // ignored 208 } 209 210 return address; 211 } 212 213 // spring injected services 214 215 /** 216 * Sets the businessObjectService attribute value. 217 * 218 * @param businessObjectService The businessObjectService to set. 219 */ 220 public void setBusinessObjectService(BusinessObjectService businessObjectService) { 221 this.businessObjectService = businessObjectService; 222 } 223 224 /** 225 * Sets the persistenceStructureService attribute value. 226 * 227 * @param persistenceStructureService The persistenceService to set. 228 */ 229 public void setPersistenceStructureService(PersistenceStructureService persistenceStructureService) { 230 this.persistenceStructureService = persistenceStructureService; 231 } 232 233 /** 234 * Sets the parameterService attribute value. 235 * 236 * @param parameterService The parameterService to set. 237 */ 238 public void setParameterService(ParameterService parameterService) { 239 this.parameterService = parameterService; 240 } 241 }