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 }