Workflow scripting

Scripts are used to perform automatic actions and fine-tune the behavior of the workflow. There are two basic types of scripts:

In addition, some elements and adornments have scripts with special purposes, as for example the decision script which determines the exit which a case takes when running through a decision node.

There are two ways of managing scripts:

The following table shows a comparison between both modes:

Mode

Description

Advantages

Disadvantages

Embedded script

The complete script content is provided in the workflow editor.

  • The whole process logic is stored in one place and can be checked in the workflow editor.

  • You can use workflowApi methods with all implicitly available objects.

  • You can benefit from strict versioning, as a workflow version contains all the related changes.

  • If the same logic is needed in several workflow elements, you need to duplicate the related code.

  • You need to activate the development mode for changes to become effective immediately.

Workflow script

The script is saved as a script of the type Workflow on the Scripts page. The embedded script references this workflow script.

  • The same script can be used in different places of the workflow.

  • Changes to the script become effective immediately, regardless of the selected deployment mode.

  • You need to check a second script to know the workflow logic.

  • Objects which are implicitly available in embedded scripts need to be passed as parameters to the script.

  • You need to do a scene export with both workflows and scripts to put a new workflow version into production.

Scripts are written in Groovy. Since Groovy code runs in the Java Virtual Machine, you can also write Java code. Groovy code allows you to use dynamic typing, and to omit getter and setter methods, thus providing a shorter syntax. The following table shows some examples of the differences between Groovy and Java:

Goal

Groovy

Java

Retrieve the subject of a case

def mysubject = ticket.subject

String mysubject = ticket.getSubject();

Retrieve the main contact of a case

def mymaincontact = ticket.mainContact

Unit mymaincontact = ticket.getMainContact();

Retrieve the value of a certain case field from a case

def myprio = ticket.get("helpdesk_fields.prio")

String myprio = ticket.get("helpdesk_fields", "prio");

Set the subject of a case

ticket.subject = "asd"

ticket.setSubject("asd");

ConSol CM API methods

The ConSol CM API provides various convenience interfaces and methods which make access to the most commonly used objects easy. Most of these convenience interfaces are part of the package com.consol.cmas.common.service and its sub-packages.

The implementing instance of the interface is always available by replacing the first letter, which is a capital letter, in the class name by a lower case one, e.g., use engineerService to call methods of the interface EngineerService. The only exception to this rule is the class WorkflowContextService whose object workflowApi provides many useful methods.

Please refer to the ConSol CM API documentation for details about the available classes and methods.

Features of the script editor

The script editor has the following features:

You can see where a script is used by clicking the Usage button. The popup window lists the places where the script is referenced and provides links to jump to the referencing objects.

Scripting examples

The following sections contain short descriptions of the most important aspects of scripting. Larger topics are covered in sub-pages:

Referencing workflow elements

Workflow elements are always referenced by their path. The path reflects the hierarchical structure of the workflow. It starts with defaultScope and contains the technical names of the scopes where the element is located and the technical name of the element.

Example: Activity information_received in the sub-scope on_hold of the scope work_in_progress:

defaultScope/work_in_progress/on_hold/information_received

You can copy the path using the Copy button in the details panel of the respective element.

Working with data fields

Data fields are always referenced by their technical names using the following pattern:

<ticket|unit|resource>.<get|set|add|remove>("<technical name of the field group>.<technical name of the field>")

The content of a data field depends on the data type, it can be either a value or an object.

Please see Using data fields in scripts for details about the available methods for different objects and field types.

Using data fields for variables

Sometimes you need variables which are required for workflow programming but should not be visible on the GUI of the Web Client and CM/Track. Depending on the object for which they are needed, you can use case, contact or resource fields for these variables.

  1. Create a data field with the required data type.

  2. Set Visibility to Never to hide the field from the GUI.

Working with user data

When working with user data, you need to distinguish between the current user, i.e., the user who is logged in and performs the action which leads to the execution of the script, and the assignee of a case.

Displaying messages

Messages are useful to provide dynamic information to the user regarding the process or the entered data. They can be displayed in a red box below the menu bar or next to a case field in an activity form. If the message should be localized, it is recommended to use labels, see Labels.

Working with overlays

Overlays stay on the case icon according to the selected overlay range. You can remove an overlay by script using the following piece of code:

def si = ticket.scopeInfo

for (ov in si.getActivatedOverlays().toArray() ) {

if (ov.parent.name == "defaultScope/ServiceDeskTicketInProgressScope/Email_received") {

si.removeOverlay(ov)

}

}

The overlay is identified by the path of the activity where it was attached.

Working with system properties

You can use methods of the class ConfigurationService to retrieve the value of system properties.

configurationService.getValue("module name","property name")

Working with text classes

You can retrieve and set text classes for case history entries.

Working with attachments

You can add and retrieve attachments with the following methods:

Modifying the visibility of data field groups

You can control the display of data field groups with the setting Visible. A common use case is to hide field groups initially by setting false, implement activity forms where the data is filled in, and show the field groups on the GUI afterwards. This helps to keep the case data concise by displaying certain fields only when they are needed in the process.

The following methods can be used for controlling the visibility of case field groups:

Searching for objects

You can search for cases, contacts and resources using criteria objects.

The criteria object is configured by using the provided methods to add one or several criteria. If you use a data field as a search criterion, the respective data field must be indexed.

The search methods return the complete objects, so they can consume a lot of memory if you perform a search. If you only need the number of objects matching certain criteria, you can use the methods getCountByCriteria() of the same classes instead.

Considering case update events

Certain methods cause so called update events (class TicketUpdateEvent). These events can decrease the system performance. Therefore, they should be avoided as long as they are not necessary for the business process.

Example: Assigning a user to a case

In addition, update events occur after a workflow element is executed. If there is a chain of elements, you should avoid triggering an update event after every single element. Select the Skip update event checkbox for all elements except for the last one to update the case only once, after the last workflow element.

Adding log output

You can add log output to your scripts by using the following syntax:

log.info "This is my debug message."

You can log messages at other log levels by using log.debug, log.warn, or log.error. The log messages are written to the server.log file.

See Log files for details about the available log files and their configuration.

Modifying the execution flow

You can treat a trigger execution with automatic activities as an exception instead of an interrupt by using the method skipInterruptRestore() of the class ScopeInfo. This method can be used only in automatic activities connected to triggers. If you add it to the script of such an activity, the case does not return to the original activity where it was located before the trigger fired, but stays in the flow of the activity where this method is called.

This allows for example to implement workflows where the case is moved to a waiting scope by a trigger and remains there until another trigger fires.