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.sys.document.authorization; 017 018 import java.text.MessageFormat; 019 import java.util.ArrayList; 020 import java.util.HashMap; 021 import java.util.HashSet; 022 import java.util.List; 023 import java.util.Map; 024 import java.util.Set; 025 026 import org.apache.commons.lang.StringUtils; 027 import org.kuali.kfs.sys.KFSConstants; 028 import org.kuali.kfs.sys.KFSKeyConstants; 029 import org.kuali.kfs.sys.businessobject.AccountingLine; 030 import org.kuali.kfs.sys.businessobject.FinancialSystemDocumentHeader; 031 import org.kuali.kfs.sys.context.SpringContext; 032 import org.kuali.kfs.sys.document.AccountingDocument; 033 import org.kuali.kfs.sys.document.Correctable; 034 import org.kuali.kfs.sys.document.web.AccountingLineRenderingContext; 035 import org.kuali.kfs.sys.document.web.AccountingLineViewAction; 036 import org.kuali.kfs.sys.document.web.AccountingLineViewField; 037 import org.kuali.kfs.sys.identity.KfsKimAttributes; 038 import org.kuali.rice.kim.bo.Person; 039 import org.kuali.rice.kim.bo.types.dto.AttributeSet; 040 import org.kuali.rice.kns.document.authorization.DocumentAuthorizer; 041 import org.kuali.rice.kns.service.DocumentHelperService; 042 import org.kuali.rice.kns.service.KualiConfigurationService; 043 import org.kuali.rice.kns.util.GlobalVariables; 044 import org.kuali.rice.kns.util.KNSConstants; 045 import org.kuali.rice.kns.util.ObjectUtils; 046 import org.kuali.rice.kns.workflow.service.KualiWorkflowDocument; 047 048 /** 049 * The default implementation of AccountingLineAuthorizer 050 */ 051 public class AccountingLineAuthorizerBase implements AccountingLineAuthorizer { 052 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AccountingLineAuthorizerBase.class); 053 054 private KualiConfigurationService kualiConfigurationService = SpringContext.getBean(KualiConfigurationService.class); 055 private static String riceImagePath; 056 private static String kfsImagePath; 057 058 /** 059 * Returns the basic actions - add for new lines, delete and balance inquiry for existing lines 060 * 061 * @see org.kuali.kfs.sys.document.authorization.AccountingLineAuthorizer#getActions(org.kuali.kfs.sys.document.AccountingDocument, 062 * org.kuali.kfs.sys.businessobject.AccountingLine, java.lang.String, java.lang.Integer, org.kuali.rice.kim.bo.Person, 063 * java.lang.String) 064 */ 065 public final List<AccountingLineViewAction> getActions(AccountingDocument accountingDocument, AccountingLineRenderingContext accountingLineRenderingContext, String accountingLinePropertyName, Integer accountingLineIndex, Person currentUser, String groupTitle) { 066 List<AccountingLineViewAction> actions = new ArrayList<AccountingLineViewAction>(); 067 068 if (accountingLineRenderingContext.isEditableLine() || isErrorMapContainingErrorsOnLine(accountingLinePropertyName)) { 069 Map<String, AccountingLineViewAction> actionMap = this.getActionMap(accountingLineRenderingContext, accountingLinePropertyName, accountingLineIndex, groupTitle); 070 actions.addAll(actionMap.values()); 071 } 072 073 return actions; 074 } 075 076 /** 077 * Determines if the error map contains any errors which exist on the currently rendered accounting line 078 * @param accountingLinePropertyName the property name of the accounting line 079 * @return true if there are errors on the line, false otherwise 080 */ 081 protected boolean isErrorMapContainingErrorsOnLine(String accountingLinePropertyName) { 082 for (Object errorKeyAsObject : GlobalVariables.getMessageMap().getPropertiesWithErrors()) { 083 if (((String)errorKeyAsObject).startsWith(accountingLinePropertyName)) return true; 084 } 085 return false; 086 } 087 088 /** 089 * Returns a new empty HashSet 090 * 091 * @see org.kuali.kfs.sys.document.authorization.AccountingLineAuthorizer#getUnviewableBlocks(org.kuali.kfs.sys.document.AccountingDocument, 092 * org.kuali.kfs.sys.businessobject.AccountingLine, java.lang.String, boolean) 093 */ 094 public Set<String> getUnviewableBlocks(AccountingDocument accountingDocument, AccountingLine accountingLine, boolean newLine, Person currentUser) { 095 return new HashSet<String>(); 096 } 097 098 /** 099 * @see org.kuali.kfs.sys.document.authorization.AccountingLineAuthorizer#renderNewLine(org.kuali.kfs.sys.document.AccountingDocument, 100 * java.lang.String) 101 */ 102 public boolean renderNewLine(AccountingDocument accountingDocument, String accountingGroupProperty) { 103 return (accountingDocument.getDocumentHeader().getWorkflowDocument().stateIsInitiated() || accountingDocument.getDocumentHeader().getWorkflowDocument().stateIsSaved()); 104 } 105 106 /** 107 * @see org.kuali.kfs.sys.document.authorization.AccountingLineAuthorizer#isGroupEditable(org.kuali.kfs.sys.document.AccountingDocument, 108 * java.lang.String, org.kuali.rice.kim.bo.Person) 109 */ 110 public boolean isGroupEditable(AccountingDocument accountingDocument, List<? extends AccountingLineRenderingContext> accountingLineRenderingContexts, Person currentUser) { 111 KualiWorkflowDocument workflowDocument = accountingDocument.getDocumentHeader().getWorkflowDocument(); 112 if (workflowDocument.stateIsInitiated() || workflowDocument.stateIsSaved()) { 113 return workflowDocument.userIsInitiator(currentUser); 114 } 115 116 for (AccountingLineRenderingContext renderingContext : accountingLineRenderingContexts) { 117 if (renderingContext.isEditableLine()) return true; 118 } 119 120 return false; 121 } 122 123 /** 124 * collection the actions that are allowed for the given accounting line 125 * 126 * @param accountingLine the given accounting line 127 * @param accountingLinePropertyName the property name of the given account line, typically, the form name 128 * @param accountingLineIndex the index of the given accounting line in its accounting line group 129 * @param groupTitle the title of the accounting line group 130 * @return the actions that are allowed for the given accounting line 131 */ 132 protected Map<String, AccountingLineViewAction> getActionMap(AccountingLineRenderingContext accountingLineRenderingContext, String accountingLinePropertyName, Integer accountingLineIndex, String groupTitle) { 133 Map<String, AccountingLineViewAction> actionMap = new HashMap<String, AccountingLineViewAction>(); 134 135 if (accountingLineIndex == null || accountingLineIndex < 0) { 136 AccountingLineViewAction addAction = this.getAddAction(accountingLineRenderingContext.getAccountingLine(), accountingLinePropertyName, groupTitle); 137 actionMap.put(KFSConstants.INSERT_METHOD, addAction); 138 } 139 else { 140 if (accountingLineRenderingContext.allowDelete()) { 141 AccountingLineViewAction deleteAction = this.getDeleteAction(accountingLineRenderingContext.getAccountingLine(), accountingLinePropertyName, accountingLineIndex, groupTitle); 142 actionMap.put(KNSConstants.DELETE_METHOD, deleteAction); 143 } 144 145 AccountingLineViewAction balanceInquiryAction = this.getBalanceInquiryAction(accountingLineRenderingContext.getAccountingLine(), accountingLinePropertyName, accountingLineIndex, groupTitle); 146 actionMap.put(KFSConstants.PERFORMANCE_BALANCE_INQUIRY_FOR_METHOD, balanceInquiryAction); 147 } 148 149 return actionMap; 150 } 151 152 /** 153 * determine whether the current user has permission to edit the given field in the given accounting line 154 * 155 * @param accountingDocument the given accounting document 156 * @param accountingLine the given accounting line in the document 157 * @param fieldName the name of a field in the given accounting line 158 * @param editableLine whether the parent line of this field is editable 159 * @param editablePage whether the parent page of this field is editable 160 * @param currentUser the current user 161 * @return true if the the current user has permission to edit the given field in the given accounting line; otherwsie, false 162 */ 163 public final boolean hasEditPermissionOnField(AccountingDocument accountingDocument, AccountingLine accountingLine, String accountingLineCollectionProperty, String fieldName, boolean editableLine, boolean editablePage, Person currentUser) { 164 if (!determineEditPermissionOnField(accountingDocument, accountingLine, accountingLineCollectionProperty, fieldName, editablePage)) { 165 return false; 166 } 167 168 // the fields in a new line should be always editable 169 if (accountingLine.getSequenceNumber() == null) { 170 return true; 171 } 172 173 // examine whether the given field can be editable 174 boolean hasEditPermissionOnField = editableLine || this.determineEditPermissionByFieldName(accountingDocument, accountingLine, getKimHappyPropertyNameForField(accountingLineCollectionProperty+"."+fieldName), currentUser); 175 if (hasEditPermissionOnField == false) { 176 // kim check shows field should not be editable based on contents of field - check if line error message occurred on this line 177 // if error message shows up, then the value must have changed recently so - we make it editable to allow user to correct it 178 KualiWorkflowDocument workflowDocument = accountingDocument.getDocumentHeader().getWorkflowDocument(); 179 if (workflowDocument.stateIsEnroute() && isErrorMapContainingErrorsOnLine(accountingLineCollectionProperty)) return true; 180 } 181 return hasEditPermissionOnField; 182 } 183 184 /** 185 * Allows the overriding of whether a field on an accounting line is editable or not 186 * @param accountingDocument the accounting document the line to test is on 187 * @param accountingLine the accounting line to test 188 * @param accountingLineCollectionProperty the property that the accounting line lives in 189 * @param fieldName the name of the field we are testing 190 * @param editableLine whether the parent line of this field is editable 191 * @param editablePage whether the parent page of this field is editable 192 * @return true if the field can be edited (subject to subsequence KIM check); false otherwise 193 */ 194 public boolean determineEditPermissionOnField(AccountingDocument accountingDocument, AccountingLine accountingLine, String accountingLineCollectionProperty, String fieldName, boolean editablePage) { 195 if (!editablePage) return false; // no edits by default on non editable pages 196 197 final FinancialSystemDocumentHeader documentHeader = (FinancialSystemDocumentHeader) accountingDocument.getDocumentHeader(); 198 final KualiWorkflowDocument workflowDocument = documentHeader.getWorkflowDocument(); 199 200 // if a document is cancelled or in error, all of its fields cannot be editable 201 if (workflowDocument.stateIsCanceled() || ObjectUtils.isNotNull(documentHeader.getFinancialDocumentInErrorNumber())) { 202 return false; 203 } 204 205 return true; 206 } 207 208 /** 209 * Determine whether the current user has permission to edit the given accounting line as a whole 210 * 211 * @param accountingDocument the given accounting document 212 * @param accountingLine the given accounting line in the document 213 * @param currentUser the current user 214 * @return true if the the current user has permission to edit the given accounting line; otherwsie, false 215 */ 216 public final boolean hasEditPermissionOnAccountingLine(AccountingDocument accountingDocument, AccountingLine accountingLine, String accountingLineCollectionProperty, Person currentUser, boolean pageIsEditable) { 217 if (determineEditPermissionOnLine(accountingDocument, accountingLine, accountingLineCollectionProperty, accountingDocument.getDocumentHeader().getWorkflowDocument().userIsInitiator(currentUser), pageIsEditable)) { 218 219 if (approvedForUnqualifiedEditing(accountingDocument, accountingLine, accountingLineCollectionProperty, accountingDocument.getDocumentHeader().getWorkflowDocument().userIsInitiator(currentUser))) { 220 return true; // don't do the KIM check, we're good 221 } 222 223 // examine whether the whole line can be editable via KIM check 224 final String lineFieldName = getKimHappyPropertyNameForField(accountingLineCollectionProperty); 225 return this.determineEditPermissionByFieldName(accountingDocument, accountingLine, lineFieldName, currentUser); 226 } 227 return false; 228 } 229 230 /** 231 * A hook to decide, pre-KIM check, if there's an edit permission on the given accounting line 232 * @param accountingDocument the accounting document the line is or wants to be associated with 233 * @param accountingLine the accounting line itself 234 * @param accountingLineCollectionProperty the collection the accounting line is or would be part of 235 * @param currentUserIsDocumentInitiator is the current user the initiator of the document? 236 * @return true if the line as a whole can be edited, false otherwise 237 */ 238 public boolean determineEditPermissionOnLine(AccountingDocument accountingDocument, AccountingLine accountingLine, String accountingLineCollectionProperty, boolean currentUserIsDocumentInitiator, boolean pageIsEditable) { 239 if (accountingDocument instanceof Correctable) { 240 String errorDocumentNumber = ((FinancialSystemDocumentHeader)accountingDocument.getDocumentHeader()).getFinancialDocumentInErrorNumber(); 241 if (StringUtils.isNotBlank(errorDocumentNumber)) 242 return false; 243 } 244 245 return true; 246 } 247 248 /** 249 * Determines if the given line is editable, no matter what a KIM check would say about line editability. In the default case, 250 * any accounting line is editable - minus KIM check - when the document is PreRoute, or if the line is a new line 251 * @param accountingDocument the accounting document the line is or wants to be associated with 252 * @param accountingLine the accounting line itself 253 * @param accountingLineCollectionProperty the collection the accounting line is or would be part of 254 * @param currentUserIsDocumentInitiator is the current user the initiator of the document? 255 * @return true if the line as a whole can be edited without the KIM check, false otherwise 256 */ 257 protected boolean approvedForUnqualifiedEditing(AccountingDocument accountingDocument, AccountingLine accountingLine, String accountingLineCollectionProperty, boolean currentUserIsDocumentInitiator) { 258 // the fields in a new line should be always editable 259 if (accountingLine.getSequenceNumber() == null) { 260 return true; 261 } 262 263 // check the initiation permission on the document if it is in the state of preroute 264 KualiWorkflowDocument workflowDocument = accountingDocument.getDocumentHeader().getWorkflowDocument(); 265 if (workflowDocument.stateIsInitiated() || workflowDocument.stateIsSaved()) { 266 return currentUserIsDocumentInitiator; 267 } 268 return false; 269 } 270 271 /** 272 * determine whether the current user has permission to edit the given field in the given accounting line 273 * 274 * @param accountingDocument the given accounting document 275 * @param accountingLine the given accounting line in the document 276 * @param fieldName the name of a field in the given accounting line 277 * @param currentUser the current user 278 * @return true if the the current user has permission to edit the given field in the given accounting line; otherwsie, false 279 */ 280 private boolean determineEditPermissionByFieldName(AccountingDocument accountingDocument, AccountingLine accountingLine, String fieldName, Person currentUser) { 281 final AttributeSet roleQualifiers = this.getRoleQualifiers(accountingDocument, accountingLine); 282 final String documentTypeName = accountingDocument.getDocumentHeader().getWorkflowDocument().getDocumentType(); 283 final AttributeSet permissionDetail = this.getPermissionDetails(documentTypeName, fieldName); 284 285 return this.hasEditPermission(accountingDocument, currentUser, permissionDetail, roleQualifiers); 286 } 287 288 /** 289 * determine whether the current user has modification permission on an accounting line with the given qualifications. The 290 * permission template and namespace have been setup in the method. 291 * 292 * @param currentUser the current user 293 * @param permissionDetails the given permission details 294 * @param roleQualifiers the given role qualifications 295 * @return true if the user has edit permission on an accounting line with the given qualifications; otherwise, false 296 */ 297 private boolean hasEditPermission(AccountingDocument accountingDocument, Person currentUser, AttributeSet permissionDetails, AttributeSet roleQualifiers) { 298 String pricipalId = currentUser.getPrincipalId(); 299 DocumentAuthorizer accountingDocumentAuthorizer = this.getDocumentAuthorizer(accountingDocument); 300 301 return accountingDocumentAuthorizer.isAuthorizedByTemplate(accountingDocument, KFSConstants.ParameterNamespaces.KFS, KFSConstants.PermissionTemplate.MODIFY_ACCOUNTING_LINES.name, pricipalId, permissionDetails, roleQualifiers); 302 } 303 304 /** 305 * Gathers together all the information for a permission detail attribute set 306 * 307 * @param documentTypeName the document 308 * @param fieldName the given field name 309 * @return all the information for a permission detail attribute set 310 */ 311 private AttributeSet getPermissionDetails(String documentTypeName, String fieldName) { 312 AttributeSet permissionDetails = new AttributeSet(); 313 314 if (StringUtils.isNotBlank(documentTypeName)) { 315 permissionDetails.put(KfsKimAttributes.DOCUMENT_TYPE_NAME, documentTypeName); 316 } 317 318 if (StringUtils.isNotBlank(fieldName)) { 319 permissionDetails.put(KfsKimAttributes.PROPERTY_NAME, fieldName); 320 } 321 322 return permissionDetails; 323 } 324 325 /** 326 * Gathers together the role qualifiers for the KIM perm call 327 * 328 * @param accountingLine the accounting line to get role qualifiers from 329 * @return the gathered AttributeSet of role qualifiers 330 */ 331 private final AttributeSet getRoleQualifiers(AccountingDocument accountingDocument, AccountingLine accountingLine) { 332 AttributeSet roleQualifiers = new AttributeSet(); 333 334 if (accountingLine != null) { 335 roleQualifiers.put(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE, accountingLine.getChartOfAccountsCode()); 336 roleQualifiers.put(KfsKimAttributes.ACCOUNT_NUMBER, accountingLine.getAccountNumber()); 337 } 338 339 return roleQualifiers; 340 } 341 342 /** 343 * @param field AccountingLineViewField to find KIM-happy property name for 344 * @return a property name that KIM will like 345 */ 346 protected String getKimHappyPropertyNameForField(String convertedName) { 347 convertedName = stripDocumentPrefixFromName(convertedName); 348 349 return replaceCollectionElementsWithPlurals(convertedName); 350 } 351 352 /** 353 * get the full property name of the given field 354 * 355 * @param field the field to get the name from 356 * @return the full property name of the given field, typically, a combination of property prefix and simple property name 357 */ 358 protected String getFieldName(AccountingLineViewField field) { 359 String propertyPrefix = field.getField().getPropertyPrefix(); 360 String propertyName = field.getField().getPropertyName(); 361 362 return StringUtils.isNotBlank(propertyPrefix) ? (propertyPrefix + "." + propertyName) : propertyName; 363 } 364 365 /** 366 * Strips "document." and everything before from the property name 367 * 368 * @param name the property name to strip the document portion off of 369 * @return the stripped name 370 */ 371 protected String stripDocumentPrefixFromName(String name) { 372 return name.replaceFirst("(.)*document\\.", StringUtils.EMPTY); 373 } 374 375 /** 376 * Replaces references to collection elements to their respective plural names WARNING: this method is totally lame and I for 377 * one wished it didn't have to exist 378 * 379 * @param name the property name with perhaps collection elements in 380 * @return the corrected name 381 */ 382 protected String replaceCollectionElementsWithPlurals(String name) { 383 String temp = name.replaceAll("\\[\\d+\\]", "s"); 384 // now - need to check if the property name ends with a double "s", which is incorrect 385 if ( temp.endsWith( "ss" ) ) { 386 temp = StringUtils.chop(temp); 387 } 388 return temp; 389 } 390 391 /** 392 * construct the balance inquiry action for the given accounting line 393 * 394 * @param accountingLine the given accounting line 395 * @param accountingLinePropertyName the property name of the given account line, typically, the form name 396 * @param accountingLineIndex the index of the given accounting line in its accounting line group 397 * @param groupTitle the title of the accounting line group 398 * @return the balance inquiry action for the given accounting line 399 */ 400 protected AccountingLineViewAction getBalanceInquiryAction(AccountingLine accountingLine, String accountingLinePropertyName, Integer accountingLineIndex, String groupTitle) { 401 String actionMethod = this.getBalanceInquiryMethod(accountingLine, accountingLinePropertyName, accountingLineIndex); 402 String actionLabel = this.getActionLabel(KFSKeyConstants.AccountingLineViewRendering.ACCOUNTING_LINE_BALANCE_INQUIRY_ACTION_LABEL, groupTitle, accountingLineIndex + 1); 403 404 String actionImageName = getKFSImagePath() + "tinybutton-balinquiry.gif"; 405 406 return new AccountingLineViewAction(actionMethod, actionLabel, actionImageName); 407 } 408 409 /** 410 * construct the delete action for the given accounting line 411 * 412 * @param accountingLine the given accounting line 413 * @param accountingLinePropertyName the property name of the given account line, typically, the form name 414 * @param accountingLineIndex the index of the given accounting line in its accounting line group 415 * @param groupTitle the title of the accounting line group 416 * @return the delete action for the given accounting line 417 */ 418 protected AccountingLineViewAction getDeleteAction(AccountingLine accountingLine, String accountingLinePropertyName, Integer accountingLineIndex, String groupTitle) { 419 String actionMethod = this.getDeleteLineMethod(accountingLine, accountingLinePropertyName, accountingLineIndex); 420 String actionLabel = this.getActionLabel(KFSKeyConstants.AccountingLineViewRendering.ACCOUNTING_LINE_DELETE_ACTION_LABEL, groupTitle, accountingLineIndex + 1); 421 422 String actionImageName = getRiceImagePath() + "tinybutton-delete1.gif"; 423 424 return new AccountingLineViewAction(actionMethod, actionLabel, actionImageName); 425 } 426 427 /** 428 * construct the add action for the given accounting line, typically, a new accounting line 429 * 430 * @param accountingLine the given accounting line 431 * @param accountingLinePropertyName the property name of the given account line, typically, the form name 432 * @param accountingLineIndex the index of the given accounting line in its accounting line group 433 * @param groupTitle the title of the accounting line group 434 * @return the add action for the given accounting line 435 */ 436 protected AccountingLineViewAction getAddAction(AccountingLine accountingLine, String accountingLinePropertyName, String groupTitle) { 437 String actionMethod = this.getAddMethod(accountingLine, accountingLinePropertyName); 438 String actionLabel = this.getActionLabel(KFSKeyConstants.AccountingLineViewRendering.ACCOUNTING_LINE_ADD_ACTION_LABEL, groupTitle); 439 440 String actionImageName = getRiceImagePath() + "tinybutton-add1.gif"; 441 442 return new AccountingLineViewAction(actionMethod, actionLabel, actionImageName); 443 } 444 445 /** 446 * get a label for an action with the specified message key and values 447 * 448 * @param messageKey the given message key that points to the label 449 * @param values the given values that would be displayed in label 450 * @return a label for an action with the specified message key and values 451 */ 452 protected String getActionLabel(String messageKey, Object... values) { 453 String messageBody = kualiConfigurationService.getPropertyString(messageKey); 454 455 return MessageFormat.format(messageBody, values); 456 } 457 458 /** 459 * Builds the action method name of the method that adds accounting lines for this group 460 * 461 * @param accountingLine the accounting line an action is being checked for 462 * @param accountingLinePropertyName the property name of the accounting line 463 * @return the action method name of the method that adds accounting lines for this group 464 */ 465 protected String getAddMethod(AccountingLine accountingLine, String accountingLineProperty) { 466 final String infix = getActionInfixForNewAccountingLine(accountingLine, accountingLineProperty); 467 return KFSConstants.INSERT_METHOD + infix + "Line.anchoraccounting" + infix + "Anchor"; 468 } 469 470 /** 471 * Builds the action method name of the method that deletes accounting lines for this group 472 * 473 * @param accountingLine the accounting line an action is being checked for 474 * @param accountingLinePropertyName the property name of the accounting line 475 * @param accountingLineIndex the index of the given accounting line within the the group being rendered 476 * @return the action method name of the method that deletes accounting lines for this group 477 */ 478 protected String getDeleteLineMethod(AccountingLine accountingLine, String accountingLineProperty, Integer accountingLineIndex) { 479 final String infix = getActionInfixForExtantAccountingLine(accountingLine, accountingLineProperty); 480 return KNSConstants.DELETE_METHOD + infix + "Line.line" + accountingLineIndex + ".anchoraccounting" + infix + "Anchor"; 481 } 482 483 /** 484 * Builds the action method name of the method that performs a balance inquiry on accounting lines for this group 485 * 486 * @param accountingLine the accounting line an action is being checked for 487 * @param accountingLinePropertyName the property name of the accounting line 488 * @param accountingLineIndex the index of the given accounting line within the the group being rendered 489 * @return the action method name of the method that performs a balance inquiry on accounting lines for this group 490 */ 491 protected String getBalanceInquiryMethod(AccountingLine accountingLine, String accountingLineProperty, Integer accountingLineIndex) { 492 final String infix = getActionInfixForExtantAccountingLine(accountingLine, accountingLineProperty); 493 return KFSConstants.PERFORMANCE_BALANCE_INQUIRY_FOR_METHOD + infix + "Line.line" + accountingLineIndex + ".anchoraccounting" + infix + "existingLineLineAnchor" + accountingLineIndex; 494 } 495 496 /** 497 * Gets the "action infix" for the given accounting line, so that the action knows it is supposed to add to source vs. target 498 * 499 * @param accountingLine the accounting line an action is being checked for 500 * @param accountingLinePropertyName the property name of the accounting line 501 * @return the name of the action infix 502 */ 503 protected String getActionInfixForNewAccountingLine(AccountingLine accountingLine, String accountingLinePropertyName) { 504 if (accountingLine.isSourceAccountingLine()) { 505 return KFSConstants.SOURCE; 506 } 507 508 if (accountingLine.isTargetAccountingLine()) { 509 return KFSConstants.TARGET; 510 } 511 512 return KFSConstants.EMPTY_STRING; 513 } 514 515 /** 516 * Gets the "action infix" for the given accounting line which already exists on the document, so that the action knows it is 517 * supposed to add to source vs. target 518 * 519 * @param accountingLine the accounting line an action is being checked for 520 * @param accountingLinePropertyName the property name of the accounting line 521 * @return the name of the action infix 522 */ 523 protected String getActionInfixForExtantAccountingLine(AccountingLine accountingLine, String accountingLinePropertyName) { 524 if (accountingLine.isSourceAccountingLine()) { 525 return KFSConstants.SOURCE; 526 } 527 528 if (accountingLine.isTargetAccountingLine()) { 529 return KFSConstants.TARGET; 530 } 531 532 return KFSConstants.EMPTY_STRING; 533 } 534 535 /** 536 * get the document authorizer of the given accounting document 537 * 538 * @param accountingDocument the given accounting document 539 * @return the document authorizer of the given accounting document 540 */ 541 private DocumentAuthorizer getDocumentAuthorizer(AccountingDocument accountingDocument) { 542 return SpringContext.getBean(DocumentHelperService.class).getDocumentAuthorizer(accountingDocument); 543 } 544 545 /** 546 * @return the path to rice images 547 */ 548 protected String getRiceImagePath() { 549 if (riceImagePath == null) { 550 riceImagePath = kualiConfigurationService.getPropertyString(KNSConstants.EXTERNALIZABLE_IMAGES_URL_KEY); 551 } 552 return riceImagePath; 553 } 554 555 /** 556 * @return the path to KFS images 557 */ 558 protected String getKFSImagePath() { 559 if (kfsImagePath == null) { 560 kfsImagePath = kualiConfigurationService.getPropertyString(KNSConstants.APPLICATION_EXTERNALIZABLE_IMAGES_URL_KEY); 561 } 562 return kfsImagePath; 563 } 564 }