1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.ole.sys.batch.service.impl;
17
18 import java.text.ParseException;
19 import java.util.Calendar;
20 import java.util.Collections;
21 import java.util.Date;
22
23 import org.joda.time.DateTime;
24 import org.kuali.ole.select.document.service.OleSelectDocumentService;
25 import org.kuali.ole.sys.OLEConstants;
26 import org.kuali.ole.sys.OLEParameterKeyConstants;
27 import org.kuali.ole.sys.batch.AutoDisapproveDocumentsStep;
28 import org.kuali.ole.sys.batch.service.AutoDisapproveDocumentsService;
29 import org.kuali.ole.sys.context.SpringContext;
30 import org.kuali.ole.sys.service.ReportWriterService;
31 import org.kuali.rice.core.api.datetime.DateTimeService;
32 import org.kuali.rice.core.api.parameter.ParameterEvaluator;
33 import org.kuali.rice.core.api.parameter.ParameterEvaluatorService;
34 import org.kuali.rice.coreservice.framework.parameter.ParameterService;
35 import org.kuali.rice.kew.api.KewApiServiceLocator;
36 import org.kuali.rice.kew.api.WorkflowRuntimeException;
37 import org.kuali.rice.kew.api.doctype.DocumentType;
38 import org.kuali.rice.kew.api.doctype.DocumentTypeService;
39 import org.kuali.rice.kew.api.document.DocumentStatus;
40 import org.kuali.rice.kew.api.document.search.DocumentSearchCriteria;
41 import org.kuali.rice.kew.api.document.search.DocumentSearchResult;
42 import org.kuali.rice.kew.api.document.search.DocumentSearchResults;
43 import org.kuali.rice.kew.api.exception.WorkflowException;
44 import org.kuali.rice.kim.api.identity.Person;
45 import org.kuali.rice.kim.api.identity.PersonService;
46 import org.kuali.rice.krad.bo.Note;
47 import org.kuali.rice.krad.datadictionary.exception.UnknownDocumentTypeException;
48 import org.kuali.rice.krad.document.Document;
49 import org.kuali.rice.krad.service.DocumentService;
50 import org.kuali.rice.krad.service.NoteService;
51 import org.kuali.rice.krad.util.ObjectUtils;
52 import org.springframework.transaction.annotation.Transactional;
53
54
55
56
57 @Transactional
58 public class AutoDisapproveDocumentsServiceImpl implements AutoDisapproveDocumentsService {
59 protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AutoDisapproveDocumentsServiceImpl.class);
60 public static final String WORKFLOW_DOCUMENT_HEADER_ID_SEARCH_RESULT_KEY = "routeHeaderId";
61
62 private DocumentService documentService;
63 private DocumentTypeService documentTypeService;
64
65 private DateTimeService dateTimeService;
66 private ParameterService parameterService;
67
68 private NoteService noteService;
69 private PersonService personService;
70
71 private ReportWriterService autoDisapproveErrorReportWriterService;
72 private OleSelectDocumentService oleSelectDocumentService;
73
74
75
76
77 public AutoDisapproveDocumentsServiceImpl() {
78
79 }
80
81
82
83
84
85 public boolean autoDisapproveDocumentsInEnrouteStatus() {
86 boolean success = true ;
87
88 if (systemParametersForAutoDisapproveDocumentsJobExist()) {
89 if (canAutoDisapproveJobRun()) {
90 LOG.debug("autoDisapproveDocumentsInEnrouteStatus() started");
91
92 Person systemUser = getPersonService().getPersonByPrincipalName(getOleSelectDocumentService().getSelectParameterValue(OLEConstants.SYSTEM_USER));
93
94 String principalId = systemUser.getPrincipalId();
95 String annotationForAutoDisapprovalDocument = getParameterService().getParameterValueAsString(AutoDisapproveDocumentsStep.class, OLEParameterKeyConstants.YearEndAutoDisapprovalConstants.YEAR_END_AUTO_DISAPPROVE_ANNOTATION);
96
97 Date documentCompareDate = getDocumentCompareDateParameter();
98 success = processAutoDisapproveDocuments(principalId, annotationForAutoDisapprovalDocument, documentCompareDate);
99 }
100 }
101
102 return success;
103 }
104
105
106
107
108
109 protected boolean systemParametersForAutoDisapproveDocumentsJobExist() {
110 LOG.debug("systemParametersForAutoDisapproveDocumentsJobExist() started.");
111
112 boolean systemParametersExists = true;
113
114 systemParametersExists &= checkIfRunDateParameterExists();
115 systemParametersExists &= checkIfParentDocumentTypeParameterExists();
116 systemParametersExists &= checkIfDocumentCompareCreateDateParameterExists();
117 systemParametersExists &= checkIfDocumentTypesExceptionParameterExists();
118 systemParametersExists &= checkIfAnnotationForDisapprovalParameterExists();
119
120 return systemParametersExists;
121 }
122
123
124
125
126
127
128 protected boolean checkIfRunDateParameterExists() {
129 boolean parameterExists = true;
130
131
132 if (!getParameterService().parameterExists(AutoDisapproveDocumentsStep.class, OLEParameterKeyConstants.YearEndAutoDisapprovalConstants.YEAR_END_AUTO_DISAPPROVE_DOCUMENT_STEP_RUN_DATE)) {
133 LOG.warn("YEAR_END_AUTO_DISAPPROVE_DOCUMENT_RUN_DATE System parameter does not exist in the parameters list. The job can not continue without this parameter");
134 autoDisapproveErrorReportWriterService.writeFormattedMessageLine("YEAR_END_AUTO_DISAPPROVE_DOCUMENTS_RUN_DATE System parameter does not exist in the parameters list. The job can not continue without this parameter");
135 return false;
136 }
137
138 return parameterExists;
139 }
140
141
142
143
144
145
146 protected boolean checkIfParentDocumentTypeParameterExists() {
147 boolean parameterExists = true;
148
149
150 if (!getParameterService().parameterExists(AutoDisapproveDocumentsStep.class, OLEParameterKeyConstants.YearEndAutoDisapprovalConstants.YEAR_END_AUTO_DISAPPROVE_PARENT_DOCUMENT_TYPE)) {
151 LOG.warn("YEAR_END_AUTO_DISAPPROVE_PARENT_DOCUMENT_TYPE System parameter does not exist in the parameters list. The job can not continue without this parameter");
152 autoDisapproveErrorReportWriterService.writeFormattedMessageLine("YEAR_END_AUTO_DISAPPROVE_PARENT_DOCUMENT_TYPE System parameter does not exist in the parameters list. The job can not continue without this parameter");
153 return false;
154 }
155
156 return parameterExists;
157 }
158
159
160
161
162
163
164 protected boolean checkIfDocumentCompareCreateDateParameterExists() {
165 boolean parameterExists = true;
166
167
168 if (!getParameterService().parameterExists(AutoDisapproveDocumentsStep.class, OLEParameterKeyConstants.YearEndAutoDisapprovalConstants.YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE)) {
169 LOG.warn("YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE System parameter does not exist in the parameters list. The job can not continue without this parameter");
170 autoDisapproveErrorReportWriterService.writeFormattedMessageLine("YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE System parameter does not exist in the parameters list. The job can not continue without this parameter");
171 return false;
172 }
173
174 return parameterExists;
175 }
176
177
178
179
180
181
182 protected boolean checkIfDocumentTypesExceptionParameterExists() {
183 boolean parameterExists = true;
184
185
186 if (!getParameterService().parameterExists(AutoDisapproveDocumentsStep.class, OLEParameterKeyConstants.YearEndAutoDisapprovalConstants.YEAR_END_AUTO_DISAPPROVE_DOCUMENT_TYPES)) {
187 LOG.warn("YEAR_END_AUTO_DISAPPROVE_DOCUMENT_TYPES System parameter does not exist in the parameters list. The job can not continue without this parameter");
188 autoDisapproveErrorReportWriterService.writeFormattedMessageLine("YEAR_END_AUTO_DISAPPROVE_DOCUMENT_TYPES System parameter does not exist in the parameters list. The job can not continue without this parameter");
189 return false;
190 }
191
192 return parameterExists;
193 }
194
195
196
197
198
199
200 protected boolean checkIfAnnotationForDisapprovalParameterExists() {
201 boolean parameterExists = true;
202
203
204 if (!getParameterService().parameterExists(AutoDisapproveDocumentsStep.class, OLEParameterKeyConstants.YearEndAutoDisapprovalConstants.YEAR_END_AUTO_DISAPPROVE_ANNOTATION)) {
205 LOG.warn("YEAR_END_AUTO_DISAPPROVE_ANNOTATION System parameter does not exist in the parameters list. The job can not continue without this parameter");
206 autoDisapproveErrorReportWriterService.writeFormattedMessageLine("YEAR_END_AUTO_DISAPPROVE_ANNOTATION System parameter does not exist in the parameters list. The job can not continue without this parameter");
207 return false;
208 }
209
210 return parameterExists;
211 }
212
213
214
215
216
217 protected boolean canAutoDisapproveJobRun() {
218 boolean autoDisapproveCanRun = true;
219
220
221 String yearEndAutoDisapproveRunDate = getParameterService().getParameterValueAsString(AutoDisapproveDocumentsStep.class, OLEParameterKeyConstants.YearEndAutoDisapprovalConstants.YEAR_END_AUTO_DISAPPROVE_DOCUMENT_STEP_RUN_DATE);
222
223 String today = getDateTimeService().toDateString(getDateTimeService().getCurrentDate());
224
225 if (!yearEndAutoDisapproveRunDate.equals(today)) {
226 LOG.warn("YEAR_END_AUTO_DISAPPROVE_DOCUMENTS_RUN_DATE: Automatic disapproval bypassed. The date on which the auto disapproval step should run: " + yearEndAutoDisapproveRunDate + " does not equal to today's date: " + today);
227 String message = ("YEAR_END_AUTO_DISAPPROVE_DOCUMENTS_RUN_DATE: Automatic disapproval bypassed. The date on which the auto disapproval step should run: ").concat(yearEndAutoDisapproveRunDate).concat(" does not equal to today's date: ").concat(today);
228 autoDisapproveErrorReportWriterService.writeFormattedMessageLine(message);
229 autoDisapproveCanRun = false;
230 }
231
232 return autoDisapproveCanRun;
233 }
234
235
236
237
238
239
240
241 protected boolean processAutoDisapproveDocuments(String principalId, String annotation, Date documentCompareDate) {
242 boolean success = true;
243
244 DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
245 criteria.setDocumentStatuses(Collections.singletonList(DocumentStatus.ENROUTE));
246 criteria.setSaveName(null);
247
248 try {
249 DocumentSearchResults results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId, criteria.build());
250
251 String documentHeaderId = null;
252
253 for (DocumentSearchResult result : results.getSearchResults()) {
254 documentHeaderId = result.getDocument().getDocumentId();
255 Document document = findDocumentForAutoDisapproval(documentHeaderId);
256 if (document != null && document.getDocumentHeader() != null && document.getDocumentHeader().getWorkflowDocument() != null) {
257 if(document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName().equals(OLEConstants.FinancialDocumentTypeCodes.PAYMENT_REQUEST) ||
258 document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName().equals(OLEConstants.FinancialDocumentTypeCodes.INVOICE) ||
259 document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName().equals(OLEConstants.FinancialDocumentTypeCodes.VENDOR_CREDIT_MEMO)) {
260 if (checkIfDocumentEligibleForAutoDispproval(document)) {
261 if (!exceptionsToAutoDisapproveProcess(document, documentCompareDate)) {
262 try {
263 autoDisapprovalYearEndDocument(document, annotation);
264 LOG.info("The document with header id: " + documentHeaderId + " is automatically disapproved by this job.");
265 }catch (Exception e) {
266 LOG.error("Exception encountered trying to auto disapprove the document " + e.getMessage());
267 String message = ("Exception encountered trying to auto disapprove the document: ").concat(documentHeaderId);
268 autoDisapproveErrorReportWriterService.writeFormattedMessageLine(message);
269 }
270 }else {
271 LOG.info("Year End Auto Disapproval Exceptions: The document: " + documentHeaderId + " is NOT AUTO DISAPPROVED.");
272 }
273 }
274 }
275 }else{
276 LOG.error("Document is NULL. It should never have been null");
277 String message = ("Error: Document with id: ").concat(documentHeaderId).concat(" - Document is NULL. It should never have been null");
278 autoDisapproveErrorReportWriterService.writeFormattedMessageLine(message);
279 }
280 }
281 } catch (WorkflowRuntimeException wfre) {
282 success = false;
283 LOG.warn("Error with workflow search for documents for auto disapproval");
284 String message = ("Error with workflow search for documents for auto disapproval. The auto disapproval job is stopped.");
285 autoDisapproveErrorReportWriterService.writeFormattedMessageLine(message);
286 }
287
288 return success;
289 }
290
291
292
293
294
295
296 protected boolean checkIfDocumentEligibleForAutoDispproval(Document document) {
297 boolean documentEligible = false;
298
299 String yearEndAutoDisapproveParentDocumentType = getParameterService().getParameterValueAsString(AutoDisapproveDocumentsStep.class, OLEParameterKeyConstants.YearEndAutoDisapprovalConstants.YEAR_END_AUTO_DISAPPROVE_PARENT_DOCUMENT_TYPE);
300
301 DocumentType parentDocumentType = (DocumentType) getDocumentTypeService().getDocumentTypeByName(yearEndAutoDisapproveParentDocumentType);
302
303 String documentTypeName = document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName();
304 DocumentType childDocumentType = (DocumentType) getDocumentTypeService().getDocumentTypeByName(documentTypeName);
305 documentEligible = childDocumentType.getParentId().equals(parentDocumentType.getId());
306 return documentEligible;
307 }
308
309
310
311
312
313
314 protected Date getDocumentCompareDateParameter() {
315 Date documentCompareDate = null;
316
317 String yearEndAutoDisapproveDocumentDate = getParameterService().getParameterValueAsString(AutoDisapproveDocumentsStep.class, OLEParameterKeyConstants.YearEndAutoDisapprovalConstants.YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE);
318
319 if (ObjectUtils.isNull(yearEndAutoDisapproveDocumentDate)) {
320 LOG.warn("Exception: System Parameter YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE can not be determined.");
321 String message = ("Exception: The value for System Parameter YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE can not be determined. The auto disapproval job is stopped.");
322 autoDisapproveErrorReportWriterService.writeFormattedMessageLine(message);
323 throw new RuntimeException("Exception: AutoDisapprovalStep job stopped because System Parameter YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE is null");
324 }
325
326 try {
327 Date compareDate = getDateTimeService().convertToDate(yearEndAutoDisapproveDocumentDate);
328 Calendar calendar = Calendar.getInstance();
329 calendar.setTime(compareDate);
330 calendar.set(Calendar.HOUR, 23);
331 calendar.set(Calendar.MINUTE, 59);
332 calendar.set(Calendar.SECOND, 59);
333 documentCompareDate = calendar.getTime();
334 }
335 catch (ParseException pe) {
336 LOG.warn("ParseException: System Parameter YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE can not be determined.");
337 String message = ("ParseException: The value for System Parameter YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE is invalid. The auto disapproval job is stopped.");
338 autoDisapproveErrorReportWriterService.writeFormattedMessageLine(message);
339 throw new RuntimeException("ParseException: AutoDisapprovalStep job stopped because System Parameter YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE is invalid");
340 }
341
342 return documentCompareDate;
343 }
344
345
346
347
348
349
350 protected Document findDocumentForAutoDisapproval(String documentHeaderId) {
351 Document document = null;
352
353 try {
354 document = documentService.getByDocumentHeaderId(documentHeaderId);
355 }
356 catch (WorkflowException ex) {
357 LOG.error("Exception encountered on finding the document: " + documentHeaderId, ex );
358 } catch ( UnknownDocumentTypeException ex ) {
359
360 LOG.error("Exception encountered on finding the document: " + documentHeaderId, ex );
361 }
362
363 return document;
364 }
365
366
367
368
369
370
371
372
373
374 protected boolean exceptionsToAutoDisapproveProcess(Document document, Date documentCompareDate) {
375 boolean exceptionToDisapprove = true;
376 Date createDate = null;
377
378 String documentNumber = document.getDocumentHeader().getDocumentNumber();
379
380 DateTime documentCreateDate = document.getDocumentHeader().getWorkflowDocument().getDateCreated();
381 createDate = documentCreateDate.toDate();
382
383 Calendar calendar = Calendar.getInstance();
384 calendar.setTime(documentCompareDate);
385 String strCompareDate = calendar.getTime().toString();
386
387 calendar.setTime(createDate);
388 String strCreateDate = calendar.getTime().toString();
389
390 if (createDate.before(documentCompareDate) || createDate.equals(documentCompareDate)) {
391 String documentTypeName = document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName();
392
393 ParameterEvaluator evaluatorDocumentType = SpringContext.getBean(ParameterEvaluatorService.class).getParameterEvaluator(AutoDisapproveDocumentsStep.class, OLEParameterKeyConstants.YearEndAutoDisapprovalConstants.YEAR_END_AUTO_DISAPPROVE_DOCUMENT_TYPES, documentTypeName);
394 exceptionToDisapprove = !evaluatorDocumentType.evaluationSucceeds();
395 if (exceptionToDisapprove) {
396 LOG.info("Document Id: " + documentNumber + " - Exception to Auto Disapprove: Document's type: " + documentTypeName + " is in the System Parameter For Document Types Exception List.");
397 }
398 }
399 else {
400 LOG.info("Document Id: " + documentNumber + " - Exception to Auto Disapprove: Document's create date: " + strCreateDate + " is NOT less than or equal to System Parameter Compare Date: " + strCompareDate);
401 exceptionToDisapprove = true;
402 }
403
404 return exceptionToDisapprove;
405 }
406
407
408
409
410
411
412
413
414 protected void autoDisapprovalYearEndDocument(Document document, String annotationForAutoDisapprovalDocument) throws Exception {
415 Person systemUser = getPersonService().getPersonByPrincipalName(getOleSelectDocumentService().getSelectParameterValue(OLEConstants.SYSTEM_USER));
416
417 Note approveNote = noteService.createNote(new Note(), document.getDocumentHeader(), systemUser.getPrincipalId());
418 approveNote.setNoteText(annotationForAutoDisapprovalDocument);
419
420 approveNote.setAuthorUniversalIdentifier(systemUser.getPrincipalId());
421
422 approveNote.setNotePostedTimestampToCurrent();
423
424 noteService.save(approveNote);
425
426 document.addNote(approveNote);
427
428 documentService.superUserDisapproveDocumentWithoutSaving(document, "Disapproval of Outstanding Documents - Year End Cancellation Process");
429 }
430
431
432
433
434
435
436 public void setDocumentService(DocumentService documentService) {
437 this.documentService = documentService;
438 }
439
440
441
442
443
444
445 public DocumentService getDocumentService() {
446 return documentService;
447 }
448
449
450
451
452
453
454 protected ParameterService getParameterService() {
455 return parameterService;
456 }
457
458
459
460
461
462
463 public void setParameterService(ParameterService parameterService) {
464 this.parameterService = parameterService;
465 }
466
467
468
469
470
471
472 protected DateTimeService getDateTimeService() {
473 return dateTimeService;
474 }
475
476
477
478
479
480
481 public void setDateTimeService(DateTimeService dateTimeService) {
482 this.dateTimeService = dateTimeService;
483 }
484
485
486
487
488
489 protected synchronized NoteService getNoteService() {
490 if (this.noteService == null) {
491 this.noteService = SpringContext.getBean(NoteService.class);
492 }
493 return this.noteService;
494 }
495
496
497
498
499
500
501 public void setNoteService(NoteService noteService) {
502 this.noteService = noteService;
503 }
504
505
506
507
508 protected PersonService getPersonService() {
509 if(personService==null)
510 personService = SpringContext.getBean(PersonService.class);
511 return personService;
512 }
513
514
515
516
517
518
519 protected DocumentTypeService getDocumentTypeService() {
520 if(documentTypeService==null)
521 documentTypeService = SpringContext.getBean(DocumentTypeService.class);
522 return documentTypeService;
523 }
524
525
526
527
528
529 protected ReportWriterService getAutoDisapproveErrorReportWriterService() {
530 return autoDisapproveErrorReportWriterService;
531 }
532
533
534
535
536
537 public void setAutoDisapproveErrorReportWriterService(ReportWriterService autoDisapproveErrorReportWriterService) {
538 this.autoDisapproveErrorReportWriterService = autoDisapproveErrorReportWriterService;
539 }
540
541 public OleSelectDocumentService getOleSelectDocumentService() {
542 if(oleSelectDocumentService == null){
543 oleSelectDocumentService = SpringContext.getBean(OleSelectDocumentService.class);
544 }
545 return oleSelectDocumentService;
546 }
547
548 public void setOleSelectDocumentService(OleSelectDocumentService oleSelectDocumentService) {
549 this.oleSelectDocumentService = oleSelectDocumentService;
550 }
551
552 }