/*
* 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.sys.document.authorization;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.KFSKeyConstants;
import org.kuali.kfs.sys.businessobject.AccountingLine;
import org.kuali.kfs.sys.businessobject.FinancialSystemDocumentHeader;
import org.kuali.kfs.sys.context.SpringContext;
import org.kuali.kfs.sys.document.AccountingDocument;
import org.kuali.kfs.sys.document.Correctable;
import org.kuali.kfs.sys.document.web.AccountingLineRenderingContext;
import org.kuali.kfs.sys.document.web.AccountingLineViewAction;
import org.kuali.kfs.sys.document.web.AccountingLineViewField;
import org.kuali.kfs.sys.identity.KfsKimAttributes;
import org.kuali.rice.core.api.config.property.ConfigurationService;
import org.kuali.rice.kew.api.WorkflowDocument;
import org.kuali.rice.kim.api.KimConstants;
import org.kuali.rice.kim.api.identity.Person;
import org.kuali.rice.kns.document.authorization.DocumentAuthorizer;
import org.kuali.rice.kns.document.authorization.DocumentAuthorizerBase;
import org.kuali.rice.kns.service.DocumentHelperService;
import org.kuali.rice.krad.document.Document;
import org.kuali.rice.krad.util.GlobalVariables;
import org.kuali.rice.krad.util.KRADConstants;
import org.kuali.rice.krad.util.ObjectUtils;
/**
* The default implementation of AccountingLineAuthorizer
*/
public class AccountingLineAuthorizerBase implements AccountingLineAuthorizer {
private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AccountingLineAuthorizerBase.class);
private static ConfigurationService kualiConfigurationService;
protected static String riceImagePath;
protected static String kfsImagePath;
/**
* Returns the basic actions - add for new lines, delete and balance inquiry for existing lines
*
* @see org.kuali.kfs.sys.document.authorization.AccountingLineAuthorizer#getActions(org.kuali.kfs.sys.document.AccountingDocument,
* org.kuali.kfs.sys.businessobject.AccountingLine, java.lang.String, java.lang.Integer, org.kuali.rice.kim.api.identity.Person,
* java.lang.String)
*/
@Override
public List<AccountingLineViewAction> getActions(AccountingDocument accountingDocument, AccountingLineRenderingContext accountingLineRenderingContext, String accountingLinePropertyName, Integer accountingLineIndex, Person currentUser, String groupTitle) {
List<AccountingLineViewAction> actions = new ArrayList<AccountingLineViewAction>();
if (accountingLineRenderingContext.isEditableLine() || isMessageMapContainingErrorsOnLine(accountingLinePropertyName)) {
Map<String, AccountingLineViewAction> actionMap = this.getActionMap(accountingLineRenderingContext, accountingLinePropertyName, accountingLineIndex, groupTitle);
actions.addAll(actionMap.values());
}
return actions;
}
/**
* Determines if the error map contains any errors which exist on the currently rendered accounting line
* @param accountingLinePropertyName the property name of the accounting line
* @return true if there are errors on the line, false otherwise
*/
protected boolean isMessageMapContainingErrorsOnLine(String accountingLinePropertyName) {
for (Object errorKeyAsObject : GlobalVariables.getMessageMap().getPropertiesWithErrors()) {
if (((String)errorKeyAsObject).startsWith(accountingLinePropertyName)) {
return true;
}
}
return false;
}
/**
* Returns a new empty HashSet
*
* @see org.kuali.kfs.sys.document.authorization.AccountingLineAuthorizer#getUnviewableBlocks(org.kuali.kfs.sys.document.AccountingDocument,
* org.kuali.kfs.sys.businessobject.AccountingLine, java.lang.String, boolean)
*/
@Override
public Set<String> getUnviewableBlocks(AccountingDocument accountingDocument, AccountingLine accountingLine, boolean newLine, Person currentUser) {
return new HashSet<String>();
}
/**
* @see org.kuali.kfs.sys.document.authorization.AccountingLineAuthorizer#renderNewLine(org.kuali.kfs.sys.document.AccountingDocument,
* java.lang.String)
*/
@Override
public boolean renderNewLine(AccountingDocument accountingDocument, String accountingGroupProperty) {
return (accountingDocument.getDocumentHeader().getWorkflowDocument().isInitiated() || accountingDocument.getDocumentHeader().getWorkflowDocument().isSaved() || accountingDocument.getDocumentHeader().getWorkflowDocument().isCompletionRequested());
}
/**
* @see org.kuali.kfs.sys.document.authorization.AccountingLineAuthorizer#isGroupEditable(org.kuali.kfs.sys.document.AccountingDocument,
* java.lang.String, org.kuali.rice.kim.api.identity.Person)
*/
@Override
public boolean isGroupEditable(AccountingDocument accountingDocument, List<? extends AccountingLineRenderingContext> accountingLineRenderingContexts, Person currentUser) {
WorkflowDocument workflowDocument = accountingDocument.getDocumentHeader().getWorkflowDocument();
if (workflowDocument.isInitiated() || workflowDocument.isSaved() || workflowDocument.isCompletionRequested()) {
return StringUtils.equalsIgnoreCase( workflowDocument.getInitiatorPrincipalId(), currentUser.getPrincipalId() );
}
for (AccountingLineRenderingContext renderingContext : accountingLineRenderingContexts) {
if (renderingContext.isEditableLine()) {
return true;
}
}
return false;
}
/**
* collection the actions that are allowed for the given accounting line
*
* @param accountingLine the given accounting line
* @param accountingLinePropertyName the property name of the given account line, typically, the form name
* @param accountingLineIndex the index of the given accounting line in its accounting line group
* @param groupTitle the title of the accounting line group
* @return the actions that are allowed for the given accounting line
*/
protected Map<String, AccountingLineViewAction> getActionMap(AccountingLineRenderingContext accountingLineRenderingContext, String accountingLinePropertyName, Integer accountingLineIndex, String groupTitle) {
Map<String, AccountingLineViewAction> actionMap = new HashMap<String, AccountingLineViewAction>();
if (accountingLineIndex == null || accountingLineIndex < 0) {
AccountingLineViewAction addAction = this.getAddAction(accountingLineRenderingContext.getAccountingLine(), accountingLinePropertyName, groupTitle);
actionMap.put(KFSConstants.INSERT_METHOD, addAction);
}
else {
if (accountingLineRenderingContext.allowDelete()) {
AccountingLineViewAction deleteAction = this.getDeleteAction(accountingLineRenderingContext.getAccountingLine(), accountingLinePropertyName, accountingLineIndex, groupTitle);
actionMap.put(KRADConstants.DELETE_METHOD, deleteAction);
}
AccountingLineViewAction balanceInquiryAction = this.getBalanceInquiryAction(accountingLineRenderingContext.getAccountingLine(), accountingLinePropertyName, accountingLineIndex, groupTitle);
actionMap.put(KFSConstants.PERFORMANCE_BALANCE_INQUIRY_FOR_METHOD, balanceInquiryAction);
}
return actionMap;
}
/**
* determine whether the current user has permission to edit the given field in the given accounting line
*
* @param accountingDocument the given accounting document
* @param accountingLine the given accounting line in the document
* @param fieldName the name of a field in the given accounting line
* @param editableLine whether the parent line of this field is editable
* @param editablePage whether the parent page of this field is editable
* @param currentUser the current user
* @return true if the the current user has permission to edit the given field in the given accounting line; otherwsie, false
*/
@Override
public boolean hasEditPermissionOnField(AccountingDocument accountingDocument, AccountingLine accountingLine, String accountingLineCollectionProperty, String fieldName, boolean editableLine, boolean editablePage, Person currentUser) {
if (!determineEditPermissionOnField(accountingDocument, accountingLine, accountingLineCollectionProperty, fieldName, editablePage)) {
return false;
}
// the fields in a new line should be always editable
if ( editableLine && accountingLine.getSequenceNumber() == null) {
return true;
}
// examine whether the given field can be editable
boolean hasEditPermissionOnField = editableLine || this.determineEditPermissionByFieldName(accountingDocument, accountingLine, getKimHappyPropertyNameForField(accountingLineCollectionProperty+"."+fieldName), currentUser);
if (!hasEditPermissionOnField) {
// kim check shows field should not be editable based on contents of field - check if line error message occurred on this line
// if error message shows up, then the value must have changed recently so - we make it editable to allow user to correct it
WorkflowDocument workflowDocument = accountingDocument.getDocumentHeader().getWorkflowDocument();
if (workflowDocument.isEnroute() && isMessageMapContainingErrorsOnLine(accountingLineCollectionProperty)) {
return true;
}
}
return hasEditPermissionOnField;
}
/**
* Allows the overriding of whether a field on an accounting line is editable or not
* @param accountingDocument the accounting document the line to test is on
* @param accountingLine the accounting line to test
* @param accountingLineCollectionProperty the property that the accounting line lives in
* @param fieldName the name of the field we are testing
* @param editableLine whether the parent line of this field is editable
* @param editablePage whether the parent page of this field is editable
* @return true if the field can be edited (subject to subsequence KIM check); false otherwise
*/
public boolean determineEditPermissionOnField(AccountingDocument accountingDocument, AccountingLine accountingLine, String accountingLineCollectionProperty, String fieldName, boolean editablePage) {
if (!editablePage)
{
return false; // no edits by default on non editable pages
}
final FinancialSystemDocumentHeader documentHeader = (FinancialSystemDocumentHeader) accountingDocument.getDocumentHeader();
final WorkflowDocument workflowDocument = documentHeader.getWorkflowDocument();
// if a document is cancelled or in error, all of its fields cannot be editable
if (workflowDocument.isCanceled() || ObjectUtils.isNotNull(documentHeader.getFinancialDocumentInErrorNumber())) {
return false;
}
return true;
}
/**
* Determine whether the current user has permission to edit the given accounting line as a whole
*
* @param accountingDocument the given accounting document
* @param accountingLine the given accounting line in the document
* @param currentUser the current user
* @return true if the the current user has permission to edit the given accounting line; otherwsie, false
*/
@Override
public boolean hasEditPermissionOnAccountingLine(AccountingDocument accountingDocument, AccountingLine accountingLine, String accountingLineCollectionProperty, Person currentUser, boolean pageIsEditable) {
if (determineEditPermissionOnLine(accountingDocument, accountingLine, accountingLineCollectionProperty, StringUtils.equalsIgnoreCase( accountingDocument.getDocumentHeader().getWorkflowDocument().getInitiatorPrincipalId(), currentUser.getPrincipalId() ), pageIsEditable)) {
if (approvedForUnqualifiedEditing(accountingDocument, accountingLine, accountingLineCollectionProperty, StringUtils.equalsIgnoreCase( accountingDocument.getDocumentHeader().getWorkflowDocument().getInitiatorPrincipalId(), currentUser.getPrincipalId() ))) {
return true; // don't do the KIM check, we're good
}
// examine whether the whole line can be editable via KIM check
final String lineFieldName = getKimHappyPropertyNameForField(accountingLineCollectionProperty);
return this.determineEditPermissionByFieldName(accountingDocument, accountingLine, lineFieldName, currentUser);
}
return false;
}
/**
* A hook to decide, pre-KIM check, if there's an edit permission on the given accounting line
* @param accountingDocument the accounting document the line is or wants to be associated with
* @param accountingLine the accounting line itself
* @param accountingLineCollectionProperty the collection the accounting line is or would be part of
* @param currentUserIsDocumentInitiator is the current user the initiator of the document?
* @return true if the line as a whole can be edited, false otherwise
*/
public boolean determineEditPermissionOnLine(AccountingDocument accountingDocument, AccountingLine accountingLine, String accountingLineCollectionProperty, boolean currentUserIsDocumentInitiator, boolean pageIsEditable) {
if (accountingDocument instanceof Correctable) {
String errorDocumentNumber = ((FinancialSystemDocumentHeader)accountingDocument.getDocumentHeader()).getFinancialDocumentInErrorNumber();
if (StringUtils.isNotBlank(errorDocumentNumber)) {
return false;
}
}
return true;
}
/**
* Determines if the given line is editable, no matter what a KIM check would say about line editability. In the default case,
* any accounting line is editable - minus KIM check - when the document is PreRoute, or if the line is a new line
* @param accountingDocument the accounting document the line is or wants to be associated with
* @param accountingLine the accounting line itself
* @param accountingLineCollectionProperty the collection the accounting line is or would be part of
* @param currentUserIsDocumentInitiator is the current user the initiator of the document?
* @return true if the line as a whole can be edited without the KIM check, false otherwise
*/
protected boolean approvedForUnqualifiedEditing(AccountingDocument accountingDocument, AccountingLine accountingLine, String accountingLineCollectionProperty, boolean currentUserIsDocumentInitiator) {
// the fields in a new line should be always editable
// KFSMI-9280 : Not sure if this is true. After entering routing, the ability to add new lines is limited by permissions.
// if (accountingLine.getSequenceNumber() == null) {
// return true;
// }
// check the initiation permission on the document if it is in the state of preroute
WorkflowDocument workflowDocument = accountingDocument.getDocumentHeader().getWorkflowDocument();
if(workflowDocument.isCompletionRequested()){
return true;
}
if (workflowDocument.isInitiated() || workflowDocument.isSaved()) {
return currentUserIsDocumentInitiator;
}
return false;
}
/**
* determine whether the current user has permission to edit the given field in the given accounting line
*
* @param accountingDocument the given accounting document
* @param accountingLine the given accounting line in the document
* @param fieldName the name of a field in the given accounting line
* @param currentUser the current user
* @return true if the the current user has permission to edit the given field in the given accounting line; otherwsie, false
*/
protected boolean determineEditPermissionByFieldName(AccountingDocument accountingDocument, AccountingLine accountingLine, String fieldName, Person currentUser) {
Map<String,String> roleQualifiers = getRoleQualifiers(accountingDocument, accountingLine);
Map<String,String> permissionDetail = getPermissionDetails( accountingDocument, fieldName);
return this.hasEditPermission(accountingDocument, currentUser, permissionDetail, roleQualifiers);
}
/**
* determine whether the current user has modification permission on an accounting line with the given qualifications. The
* permission template and namespace have been setup in the method.
*
* @param currentUser the current user
* @param permissionDetails the given permission details
* @param roleQualifiers the given role qualifications
* @return true if the user has edit permission on an accounting line with the given qualifications; otherwise, false
*/
protected boolean hasEditPermission(AccountingDocument accountingDocument, Person currentUser, Map<String,String> permissionDetails, Map<String,String> roleQualifiers) {
String pricipalId = currentUser.getPrincipalId();
DocumentAuthorizer accountingDocumentAuthorizer = this.getDocumentAuthorizer(accountingDocument);
return accountingDocumentAuthorizer.isAuthorizedByTemplate(accountingDocument, KFSConstants.PermissionTemplate.MODIFY_ACCOUNTING_LINES.namespace, KFSConstants.PermissionTemplate.MODIFY_ACCOUNTING_LINES.name, pricipalId, permissionDetails, roleQualifiers);
}
/**
* Gathers together all the information for a permission detail attribute set
*
* @param documentTypeName the document
* @param fieldName the given field name
* @return all the information for a permission detail attribute set
*/
protected Map<String,String> getPermissionDetails(Document document, String fieldName) {
Map<String,String> permissionDetails = new HashMap<String,String>();
WorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument();
if (StringUtils.isNotBlank(workflowDocument.getDocumentTypeName())) {
permissionDetails.put(KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME, workflowDocument.getDocumentTypeName());
}
if ( workflowDocument.isEnroute() && !workflowDocument.isApproved() ) {
Set<String> currentNodes = workflowDocument.getCurrentNodeNames();
if (CollectionUtils.isNotEmpty(currentNodes)) {
String routeNode = currentNodes.iterator().next();
if (StringUtils.isNotBlank(routeNode)) {
permissionDetails.put(KimConstants.AttributeConstants.ROUTE_NODE_NAME, routeNode);
}
}
} else {
// document has not been routed yet - use the "PreRoute" note
permissionDetails.put(KimConstants.AttributeConstants.ROUTE_NODE_NAME, DocumentAuthorizerBase.PRE_ROUTING_ROUTE_NAME);
}
if (StringUtils.isNotBlank(fieldName)) {
permissionDetails.put(KimConstants.AttributeConstants.PROPERTY_NAME, fieldName);
}
return permissionDetails;
}
/**
* Gathers together the role qualifiers for the KIM perm call
*
* @param accountingLine the accounting line to get role qualifiers from
* @return the gathered Map<String,String> of role qualifiers
*/
protected final Map<String,String> getRoleQualifiers(AccountingDocument accountingDocument, AccountingLine accountingLine) {
Map<String,String> roleQualifiers = new HashMap<String,String>();
if (accountingLine != null
&& StringUtils.isNotBlank(accountingLine.getAccountNumber())
&& StringUtils.isNotBlank(accountingLine.getChartOfAccountsCode())) {
roleQualifiers.put(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE, accountingLine.getChartOfAccountsCode());
roleQualifiers.put(KfsKimAttributes.ACCOUNT_NUMBER, accountingLine.getAccountNumber());
}
return roleQualifiers;
}
/**
* @param field AccountingLineViewField to find KIM-happy property name for
* @return a property name that KIM will like
*/
protected String getKimHappyPropertyNameForField(String convertedName) {
convertedName = stripDocumentPrefixFromName(convertedName);
return replaceCollectionElementsWithPlurals(convertedName);
}
/**
* get the full property name of the given field
*
* @param field the field to get the name from
* @return the full property name of the given field, typically, a combination of property prefix and simple property name
*/
protected String getFieldName(AccountingLineViewField field) {
String propertyPrefix = field.getField().getPropertyPrefix();
String propertyName = field.getField().getPropertyName();
return StringUtils.isNotBlank(propertyPrefix) ? (propertyPrefix + "." + propertyName) : propertyName;
}
/**
* Strips "document." and everything before from the property name
*
* @param name the property name to strip the document portion off of
* @return the stripped name
*/
protected String stripDocumentPrefixFromName(String name) {
return name.replaceFirst("(.)*document\\.", StringUtils.EMPTY);
}
/**
* Replaces references to collection elements to their respective plural names WARNING: this method is totally lame and I for
* one wished it didn't have to exist
*
* @param name the property name with perhaps collection elements in
* @return the corrected name
*/
protected String replaceCollectionElementsWithPlurals(String name) {
//KFSMI-9923 - modified to replace collection elements in each part of the name otherwise prefixes could end up
//with the unwanted double "s" (ex: targetAccountingLiness.financialObjectCode)
String newName = "";
String[] names = name.split("\\.");
for (int i = 0;i < names.length;i++) {
String temp = names[i].replaceAll("\\[\\d+\\]", "s");
// now - need to check if the property name ends with a double "s", which is incorrect
if ( temp.endsWith( "ss" ) ) {
temp = StringUtils.chop(temp);
}
if (i > 0) {
newName += "." + temp;
} else {
newName = temp;
}
}
return newName;
}
/**
* construct the balance inquiry action for the given accounting line
*
* @param accountingLine the given accounting line
* @param accountingLinePropertyName the property name of the given account line, typically, the form name
* @param accountingLineIndex the index of the given accounting line in its accounting line group
* @param groupTitle the title of the accounting line group
* @return the balance inquiry action for the given accounting line
*/
protected AccountingLineViewAction getBalanceInquiryAction(AccountingLine accountingLine, String accountingLinePropertyName, Integer accountingLineIndex, String groupTitle) {
String actionMethod = this.getBalanceInquiryMethod(accountingLine, accountingLinePropertyName, accountingLineIndex);
String actionLabel = this.getActionLabel(KFSKeyConstants.AccountingLineViewRendering.ACCOUNTING_LINE_BALANCE_INQUIRY_ACTION_LABEL, groupTitle, accountingLineIndex + 1);
String actionImageName = getKFSImagePath() + "tinybutton-balinquiry.gif";
return new AccountingLineViewAction(actionMethod, actionLabel, actionImageName);
}
/**
* construct the delete action for the given accounting line
*
* @param accountingLine the given accounting line
* @param accountingLinePropertyName the property name of the given account line, typically, the form name
* @param accountingLineIndex the index of the given accounting line in its accounting line group
* @param groupTitle the title of the accounting line group
* @return the delete action for the given accounting line
*/
protected AccountingLineViewAction getDeleteAction(AccountingLine accountingLine, String accountingLinePropertyName, Integer accountingLineIndex, String groupTitle) {
String actionMethod = this.getDeleteLineMethod(accountingLine, accountingLinePropertyName, accountingLineIndex);
String actionLabel = this.getActionLabel(KFSKeyConstants.AccountingLineViewRendering.ACCOUNTING_LINE_DELETE_ACTION_LABEL, groupTitle, accountingLineIndex + 1);
String actionImageName = getRiceImagePath() + "tinybutton-delete1.gif";
return new AccountingLineViewAction(actionMethod, actionLabel, actionImageName);
}
/**
* construct the add action for the given accounting line, typically, a new accounting line
*
* @param accountingLine the given accounting line
* @param accountingLinePropertyName the property name of the given account line, typically, the form name
* @param accountingLineIndex the index of the given accounting line in its accounting line group
* @param groupTitle the title of the accounting line group
* @return the add action for the given accounting line
*/
protected AccountingLineViewAction getAddAction(AccountingLine accountingLine, String accountingLinePropertyName, String groupTitle) {
String actionMethod = this.getAddMethod(accountingLine, accountingLinePropertyName);
String actionLabel = this.getActionLabel(KFSKeyConstants.AccountingLineViewRendering.ACCOUNTING_LINE_ADD_ACTION_LABEL, groupTitle);
String actionImageName = getRiceImagePath() + "tinybutton-add1.gif";
return new AccountingLineViewAction(actionMethod, actionLabel, actionImageName);
}
/**
* get a label for an action with the specified message key and values
*
* @param messageKey the given message key that points to the label
* @param values the given values that would be displayed in label
* @return a label for an action with the specified message key and values
*/
protected String getActionLabel(String messageKey, Object... values) {
String messageBody = SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(messageKey);
return MessageFormat.format(messageBody, values);
}
/**
* Builds the action method name of the method that adds accounting lines for this group
*
* @param accountingLine the accounting line an action is being checked for
* @param accountingLinePropertyName the property name of the accounting line
* @return the action method name of the method that adds accounting lines for this group
*/
protected String getAddMethod(AccountingLine accountingLine, String accountingLineProperty) {
final String infix = getActionInfixForNewAccountingLine(accountingLine, accountingLineProperty);
return KFSConstants.INSERT_METHOD + infix + "Line.anchoraccounting" + infix + "Anchor";
}
/**
* Builds the action method name of the method that deletes accounting lines for this group
*
* @param accountingLine the accounting line an action is being checked for
* @param accountingLinePropertyName the property name of the accounting line
* @param accountingLineIndex the index of the given accounting line within the the group being rendered
* @return the action method name of the method that deletes accounting lines for this group
*/
protected String getDeleteLineMethod(AccountingLine accountingLine, String accountingLineProperty, Integer accountingLineIndex) {
final String infix = getActionInfixForExtantAccountingLine(accountingLine, accountingLineProperty);
return KRADConstants.DELETE_METHOD + infix + "Line.line" + accountingLineIndex + ".anchoraccounting" + infix + "Anchor";
}
/**
* Builds the action method name of the method that performs a balance inquiry on accounting lines for this group
*
* @param accountingLine the accounting line an action is being checked for
* @param accountingLinePropertyName the property name of the accounting line
* @param accountingLineIndex the index of the given accounting line within the the group being rendered
* @return the action method name of the method that performs a balance inquiry on accounting lines for this group
*/
protected String getBalanceInquiryMethod(AccountingLine accountingLine, String accountingLineProperty, Integer accountingLineIndex) {
final String infix = getActionInfixForExtantAccountingLine(accountingLine, accountingLineProperty);
return KFSConstants.PERFORMANCE_BALANCE_INQUIRY_FOR_METHOD + infix + "Line.line" + accountingLineIndex + ".anchoraccounting" + infix + "existingLineLineAnchor" + accountingLineIndex;
}
/**
* Gets the "action infix" for the given accounting line, so that the action knows it is supposed to add to source vs. target
*
* @param accountingLine the accounting line an action is being checked for
* @param accountingLinePropertyName the property name of the accounting line
* @return the name of the action infix
*/
protected String getActionInfixForNewAccountingLine(AccountingLine accountingLine, String accountingLinePropertyName) {
if (accountingLine.isSourceAccountingLine()) {
return KFSConstants.SOURCE;
}
if (accountingLine.isTargetAccountingLine()) {
return KFSConstants.TARGET;
}
return KFSConstants.EMPTY_STRING;
}
/**
* Gets the "action infix" for the given accounting line which already exists on the document, so that the action knows it is
* supposed to add to source vs. target
*
* @param accountingLine the accounting line an action is being checked for
* @param accountingLinePropertyName the property name of the accounting line
* @return the name of the action infix
*/
protected String getActionInfixForExtantAccountingLine(AccountingLine accountingLine, String accountingLinePropertyName) {
if (accountingLine.isSourceAccountingLine()) {
return KFSConstants.SOURCE;
}
if (accountingLine.isTargetAccountingLine()) {
return KFSConstants.TARGET;
}
return KFSConstants.EMPTY_STRING;
}
/**
* get the document authorizer of the given accounting document
*
* @param accountingDocument the given accounting document
* @return the document authorizer of the given accounting document
*/
protected DocumentAuthorizer getDocumentAuthorizer(AccountingDocument accountingDocument) {
return SpringContext.getBean(DocumentHelperService.class).getDocumentAuthorizer(accountingDocument);
}
/**
* @return the path to rice images
*/
protected String getRiceImagePath() {
if (riceImagePath == null) {
riceImagePath = getConfigurationService().getPropertyValueAsString(KRADConstants.EXTERNALIZABLE_IMAGES_URL_KEY);
}
return riceImagePath;
}
/**
* @return the path to KFS images
*/
protected String getKFSImagePath() {
if (kfsImagePath == null) {
kfsImagePath = getConfigurationService().getPropertyValueAsString(KRADConstants.APPLICATION_EXTERNALIZABLE_IMAGES_URL_KEY);
}
return kfsImagePath;
}
protected ConfigurationService getConfigurationService() {
if ( kualiConfigurationService == null ) {
kualiConfigurationService = SpringContext.getBean(ConfigurationService.class);
}
return kualiConfigurationService;
}
}