/*
* 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;
}
}