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.batch.service.impl; 017 018 import java.util.List; 019 020 import org.kuali.kfs.fp.document.DistributionOfIncomeAndExpenseDocument; 021 import org.kuali.kfs.sys.KFSConstants; 022 import org.kuali.kfs.sys.businessobject.ElectronicPaymentClaim; 023 import org.kuali.kfs.sys.businessobject.SourceAccountingLine; 024 import org.kuali.kfs.sys.context.SpringContext; 025 import org.kuali.kfs.sys.service.ElectronicPaymentClaimingDocumentGenerationStrategy; 026 import org.kuali.kfs.sys.service.ElectronicPaymentClaimingService; 027 import org.kuali.rice.kew.exception.WorkflowException; 028 import org.kuali.rice.kew.util.KEWConstants; 029 import org.kuali.rice.kim.bo.Person; 030 import org.kuali.rice.kns.bo.Note; 031 import org.kuali.rice.kns.service.DataDictionaryService; 032 import org.kuali.rice.kns.service.DocumentService; 033 import org.kuali.rice.kns.service.KNSServiceLocator; 034 import org.kuali.rice.kns.service.ParameterService; 035 import org.kuali.rice.kns.workflow.service.KualiWorkflowInfo; 036 import org.kuali.rice.kns.workflow.service.WorkflowInfoService; 037 038 public class DistributionOfIncomeAndExpenseElectronicPaymentClaimingHelperStrategyImpl implements ElectronicPaymentClaimingDocumentGenerationStrategy { 039 private org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DistributionOfIncomeAndExpenseElectronicPaymentClaimingHelperStrategyImpl.class); 040 041 private DataDictionaryService dataDictionaryService; 042 private DocumentService documentService; 043 private ElectronicPaymentClaimingService electronicPaymentClaimingService; 044 private ParameterService parameterService; 045 046 /** 047 * The name of the parameter to get the description for this document; without a description, we can't save the document, and if 048 * we don't save the document, there's a chance that electronic payment claims will go to limbo 049 */ 050 private final static String DOCUMENT_DESCRIPTION_PARAM_NAME = "ELECTRONIC_FUNDS_DOCUMENT_DESCRIPTION"; 051 private final static String URL_PREFIX = "financial"; 052 private final static String URL_MIDDLE = ".do?methodToCall=docHandler&command="; 053 private final static String URL_SUFFIX = "&docId="; 054 private final static String URL_DOC_TYPE = "DistributionOfIncomeAndExpense"; 055 056 /** 057 * @see org.kuali.kfs.sys.service.ElectronicPaymentClaimingDocumentGenerationStrategy#createDocumentFromElectronicPayments(java.util.List) 058 */ 059 public String createDocumentFromElectronicPayments(List<ElectronicPaymentClaim> electronicPayments, Person user) { 060 DistributionOfIncomeAndExpenseDocument document = null; 061 try { 062 document = (DistributionOfIncomeAndExpenseDocument) documentService.getNewDocument(getClaimingDocumentWorkflowDocumentType()); 063 addAccountingLinesToDocument(document, electronicPayments); 064 addDescriptionToDocument(document); 065 addNotesToDocument(document, electronicPayments, user); 066 documentService.saveDocument(document); 067 electronicPaymentClaimingService.claimElectronicPayments(electronicPayments, document.getDocumentNumber()); 068 } 069 catch (WorkflowException we) { 070 throw new RuntimeException("WorkflowException while creating a DistributionOfIncomeAndExpenseDocument to claim ElectronicPaymentClaim records.", we); 071 } 072 073 return getURLForDocument(document); 074 } 075 076 /** 077 * Builds the URL that can be used to redirect to the correct document 078 * 079 * @param doc the document to build the URL for 080 * @return the relative URL to redirect to 081 */ 082 protected String getURLForDocument(DistributionOfIncomeAndExpenseDocument doc) { 083 StringBuilder url = new StringBuilder(); 084 url.append(URL_PREFIX); 085 url.append(getUrlDocType()); 086 url.append(URL_MIDDLE); 087 url.append(KEWConstants.ACTIONLIST_COMMAND); 088 url.append(URL_SUFFIX); 089 url.append(doc.getDocumentNumber()); 090 return url.toString(); 091 } 092 093 /** 094 * Creates notes for the claims (using the ElectronicPaymentClaimingService) and then adds them to the document 095 * 096 * @param claimingDoc the claiming document 097 * @param claims the electronic payments being claimed 098 * @param user the user doing the claiming 099 */ 100 protected void addNotesToDocument(DistributionOfIncomeAndExpenseDocument claimingDoc, List<ElectronicPaymentClaim> claims, Person user) { 101 for (String noteText : electronicPaymentClaimingService.constructNoteTextsForClaims(claims)) { 102 try { 103 Note note = documentService.createNoteFromDocument(claimingDoc, noteText); 104 documentService.addNoteToDocument(claimingDoc, note); 105 } 106 catch (Exception e) { 107 LOG.error("Exception while attempting to create or add note: " + e); 108 } 109 } 110 } 111 112 /** 113 * Adds an accounting line to the document for each ElectronicPaymentClaim record that is being added 114 * 115 * @param document the claiming Distribution of Income and Expense document 116 * @param electronicPayments the list of ElectronicPaymentClaim records that are being claimed 117 */ 118 protected void addAccountingLinesToDocument(DistributionOfIncomeAndExpenseDocument document, List<ElectronicPaymentClaim> electronicPayments) { 119 for (ElectronicPaymentClaim payment : electronicPayments) { 120 SourceAccountingLine claimingAccountingLine = copyAccountingLineToNew(payment.getGeneratingAccountingLine(), createNewAccountingLineForDocument(document)); 121 document.addSourceAccountingLine(claimingAccountingLine); 122 } 123 } 124 125 /** 126 * Adds the parameterized description to the document, so the doc can be saved 127 * 128 * @param document the document to add a description to 129 */ 130 protected void addDescriptionToDocument(DistributionOfIncomeAndExpenseDocument document) { 131 String description = parameterService.getParameterValue(DistributionOfIncomeAndExpenseDocument.class, DistributionOfIncomeAndExpenseElectronicPaymentClaimingHelperStrategyImpl.DOCUMENT_DESCRIPTION_PARAM_NAME); 132 if (description != null) { 133 document.getDocumentHeader().setDocumentDescription(description); 134 } 135 else { 136 throw new RuntimeException("There is evidently no value for Parameter KFS-FP / Distribution of Income and Expense / " + DistributionOfIncomeAndExpenseElectronicPaymentClaimingHelperStrategyImpl.DOCUMENT_DESCRIPTION_PARAM_NAME + "; please set a value before claiming Electronic Payments"); 137 } 138 } 139 140 /** 141 * Creates a new accounting line, based on what the source accounting line class for the document is 142 * 143 * @param document the document that is claiming these payments 144 * @return a new, ready-to-be-filled in accounting line of the class that the given document uses for Source Accounting Lines 145 */ 146 protected SourceAccountingLine createNewAccountingLineForDocument(DistributionOfIncomeAndExpenseDocument document) { 147 SourceAccountingLine newLine = null; 148 try { 149 Class accountingLineClass = document.getSourceAccountingLineClass(); 150 newLine = (SourceAccountingLine) accountingLineClass.newInstance(); 151 } 152 catch (InstantiationException ie) { 153 throw new RuntimeException(ie); 154 } 155 catch (IllegalAccessException iae) { 156 throw new RuntimeException(iae); 157 } 158 return newLine; 159 } 160 161 /** 162 * Copies an original accounting line to a new accounting line 163 * 164 * @param line the original accounting line 165 * @return an accounting line that copies that accounting line 166 */ 167 protected SourceAccountingLine copyAccountingLineToNew(SourceAccountingLine line, SourceAccountingLine newLine) { 168 newLine.setChartOfAccountsCode(line.getChartOfAccountsCode()); 169 newLine.setAccountNumber(line.getAccountNumber()); 170 newLine.setSubAccountNumber(line.getSubAccountNumber()); 171 newLine.setFinancialObjectCode(line.getFinancialObjectCode()); 172 newLine.setFinancialSubObjectCode(line.getFinancialSubObjectCode()); 173 newLine.setProjectCode(line.getProjectCode()); 174 newLine.setOrganizationReferenceId(line.getOrganizationReferenceId()); 175 newLine.setAmount(line.getAmount()); 176 return newLine; 177 } 178 179 /** 180 * @see org.kuali.kfs.sys.service.ElectronicPaymentClaimingDocumentGenerationStrategy#getClaimingDocumentWorkflowDocumentType() 181 * @return the name DistributionOfIncomeAndExpenseDocument workflow document type 182 */ 183 public String getClaimingDocumentWorkflowDocumentType() { 184 return "DI"; 185 } 186 187 /** 188 * @return the class of the document which claims these electronic payments 189 */ 190 protected String getUrlDocType() { 191 return DistributionOfIncomeAndExpenseElectronicPaymentClaimingHelperStrategyImpl.URL_DOC_TYPE; 192 } 193 194 /** 195 * Uses the data dictionary to find the label for this document 196 * 197 * @see org.kuali.kfs.sys.service.ElectronicPaymentClaimingDocumentGenerationStrategy#getDocumentLabel() 198 */ 199 public String getDocumentLabel() { 200 try { 201 KualiWorkflowInfo workflowInfo = KNSServiceLocator.getWorkflowInfoService(); 202 203 return workflowInfo.getDocType(getClaimingDocumentWorkflowDocumentType()).getDocTypeLabel(); 204 } 205 catch (WorkflowException e) { 206 throw new RuntimeException("Caught Exception trying to get Workflow Document Type", e); 207 } 208 } 209 210 /** 211 * This always returns true if the given user in the claiming workgroup. 212 * 213 * @see org.kuali.kfs.sys.service.ElectronicPaymentClaimingDocumentGenerationStrategy#userMayUseToClaim(org.kuali.rice.kim.bo.Person) 214 */ 215 public boolean userMayUseToClaim(Person claimingUser) { 216 final String documentTypeName = this.getClaimingDocumentWorkflowDocumentType(); 217 218 final boolean canClaim = electronicPaymentClaimingService.isAuthorizedForClaimingElectronicPayment(claimingUser, documentTypeName) || electronicPaymentClaimingService.isAuthorizedForClaimingElectronicPayment(claimingUser, null); 219 220 return canClaim; 221 } 222 223 /** 224 * @see org.kuali.kfs.sys.service.ElectronicPaymentClaimingDocumentGenerationStrategy#isDocumentReferenceValid(java.lang.String) 225 */ 226 public boolean isDocumentReferenceValid(String referenceDocumentNumber) { 227 boolean valid = false; 228 try { 229 long docNumberAsLong = Long.parseLong(referenceDocumentNumber); 230 if (docNumberAsLong > 0L) { 231 valid = documentService.documentExists(referenceDocumentNumber); 232 } 233 } 234 catch (NumberFormatException nfe) { 235 valid = false; // the doc # can't be parsed into a Long? Then it ain't no valid! 236 } 237 return valid; 238 } 239 240 /** 241 * Sets the ddService attribute value. 242 * 243 * @param ddService The ddService to set. 244 */ 245 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) { 246 this.dataDictionaryService = dataDictionaryService; 247 } 248 249 /** 250 * Gets the dataDictionaryService attribute. 251 * @return Returns the dataDictionaryService. 252 */ 253 public DataDictionaryService getDataDictionaryService() { 254 return dataDictionaryService; 255 } 256 257 /** 258 * Sets the documentService attribute value. 259 * 260 * @param documentService The documentService to set. 261 */ 262 public void setDocumentService(DocumentService documentService) { 263 this.documentService = documentService; 264 } 265 266 /** 267 * Sets the electronicPaymentClaimingService attribute value. 268 * 269 * @param electronicPaymentClaimingService The electronicPaymentClaimingService to set. 270 */ 271 public void setElectronicPaymentClaimingService(ElectronicPaymentClaimingService electronicPaymentClaimingService) { 272 this.electronicPaymentClaimingService = electronicPaymentClaimingService; 273 } 274 275 /** 276 * Sets the parameterService attribute value. 277 * 278 * @param parameterService The parameterService to set. 279 */ 280 public void setParameterService(ParameterService parameterService) { 281 this.parameterService = parameterService; 282 } 283 }