001/*
002 * Copyright 2008-2009 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 */
016package org.kuali.ole.fp.document.validation.impl;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.ole.fp.document.authorization.ServiceBillingDocumentAuthorizer;
020import org.kuali.ole.sys.OLEKeyConstants;
021import org.kuali.ole.sys.OLEPropertyConstants;
022import org.kuali.ole.sys.businessobject.AccountingLine;
023import org.kuali.ole.sys.businessobject.FinancialSystemDocumentHeader;
024import org.kuali.ole.sys.document.AccountingDocument;
025import org.kuali.ole.sys.document.Correctable;
026import org.kuali.ole.sys.document.validation.GenericValidation;
027import org.kuali.ole.sys.document.validation.event.AddAccountingLineEvent;
028import org.kuali.ole.sys.document.validation.event.AttributedDocumentEvent;
029import org.kuali.ole.sys.document.validation.event.DeleteAccountingLineEvent;
030import org.kuali.ole.sys.document.validation.event.UpdateAccountingLineEvent;
031import org.kuali.rice.kew.api.WorkflowDocument;
032import org.kuali.rice.kim.api.identity.Person;
033import org.kuali.rice.kns.service.DataDictionaryService;
034import org.kuali.rice.krad.rules.rule.event.KualiDocumentEvent;
035import org.kuali.rice.krad.util.GlobalVariables;
036
037/**
038 * A validation that checks whether the given accounting line is accessible to the given user or not
039 */
040public 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(OLEKeyConstants.ERROR_ACCOUNTINGLINE_INACCESSIBLE_ADD), DELETE(OLEKeyConstants.ERROR_ACCOUNTINGLINE_INACCESSIBLE_DELETE), UPDATE(OLEKeyConstants.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.ole.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 WorkflowDocument workflowDocument = accountingDocumentForValidation.getDocumentHeader().getWorkflowDocument();
073        if (accountingLineForValidation.isTargetAccountingLine() && (workflowDocument.isInitiated() || workflowDocument.isSaved())) {
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(), OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE), accountingLineForValidation.getChartOfAccountsCode(),  principalName};
084            GlobalVariables.getMessageMap().putError(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, convertEventToMessage(event), chartErrorParams);
085            
086            final String[] accountErrorParams = new String[] { getDataDictionaryService().getAttributeLabel(accountingLineForValidation.getClass(), OLEPropertyConstants.ACCOUNT_NUMBER), accountingLineForValidation.getAccountNumber(), principalName };
087            GlobalVariables.getMessageMap().putError(OLEPropertyConstants.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