View Javadoc
1   /*
2    * Copyright 2008 The Kuali Foundation
3    * 
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    * http://www.opensource.org/licenses/ecl2.php
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.ole.fp.document.validation.impl;
17  
18  import java.util.ArrayList;
19  import java.util.List;
20  import java.util.Set;
21  
22  import org.kuali.ole.sys.OLEPropertyConstants;
23  import org.kuali.ole.sys.OleAuthorizationConstants;
24  import org.kuali.ole.sys.businessobject.AccountingLine;
25  import org.kuali.ole.sys.context.SpringContext;
26  import org.kuali.ole.sys.document.AccountingDocument;
27  import org.kuali.ole.sys.document.authorization.AccountingLineAuthorizer;
28  import org.kuali.ole.sys.document.validation.event.AttributedDocumentEvent;
29  import org.kuali.ole.sys.document.validation.impl.AccountingLineAccessibleValidation;
30  import org.kuali.rice.kew.api.WorkflowDocument;
31  import org.kuali.rice.kim.api.identity.Person;
32  import org.kuali.rice.kns.document.authorization.TransactionalDocumentAuthorizer;
33  import org.kuali.rice.kns.document.authorization.TransactionalDocumentPresentationController;
34  import org.kuali.rice.kns.service.DocumentHelperService;
35  import org.kuali.rice.krad.util.GlobalVariables;
36  
37  public class DisbursementVoucherAccountingLineAccessibleValidation extends AccountingLineAccessibleValidation {
38      protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DisbursementVoucherAccountingLineAccessibleValidation.class);
39      protected AccountingLine oldAccountingLineForValidation;
40  
41      /**
42       * Validates that the given accounting line is accessible for editing by the current user. <strong>This method expects a
43       * document as the first parameter and an accounting line as the second</strong>
44       * 
45       * @see org.kuali.ole.sys.document.validation.impl.AccountingLineAccessibleValidation#validate(org.kuali.ole.sys.document.validation.event.AttributedDocumentEvent)
46       */
47      @Override
48      public boolean validate(AttributedDocumentEvent event) {
49          LOG.debug("validate start");
50  
51          Person financialSystemUser = GlobalVariables.getUserSession().getPerson();
52          AccountingDocument accountingDocument = this.getAccountingDocumentForValidation();
53          AccountingLine accountingLineForValidation = this.getAccountingLineForValidation();
54  
55          final AccountingLineAuthorizer accountingLineAuthorizer = lookupAccountingLineAuthorizer();
56          final boolean lineIsAccessible = accountingLineAuthorizer.hasEditPermissionOnAccountingLine(accountingDocument, accountingLineForValidation, getAccountingLineCollectionProperty(), financialSystemUser, true);
57          boolean isAccessible = accountingLineAuthorizer.hasEditPermissionOnField(accountingDocument, accountingLineForValidation, getAccountingLineCollectionProperty(), OLEPropertyConstants.ACCOUNT_NUMBER, lineIsAccessible, true, financialSystemUser);
58  
59          // get the authorizer class to check for special conditions routing and if the user is part of a particular workgroup
60          // but only if the document is enroute
61          WorkflowDocument workflowDocument = accountingDocument.getDocumentHeader().getWorkflowDocument();
62          if (!isAccessible && workflowDocument.isEnroute()) {
63          	
64          	if (oldAccountingLineForValidation == null || accountUnchanged(accountingLineForValidation, oldAccountingLineForValidation)) {
65          		isAccessible = true;
66          	} else {
67                  // if approval is requested and the user has required edit permission, then the line is accessible
68                  List<String> candidateEditModes = this.getCandidateEditModes();
69                  if (workflowDocument.isApprovalRequested() && this.hasRequiredEditMode(accountingDocument, financialSystemUser, candidateEditModes)) {
70                      isAccessible = true;
71                  }
72          	}
73          }
74  
75          // report errors if the current user can have no access to the account
76          if (!isAccessible) {
77              String accountNumber = accountingLineForValidation.getAccountNumber();
78              String principalName = GlobalVariables.getUserSession().getPerson().getPrincipalName();
79              String errorKey = this.convertEventToMessage(event);
80  
81              GlobalVariables.getMessageMap().putError(OLEPropertyConstants.ACCOUNT_NUMBER, errorKey, accountNumber, principalName);
82          }
83  
84          return isAccessible;
85      }
86  
87      /**
88       * determine whether the give user has permission to any edit mode defined in the given candidate edit modes
89       * 
90       * @param accountingDocument the given accounting document
91       * @param financialSystemUser the given user
92       * @param candidateEditEditModes the given candidate edit modes
93       * @return true if the give user has permission to any edit mode defined in the given candidate edit modes; otherwise, false
94       */
95      protected boolean hasRequiredEditMode(AccountingDocument accountingDocument, Person financialSystemUser, List<String> candidateEditModes) {
96          DocumentHelperService documentHelperService = SpringContext.getBean(DocumentHelperService.class);
97          TransactionalDocumentAuthorizer documentAuthorizer = (TransactionalDocumentAuthorizer) documentHelperService.getDocumentAuthorizer(accountingDocument);
98          TransactionalDocumentPresentationController presentationController = (TransactionalDocumentPresentationController) documentHelperService.getDocumentPresentationController(accountingDocument);
99  
100         Set<String> presentationControllerEditModes = presentationController.getEditModes(accountingDocument);
101         Set<String> editModes = documentAuthorizer.getEditModes(accountingDocument, financialSystemUser, presentationControllerEditModes);
102 
103         for (String editMode : candidateEditModes) {
104             if (editModes.contains(editMode)) {
105                 return true;
106             }
107         }
108 
109         return false;
110     }
111 
112     /**
113      * define the possibly desired edit modes
114      * 
115      * @return the possibly desired edit modes
116      */
117     protected List<String> getCandidateEditModes() {
118         List<String> candidateEdiModes = new ArrayList<String>();
119         candidateEdiModes.add(OleAuthorizationConstants.DisbursementVoucherEditMode.TAX_ENTRY);
120         candidateEdiModes.add(OleAuthorizationConstants.DisbursementVoucherEditMode.FRN_ENTRY);
121         candidateEdiModes.add(OleAuthorizationConstants.DisbursementVoucherEditMode.TRAVEL_ENTRY);
122         candidateEdiModes.add(OleAuthorizationConstants.DisbursementVoucherEditMode.WIRE_ENTRY);
123 
124         return candidateEdiModes;
125     }
126     
127     /**
128      * Determines if the two given accounting lines have not have their account changed
129      * @param pollux the first accounting line to check
130      * @param castor the second accounting line to check
131      * @return true if the account is the same for the two, false otherwise
132      */
133     protected boolean accountUnchanged(AccountingLine pollux, AccountingLine castor) {
134     	return ((pollux.getChartOfAccountsCode() == null && castor.getChartOfAccountsCode() == null) || (pollux.getChartOfAccountsCode() != null && pollux.getChartOfAccountsCode().equals(castor.getChartOfAccountsCode()))) && ((pollux.getAccountNumber() == null && castor.getAccountNumber() == null) || (pollux.getAccountNumber() != null && pollux.getAccountNumber().equals(castor.getAccountNumber()))); 
135     }
136 
137     /**
138      * Sets the oldAccountingLineForValidation attribute value.
139      * @param oldAccountingLineForValidation The oldAccountingLineForValidation to set.
140      */
141     public void setOldAccountingLineForValidation(AccountingLine oldAccountingLineForValidation) {
142         this.oldAccountingLineForValidation = oldAccountingLineForValidation;
143     }
144 }