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 }