Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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

Anchor
parameterClasses
parameterClasses
Parameter Classes

The org.kuali.ricekfs.coreservice.knsapi.boparameter.Parameter BO represents a record in KRNSthe 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.Within KFS, the use of the Parameter has been restricted to KFS core classes, and module code has been made agnostic of the Parameter BO by using the ParameterService.

Anchor
parameterDataModel
parameterDataModel
Parameter Data Model

  • Parameter (KRNSKRCR_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 (KRNSKRCR_PARM_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-SY SYS (KFS System Wide)
    • Namespace Code (primary key)
    • Namespace Name
    • Active Indicator
  • Parameter Type (KRNSKRCR_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
  • Parameter Detailed Type Component (KRNSKRCR_PARMCMPNT_DTL_TYP_T): I.E. Component - Entities such as maintenance tables or business objects, transactional documents and , 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, Inquiry, Document, Batch, and All.
    • Namespace Code (primary key)
    • Detailed Type Component Code (primary key)
    • Detailed Type Component Name
    • Active Indicator

Anchor
kfsParameterConventions
kfsParameterConventions

...

Financials Parameter Conventions

There are three 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 be333 be 3333 or 4444.

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

  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.

...

Info
titleRole of parameters for validation

There are various data validation mechanisms in Rice/KFSFinancials:

  • 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.

...

Because of the data model, a parameter (i.e. a row in KRNS_PARM_T) 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.

...

  • 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).

Anchor
parameterService
parameterService

...

Financials Parameter Service

The parameter table , KRNS_PARM_T, has fields that has four fields to comprise its primary key: namespace, detail type/component, and parameter name, and aplpication id.  In KFSFinancials, 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.

Info
titleNon-existent parameters

If the parameter service In several methods on ParameterService, if the method attempts to retrieve a non-existent parameter, the parameter service will throw an exception . This 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.

Anchor
parameterServiceClassArguments
parameterServiceClassArguments
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.

...

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 the parameter serviceParameterService.

Using Indicator Parameters

...

Code Block
typejava
boolean autoApprove = parameterService.getIndicatorParametergetParameterValueAsBoolean(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
}

...

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.

  • getParameterValuegetParameterValueAsString(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.
  • getParameterValuegetSubParameterValuesAsString(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:
    •  getParameterValuegetSubParameterValueAsString(someClass, paramName, "AA") returns "123" because AA is mapped to exactly one value
    •  getParameterValuegetSubParameterValueAsString(someClass, paramName, "BB") returns null because BB is mapped to two values (222 and33and 333)
    •  getParameterValuegetSubParameterValueAsString(someClass, paramName, "CC") returns null because CC is not mapped to any value
  •  getParameterValuesgetParameterValuesAsString(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).
  •  getParameterValues(Class componentClass, String paramName, String constrainingValue): Returns a java.util.List of constrained values for the constraining value. For example: if the parameter value were "AA=123;BB=222,333", then calling:
    •  getParameterValue(someClass, paramName, "AA") returns a list with only "123" because AA is mapped to exactly one value
    •  getParameterValue(someClass, paramName, "BB") returns a list with only "222" and "333" because BB is mapped to two values
    •  getParameterValue(someClass, paramName, "CC") returns an empty list because "CC" is not mapped to anything

...

Anchor
parametersForValidation
parametersForValidation
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:

...

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

...

Code Block
typejava
private void validateDocumentationLocation(DisbursementVoucherDocument document) {
    String documentationLocationCode = document.getDisbursementVoucherDocumentationLocationCode();
    ParameterEvaluator e = getParameterServicegetParameterEvaluatorService().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".

Anchor
resolution
resolution

...

Financials Parameter Namespace and Component Resolution

This section will describe how the KFS 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.

...

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

  1. If the class is annotated with the orgthe org.kuali.ricekfs.coreservice.knsframework.serviceparameter.ParameterConstants.NAMESPACE annotationNAMESPACE 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> ".

    Code Block
    titleSimplified 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, if the fully qualified class name begins with org.kuali.kns, then the namespace is "KR-NS", which is primarily used for core Rice parameters.
  4. Otherwise, if the fully qualified class name begins with org.kuali.kfs, then the namespace is "KFS-SYS", which is primarily used for KFS Nervous System parameters
  5. Otherwise, it looks at the package names and tries to match to Rice's specified package names to namespace constants.
  6. Otherwise, it's an error.

Anchor
detailTypeResolution
detailTypeResolution

...

Component Resolution

The detail type component code for a class is resolved using the following rules, in the following orderfollowing 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.ricekfs.coreservice.knsframework.serviceparameter.ParameterConstants.COMPONENT annotation, then the detail type component is whatever's defined as the annotation parameter.
  2. Otherwise, if the class is assignable from the TransactionalDocument interface, then the detail type component is the simple name of the class with all instances of the "Document" string removed. For example, the InternalBillingDocument class would have a detail type component of "InternalBilling".
  3. Otherwise, if the class is assignable from the BusinessObject or the Step interfaces, then the detail type component is the simple class name.
  4. Otherwise, it's an error.

...

Runtime parameter specification

Static parameter specification

Code Block
typejava
public boolean validateObjectCode(Document doc, AccountingLine line) {
    ParameterEvaluator e = parameterServiceparameterEvaluatorService.getParameterEvaluator(doc.getClass(),
            "OBJECT_CODES", line.getFinancialObjectCode());
    return e.evaluationSucceeds();
}
Code Block
typejava
// 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;
}

Anchor
namingConventions
namingConventions

...

Financials Parameter Naming Conventions

The parameter names used within KFS 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 KRNSKRCR_PARMCMPNT_DTL_TYP_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 /detailed type 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.

...