Working With Data Fields

This chapter discusses the following:

Introduction to Data Fields

The access to data fields is an essential part of ConSol CM programming. It is potentially required in all scripts of the system, workflow as well as Admin Tool scripts, no matter of which type. Here, we will set the focus on workflow programming, but the access to data fields is basically the same in all scripts.

ConSol CM Version 6.9 and Higher

Starting with ConSol CM version 6.9.0, there are two types of data fields:

The work with Custom Fields of the new (version 6.9 and higher) customer data model (FlexCDM) is explained in detail in the ConSol CM Administrator Manual - Customer Data Model 6.9: FlexCDM and in the ConSol CM Administrator Manual (Version 6.9), section The CM Customer Data Model: FlexCDM.

Rules for work with data fields CM 6.9 and higher:

When you work with Custom Fields and Data Object Group Fields, there are three main rules you have to keep in mind:

  1. Custom Fields are always managed and referenced in Custom Field Groups, e.g. when you want to retrieve the value of a CF, you use <CF GroupName>.<CF FieldName>
  2. Data Object Group Fields are always managed and referenced in Data Object Groups, e.g. when you want to retrieve the value of a Data Object Group Field, you use <Data Object GroupName>:<Data Object Group FieldName>
  3. You always use the technical unique name to reference a Data Object Group Field or a Data Object Group, not the localized value.

ConSol CM Version 6.10 and Higher

In ConSol CM version 6.10, the module CM.Resource Pool was introduced. A detailed explanation of all objects in the new module is provided in the ConSol CM Administrator Manual, section CM.Resource Pool. Thus, in addition to the data fields already known from version 6.9, there is a new type of data fields: resource fields. In CM versions 6.10 and up, we work with the following data fields: 

Data Types for Data Fields

A data field is always of a certain data type. As for any variable in programming, it depends on the data type how you have to handle the value of the field, e.g. a string field cannot be used for calculating numbers, an enum field needs a specific access method.

The following data types are available for Custom Fields, Data Object Group Fields and Resource Fields.

The data type you choose on creating a data field cannot be changed afterwards!

Details about String Fields: Use Annotations to Fine-Tune Strings

String fields are widely used for customer, ticket, and resource data and strings can be used to contain various content, for example, a text box with a comment, a simple input field with only 20 characters, a URL or a password. The fine-tuning of string fields is implemented using specific annotations which are all listed on the Annotations page. However, since work with these annotations is an every-day task of CM administrators, the most important and most commonly used annotations will be explained here as well.

How can I ...

... insert a text box instead of a single line?

Value for annotation text-type: textarea

The size of the text box can be adjusted, displayed as standard text box depending on web browser. Use the field-size annotation in case a specific size of the text box is required.

... hide the input of the fields for passwords?

Value for annotation text-type: password

Only dots will be displayed. This annotation does not define the field to contain a password! It only defines the display mode! Use the password annotation to define a string field to contain the CM.Track password.

... display a hyperlink, display the name instead of the link?

Value for annotation text-type: url

Input will be displayed as a hyperlink in view mode. String has to match a specific URL pattern:

First part of the string is the link (url), second part is the name which should be displayed.

Example: "http://consol.de ConSol"

... display a file link?

Value for annotation text-type: file-url

Input will be displayed as a link to a file on the file system. The web browser has to allow/support those links!

Example: Enabling file:// URLs in a Firefox browser

Add the following lines to either the configuration file prefs.js or to user.js in the user profile. On a Windows system usually in a folder like C:\Users\<USERNAME>\AppData\Roaming\Mozilla\Firefox\Profiles\uvubg4fj.default

Alternatively a Firefox browser add-on like Local Filesystem Links can be installed for better access to the referenced files and folders.

The link will also be displayed as tooltip.

The URL is correctly formed if the following conditions are met:

Example URLs:

... define a label?

Value for annotation text-type: label

This will be a read-only field which is displayed in gray, use the label-group annotation to link label and input fields which belong together.

... define a field for the CM.Track login?

Value for annotation username: true

Will be used for authentication against CM.Track server. Only for Data Object Group Fields in a contact object.

... define a field for the CM.Track password?

Value for annotation password: true

Will be used for authentication against CM.Track server (in DATABASE mode). Only for Data Object Group Fields in a contact object.

... define a field for the valid e-mail addresses?

Value for annotation email: true

The field may only contain valid e-mail addresses. Input will be validated according to standard e-mail format <name>@<domain>.

Custom Fields for Ticket Data

In the Admin Tool, the Custom Fields for ticket data are defined in the Custom Field Administration: navigation group Tickets, navigation item Custom Fields.

Figure 120: ConSol CM Admin Tool: Custom Field administration for ticket data (CM version 6.10)

Most Important Methods for Access to Ticket Custom Fields

Three methods are of major importance for programming CF access in CM scripts. They all are methods of the class Ticket:

Another method might be used when a field should be emptied, i.e. when its value should be set to null:

Retrieve Custom Field Values for Ticket Data

To retrieve data from a Custom Field in a script, you have to reference it by using the technical names of the Custom Field Group and of the Custom Field.The method which has to be used can vary depending on the data type of the CF.

Simple Data Types

The following examples refer to the Custom Fields in the figure above.The method which should to be used (because it is the most convenient way) is:

ticket.get("<Group_name>.<CF_name>")

Please keep in mind that the getter method for a field might return either a value or an object, depending on the type of data field! Please see the following exampl efor an explanation

The following Admin Tool script, e.g. called from a workflow, will display ticket data:

// display info from custom types of various data types:

import com.consol.cmas.common.model.ticket.Ticket

 

Ticket ticket = workflowApi.ticket

println 'Display enum from helpdesk CF group ... '

 

def myfield = ticket.get("helpdesk_standard.priority")

println 'Class of helpdesk_standard.priority field is ' + myfield.getClass()

println 'Value of helpdesk_standard.priority field is ' + myfield.getName()

println 'Retrieve value directly, method 1, using getter method ... '

 

def my_new_field1 = ticket.get("helpdesk_standard.priority").getName()

println 'Result is ' + my_new_field1

println 'Retrieve value directly, method 2, using direct access to attribute ... '

 

def my_new_field2 = ticket.get("helpdesk_standard.priority").name

println 'Result is ' + my_new_field2

println 'Display value of simple data field ...'

 

def fb = ticket.get("helpdesk_standard.feedback")

println 'Value of feedback boolean field is ' + fb

Code example 24: Admin Tool script used to display Custom Fields

The following output will be displayed in the server.log file: 

Explanation:

If you want to retrieve the value of a Custom Field which contains an object (e.g., an EnumValue), you have to use methods like getName() to retrieve the actual value, becaue ticket.get ... only provides the object. The .name notation is a simplified (Groovy) version of the getter method.

If you want to retrieve the value of a simple data field, you can do this "directly": ticket.get ... will provide the value.

A precondition script of a workflow activity could look like the following code:

boolean vip_info = ticket.get("am_fields.vip")

 

if(vip_info == true){

return true

}

else {

return false

}

Code example 25: Precondition script where boolean value is checked

Or shorter:

return ticket.get("am_fields.vip")

Code example 26: Precondition script where boolean value is checked, short version

Enum Values

An enum (ordered list) field is a field where the value is one of various list values. For example, a list with priorities is the basis for an enum field. To retrieve the value of an enum field, you can use the same syntax as for simple data types. The get method provides the enum list value, the getName() method provides the string attribute with the name of the value.

def prio = ticket.get("helpdesk_standard.priority")

println "Priority is now " + prio.getName()

//or shorter:

println "Priority is now " + prio.name

Code example 27: Retrieving an enum value for a CF

MLAs

Work with one MLA value (the selected "leaf" of the MLA tree)

The Java class for MLAs (Multi Level Attributes) is MultiEnumField. It is handled like a regular enum field, i.e. to retrieve the current value of an MLA field, you can use the Java/Groovy code like the one shown in the example below.

Figure 121: Admin Tool: Definition of a Custom Filed of type MLA

Figure 122: Admin Tool: MLA definition

Figure 123: Web Client: Setting a value (technically: name) of the MLA

// Get

def myEnumValueName = ticket.get("GROUP_NAME.MLA_FIELD_NAME").name

// Set

EnumValue enumValue = enumService.getValueByName("ENUM_NAME","ENUM_VALUE_NAME")

ticket.set("GROUP_NAME.MLA_FIELD_NAME", enumValue)

Example with technical name of the field and localized name: 

import com.consol.cmas.common.model.customfield.enums.EnumValue

 

println 'Displaying MLA value ...'

def my_mla_field = ticket.get("helpdesk_standard.categories")

println 'MLA value categories (technical name) is now ' + my_mla_field.name

def my_mla_field_localized = localizationService.getLocalizedProperty(EnumValue.class, "name", my_mla_field.id, engineerService.getCurrentLocale())

println 'MLA value categories (localized name) is now ' + my_mla_field_localized

Code example 28: Code (Workflow or Admin Tool script) for displaying MLA data

Figure 124: Log output for the example above

Work with the entire branch of the selected MLA value

If you need to retrieve the entire path to the selected MLA value, you can proceed as follows: 

println 'Displaying MLA branch ...'

List<EnumValue> mlaPathElements = mlaService.getAssignedMla(ticket, "helpdesk_standard", "categories")

def mlaPath1=""

mlaPathElements.each() {elem ->

mlaPath1 = elem.name + ' -- ' + mlaPath1

}

println 'mlaPath1 is now ' + mlaPath1

 

//or shorter:

def mlaPath2 = mlaService.getAssignedMla(ticket, "helpdesk_standard", "categories").reverse()*.name.join(" -- ")

println 'mlaPath2 is now ' + mlaPath2

Code example 29: Retrieving the entire path to the selected MLA value

Figure 125: Log output for the example above

Lists

Lists of Simple Data Types

A list of simple data types consists of a list (= array) which has a value of a simple data type in each line, a date in our example. The CF of type date has to have the parameter Belongs to which points to the list.

Figure 126: ConSol CM Admin Tool - CFs for a list of date fields

Figure 127: ConSol CM Web Client - List of date fields in a ticket (edit mode)

For access to each date CF within a list use the following lines of code:

def convs = ticket.get("conversation_data.conversation_list").each() { conv ->

println "NEXT DATE is :" + conv

println "CLASS of NEXT DATE is " + conv.getClass()

}

Code example 30: Displaying the content of a list of date objects

Figure 128: Log output of the script above

To access a certain line, you can use the following syntax:

def mydate = ticket.get("conversation_data.conversation_list[1]")

Code example 31: Retrieve a certain value from a list of simple data types

Lists of Structs (Tables)

The data construct list of structs is the technical basis for a multi-column table structure in the Web Client. The list is the parent object which contains lines. Each line is an instance of a struct. Each line (struct) contains as many Custom Fields (table columns) as required. PLease see the figures in the introductory part of this section.

To retrieve the data from a list of structs you can work with an iteration over the lines (= structs). In the following example (from an order system, not displayed in the figure above) we work with a table where ...

Figure 129: ConSol CM Admin Tool - Custom Fields for list

Figure 130: ConSol CM Web Client - Ticket with filled-in table

def structs = ticket.get("order_data.orders_list").each() { str ->

println("CLASS of LINE is " + str.getClass())

println("FIELD VALUE HARDWARE is " + str.orders_hardware.getName())

println("CLASS of FIELD VALUE HARDWARE is " + str.orders_hardware.getName().getClass())

println("FIELD VALUE CONTACT is " + str.orders_contact)

println("CLASS of FIELD VALUE CONTACT is " + str.orders_contact.getClass())

println("FIELD VALUE NUMBER is " + str.orders_number)

println("CLASS of FIELD VALUE NUMBER is " + str.orders_number.getClass())

}

Code example 32: Retrieve data from a list of structs

Figure 131: Log File - Script Output

Setting Custom Field Values for Ticket Data

To set values for ticket CFs, you follow the same principle as for getting data: use the CF group name and the technical name of the CF as a reference. Of course, additionally, the new value is required. And of course it has to be of the correct data type.

ticket.set("<Group_name>.<CF_name>", <value>)

Setting Values for Custom Fields with Simple Data Types

ticket.set("fields.reaction_time", new Date());

Code example 33: Set a CF value for a Date CF

When you work with number or date fields, you can even calculate with the CF values in a very comfortable way, see following example.

//add 24 hours (in millis) to current field value

ticket.add("fields.deadline", 24*60*60*1000)

Code example 34: Calculate with value of date CF

Setting a value to null (i.e. emptying the field) is the same as removing the value:

ticket.set("fields.numberOfEmployees", null)

Code example 35: Setting a CF value to null

Or shorter:

ticket.remove("fields.numberOfEmployees" )

Code example 36: Setting a CF value to null via removing the value

Setting Enum Values

To set an enum value use the following syntax. Of course, the new value has to be present in the ordered list (enum) which is referenced by the CF.

ticket.set("Group_name.CF_name",<technical name of value>)

ticket.set("fields.priority", "URGENT");

Code example 37: Setting an enum value

Setting List Values

Setting Values in Lists of Simple Data Types

When you want to add a line, you can simply use the add method:

ticket.add("fields.tags", "my new String")

Code example 38: Adding a new line in a list of strings

When you want to refer to a certain value to set a new value for it, you have to use the syntax for an array:

ticket.set("fields.tags[last]", "consol cm6")

Code example 39: Setting a value in a list of strings

Setting Values in Lists of Structs

Working with structs, you always have to work with the key of the value you would like to add or set. When you want to add a new line, you have to build a new struct as new line. The set method can be used one after another for each new field.

ticket.add("order_data.orders_list", new Struct()

.set("tA_Id", id).set("orders_hardware",mynewhardware_model)

.set("orders_contact", thenewcontactname)

.set("orders_number",thenewnumber)

Code example 40: Adding a new line in a list of structs

Fading-in and -out of Custom Field Groups

A Custom Field Group (CF group) can be faded-in (made visible) and faded-out (made invisible) using a workflowApi method. This works for CF groups which are displayed in the main ticket data section as well as for CF groups which are displayed in the tabbed section.

A typical use case is a CF group which is invisible at first (CF group annotation group-visibility = false) and is faded-in when the engineer needs to work with the data in the process. For example, a CF group which contains reasons for the dismissal of a request is only displayed (faded-in) when the engineer has used the workflow activity Dismiss ticket .... This prevents an information overload of the ticket.

workflowApi.setGroupProperty("CF_Group_Dismissal",GroupPropertyType.VISIBLE,"true")

Code example 41: Fade-in a CF group

To fade-out some CF groups, e.g. when the ticket has been qualified and some of the CF groups will no longer be required in the process, use code according to the following example:

workflowApi.setGroupProperty("CF_Group_HardwareInfo",GroupPropertyType.VISIBLE,"false")

workflowApi.setGroupProperty("CF_Group_SoftwareInfo",GroupPropertyType.VISIBLE,"false")

Code example 42: Fade-out CF groups

Data Fields for Customer Data

Data Object Group Fields for Customer Data (CM Version 6.9 and Higher)

In CM version 6.9 and higher, the customer Data Object Groups are part of the new customer data model (FlexCDM). In version 6.9 they are defined in the Admin Tool, section User attributes, file card Customer data model. In version 6.10 they are defined in the Admin Tool, navigation group Customers, navigation item Data Models (also see Data Object Group Fields for Customer Data (CM Version 6.10 and Higher).

Figure 132: ConSol CM Admin Tool - Data Object Group Field administration for customer data (CM Version 6.9)

The fields, which were called Custom Fields in the customer data model of previous versions, are now called Data Object Group Fields. However, the principle you use to retrieve and set values for the data fields is principally the same as in CM version 6.8 and older.

Most Important Methods for Access to Customer Data Data Object Group Fields

Three methods are of major importance for programming access to Data Object Group Fields (DOGF) in CM scripts. They all are methods of the class Unit:

Another method might be used when a field should be emptied, i.e. when its value should be set to null:

Retrieving Values for Customer Data in CM Version 6.9 and Higher

Because the name of a Data Object Group Field might appear in more than one Data Object Group, the name of the Data Object Group has to be provided when accessing the customer data. For example, in the customer data model shown in the figure above, the Data Object Groups ResellerCompanyData and DirCustCompanyData could have a Data Object Group Field named city. Therefore, it is important to mention group name and field name.

Please use the following syntax:

unit.get("group1:name")

For example:

def mycity = company.get("ResellerCompanyData:city")

Code example 43: Retrieving a field value for a company

There are various objects and methods to work with data on different levels of the FlexCDM. Please see the following example where several common objects and methods have been applied. It is an Admin Tool script which is accessed from a workflow activity. The only purpose is to display some data of the ticket's main customer. The following figure shows the Java objects used in the script and the ConSol CM objects in the Admin Tool which are referenced.

Figure 133: ConSol CM customer objects in script and Admin Tool

Please keep in mind that you might also use the short notation like unit.definition.type for getter methods like unit.getDefinition().getType().

import com.consol.cmas.common.model.ticket.Ticket

import com.consol.cmas.common.model.customfield.meta.UnitDefinitionType

 

def ticket = workflowApi.getTicket()

 

def mcont = ticket.getMainContact()

println "CustomerGroup of main contact is now " + mcont.getCustomerGroup().getName()

println "Customer definition of main contact is now " + mcont.getCustomerDefinition().getName()

println "UnitDefinition of main contact is now " + mcont.getDefinition().getName()

 

def custmod = mcont.getCustomerDefinition().getName()

// println "CUSTMOD is now " + custmod

 

def cityfield

 

switch (custmod) {

case "BasicModel" : cityfield = "company:city";

break;

case "DirectCustomerModel" : cityfield = "DirCustCompanyData:dir_cust_company_city";

break;

case "ResellerModel": cityfield = "ResellerCompanyData:city";

break;

}

 

 

println "CITYFIELD is now " + cityfield

 

def utype1 = mcont.getDefinition().getType()

def utype2 = mcont.definition.type

 

println "UTYPE1 is now " + utype1

println "UTYPE2 is now " + utype2

 

def company = mcont

 

if (utype2 == UnitDefinitionType.CONTACT) {

company = mcont.get("company()")

}

 

def mycity = company.get(cityfield)

println " CITY is now " + mycity

Code example 44: Admin Tool script (called from workflow) for displaying customer data

For the following data set the log file output is shown below. The Reseller model of the figure above is used.

Figure 134: ConSol CM Web Client - Customer data set

Figure 135: Log file - Script output FlexCDM

String firstName = company.get("responsibleConsultants[0].firstName");

Code example 45: Retrieving a value from a list of structs using index notation

Setting Values for Customer Data in CM Version 6.9 and Higher

Setting Values for Data Object Group Fields with Simple Data Types

The set and add methods work as described for ticket Custom Fields. For example:

//set number field

company.set("numberOfEmployees", 1);

//add 1 to field value, afterwards the value of the field is 2

company.add("numberOfEmployees", 1);

Code example 46: Set and add values for a Data Object Group Field of type integer

Lists
Setting Values in a List of Structs for Customer Data

company.set("responsibleConsultants", [

new Struct().set("lastName", "Miller").set("email", "miller@consol.com"),

new Struct().set("lastName", "Smith").set("email", "smith@consol.com"),

new Struct().set("lastName", "Burger").set("email", "burger@consol.com")

]);

Code example 47: Creating a new list of structs, version 2

company.add("responsibleConsultants", new Struct().set("lastName", " Nowitzki ").set("email", "dnowitzki@consol.us"));

Code example 48: Adding a new line in a list of structs for company data

company.set("responsibleConsultants[0].firstName", "John");

Code example 49: Setting a value in a list of structs using index notation

company.set("responsibleConsultants[last]", null);

Code example 50: Removing a struct (= line) from a list of structs (= table)

Convenience Methods for Access to Customer Data in CM Version 6.9 and Higher

Unit mainContact = ticket.getMainContact();

 

// "company" extension returns company for contact

Unit company = mainContact.get("company()");

 

// it is also possible to set company using "company" extension

mainContact.set("company()", company);

 

// "contacts" extension returns list of contacts for company

List contacts = company.get("contacts()");

 

// "tickets" extension returns list of tickets for contact or company

List tickets = company.get("tickets()");

tickets = mainContact.get("tickets()");

 

// extensions can be chained

Integer count = contact.get("company().contacts()[0].tickets()[count]");

 

// parentheses can be omitted, but it is not recommended (possible collision with name of group or field)

count = contact.get("company.contacts[0].tickets[count]"); // here "company" is not extension but name of field

Code example 51: Convenience methods for access to customer data

Data Object Group Fields for Customer Data (CM Version 6.10 and Higher)

In CM version 6.10 and higher, as in version 6.9, the customer Data Object Groups are part of the customer data model (FlexCDM). They are defined in the Admin Tool, navigation group Customers, navigation item Data Models.

Figure 136: ConSol CM Admin Tool - Data Object Group Field administration for customer data (CM version 6.10)

Everything you have learned about Data Object Groups Fields in version 6.9 also applies to CM version 6.10. But some methods have become deprecated!

In CM version 6.9, it is still possible to use Unit methods which do not include the Data Object Group name as parameter, e.g.,

Unit.getField(String pFieldName)

This only works smoothly when a Data Object Group Field has the same name over all customer groups where the script is applied, or when the surrounding code ensures that it is not used in ambiguous runtime situations. In Version 6.10, the Unit methods without Data Object Group name have become deprecated, and they will no longer be supported in version 6.11 and up. The following table lists all those methods:

CM versions up to 6.9, deprecated in 6.10, not in 6.11 CM version 6.10 and up
getField(String pFieldName) getField(String pGroupName, String pFieldName)
getFieldValue(String pFieldName) getFieldValue(String pGroupName, String pFieldName)
setFieldValue(String pFieldName, Object pFieldValue) setFieldValue(String pGroupName, String pFieldName, Object pValue)
removeField(String pFieldName) removeField(String pGroupName, String pFieldName)

Resource Data

Starting with version 6.10.0, ConSol CM can contain the optional module CM.Resource Pool. This module allows it to extends the CM database and store resource objects. This can be various objects like IT assets, contracts, shop items or whatever is required in the respective company. Similar to the Customer Data Model, the Resource Data Model is defined using the Admin Tool. In the navigation group Resources, navigation item Data Models, the model is defined. In order to be able to work with resource data in workflow scripts, you should first get a profound knowledge of the Resource Pool principle and the set-up of the data model, so please read the section about the CM.Resource Pool in the ConSol CM Administrator Manual first.

Similar to ticket and customer data, resource data is stored in Resource Field Groups which contain Resource Fields.

Figure 137: Admin Tool: Definition of the resource data model

To retrieve data from Resource Fields, you can use methods as the ones shown in the following examples.

// Display info about HP Printer, priting infos about resource fields into server.log

 

def my_resource_name = resource.get("HP_Printer_Fields_basic.name")

println 'Displaying resource information ...'

println ' Name is : ' + my_resource_name

 

def my_resource_inv_number = resource.get("HP_Printer_Fields_basic.inventory_number")

println ' Inventory number is : ' + my_resource_inv_number

Code example 52: Simple resource action script which displays information about the resource in the log file

Figure 138: Web Client: Resource page of a HP printer resource

Figure 139: Log output of the script for the printer shown in the GUI example

In the real world, the circumstances usually are more complex. Often it is required to retrieve all resources of a certain type which are linked by a certain type of relation to a ticket or to a resource. This topic is treated in detail in the section Working With Resource Relations.

More coding examples, taken from the ConSol CM Action Framework, are provided in the ConSol CM Administrator Manual, section Scripts for the Action Framework.

Using Data Fields for (Invisible) Variables

Sometimes it is necessary to work with variables which are not used as values for Custom Fields, Data Object Group Fields or Resource Fields, which are not visible on the GUI, but which are only used as containers for internal programming variables.

Those of you who know how to program ConSol CM5 workflows know those containers as global variables. In ConSol CM6, you can achieve the same goal by creating regular Custom Fields (for ticket data), Data Object Group Fields (for customer data) or Resource Fields (for resource data) with the required data type and setting the field to invisible. This has to be done by using the annotation visibility = none. You can even let the variable be visible during the development of the process and control the field's value. Then you can set it to invisible when the system is handed-over to QA and users.