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) {
257 if (checkIfDocumentEligibleForAutoDispproval(document)) {
258 if (!exceptionsToAutoDisapproveProcess(document, documentCompareDate)) {
259 try {
260 autoDisapprovalYearEndDocument(document, annotation);
261 LOG.info("The document with header id: " + documentHeaderId + " is automatically disapproved by this job.");
262 }catch (Exception e) {
263 LOG.error("Exception encountered trying to auto disapprove the document " + e.getMessage());
264 String message = ("Exception encountered trying to auto disapprove the document: ").concat(documentHeaderId);
265 autoDisapproveErrorReportWriterService.writeFormattedMessageLine(message);
266 }
267 }else {
268 LOG.info("Year End Auto Disapproval Exceptions: The document: " + documentHeaderId + " is NOT AUTO DISAPPROVED.");
269 }
270 }
271 }else{
272 LOG.error("Document is NULL. It should never have been null");
273 String message = ("Error: Document with id: ").concat(documentHeaderId).concat(" - Document is NULL. It should never have been null");
274 autoDisapproveErrorReportWriterService.writeFormattedMessageLine(message);
275 }
276 }
277 } catch (WorkflowRuntimeException wfre) {
278 success = false;
279 LOG.warn("Error with workflow search for documents for auto disapproval");
280 String message = ("Error with workflow search for documents for auto disapproval. The auto disapproval job is stopped.");
281 autoDisapproveErrorReportWriterService.writeFormattedMessageLine(message);
282 }
283
284 return success;
285 }
286
287
288
289
290
291
292 protected boolean checkIfDocumentEligibleForAutoDispproval(Document document) {
293 boolean documentEligible = false;
294
295 String yearEndAutoDisapproveParentDocumentType = getParameterService().getParameterValueAsString(AutoDisapproveDocumentsStep.class, OLEParameterKeyConstants.YearEndAutoDisapprovalConstants.YEAR_END_AUTO_DISAPPROVE_PARENT_DOCUMENT_TYPE);
296
297 DocumentType parentDocumentType = (DocumentType) getDocumentTypeService().getDocumentTypeByName(yearEndAutoDisapproveParentDocumentType);
298
299 String documentTypeName = document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName();
300 DocumentType childDocumentType = (DocumentType) getDocumentTypeService().getDocumentTypeByName(documentTypeName);
301 documentEligible = childDocumentType.getParentId().equals(parentDocumentType.getId());
302 return documentEligible;
303 }
304
305
306
307
308
309
310 protected Date getDocumentCompareDateParameter() {
311 Date documentCompareDate = null;
312
313 String yearEndAutoDisapproveDocumentDate = getParameterService().getParameterValueAsString(AutoDisapproveDocumentsStep.class, OLEParameterKeyConstants.YearEndAutoDisapprovalConstants.YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE);
314
315 if (ObjectUtils.isNull(yearEndAutoDisapproveDocumentDate)) {
316 LOG.warn("Exception: System Parameter YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE can not be determined.");
317 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.");
318 autoDisapproveErrorReportWriterService.writeFormattedMessageLine(message);
319 throw new RuntimeException("Exception: AutoDisapprovalStep job stopped because System Parameter YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE is null");
320 }
321
322 try {
323 Date compareDate = getDateTimeService().convertToDate(yearEndAutoDisapproveDocumentDate);
324 Calendar calendar = Calendar.getInstance();
325 calendar.setTime(compareDate);
326 calendar.set(Calendar.HOUR, 23);
327 calendar.set(Calendar.MINUTE, 59);
328 calendar.set(Calendar.SECOND, 59);
329 documentCompareDate = calendar.getTime();
330 }
331 catch (ParseException pe) {
332 LOG.warn("ParseException: System Parameter YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE can not be determined.");
333 String message = ("ParseException: The value for System Parameter YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE is invalid. The auto disapproval job is stopped.");
334 autoDisapproveErrorReportWriterService.writeFormattedMessageLine(message);
335 throw new RuntimeException("ParseException: AutoDisapprovalStep job stopped because System Parameter YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE is invalid");
336 }
337
338 return documentCompareDate;
339 }
340
341
342
343
344
345
346 protected Document findDocumentForAutoDisapproval(String documentHeaderId) {
347 Document document = null;
348
349 try {
350 document = documentService.getByDocumentHeaderId(documentHeaderId);
351 }
352 catch (WorkflowException ex) {
353 LOG.error("Exception encountered on finding the document: " + documentHeaderId, ex );
354 } catch ( UnknownDocumentTypeException ex ) {
355
356 LOG.error("Exception encountered on finding the document: " + documentHeaderId, ex );
357 }
358
359 return document;
360 }
361
362
363
364
365
366
367
368
369
370 protected boolean exceptionsToAutoDisapproveProcess(Document document, Date documentCompareDate) {
371 boolean exceptionToDisapprove = true;
372 Date createDate = null;
373
374 String documentNumber = document.getDocumentHeader().getDocumentNumber();
375
376 DateTime documentCreateDate = document.getDocumentHeader().getWorkflowDocument().getDateCreated();
377 createDate = documentCreateDate.toDate();
378
379 Calendar calendar = Calendar.getInstance();
380 calendar.setTime(documentCompareDate);
381 String strCompareDate = calendar.getTime().toString();
382
383 calendar.setTime(createDate);
384 String strCreateDate = calendar.getTime().toString();
385
386 if (createDate.before(documentCompareDate) || createDate.equals(documentCompareDate)) {
387 String documentTypeName = document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName();
388
389 ParameterEvaluator evaluatorDocumentType = SpringContext.getBean(ParameterEvaluatorService.class).getParameterEvaluator(AutoDisapproveDocumentsStep.class, OLEParameterKeyConstants.YearEndAutoDisapprovalConstants.YEAR_END_AUTO_DISAPPROVE_DOCUMENT_TYPES, documentTypeName);
390 exceptionToDisapprove = !evaluatorDocumentType.evaluationSucceeds();
391 if (exceptionToDisapprove) {
392 LOG.info("Document Id: " + documentNumber + " - Exception to Auto Disapprove: Document's type: " + documentTypeName + " is in the System Parameter For Document Types Exception List.");
393 }
394 }
395 else {
396 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);
397 exceptionToDisapprove = true;
398 }
399
400 return exceptionToDisapprove;
401 }
402
403
404
405
406
407
408
409
410 protected void autoDisapprovalYearEndDocument(Document document, String annotationForAutoDisapprovalDocument) throws Exception {
411 Person systemUser = getPersonService().getPersonByPrincipalName(getOleSelectDocumentService().getSelectParameterValue(OLEConstants.SYSTEM_USER));
412
413 Note approveNote = noteService.createNote(new Note(), document.getDocumentHeader(), systemUser.getPrincipalId());
414 approveNote.setNoteText(annotationForAutoDisapprovalDocument);
415
416 approveNote.setAuthorUniversalIdentifier(systemUser.getPrincipalId());
417
418 approveNote.setNotePostedTimestampToCurrent();
419
420 noteService.save(approveNote);
421
422 document.addNote(approveNote);
423
424 documentService.superUserDisapproveDocumentWithoutSaving(document, "Disapproval of Outstanding Documents - Year End Cancellation Process");
425 }
426
427
428
429
430
431
432 public void setDocumentService(DocumentService documentService) {
433 this.documentService = documentService;
434 }
435
436
437
438
439
440
441 public DocumentService getDocumentService() {
442 return documentService;
443 }
444
445
446
447
448
449
450 protected ParameterService getParameterService() {
451 return parameterService;
452 }
453
454
455
456
457
458
459 public void setParameterService(ParameterService parameterService) {
460 this.parameterService = parameterService;
461 }
462
463
464
465
466
467
468 protected DateTimeService getDateTimeService() {
469 return dateTimeService;
470 }
471
472
473
474
475
476
477 public void setDateTimeService(DateTimeService dateTimeService) {
478 this.dateTimeService = dateTimeService;
479 }
480
481
482
483
484
485 protected synchronized NoteService getNoteService() {
486 if (this.noteService == null) {
487 this.noteService = SpringContext.getBean(NoteService.class);
488 }
489 return this.noteService;
490 }
491
492
493
494
495
496
497 public void setNoteService(NoteService noteService) {
498 this.noteService = noteService;
499 }
500
501
502
503
504 protected PersonService getPersonService() {
505 if(personService==null)
506 personService = SpringContext.getBean(PersonService.class);
507 return personService;
508 }
509
510
511
512
513
514
515 protected DocumentTypeService getDocumentTypeService() {
516 if(documentTypeService==null)
517 documentTypeService = SpringContext.getBean(DocumentTypeService.class);
518 return documentTypeService;
519 }
520
521
522
523
524
525 protected ReportWriterService getAutoDisapproveErrorReportWriterService() {
526 return autoDisapproveErrorReportWriterService;
527 }
528
529
530
531
532
533 public void setAutoDisapproveErrorReportWriterService(ReportWriterService autoDisapproveErrorReportWriterService) {
534 this.autoDisapproveErrorReportWriterService = autoDisapproveErrorReportWriterService;
535 }
536
537 public OleSelectDocumentService getOleSelectDocumentService() {
538 if(oleSelectDocumentService == null){
539 oleSelectDocumentService = SpringContext.getBean(OleSelectDocumentService.class);
540 }
541 return oleSelectDocumentService;
542 }
543
544 public void setOleSelectDocumentService(OleSelectDocumentService oleSelectDocumentService) {
545 this.oleSelectDocumentService = oleSelectDocumentService;
546 }
547
548 }