001/*
002 * Copyright 2006 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.sys.batch.service.impl;
017
018import java.text.ParseException;
019import java.util.Calendar;
020import java.util.Collections;
021import java.util.Date;
022
023import org.joda.time.DateTime;
024import org.kuali.ole.sys.OLEConstants;
025import org.kuali.ole.sys.OLEParameterKeyConstants;
026import org.kuali.ole.sys.batch.AutoDisapproveDocumentsStep;
027import org.kuali.ole.sys.batch.service.AutoDisapproveDocumentsService;
028import org.kuali.ole.sys.context.SpringContext;
029import org.kuali.ole.sys.service.ReportWriterService;
030import org.kuali.rice.core.api.datetime.DateTimeService;
031import org.kuali.rice.core.api.parameter.ParameterEvaluator;
032import org.kuali.rice.core.api.parameter.ParameterEvaluatorService;
033import org.kuali.rice.coreservice.framework.parameter.ParameterService;
034import org.kuali.rice.kew.api.KewApiServiceLocator;
035import org.kuali.rice.kew.api.WorkflowRuntimeException;
036import org.kuali.rice.kew.api.doctype.DocumentType;
037import org.kuali.rice.kew.api.doctype.DocumentTypeService;
038import org.kuali.rice.kew.api.document.DocumentStatus;
039import org.kuali.rice.kew.api.document.search.DocumentSearchCriteria;
040import org.kuali.rice.kew.api.document.search.DocumentSearchResult;
041import org.kuali.rice.kew.api.document.search.DocumentSearchResults;
042import org.kuali.rice.kew.api.exception.WorkflowException;
043import org.kuali.rice.kim.api.identity.Person;
044import org.kuali.rice.kim.api.identity.PersonService;
045import org.kuali.rice.krad.bo.Note;
046import org.kuali.rice.krad.datadictionary.exception.UnknownDocumentTypeException;
047import org.kuali.rice.krad.document.Document;
048import org.kuali.rice.krad.service.DocumentService;
049import org.kuali.rice.krad.service.NoteService;
050import org.kuali.rice.krad.util.ObjectUtils;
051import org.springframework.transaction.annotation.Transactional;
052
053/**
054 * This class implements the AutoDisapproveDocumentsService batch job.
055 */
056@Transactional
057public class AutoDisapproveDocumentsServiceImpl implements AutoDisapproveDocumentsService {
058    protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AutoDisapproveDocumentsServiceImpl.class);
059    public static final String WORKFLOW_DOCUMENT_HEADER_ID_SEARCH_RESULT_KEY = "routeHeaderId";
060    
061    private DocumentService documentService;
062    private DocumentTypeService documentTypeService;
063    
064    private DateTimeService dateTimeService;
065    private ParameterService parameterService;
066    
067    private NoteService noteService;
068    private PersonService personService;
069    
070    private ReportWriterService autoDisapproveErrorReportWriterService;
071    
072    /**
073     * Constructs a AutoDisapproveDocumentsServiceImpl instance
074     */
075    public AutoDisapproveDocumentsServiceImpl() {
076        
077    }
078
079    /**
080     * Gathers all documents that are in ENROUTE status and auto disapproves them.
081     * @see org.kuali.ole.sys.batch.service.autoDisapproveDocumentsInEnrouteStatus#autoDisapproveDocumentsInEnrouteStatus()
082     */
083    public boolean autoDisapproveDocumentsInEnrouteStatus() {
084        boolean success = true ;
085        
086        if (systemParametersForAutoDisapproveDocumentsJobExist()) {
087            if (canAutoDisapproveJobRun()) {
088                LOG.debug("autoDisapproveDocumentsInEnrouteStatus() started");
089                
090                Person systemUser = getPersonService().getPersonByPrincipalName(OLEConstants.SYSTEM_USER);
091                
092                String principalId = systemUser.getPrincipalId();
093                String annotationForAutoDisapprovalDocument = getParameterService().getParameterValueAsString(AutoDisapproveDocumentsStep.class, OLEParameterKeyConstants.YearEndAutoDisapprovalConstants.YEAR_END_AUTO_DISAPPROVE_ANNOTATION);                
094                
095                Date documentCompareDate = getDocumentCompareDateParameter();
096                success = processAutoDisapproveDocuments(principalId, annotationForAutoDisapprovalDocument, documentCompareDate);
097            }
098        }
099        
100        return success;
101    }
102    
103    /**
104     * This method checks if the System parameters have been set up for this batch job.
105     * @result return true if the system parameters exist, else false
106     */
107    protected boolean systemParametersForAutoDisapproveDocumentsJobExist() {
108        LOG.debug("systemParametersForAutoDisapproveDocumentsJobExist() started.");
109        
110        boolean systemParametersExists = true;
111        
112        systemParametersExists &= checkIfRunDateParameterExists();
113        systemParametersExists &= checkIfParentDocumentTypeParameterExists();  
114        systemParametersExists &= checkIfDocumentCompareCreateDateParameterExists();  
115        systemParametersExists &= checkIfDocumentTypesExceptionParameterExists();          
116        systemParametersExists &= checkIfAnnotationForDisapprovalParameterExists();
117        
118        return systemParametersExists;
119    }
120    
121    /**
122     * This method checks for the system parameter for YEAR_END_AUTO_DISAPPROVE_DOCUMENTS_RUN_DATE
123     * @param outputErrorFile_ps output error file stream to write any error messages.
124     * @return true if YEAR_END_AUTO_DISAPPROVE_DOCUMENTS_RUN_DATE exists else false
125     */
126    protected boolean checkIfRunDateParameterExists() {
127        boolean parameterExists = true;
128        
129        // check to make sure the system parameter for run date check has already been setup...
130        if (!getParameterService().parameterExists(AutoDisapproveDocumentsStep.class, OLEParameterKeyConstants.YearEndAutoDisapprovalConstants.YEAR_END_AUTO_DISAPPROVE_DOCUMENT_STEP_RUN_DATE)) {
131            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");
132            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");
133            return false;
134        }
135        
136        return parameterExists;
137    }
138
139    /**
140     * This method checks for the system parameter for YEAR_END_AUTO_DISAPPROVE_PARENT_DOCUMENT_TYPE
141     * @param outputErrorFile_ps output error file stream to write any error messages.
142     * @return true if YEAR_END_AUTO_DISAPPROVE_PARENT_DOCUMENT_TYPE exists else false
143     */
144    protected boolean checkIfParentDocumentTypeParameterExists() {
145        boolean parameterExists = true;
146        
147        // check to make sure the system parameter for Parent Document Type = FP has been setup...
148        if (!getParameterService().parameterExists(AutoDisapproveDocumentsStep.class, OLEParameterKeyConstants.YearEndAutoDisapprovalConstants.YEAR_END_AUTO_DISAPPROVE_PARENT_DOCUMENT_TYPE)) {
149            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");
150            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");
151            return false;
152        }
153        
154        return parameterExists;
155    }
156    
157    /**
158     * This method checks for the system parameter for YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE
159     * @param outputErrorFile_ps output error file stream to write any error messages.
160     * @return true if YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE exists else false
161     */
162    protected boolean checkIfDocumentCompareCreateDateParameterExists() {
163        boolean parameterExists = true;
164        
165        // check to make sure the system parameter for create date to compare has been setup...
166        if (!getParameterService().parameterExists(AutoDisapproveDocumentsStep.class, OLEParameterKeyConstants.YearEndAutoDisapprovalConstants.YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE)) {
167          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");
168          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");
169          return false;
170        }
171        
172        return parameterExists;
173    }
174    
175    /**
176     * This method checks for the system parameter for YEAR_END_AUTO_DISAPPROVE_DOCUMENT_TYPES
177     * @param outputErrorFile_ps output error file stream to write any error messages.
178     * @return true if YEAR_END_AUTO_DISAPPROVE_DOCUMENT_TYPES exists else false
179     */
180    protected boolean checkIfDocumentTypesExceptionParameterExists() {
181        boolean parameterExists = true;
182        
183        // check to make sure the system parameter for Document Types that are exceptions has been setup...
184        if (!getParameterService().parameterExists(AutoDisapproveDocumentsStep.class, OLEParameterKeyConstants.YearEndAutoDisapprovalConstants.YEAR_END_AUTO_DISAPPROVE_DOCUMENT_TYPES)) {
185          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");
186          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");
187          return false;
188        }
189        
190        return parameterExists;
191    }
192
193    /**
194     * This method checks for the system parameter for YEAR_END_AUTO_DISAPPROVE_ANNOTATION
195     * @param outputErrorFile_ps output error file stream to write any error messages.
196     * @return true if YEAR_END_AUTO_DISAPPROVE_ANNOTATION exists else false
197     */
198    protected boolean checkIfAnnotationForDisapprovalParameterExists() {
199        boolean parameterExists = true;
200        
201        // check to make sure the system parameter for annotation for notes has been setup...
202        if (!getParameterService().parameterExists(AutoDisapproveDocumentsStep.class, OLEParameterKeyConstants.YearEndAutoDisapprovalConstants.YEAR_END_AUTO_DISAPPROVE_ANNOTATION)) {
203          LOG.warn("YEAR_END_AUTO_DISAPPROVE_ANNOTATION System parameter does not exist in the parameters list.  The job can not continue without this parameter");
204          autoDisapproveErrorReportWriterService.writeFormattedMessageLine("YEAR_END_AUTO_DISAPPROVE_ANNOTATION System parameter does not exist in the parameters list.  The job can not continue without this parameter");
205          return false;
206        }        
207        
208        return parameterExists;
209    }
210    
211    /**
212     * This method will compare today's date to the system parameter for year end auto disapproval run date
213     * @return true if today's date equals to the system parameter run date
214     */
215    protected boolean canAutoDisapproveJobRun() {
216      boolean autoDisapproveCanRun = true;
217      
218      // IF trunc(SYSDATE - 14/24) = v_yec_cncl_doc_run_dt THEN...FIS CODE equivalent here...
219      String yearEndAutoDisapproveRunDate = getParameterService().getParameterValueAsString(AutoDisapproveDocumentsStep.class, OLEParameterKeyConstants.YearEndAutoDisapprovalConstants.YEAR_END_AUTO_DISAPPROVE_DOCUMENT_STEP_RUN_DATE);
220      
221      String today = getDateTimeService().toDateString(getDateTimeService().getCurrentDate());
222      
223      if (!yearEndAutoDisapproveRunDate.equals(today)) {
224          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);
225          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);
226          autoDisapproveErrorReportWriterService.writeFormattedMessageLine(message);          
227          autoDisapproveCanRun = false;
228      }
229      
230      return autoDisapproveCanRun;
231    }
232    
233    /**
234     * This method will use documentsearchcriteriaDTO to search for the documents that are in enroute status and disapproves them
235     * @param principalId The principal id which is OLE-SYS System user to run the process under.
236     * @param annotation The annotation to be set as note in the note of the document.
237     * @param documentCompareDate The document create date to compare to
238     */
239    protected boolean processAutoDisapproveDocuments(String principalId, String annotation, Date documentCompareDate) {
240        boolean success = true;
241        
242        DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
243        criteria.setDocumentStatuses(Collections.singletonList(DocumentStatus.ENROUTE));
244        criteria.setSaveName(null);
245        
246        try {
247            DocumentSearchResults results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId, criteria.build());
248
249            String documentHeaderId = null;
250            
251            for (DocumentSearchResult result : results.getSearchResults()) {
252                documentHeaderId = result.getDocument().getDocumentId();
253                Document document = findDocumentForAutoDisapproval(documentHeaderId);
254                if (document != null) {
255                    if (checkIfDocumentEligibleForAutoDispproval(document)) {
256                        if (!exceptionsToAutoDisapproveProcess(document, documentCompareDate)) {
257                            try {
258                                autoDisapprovalYearEndDocument(document, annotation);
259                                LOG.info("The document with header id: " + documentHeaderId + " is automatically disapproved by this job.");
260                            }catch (Exception e) {
261                                LOG.error("Exception encountered trying to auto disapprove the document " + e.getMessage());
262                                String message = ("Exception encountered trying to auto disapprove the document: ").concat(documentHeaderId);                                    
263                                autoDisapproveErrorReportWriterService.writeFormattedMessageLine(message); 
264                            }
265                        }else {
266                            LOG.info("Year End Auto Disapproval Exceptions:  The document: " + documentHeaderId + " is NOT AUTO DISAPPROVED.");
267                        }
268                    } 
269                }else{
270                        LOG.error("Document is NULL.  It should never have been null");
271                        String message = ("Error: Document with id: ").concat(documentHeaderId).concat(" - Document is NULL.  It should never have been null");
272                        autoDisapproveErrorReportWriterService.writeFormattedMessageLine(message);                         
273                }
274            } 
275       } catch (WorkflowRuntimeException wfre) {
276            success = false;
277            LOG.warn("Error with workflow search for documents for auto disapproval");
278            String message = ("Error with workflow search for documents for auto disapproval.  The auto disapproval job is stopped.");
279            autoDisapproveErrorReportWriterService.writeFormattedMessageLine(message);                                     
280            }
281       
282       return success;
283    }
284        
285    /**
286     * This method will check the document's document type against the parent document type as specified in the system parameter
287     * @param document
288     * @return true if  document type of the document is a child of the parent document.
289     */
290    protected boolean checkIfDocumentEligibleForAutoDispproval(Document document) {
291        boolean documentEligible = false;
292     
293        String yearEndAutoDisapproveParentDocumentType = getParameterService().getParameterValueAsString(AutoDisapproveDocumentsStep.class, OLEParameterKeyConstants.YearEndAutoDisapprovalConstants.YEAR_END_AUTO_DISAPPROVE_PARENT_DOCUMENT_TYPE);
294        
295        DocumentType parentDocumentType = (DocumentType) getDocumentTypeService().getDocumentTypeByName(yearEndAutoDisapproveParentDocumentType);
296     
297        String documentTypeName = document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName();
298        DocumentType childDocumentType = (DocumentType) getDocumentTypeService().getDocumentTypeByName(documentTypeName);
299        documentEligible = childDocumentType.getParentId().equals(parentDocumentType.getId());     
300        return documentEligible;
301    }
302    
303    /**
304     * This method finds the date in the system parameters that will be used to compare the create date.
305     * It then adds 23 hours, 59 minutes and 59 seconds to the compare date.
306     * @return  documentCompareDate returns YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE from the system parameter
307     */
308    protected Date getDocumentCompareDateParameter() {
309        Date documentCompareDate = null;
310        
311        String yearEndAutoDisapproveDocumentDate = getParameterService().getParameterValueAsString(AutoDisapproveDocumentsStep.class, OLEParameterKeyConstants.YearEndAutoDisapprovalConstants.YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE);
312        
313        if (ObjectUtils.isNull(yearEndAutoDisapproveDocumentDate)) {
314            LOG.warn("Exception: System Parameter YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE can not be determined.");
315            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.");
316            autoDisapproveErrorReportWriterService.writeFormattedMessageLine(message);                         
317            throw new RuntimeException("Exception: AutoDisapprovalStep job stopped because System Parameter YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE is null");   
318        }
319        
320        try {
321            Date compareDate = getDateTimeService().convertToDate(yearEndAutoDisapproveDocumentDate);
322            Calendar calendar = Calendar.getInstance();
323            calendar.setTime(compareDate);
324            calendar.set(Calendar.HOUR, 23);
325            calendar.set(Calendar.MINUTE, 59);
326            calendar.set(Calendar.SECOND, 59);
327            documentCompareDate = calendar.getTime();
328        }
329        catch (ParseException pe) {
330            LOG.warn("ParseException: System Parameter YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE can not be determined.");
331            String message = ("ParseException: The value for System Parameter YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE is invalid.  The auto disapproval job is stopped.");
332            autoDisapproveErrorReportWriterService.writeFormattedMessageLine(message);                         
333            throw new RuntimeException("ParseException: AutoDisapprovalStep job stopped because System Parameter YEAR_END_AUTO_DISAPPROVE_DOCUMENT_CREATE_DATE is invalid");   
334        }
335        
336        return documentCompareDate;
337    }
338    
339    /**
340     * This method finds the document for the given document header id
341     * @param documentHeaderId
342     * @return document The document in the workflow that matches the document header id.
343     */
344    protected Document findDocumentForAutoDisapproval(String documentHeaderId) {
345        Document document = null;
346        
347        try {
348            document = documentService.getByDocumentHeaderId(documentHeaderId);
349        }
350        catch (WorkflowException ex) {
351            LOG.error("Exception encountered on finding the document: " + documentHeaderId, ex );
352        } catch ( UnknownDocumentTypeException ex ) {
353            // don't blow up just because a document type is not installed (but don't return it either)
354            LOG.error("Exception encountered on finding the document: " + documentHeaderId, ex );
355        }
356        
357        return document;
358    }
359        
360    /**
361     * This method first checks the document's create date with system parameter date and then
362     * checks the document type name to the system parameter values and returns true if the type name exists
363     * @param document document to check for its document type,  documentCompareDate the system parameter specified date
364     * to compare the current date to this date.
365     * @return true if  document's create date is <= documentCompareDate and if document type is not in the
366     * system parameter document types that are set to disallow.
367     */
368    protected boolean exceptionsToAutoDisapproveProcess(Document document, Date documentCompareDate) {
369        boolean exceptionToDisapprove = true;
370        Date createDate = null;
371
372        String documentNumber =  document.getDocumentHeader().getDocumentNumber();
373        
374        DateTime documentCreateDate = document.getDocumentHeader().getWorkflowDocument().getDateCreated();
375        createDate = documentCreateDate.toDate();
376        
377        Calendar calendar = Calendar.getInstance();
378        calendar.setTime(documentCompareDate);
379        String strCompareDate = calendar.getTime().toString();
380        
381        calendar.setTime(createDate);
382        String strCreateDate = calendar.getTime().toString();
383        
384        if (createDate.before(documentCompareDate) || createDate.equals(documentCompareDate)) {
385            String documentTypeName = document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName();
386            
387            ParameterEvaluator evaluatorDocumentType = /*REFACTORME*/SpringContext.getBean(ParameterEvaluatorService.class).getParameterEvaluator(AutoDisapproveDocumentsStep.class, OLEParameterKeyConstants.YearEndAutoDisapprovalConstants.YEAR_END_AUTO_DISAPPROVE_DOCUMENT_TYPES, documentTypeName);
388            exceptionToDisapprove = !evaluatorDocumentType.evaluationSucceeds();
389            if (exceptionToDisapprove) {
390                LOG.info("Document Id: " + documentNumber + " - Exception to Auto Disapprove:  Document's type: " + documentTypeName + " is in the System Parameter For Document Types Exception List.");
391            }
392        }
393        else {
394            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);            
395            exceptionToDisapprove = true;
396        }
397                
398        return exceptionToDisapprove;
399    }
400    
401    /** autoDisapprovalYearEndDocument uses DocumentServiceImpl to  mark as disapproved by calling
402     *  DocumentServiceImpl's disapproveDocument method.
403     * 
404     *@param document The document that needs to be auto disapproved in this process
405     *@param annotationForAutoDisapprovalDocument The annotationForAutoDisapprovalDocument that is set as annotations when canceling the edoc.
406     *     
407     */
408    protected void autoDisapprovalYearEndDocument(Document document, String annotationForAutoDisapprovalDocument)  throws Exception {
409        Person systemUser = getPersonService().getPersonByPrincipalName(OLEConstants.SYSTEM_USER);      
410        
411        Note approveNote = noteService.createNote(new Note(), document.getDocumentHeader(), systemUser.getPrincipalId());
412        approveNote.setNoteText(annotationForAutoDisapprovalDocument);
413
414        approveNote.setAuthorUniversalIdentifier(systemUser.getPrincipalId());
415        
416        approveNote.setNotePostedTimestampToCurrent();
417        
418        noteService.save(approveNote);
419        
420        document.addNote(approveNote);
421        
422        documentService.superUserDisapproveDocumentWithoutSaving(document, "Disapproval of Outstanding Documents - Year End Cancellation Process");
423    }
424        
425    /**
426     * Sets the documentService attribute value.
427     * 
428     * @param documentService The documentService to set.
429     */    
430    public void setDocumentService(DocumentService documentService) {
431        this.documentService = documentService;
432    }
433    
434    /**
435     * Gets the documentService attribute.
436     * 
437     * @return Returns the documentService.
438     */
439    public DocumentService getDocumentService() {
440        return documentService;
441    }   
442    
443    /**
444     * Gets the parameterService attribute.
445     * 
446     * @return Returns the parameterService.
447     */    
448    protected ParameterService getParameterService() {
449        return parameterService;
450    }
451
452    /**
453     * Sets the parameterService attribute value.
454     * 
455     * @param parameterService The parameterService to set.
456     */    
457    public void setParameterService(ParameterService parameterService) {
458        this.parameterService = parameterService;
459    }
460
461    /**
462     * Gets the dateTimeService attribute.
463     * 
464     * @return Returns the dateTimeService.
465     */
466    protected DateTimeService getDateTimeService() {
467        return dateTimeService;
468    }
469
470    /**
471     * Sets the dateTimeService attribute value.
472     * 
473     * @param dateTimeService The dateTimeService to set.
474     */
475    public void setDateTimeService(DateTimeService dateTimeService) {
476        this.dateTimeService = dateTimeService;
477    }
478    
479    /**
480     * Gets the NoteService, lazily initializing if necessary
481     * @return the NoteService
482     */
483    protected synchronized NoteService getNoteService() {
484        if (this.noteService == null) {
485            this.noteService = SpringContext.getBean(NoteService.class);
486        }
487        return this.noteService;
488    }
489    
490    /**
491     * Sets the noteService attribute value.
492     * 
493     * @param noteService The noteService to set.
494     */
495    public void setNoteService(NoteService noteService) {
496        this.noteService = noteService;
497    }
498
499    /**
500     * @return Returns the personService.
501     */
502    protected PersonService getPersonService() {
503        if(personService==null)
504            personService = SpringContext.getBean(PersonService.class);
505        return personService;
506    }
507    
508    /**
509     * Gets the documentTypeService attribute.
510     * 
511     * @return Returns the documentTypeService.
512     */
513    protected DocumentTypeService getDocumentTypeService() {
514        if(documentTypeService==null)
515            documentTypeService = SpringContext.getBean(DocumentTypeService.class);
516        return documentTypeService;
517    }
518    
519    /**
520     * Gets the autoDisapproveErrorReportWriterService attribute. 
521     * @return Returns the autoDisapproveErrorReportWriterService.
522     */
523    protected ReportWriterService getAutoDisapproveErrorReportWriterService() {
524        return autoDisapproveErrorReportWriterService;
525    }
526    
527    /**
528     * Sets the autoDisapproveErrorReportWriterService attribute value.
529     * @param autoDisapproveErrorReportWriterService The autoDisapproveErrorReportWriterService to set.
530     */
531    public void setAutoDisapproveErrorReportWriterService(ReportWriterService autoDisapproveErrorReportWriterService) {
532        this.autoDisapproveErrorReportWriterService = autoDisapproveErrorReportWriterService;
533    }
534    
535}