001/*
002 * Copyright 2009 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.fp.document.validation.impl;
017
018import java.util.List;
019import java.util.Set;
020
021import org.kuali.ole.fp.document.DisbursementVoucherConstants;
022import org.kuali.ole.fp.document.DisbursementVoucherDocument;
023import org.kuali.ole.sys.OLEKeyConstants;
024import org.kuali.ole.sys.context.SpringContext;
025import org.kuali.ole.sys.document.validation.GenericValidation;
026import org.kuali.ole.sys.document.validation.event.AttributedDocumentEvent;
027import org.kuali.ole.sys.document.validation.impl.AccountingDocumentRuleBaseConstants;
028import org.kuali.rice.kew.api.action.ActionRequest;
029import org.kuali.rice.kew.api.document.WorkflowDocumentService;
030import org.kuali.rice.kew.api.exception.WorkflowException;
031import org.kuali.rice.krad.bo.Note;
032import org.kuali.rice.krad.service.DocumentService;
033import org.kuali.rice.krad.util.GlobalVariables;
034
035/**
036 * Validates that if a disbursement voucher had special handling turned off at the campus node, an extra note explaining that change has been added.
037 */
038public class DisbursementVoucherCampusSpecialHandlingValidation extends GenericValidation {
039    protected DisbursementVoucherDocument disbursementVoucherDocumentForValidation;
040    protected DocumentService documentService;
041    
042    public static final String DOCUMENT_EDITOR_ROLE_NAME = "Document Editor";
043
044    /**
045     * Carries out the validation
046     * @see org.kuali.ole.sys.document.validation.Validation#validate(org.kuali.ole.sys.document.validation.event.AttributedDocumentEvent)
047     */
048    public boolean validate(AttributedDocumentEvent event) {
049        boolean result = true;
050        
051        if (isAtNodeToCheck()) {
052            final DisbursementVoucherDocument persistedDocument = getPersistedDisbursementVoucherDocument();
053            if (isSpecialHandlingChanged(persistedDocument) && !isNoteAdded()) {
054                result = false;
055                GlobalVariables.getMessageMap().putError(AccountingDocumentRuleBaseConstants.ERROR_PATH.DOCUMENT_ERROR_PREFIX+"disbVchrSpecialHandlingCode", OLEKeyConstants.ERROR_DV_CAMPUS_TURNED_OFF_SPECIAL_HANDLING_WITHOUT_EXPLANATORY_NOTE, new String[] {});
056            }
057        }
058        
059        return result;
060    }
061
062    /**
063     * Determines if the DisbursementVoucherDocumentForValidation is at the Campus route node 
064     * @return true if the document is at the campus route node, false otherwise
065     */
066    protected boolean isAtNodeToCheck() {
067        Set<String> currentNodes = getDisbursementVoucherDocumentForValidation().getDocumentHeader().getWorkflowDocument().getCurrentNodeNames();
068        return (!currentNodes.contains(DisbursementVoucherConstants.RouteLevelNames.PURCHASING));
069    }
070    
071    /**
072     * Retrieves from the persistence store the persisted version of the given document
073     * @param document the document to find the persisted version of
074     * @return the persisted version of that document
075     */
076    protected DisbursementVoucherDocument getPersistedDisbursementVoucherDocument() {
077        try {
078            return (DisbursementVoucherDocument)getDocumentService().getByDocumentHeaderId(getDisbursementVoucherDocumentForValidation().getDocumentNumber());
079        }
080        catch (WorkflowException we) {
081            throw new RuntimeException("Could not retrieve persisted version of document "+getDisbursementVoucherDocumentForValidation().getDocumentNumber()+" for Special Handling validation", we);
082        }
083    }
084    
085    /**
086     * Determines if special handling was turned off from the DisbursementVoucherDocumentForValidation
087     * @param persistedDocument the persisted version of the document
088     * @return true if special handling was turned off, false otherwise
089     */
090    protected boolean isSpecialHandlingChanged(DisbursementVoucherDocument persistedDocument) {
091        return persistedDocument.isDisbVchrSpecialHandlingCode() != getDisbursementVoucherDocumentForValidation().isDisbVchrSpecialHandlingCode();
092    }
093    
094    /**
095     * Determines if another note was added from the time the DisbursementVoucherDocumentForValidation was persisted
096     * @param persistedDocument the persisted version of the document
097     * @return true if an extra note was added, false otherwise
098     */
099    protected boolean isNoteAdded() {
100       boolean foundNoteByCurrentApprover = false;
101       int count = 0;
102       final int noteCount = getDisbursementVoucherDocumentForValidation().getNotes().size();
103       while (!foundNoteByCurrentApprover && count < noteCount) {
104           foundNoteByCurrentApprover |= noteAddedByApproverForCurrentNode(getDisbursementVoucherDocumentForValidation().getNote(count));
105           count += 1;
106       }
107       return foundNoteByCurrentApprover;
108    }
109    
110    /**
111     * Determines if the given note was added by the current approver
112     * @param note the note to see added
113     * @return true if the note was added by the current approver, false otherwise
114     */
115    protected boolean noteAddedByApproverForCurrentNode(Note note) {
116        List<ActionRequest> actionRequests = null;
117        try {
118            actionRequests = SpringContext.getBean(WorkflowDocumentService.class).getActionRequestsForPrincipalAtNode(getDisbursementVoucherDocumentForValidation().getDocumentNumber(), getDisbursementVoucherDocumentForValidation().getDocumentHeader().getWorkflowDocument().getCurrentNodeNames().iterator().next(), note.getAuthorUniversalIdentifier());
119        } catch (NumberFormatException nfe) {
120            throw new RuntimeException("Could not convert Disbursement Voucher document number "+getDisbursementVoucherDocumentForValidation().getDocumentNumber()+" to long", nfe);
121        }
122        return actionRequests != null && !actionRequests.isEmpty();
123    }
124    
125    /**
126     * Determines the count of notes on the given document
127     * @param dvDoc a document to find the count of notes on
128     * @return the count of notes on the document
129     */
130    protected int getNoteCount(DisbursementVoucherDocument dvDoc) {
131        return dvDoc.getNotes().size();
132    }
133
134    /**
135     * Gets the disbursementVoucherDocumentForValidation attribute. 
136     * @return Returns the disbursementVoucherDocumentForValidation.
137     */
138    public DisbursementVoucherDocument getDisbursementVoucherDocumentForValidation() {
139        return disbursementVoucherDocumentForValidation;
140    }
141
142    /**
143     * Sets the disbursementVoucherDocumentForValidation attribute value.
144     * @param disbursementVoucherDocumentForValidation The disbursementVoucherDocumentForValidation to set.
145     */
146    public void setDisbursementVoucherDocumentForValidation(DisbursementVoucherDocument disbursementVoucherDocumentForValidation) {
147        this.disbursementVoucherDocumentForValidation = disbursementVoucherDocumentForValidation;
148    }
149
150    /**
151     * Sets the documentService attribute value.
152     * @param documentService The documentService to set.
153     */
154    public void setDocumentService(DocumentService documentService) {
155        this.documentService = documentService;
156    }
157 
158    public DocumentService getDocumentService() {
159        return documentService;
160    }
161}