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