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.HashMap; 019 import java.util.Map; 020 import java.util.Set; 021 022 import org.kuali.kfs.sys.KFSConstants; 023 import org.kuali.kfs.sys.businessobject.AccountingLine; 024 import org.kuali.kfs.sys.context.SpringContext; 025 import org.kuali.kfs.sys.document.AccountingDocument; 026 import org.kuali.kfs.sys.document.authorization.AccountingDocumentAuthorizerBase; 027 import org.kuali.kfs.sys.identity.KfsKimAttributes; 028 import org.kuali.rice.kim.bo.Person; 029 import org.kuali.rice.kns.document.Document; 030 import org.kuali.rice.kns.document.authorization.DocumentAuthorizerBase; 031 import org.kuali.rice.kns.service.DataDictionaryService; 032 import org.kuali.rice.kns.util.KNSConstants; 033 034 /** 035 * The customized document authorizer for the Service Billing document 036 */ 037 public class ServiceBillingDocumentAuthorizer extends AccountingDocumentAuthorizerBase { 038 protected static String serviceBillingDocumentTypeName; 039 040 /** 041 * Overridden to only allow error correction and copy actions if the current user has Modify Accounting Document permission on every accounting line on the document 042 * @see org.kuali.kfs.sys.document.authorization.FinancialSystemTransactionalDocumentAuthorizerBase#getDocumentActions(org.kuali.rice.kns.document.Document, org.kuali.rice.kim.bo.Person, java.util.Set) 043 */ 044 @Override 045 public Set<String> getDocumentActions(Document document, Person user, Set<String> documentActionsFromPresentationController) { 046 Set<String> documentActions = super.getDocumentActions(document, user, documentActionsFromPresentationController); 047 048 final boolean canCopyOrErrorCorrect = (documentActions.contains(KNSConstants.KUALI_ACTION_CAN_COPY) || documentActions.contains(KFSConstants.KFS_ACTION_CAN_ERROR_CORRECT)) ? canModifyAllSourceAccountingLines(document, user) : true; 049 050 if (documentActions.contains(KNSConstants.KUALI_ACTION_CAN_COPY)) { 051 if (!canCopyOrErrorCorrect) { 052 documentActions.remove(KNSConstants.KUALI_ACTION_CAN_COPY); 053 } 054 } 055 if (documentActions.contains(KFSConstants.KFS_ACTION_CAN_ERROR_CORRECT)) { 056 if (!canCopyOrErrorCorrect) { 057 documentActions.remove(KFSConstants.KFS_ACTION_CAN_ERROR_CORRECT); 058 } 059 } 060 return documentActions; 061 } 062 063 /** 064 * Determines if the given user has permission to modify all accounting lines on the document 065 * @param document the document with source accounting lines to check 066 * @param user the user to check 067 * @return true if the user can modify all the accounting lines, false otherwise 068 */ 069 protected boolean canModifyAllSourceAccountingLines(Document document, Person user) { 070 for (Object accountingLineAsObject : ((AccountingDocument)document).getSourceAccountingLines()) { 071 if (!canModifyAccountingLine(document, ((AccountingLine)accountingLineAsObject), user)) return false; 072 } 073 return true; 074 } 075 076 /** 077 * Determines if the given user can modify the given accounting line, which is a source line on the given document 078 * @param document a document with source accounting lines 079 * @param accountingLine the accounting line to check the modifyability of 080 * @param user the user being checked 081 * @return true if the user can modify the given accounting line, false otherwise 082 */ 083 public boolean canModifyAccountingLine(Document document, AccountingLine accountingLine, Person user) { 084 return this.isAuthorized(document, KFSConstants.ParameterNamespaces.FINANCIAL, KFSConstants.PermissionTemplate.MODIFY_ACCOUNTING_LINES.name, user.getPrincipalId(), buildPermissionDetails(document), buildRoleQualifiers(accountingLine)); 085 } 086 087 /** 088 * Builds the permission details map for permission check 089 * @param document the document, which is used to find the real document type name 090 * @return a Map of permissionDetail values 091 */ 092 protected Map<String, String> buildPermissionDetails(Document document) { 093 Map<String, String> permissionDetails = new HashMap<String, String>(); 094 permissionDetails.put(KfsKimAttributes.DOCUMENT_TYPE_NAME, getDocumentTypeName(document)); // document type name 095 permissionDetails.put(KfsKimAttributes.ROUTE_NODE_NAME, DocumentAuthorizerBase.PRE_ROUTING_ROUTE_NAME); // route node = PreRoute 096 permissionDetails.put(KfsKimAttributes.PROPERTY_NAME, "sourceAccountingLines"); // property = sourceAccountingLines 097 return permissionDetails; 098 } 099 100 /** 101 * Looks up in the data dictionary the document type name 102 * @param document the document to find a document type name for 103 * @return the document type name 104 */ 105 protected String getDocumentTypeName(Document document) { 106 if (serviceBillingDocumentTypeName == null) { 107 serviceBillingDocumentTypeName = SpringContext.getBean(DataDictionaryService.class).getDocumentTypeNameByClass(document.getClass()); 108 } 109 return serviceBillingDocumentTypeName; 110 } 111 112 /** 113 * Builds a map of role qualifiers, each containing the chart and account of the given accounting line 114 * @param accountingLine the accounting line to build role qualifiers for 115 * @return the Map of role qualifiers 116 */ 117 protected Map<String, String> buildRoleQualifiers(AccountingLine accountingLine) { 118 Map<String, String> roleQualifiers = new HashMap<String, String>(); 119 roleQualifiers.put(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE, accountingLine.getChartOfAccountsCode()); 120 roleQualifiers.put(KfsKimAttributes.ACCOUNT_NUMBER, accountingLine.getAccountNumber()); 121 return roleQualifiers; 122 } 123 }