/* * The Kuali Financial System, a comprehensive financial management system for higher education. * * Copyright 2005-2014 The Kuali Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.kuali.kfs.fp.document.validation.impl; import org.apache.commons.lang.StringUtils; import org.kuali.kfs.fp.document.authorization.ServiceBillingDocumentAuthorizer; import org.kuali.kfs.sys.KFSKeyConstants; import org.kuali.kfs.sys.KFSPropertyConstants; import org.kuali.kfs.sys.businessobject.AccountingLine; import org.kuali.kfs.sys.businessobject.FinancialSystemDocumentHeader; import org.kuali.kfs.sys.document.AccountingDocument; import org.kuali.kfs.sys.document.Correctable; import org.kuali.kfs.sys.document.validation.GenericValidation; import org.kuali.kfs.sys.document.validation.event.AddAccountingLineEvent; import org.kuali.kfs.sys.document.validation.event.AttributedDocumentEvent; import org.kuali.kfs.sys.document.validation.event.DeleteAccountingLineEvent; import org.kuali.kfs.sys.document.validation.event.UpdateAccountingLineEvent; import org.kuali.rice.kew.api.WorkflowDocument; import org.kuali.rice.kim.api.identity.Person; import org.kuali.rice.kns.service.DataDictionaryService; import org.kuali.rice.krad.rules.rule.event.KualiDocumentEvent; import org.kuali.rice.krad.util.GlobalVariables; /** * A validation that checks whether the given accounting line is accessible to the given user or not */ public class ServiceBillingAccountingLineAccessibleValidation extends GenericValidation { private DataDictionaryService dataDictionaryService; private AccountingDocument accountingDocumentForValidation; private AccountingLine accountingLineForValidation; /** * Indicates what is being done to an accounting line. This allows the same method to be used for different actions. */ public enum AccountingLineAction { ADD(KFSKeyConstants.ERROR_ACCOUNTINGLINE_INACCESSIBLE_ADD), DELETE(KFSKeyConstants.ERROR_ACCOUNTINGLINE_INACCESSIBLE_DELETE), UPDATE(KFSKeyConstants.ERROR_ACCOUNTINGLINE_INACCESSIBLE_UPDATE); public final String accessibilityErrorKey; AccountingLineAction(String accessabilityErrorKey) { this.accessibilityErrorKey = accessabilityErrorKey; } } /** * Validates that the given accounting line is accessible for editing by the current user. * <strong>This method expects a document as the first parameter and an accounting line as the second</strong> * @see org.kuali.kfs.sys.document.validation.Validation#validate(java.lang.Object[]) */ public boolean validate(AttributedDocumentEvent event) { final Person currentUser = GlobalVariables.getUserSession().getPerson(); if (accountingDocumentForValidation instanceof Correctable) { final String errorDocumentNumber = ((FinancialSystemDocumentHeader)accountingDocumentForValidation.getDocumentHeader()).getFinancialDocumentInErrorNumber(); if (StringUtils.isNotBlank(errorDocumentNumber)) return true; } final WorkflowDocument workflowDocument = accountingDocumentForValidation.getDocumentHeader().getWorkflowDocument(); if (accountingLineForValidation.isTargetAccountingLine() && (workflowDocument.isInitiated() || workflowDocument.isSaved())) { return true; // all target lines are accessible PreRoute, no matter the account } final boolean isAccessible = new ServiceBillingDocumentAuthorizer().canModifyAccountingLine(accountingDocumentForValidation, accountingLineForValidation, currentUser); // report errors if (!isAccessible) { final String principalName = currentUser.getPrincipalName(); final String[] chartErrorParams = new String[] { getDataDictionaryService().getAttributeLabel(accountingLineForValidation.getClass(), KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE), accountingLineForValidation.getChartOfAccountsCode(), principalName}; GlobalVariables.getMessageMap().putError(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, convertEventToMessage(event), chartErrorParams); final String[] accountErrorParams = new String[] { getDataDictionaryService().getAttributeLabel(accountingLineForValidation.getClass(), KFSPropertyConstants.ACCOUNT_NUMBER), accountingLineForValidation.getAccountNumber(), principalName }; GlobalVariables.getMessageMap().putError(KFSPropertyConstants.ACCOUNT_NUMBER, convertEventToMessage(event), accountErrorParams); } return isAccessible; } /** * Determines what error message should be shown based on the event that required this validation * @param event the event to use to determine the error message * @return the key of the error message to display */ protected String convertEventToMessage(KualiDocumentEvent event) { if (event instanceof AddAccountingLineEvent) { return AccountingLineAction.ADD.accessibilityErrorKey; } else if (event instanceof UpdateAccountingLineEvent) { return AccountingLineAction.UPDATE.accessibilityErrorKey; } else if (event instanceof DeleteAccountingLineEvent) { return AccountingLineAction.DELETE.accessibilityErrorKey; } else { return ""; } } /** * Gets the accountingDocumentForValidation attribute. * @return Returns the accountingDocumentForValidation. */ public AccountingDocument getAccountingDocumentForValidation() { return accountingDocumentForValidation; } /** * Sets the accountingDocumentForValidation attribute value. * @param accountingDocumentForValidation The accountingDocumentForValidation to set. */ public void setAccountingDocumentForValidation(AccountingDocument accountingDocumentForValidation) { this.accountingDocumentForValidation = accountingDocumentForValidation; } /** * Gets the accountingLineForValidation attribute. * @return Returns the accountingLineForValidation. */ public AccountingLine getAccountingLineForValidation() { return accountingLineForValidation; } /** * Sets the accountingLineForValidation attribute value. * @param accountingLineForValidation The accountingLineForValidation to set. */ public void setAccountingLineForValidation(AccountingLine accountingLineForValidation) { this.accountingLineForValidation = accountingLineForValidation; } /** * Gets the dataDictionaryService attribute. * @return Returns the dataDictionaryService. */ public DataDictionaryService getDataDictionaryService() { return dataDictionaryService; } /** * Sets the dataDictionaryService attribute value. * @param dataDictionaryService The dataDictionaryService to set. */ public void setDataDictionaryService(DataDictionaryService dataDictionaryService) { this.dataDictionaryService = dataDictionaryService; } }