Parameters

KFS provides an abstraction layer over Rice's parameter system to make it easier to use.  This page will describe Financials' parameter system and parameter naming conventions within Financials.

Parameter Classes

The org.kuali.kfs.coreservice.api.parameter.Parameter BO represents a record in the client side KRCR_PARM_T table. If a parameter represents one of many allowed or denied values, then each of the values should be delimited by a semicolon. For example, the parameter value with "A;B;C" represents a list containing the values A, B, and C.

Parameter Data Model

  • Parameter (KRCR_PARM_T): Parameters allow users to control the aspects of the application's behavior that they should be responsible for and which should be able to change independently of application releases.
    • Namespace Code (primary key)
    • Detailed Type Code (primary key)
    • Name (primary key)
    • Type Code
    • Value
    • Description
    • Constraint (values allowed or disallowed)- must be A or D
    • Application Namespace code (KFS)
  • Parameter Namespace (KRCR_NMSPC_T): High-level classification that allows the association of parameters with a particular application and module. Format is Application-Module, e.g. KFS-FP (KFS Financial Processing), KR-NS (Rice Nervous System), KFS-SYS (KFS System Wide)
    • Namespace Code (primary key)
    • Namespace Name
    • Active Indicator
  • Parameter Type (KRCR_PARM_TYP_T): High-Level classification that allows the grouping of parameters by functional type: e.g Configuration, Authorization, Validation, Help
    • Type Code (primary key)
    • Type Name
    • Active Indicator
  • Component (KRCR_CMPNT_T): I.E. Entities such as business objects, transactional documents, or batch steps with which a given parameter is associated. There are also general values that can be used when the parameter does not relate to a specific entity or batch step: Lookup, Document, Batch, and All.
    • Namespace Code (primary key)
    • Component Code (primary key)
    • Component Name
    • Active Indicator

Financials Parameter Conventions

There are four primary formats for a parameter's value:

  1. A simple text value.
  2. Indicator value: Y (true) or N (false).
  3. List of values: a list of values in a string delimited by semicolons (e.g. A;B123;C for A, B123, and C). Whether the list represents allowed or denied values is determined by the parameter's constraint code. Each element of the list is delimited with a semicolon.
  4. List of constraining/constrained value mappings: a semicolon delimited list of constraining/constrained value pairs.  A constraining value maps to a list of constrained values, which are comma delimited.  A constraining/constrained value pair represents all of the values associated with the constraining value.  Whether the association refers to an allowed or denied relationship is based on the parameter's constraint code.  For example, assume that the chart code DD may only be associated with the object codes 1111 and 2222.  The constraining value is the chart code, and the constrained value is the object code.  The pair would be "DD=1111,2222", and if the parameter constraint is A (allow), then this value would be interpreted as, "chart code DD (i.e. the constraining value) must have object codes 1111 or 2222 (i.e.the constrained values)".  Multiple pairs may be delimited with semicolons.  For example, a deny parameter with the value of "DD=1111,2222;EE=3333,4444" (note the semicolons and commas) can be interpreted as, "If the chart code is DD, then the object code cannot be 1111 or 2222.  If the chart code is EE then the object code cannot be 3333 or 4444.

In addition, there are two primary uses for a parameter in Financials:

  1. Parameters are used to provide configuration values. Examples include flags to turn on/off certain processing and email addresses to which to send notifications.
  2. Parameters are used to define valid/invalid values for validation purposes.

How a parameter is used depends on the code is implemented, which will be discussed below.

Role of parameters for validation

There are various data validation mechanisms in Rice/Financials:

  • Data dictionary-based validation
  • Document/business rules
  • Parameters

Data dictionary-based (see DictionaryValidationService) validation uses attribute metadata specified in the data dictionary file to perform elementary validations of a business object/document prior to persistence. For example, it is able to determine which attributes are required and whether they conform to a necessary format (e.g. all numbers), and to display error messages if they do not conform.

Document/business rules are full-fledged java classes that allow for very flexible validation rule logic. Rules have access to all Spring services, giving them a wide range of computational power. In fact, document/business rules use parameters to perform some of its validation.

Parameters are ideal when functional specifications require that a value be in a list of allowed values (or not on a list of denied values). That is, parameters work extremely well for straightforward matching. However, institutions may desire to do the matching logic, but use a different list of values. Parameter-based validation allows them to change the list of values without revising code.

Compound Parameters

Because of the data model, a parameter may represent either a list of allowed values or a list of denied values.   To provide flexibility, one allowed and one deny constraining/constrained parameters can be logically combined to form a compound parameter. The only restriction on the mappings for both parameters is that they may not share the same constraining value. For example, if the allow parameter is "AA=11;BB=2", then the deny parameter cannot have a mapping for either AA or BB.

For any constraining value and compound parameter:

  • if both parameters define a mapping for the constraining value, then an error occurs.
  • Otherwise, if both parameters do not define a mapping for a constraining value or have an empty mapping, then the validation will always succeed.
  • Otherwise, the constrained value must satisfy whichever parameter has a mapping for the constraining value.

Parameters in a compound parameter have the same namespace and detail type and have very similar names (see naming conventions).

Financials Parameter Service

The parameter table has four fields to comprise its primary key: namespace, detail type/component, parameter name, and aplpication id.  In Financials, most of the ParameterService's methods take in a java.lang.class object and a parameter name to specify a parameter.  The mapping mechanism is described in the next section.  This section will deal primarily with how to use parameters with the parameter service.

Non-existent parameters

In several methods on ParameterService, if the method attempts to retrieve a non-existent parameter, an exception will be thrown. A rationale was given that this allows for missing parameters to be easily detected during development and to avoid undefined behavior when parameters are missing; but in many cases, this behavior is annoying.

The method ParameterService.parameterExists allows code to determine whether a parameter exists. Furthermore, as of Rice 2.0, many ParameterService methods have a way to pass a default value which, if the parameter does not exist, will be returned in its stead. These new methods are especially helpful for retrieving values from indicator parameters.

Parameter Service Class Arguments

As noted already, the parameter service takes in as arguments a class object instead of the namespace and detail type. The class object should be closely related to the processing being done.

For example:

  • if the code is accessing a parameter necessary to validate a document, then the document class should be passed in as the argument.
  • if the code is accessing a parameter related to running a batch step, then the step class should be passed in as the argument.

How a class is resolved into a namespace and detail type will be discussed below. For the purposes of discussion about how to use the parameter service, it is sufficient to understand that a class object is mapped to a namespace and detail type in a one-to-one mapping.

Using Parameters in Code

Using Parameters to Provide Configuration Values

Parameters can be used to store configuration values within the database, so that the application server does not need to be restarted to make the changes. This section will describe how developers should use ParameterService.

Using Indicator Parameters

Indicator parameters are analogous to configuration flags and are simple to use. For example:

boolean autoApprove = parameterService.getParameterValueAsBoolean(ProcurementCardAutoApproveDocumentsStep.class, "AUTO_APPROVE_DOCUMENTS_IND", false); // use "false" as a default - if the parameter cannot be found, simply return false
if (autoApprove) {
    // do something
}
Retrieving Configuration Values

The ParameterService methods named getParameterValue and getParameterValues are used to retrieve parameter values. There are two variations of each of these method, with slightly different uses.

  • getParameterValueAsString(Class componentClass, String paramName): Returns the value is stored in the database for the parameter. This method does no parsing whatsoever of the parameter value and treats delimiter characters as regular text.
  • getSubParameterValuesAsString(Class componentClass, String paramName, String constrainingValue): Returns the constrained value for the constraining value. For the KFS default implementation, if there are multiple constrained values for a constraining value (i.e. a comma in the list of constrained values for the constraining value), then the method will return null. For example, if the parameter value were "AA=123;BB=222,333", then calling:
    •  getSubParameterValueAsString(someClass, paramName, "AA") returns "123" because AA is mapped to exactly one value
    •  getSubParameterValueAsString(someClass, paramName, "BB") returns null because BB is mapped to two values (222 and 333)
    •  getSubParameterValueAsString(someClass, paramName, "CC") returns null because CC is not mapped to any value
  •  getParameterValuesAsString(Class componentClass, String paramName): Returns a java.util.List of the parameter's values, delimited using the semicolons in the value. For example:
    •  If the parameter value is "A", then a list containing only "A" is returned.
    •  If the parameter value is "A;B;C", then a list containing only "A", "B", and "C" is returned.
    •  If the parameter value is AA=123;BB=222,333, then a list containing only "AA=123" and "BB=222,333" is returned (the comma delimiters are ignored).

Using Parameters for Validation

Financials also has a ParameterEvaluatorService, which uses Parameters to return ParameterEvaluator objects. The evaluator is a wrapper around a parameter object to evaluate whether a value passes validation. The following are the primary methods that retrieve evaluator objects:

  • getParameterEvaluator(Class componentClass, String parameterName)
  • getParameterEvaluator(Class componentClass, String parameterName, String constrainedValue)
  • getParameterEvaluator(Class componentClass, String allowParameterName, String denyParameterName, String constrainingValue, String constrainedValue)

There are other methods. See javadocs for more information.

The meaning of the above method arguments are as follows:

  • componentClass: the class that maps to a namespace and detail type
  • parameterName: the name of the parameter
  • constrainedValue: the value to validate (e.g. a value coming from a form).
  • allowParameterName: the name of the allow parameter in a compound parameter.
  • denyParameterName: the name of the deny parameter in a compound parameter.
Parameter Evaluators

Parameter evaluators are wrappers around a parameter BO that facilitate the evaluation of whether a constrained value satisfies the conditions of the parameter. Constrained values need to be set within the evaluator, either by calling a ParameterService method that takes in the constrained value or calling ParameterEvaluator.setConstrainedValue. Parameter evaluators have two main methods:

  • evaluationSucceeds(): returns whether the constrained value already set into the evaluator meets the condition of the parameter
  • evaluateAndAddError(...): calls evaluationSucceeds and if the constrained value does not satisfy the parameter, an error is added into the ErrorMap.

This code sample demonstrates how to use parameter evaluators' evaluationSucceeds method.

public boolean isTravelNonEmplPaymentReason(DisbursementVoucherDocument disbursementVoucherDocument) {
    ParameterEvaluator travelNonEmplPaymentReasonEvaluator = getParameterEvaluatorService().getParameterEvaluator(DisbursementVoucherDocument.class,
            "NONEMPLOYEE_TRAVEL_PAYMENT_REASONS", disbursementVoucherDocument.getDvPayeeDetail().getDisbVchrPaymentReasonCode());
    return travelNonEmplPaymentReasonEvaluator.evaluationSucceeds();
}

In the above sample, "DisbursementVoucherDocument.class" represents the component class for the parameter. "NONEMPLOYEE_TRAVEL_PAYMENT_REASONS" is the parameter name. "disbursementVoucherDocument.getDvPayeeDetail().getDisbVchrPaymentReasonCode() represents the constrained value to see if it satisfies the constraint specified by the parameter.

This following code sample demonstrates how to use a compound parameter and the evaluateAndAddError(...) method.

private void validateDocumentationLocation(DisbursementVoucherDocument document) {
    String documentationLocationCode = document.getDisbursementVoucherDocumentationLocationCode();
    ParameterEvaluator e = getParameterEvaluatorService().getParameterEvaluator(document.getClass(), // the component class
            "VALID_DOCUMENTATION_LOCATIONS_BY_PAYMENT_REASON", "INVALID_DOCUMENTATION_LOCATIONS_BY_PAYMENT_REASON", // allow and deny parameter names
            document.getDvPayeeDetail().getDisbVchrPaymentReasonCode(), documentationLocationCode); // payment reason is the constraining value, loc code is the constrained value
    e.evaluateAndAddError(document.getClass(), "disbursementVoucherDocumentationLocationCode");
}

In the above sample, the first document.getClass() represents the component class for the parameter. "VALID_DOCUMENTATION_LOCATIONS_BY_PAYMENT_REASON" and "INVALID_DOCUMENTATION_LOCATIONS_BY_PAYMENT_REASON" represent the allow and deny parameter of the compound parameter. "document.getDvPayeeDetail().getDisbVchrPaymentReasonCode()" is the constraining value. "documentationLocationCode" is the constrained value. If there's an error, the framework will highlight the "disbursementVoucherDocumentationLocationCode" attribute on the document, and uses the DD to help build the error text using the DD entry for document.getClass() and the attribute name of "disbursementVoucherDocumentationLocationCode".

Financials Parameter Namespace and Component Resolution

This section will describe how the Financials parameter service maps a class object to a namespace and detail type code.  This will allow developers to determine which parameter is associated with a document, step, business object, etc and to determine what the primary key values of a new parameter should be.

Namespace Resolution

The namespace is resolved using the following rules in the following order (see org.kuali.kfs.krad.service.impl.KualiModuleServiceImpl#getNamespaceCode(Class<?> documentClass)):

  1. If the class is annotated with the org.kuali.kfs.coreservice.framework.parameter.ParameterConstants.NAMESPACE annotation, then the namespace is whatever's defined as the annotation parameter.
  2. Otherwise, will try to get the responsible module service and get corresponding module configuration from which namespace code is readily available, or if package starts with "org.kuali.rice.kns" then "KR-NS", if "org.kuali.rice.kew" then it is "KR-WKFLW", if "org.kuali.rice.kim" then "KR-IDM" and if no match found then exception is thrown with message "Unable to determine the namespace for documentOrStepClass: <classname> ".

    Simplified GL module bean definition from spring-gl.xml
    <bean id="glModuleConfiguration-parentBean" class="org.kuali.kfs.sys.FinancialSystemModuleConfiguration" abstract="true">
        	<property name="namespaceCode" value="KFS-GL" />
    		<property name="initializeDataDictionary" value="true" />
            <property name="packagePrefixes">
                <list>
                    <value>org.kuali.kfs.gl</value>
                </list>
            </property>
    </bean>
    
  3. Otherwise, it looks at the package names and tries to match to Rice's specified package names to namespace constants.
  4. Otherwise, it's an error.

Component Resolution

The component code for a class is resolved using the following rules, in the following order (see see org.kuali.kfs.krad.service.impl.KualiModuleServiceImpl#getComponentCode(Class<?> documentClass)):

  1. If the class is annotated with the import org.kuali.kfs.coreservice.framework.parameter.ParameterConstants.COMPONENT annotation, then the component is whatever's defined as the annotation parameter.
  2. Otherwise, if the class is assignable from the TransactionalDocument interface, then the component is the simple name of the class with all instances of the "Document" string removed. For example, the InternalBillingDocument class would have a component of "InternalBilling".
  3. Otherwise, if the class is assignable from the BusinessObject or the Step interfaces, then the component is the simple class name.
  4. Otherwise, it's an error.

Runtime Parameter Specification

An advantage of this method of resolution is to allow for the runtime resolution of a parameter based on the type of the document/step/etc being validated. For example, assume that for all accounting documents, there is a list of valid object codes. In the following hypothetical rule methods, which validates a document's accounting line to ensure that the object code is valid, we see that using runtime parameter specification results in much shorter and cleaner code.

The disadvantage is that developers need to be careful to ensure that all of the necessary parameters exist depending on all of the possible classes that are passed in to retrieve a parameter evaluator.

Runtime parameter specification

Static parameter specification

public boolean validateObjectCode(Document doc, AccountingLine line) {
    ParameterEvaluator e = parameterEvaluatorService.getParameterEvaluator(doc.getClass(),
            "OBJECT_CODES", line.getFinancialObjectCode());
    return e.evaluationSucceeds();
}
// the code is not complete for this method, but this will show the complexity
// without the runtime parameter specification provided by the parameter service.
public boolean validateObjectCode(Document doc, AccountingLine line) {
    String namespace = "";
    String detailType = "";
    if (doc instanceof DisbursementVoucherDocument) {
        namespace = "KFS-FP"; // the namespace for Financial Processing parameters
        detailType = "DisbursementVoucher";
    }
    // and more if statements for the other doc types

    // then retrieve the parameter from the DB using the BusinessObjectService

    // then determine whether the object code is one of the allowed or denied values
    return successful;
}

Financials Parameter Naming Conventions

The parameter names used within Financials generally follow these conventions:

  • Words are not abbreviated.
  • Underscores separate words (as opposed to spaces or camelCaps).
  • The list of valid values for component/detailed type is built from what's actually in KRCR_CMPNT_T, the simple names of business objects, the workflow document type names specified in the data dictionary, and the names of batch steps in spring.
  • Entities are referred to by the same name under which they are listed in the component lookup (substituting underscores for case changes).
  • Parameter names avoid the use of the words VALID, INVALID, ALLOW, DENY, and RESTRICTED, unless otherwise specified below. The constraint column should account for that information.
  • Parameters that can have a value of Y or N should have a suffix of _IND (e.g. SHOW_CONTINUATION_ACCOUNT_WARNING_FISCAL_OFFICERS_IND).  These are indicator parameters and are generally treated as booleans throughout the system.
  • When defining restrictions on one value (the constrained value) based on another value (the constraining value), i.e. creating a compound rule, the terms VALID and INVALID are used to distinguish between the allow and deny parameters. But, we also have examples where INCLUDE and EXCLUDE make more sense, and one case of even more custom naming. Users should still be able to find all of these compound rules by search for name like *_BY_*. The format of the parameter values should be "constraining value 1=constrained value 1,constrained value 2;constraining value 2=constrained value,constrained value 4,constrained value 5;...".
    • <optional grouping prefix>-VALID_<name of entity associated with constrained field>BY<name of entity associated with constraining field>, e.g. VALID_DOCUMENTATION_LOCATIONS_BY_CAMPUS.
    • <optional grouping prefix>-INVALID_<name of entity associated with constrained field>BY<name of entity associated with constraining field>, e.g. INVALID_DOCUMENTATION_LOCATIONS_BY_CAMPUS.
  • When defining what the value of one field (determined field) should be, based on a the value of another field (determining field), you should create one parameter. The format of the parameter value should be "determining value 1=determined value 1;determining value 2=determined value 2;...".
    • <optional grouping prefix>-<name of entity associated with the value that is being derived>_BY_<name of entity associated with the value that is determining the value that is being derived>, e.g. NRA_TAX_FEDERAL-OBJECT_BY_INCOME_CLASS
  • When creating a run indicator of user parameter for a batch step, the name should be RUN_IND or USER. By default steps will run and a session will be created for the system user, so these are needed only to specify these when the step should not run or should run as another user.

 

 

Kuali documentation is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 2.5 License. 

Kuali software is licensed for use pursuant to the Affero General Public License, version 3.

 Copyright © 2014 Kuali, Inc. All rights reserved. 

Portions of Kuali are copyrighted by other parties as described in the Acknowledgments screen. 

Kuali ® is a registered trademark of the Trustees of Indiana University.