View Javadoc
1   /*
2    * The Kuali Financial System, a comprehensive financial management system for higher education.
3    * 
4    * Copyright 2005-2014 The Kuali Foundation
5    * 
6    * This program is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU Affero General Public License as
8    * published by the Free Software Foundation, either version 3 of the
9    * License, or (at your option) any later version.
10   * 
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU Affero General Public License for more details.
15   * 
16   * You should have received a copy of the GNU Affero General Public License
17   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  package org.kuali.kfs.fp.document.authorization;
20  
21  import java.util.List;
22  import java.util.Map;
23  import java.util.Set;
24  
25  import org.apache.commons.lang.StringUtils;
26  import org.kuali.kfs.fp.document.DisbursementVoucherConstants;
27  import org.kuali.kfs.fp.document.DisbursementVoucherDocument;
28  import org.kuali.kfs.sys.businessobject.AccountingLine;
29  import org.kuali.kfs.sys.document.authorization.AccountingDocumentAuthorizerBase;
30  import org.kuali.kfs.sys.identity.KfsKimAttributes;
31  import org.kuali.rice.kew.api.WorkflowDocument;
32  import org.kuali.rice.kim.api.KimConstants;
33  import org.kuali.rice.kim.api.identity.Person;
34  import org.kuali.rice.krad.util.GlobalVariables;
35  import org.kuali.rice.krad.util.ObjectUtils;
36  
37  /**
38   * Adds extra role qualifiers for funky travel edit mode permission
39   */
40  public class DisbursementVoucherDocumentAuthorizer extends AccountingDocumentAuthorizerBase {
41  
42      /**
43       * Adds chart codes and account numbers for accounting lines if we're at Account level, so that the fiscal officer gets travel edit mode
44       * @see org.kuali.kfs.sys.document.authorization.AccountingDocumentAuthorizerBase#addRoleQualification(org.kuali.rice.krad.bo.BusinessObject, java.util.Map)
45       */
46      @Override
47      protected void addRoleQualification(Object dataObject, Map<String, String> attributes) {
48          super.addRoleQualification(dataObject, attributes);
49          final DisbursementVoucherDocument disbursementVoucherDocument = (DisbursementVoucherDocument)dataObject;
50  
51          // are we add Account level?  Then let's add our qualifiers
52          if (isAtAccountLevel(disbursementVoucherDocument)) {
53              addAccountQualification(getAccountingLines(disbursementVoucherDocument), attributes);
54          }
55  
56          // add campus code if we have one
57          if (!StringUtils.isBlank(disbursementVoucherDocument.getCampusCode())) {
58              attributes.put(KimConstants.AttributeConstants.CAMPUS_CODE, disbursementVoucherDocument.getCampusCode());
59          }
60      }
61  
62      /**
63       * Finds the source accounting lines in the given business object
64       * @param disbursementVoucherDocument a document to get accounting lines from
65       * @return a List of accounting lines
66       */
67      protected List<? extends AccountingLine> getAccountingLines(DisbursementVoucherDocument disbursementVoucherDocument) {
68          return disbursementVoucherDocument.getSourceAccountingLines();
69      }
70  
71      /**
72       * Goes through the given List of accounting lines and fines one line where the current user is the fiscal officer; it uses that line to put chart of accounts
73       * code and account number qualifications into the given Map of attributes for role qualification
74       * @param accountingLines a List of AccountingLines
75       * @param attributes a Map of role qualification attributes
76       */
77      protected void addAccountQualification(List<? extends AccountingLine> accountingLines, Map<String, String> attributes) {
78          final Person currentUser = GlobalVariables.getUserSession().getPerson();
79          boolean foundQualification = false;
80          int count = 0;
81          while (!foundQualification && count < accountingLines.size()) {
82              AccountingLine accountingLine = accountingLines.get(count);
83              if (ObjectUtils.isNull(accountingLine.getAccount())) {
84                  accountingLine.refreshReferenceObject("account");
85              }
86              if (!ObjectUtils.isNull(accountingLine.getAccount()) && currentUser.getPrincipalId().equalsIgnoreCase(accountingLine.getAccount().getAccountFiscalOfficerSystemIdentifier())) {
87                  attributes.put(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE, accountingLine.getChartOfAccountsCode());
88                  attributes.put(KfsKimAttributes.ACCOUNT_NUMBER, accountingLine.getAccountNumber());
89                  foundQualification = true;
90              }
91              count += 1;
92          }
93      }
94  
95      /**
96       * A helper method for determining the route levels for a given document.
97       *
98       * @param workflowDocument
99       * @return List
100      */
101     protected Set<String> getCurrentRouteLevels(WorkflowDocument workflowDocument) {
102         return workflowDocument.getCurrentNodeNames();
103     }
104 
105     /**
106      * Determines if the document is at the Account route level
107      * @param disbursementVoucherDocument the Disbursement Voucher document to determine the account level of
108      * @return true if the document is at the account level, false otherwise
109      */
110     protected boolean isAtAccountLevel(DisbursementVoucherDocument disbursementVoucherDocument) {
111         final WorkflowDocument workflowDocument = disbursementVoucherDocument.getDocumentHeader().getWorkflowDocument();
112 
113         return getCurrentRouteLevels(workflowDocument).contains(DisbursementVoucherConstants.RouteLevelNames.ACCOUNT);
114     }
115 }