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 }