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 }