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.validation.impl;
017
018 import org.apache.commons.lang.StringUtils;
019 import org.kuali.kfs.fp.document.authorization.ServiceBillingDocumentAuthorizer;
020 import org.kuali.kfs.sys.KFSKeyConstants;
021 import org.kuali.kfs.sys.KFSPropertyConstants;
022 import org.kuali.kfs.sys.businessobject.AccountingLine;
023 import org.kuali.kfs.sys.businessobject.FinancialSystemDocumentHeader;
024 import org.kuali.kfs.sys.document.AccountingDocument;
025 import org.kuali.kfs.sys.document.Correctable;
026 import org.kuali.kfs.sys.document.validation.GenericValidation;
027 import org.kuali.kfs.sys.document.validation.event.AddAccountingLineEvent;
028 import org.kuali.kfs.sys.document.validation.event.AttributedDocumentEvent;
029 import org.kuali.kfs.sys.document.validation.event.DeleteAccountingLineEvent;
030 import org.kuali.kfs.sys.document.validation.event.UpdateAccountingLineEvent;
031 import org.kuali.rice.kim.bo.Person;
032 import org.kuali.rice.kns.rule.event.KualiDocumentEvent;
033 import org.kuali.rice.kns.service.DataDictionaryService;
034 import org.kuali.rice.kns.util.GlobalVariables;
035 import org.kuali.rice.kns.workflow.service.KualiWorkflowDocument;
036
037 /**
038 * A validation that checks whether the given accounting line is accessible to the given user or not
039 */
040 public class ServiceBillingAccountingLineAccessibleValidation extends GenericValidation {
041 private DataDictionaryService dataDictionaryService;
042 private AccountingDocument accountingDocumentForValidation;
043 private AccountingLine accountingLineForValidation;
044
045 /**
046 * Indicates what is being done to an accounting line. This allows the same method to be used for different actions.
047 */
048 public enum AccountingLineAction {
049 ADD(KFSKeyConstants.ERROR_ACCOUNTINGLINE_INACCESSIBLE_ADD), DELETE(KFSKeyConstants.ERROR_ACCOUNTINGLINE_INACCESSIBLE_DELETE), UPDATE(KFSKeyConstants.ERROR_ACCOUNTINGLINE_INACCESSIBLE_UPDATE);
050
051 public final String accessibilityErrorKey;
052
053 AccountingLineAction(String accessabilityErrorKey) {
054 this.accessibilityErrorKey = accessabilityErrorKey;
055 }
056 }
057
058 /**
059 * Validates that the given accounting line is accessible for editing by the current user.
060 * <strong>This method expects a document as the first parameter and an accounting line as the second</strong>
061 * @see org.kuali.kfs.sys.document.validation.Validation#validate(java.lang.Object[])
062 */
063 public boolean validate(AttributedDocumentEvent event) {
064 final Person currentUser = GlobalVariables.getUserSession().getPerson();
065
066 if (accountingDocumentForValidation instanceof Correctable) {
067 final String errorDocumentNumber = ((FinancialSystemDocumentHeader)accountingDocumentForValidation.getDocumentHeader()).getFinancialDocumentInErrorNumber();
068 if (StringUtils.isNotBlank(errorDocumentNumber))
069 return true;
070 }
071
072 final KualiWorkflowDocument workflowDocument = accountingDocumentForValidation.getDocumentHeader().getWorkflowDocument();
073 if (accountingLineForValidation.isTargetAccountingLine() && (workflowDocument.stateIsInitiated() || workflowDocument.stateIsSaved())) {
074 return true; // all target lines are accessible PreRoute, no matter the account
075 }
076
077 final boolean isAccessible = new ServiceBillingDocumentAuthorizer().canModifyAccountingLine(accountingDocumentForValidation, accountingLineForValidation, currentUser);
078
079 // report errors
080 if (!isAccessible) {
081 final String principalName = currentUser.getPrincipalName();
082
083 final String[] chartErrorParams = new String[] { getDataDictionaryService().getAttributeLabel(accountingLineForValidation.getClass(), KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE), accountingLineForValidation.getChartOfAccountsCode(), principalName};
084 GlobalVariables.getMessageMap().putError(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, convertEventToMessage(event), chartErrorParams);
085
086 final String[] accountErrorParams = new String[] { getDataDictionaryService().getAttributeLabel(accountingLineForValidation.getClass(), KFSPropertyConstants.ACCOUNT_NUMBER), accountingLineForValidation.getAccountNumber(), principalName };
087 GlobalVariables.getMessageMap().putError(KFSPropertyConstants.ACCOUNT_NUMBER, convertEventToMessage(event), accountErrorParams);
088 }
089
090 return isAccessible;
091 }
092
093
094 /**
095 * Determines what error message should be shown based on the event that required this validation
096 * @param event the event to use to determine the error message
097 * @return the key of the error message to display
098 */
099 protected String convertEventToMessage(KualiDocumentEvent event) {
100 if (event instanceof AddAccountingLineEvent) {
101 return AccountingLineAction.ADD.accessibilityErrorKey;
102 } else if (event instanceof UpdateAccountingLineEvent) {
103 return AccountingLineAction.UPDATE.accessibilityErrorKey;
104 } else if (event instanceof DeleteAccountingLineEvent) {
105 return AccountingLineAction.DELETE.accessibilityErrorKey;
106 } else {
107 return "";
108 }
109 }
110
111 /**
112 * Gets the accountingDocumentForValidation attribute.
113 * @return Returns the accountingDocumentForValidation.
114 */
115 public AccountingDocument getAccountingDocumentForValidation() {
116 return accountingDocumentForValidation;
117 }
118
119 /**
120 * Sets the accountingDocumentForValidation attribute value.
121 * @param accountingDocumentForValidation The accountingDocumentForValidation to set.
122 */
123 public void setAccountingDocumentForValidation(AccountingDocument accountingDocumentForValidation) {
124 this.accountingDocumentForValidation = accountingDocumentForValidation;
125 }
126
127 /**
128 * Gets the accountingLineForValidation attribute.
129 * @return Returns the accountingLineForValidation.
130 */
131 public AccountingLine getAccountingLineForValidation() {
132 return accountingLineForValidation;
133 }
134
135 /**
136 * Sets the accountingLineForValidation attribute value.
137 * @param accountingLineForValidation The accountingLineForValidation to set.
138 */
139 public void setAccountingLineForValidation(AccountingLine accountingLineForValidation) {
140 this.accountingLineForValidation = accountingLineForValidation;
141 }
142
143 /**
144 * Gets the dataDictionaryService attribute.
145 * @return Returns the dataDictionaryService.
146 */
147 public DataDictionaryService getDataDictionaryService() {
148 return dataDictionaryService;
149 }
150
151 /**
152 * Sets the dataDictionaryService attribute value.
153 * @param dataDictionaryService The dataDictionaryService to set.
154 */
155 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
156 this.dataDictionaryService = dataDictionaryService;
157 }
158
159 }
160