001 /*
002 * Copyright 2011 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 */
016 package org.kuali.kfs.fp.document.authorization;
017
018 import java.util.Arrays;
019 import java.util.List;
020 import java.util.Map;
021
022 import org.kuali.kfs.fp.document.DisbursementVoucherConstants;
023 import org.kuali.kfs.fp.document.DisbursementVoucherDocument;
024 import org.kuali.kfs.sys.businessobject.AccountingLine;
025 import org.kuali.kfs.sys.document.authorization.AccountingDocumentAuthorizerBase;
026 import org.kuali.kfs.sys.identity.KfsKimAttributes;
027 import org.kuali.rice.kew.exception.WorkflowException;
028 import org.kuali.rice.kim.bo.Person;
029 import org.kuali.rice.kns.bo.BusinessObject;
030 import org.kuali.rice.kns.util.GlobalVariables;
031 import org.kuali.rice.kns.util.ObjectUtils;
032 import org.kuali.rice.kns.workflow.service.KualiWorkflowDocument;
033
034 /**
035 * Adds extra role qualifiers for funky travel edit mode permission
036 */
037 public class DisbursementVoucherDocumentAuthorizer extends AccountingDocumentAuthorizerBase {
038
039 /**
040 * Adds chart codes and account numbers for accounting lines if we're at Account level, so that the fiscal officer gets travel edit mode
041 * @see org.kuali.kfs.sys.document.authorization.AccountingDocumentAuthorizerBase#addRoleQualification(org.kuali.rice.kns.bo.BusinessObject, java.util.Map)
042 */
043 @Override
044 protected void addRoleQualification(BusinessObject businessObject, Map<String, String> attributes) {
045 super.addRoleQualification(businessObject, attributes);
046 final DisbursementVoucherDocument disbursementVoucherDocument = (DisbursementVoucherDocument)businessObject;
047
048 // are we add Account level? Then let's add our qualifiers
049 if (isAtAccountLevel(disbursementVoucherDocument)) {
050 addAccountQualification(getAccountingLines(disbursementVoucherDocument), attributes);
051 }
052 }
053
054 /**
055 * Finds the source accounting lines in the given business object
056 * @param disbursementVoucherDocument a document to get accounting lines from
057 * @return a List of accounting lines
058 */
059 protected List getAccountingLines(DisbursementVoucherDocument disbursementVoucherDocument) {
060 return disbursementVoucherDocument.getSourceAccountingLines();
061 }
062
063 /**
064 * 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
065 * code and account number qualifications into the given Map of attributes for role qualification
066 * @param accountingLines a List of AccountingLines
067 * @param attributes a Map of role qualification attributes
068 */
069 protected void addAccountQualification(List accountingLines, Map<String, String> attributes) {
070 final Person currentUser = GlobalVariables.getUserSession().getPerson();
071 boolean foundQualification = false;
072 int count = 0;
073 while (!foundQualification && count < accountingLines.size()) {
074 AccountingLine accountingLine = (AccountingLine)accountingLines.get(count);
075 if (ObjectUtils.isNull(accountingLine.getAccount())) {
076 accountingLine.refreshReferenceObject("account");
077 }
078 if (!ObjectUtils.isNull(accountingLine.getAccount()) && currentUser.getPrincipalId().equalsIgnoreCase(accountingLine.getAccount().getAccountFiscalOfficerSystemIdentifier())) {
079 attributes.put(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE, accountingLine.getChartOfAccountsCode());
080 attributes.put(KfsKimAttributes.ACCOUNT_NUMBER, accountingLine.getAccountNumber());
081 foundQualification = true;
082 }
083 count += 1;
084 }
085 }
086
087 /**
088 * A helper method for determining the route levels for a given document.
089 *
090 * @param workflowDocument
091 * @return List
092 */
093 protected List<String> getCurrentRouteLevels(KualiWorkflowDocument workflowDocument) {
094 try {
095 return Arrays.asList(workflowDocument.getNodeNames());
096 }
097 catch (WorkflowException e) {
098 throw new RuntimeException(e);
099 }
100 }
101
102 /**
103 * Determines if the document is at the Account route level
104 * @param disbursementVoucherDocument the Disbursement Voucher document to determine the account level of
105 * @return true if the document is at the account level, false otherwise
106 */
107 protected boolean isAtAccountLevel(DisbursementVoucherDocument disbursementVoucherDocument) {
108 final KualiWorkflowDocument workflowDocument = disbursementVoucherDocument.getDocumentHeader().getWorkflowDocument();
109
110 return getCurrentRouteLevels(workflowDocument).contains(DisbursementVoucherConstants.RouteLevelNames.ACCOUNT);
111 }
112 }