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 }