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 }