FI Finnish
SE Swedish
FR French
PL Polish
DE German
US English (US)

Contact Us

If you still have questions or prefer to get help directly from an agent, please submit a request.
We’ll get back to you as soon as possible.

Please fill out the contact form below and we will reply as soon as possible.

English (US)
FI Finnish
SE Swedish
FR French
PL Polish
DE German
US English (US)
  • Log in
  • Home
  • Platform
  • ESM
  • Other Technical ESM Documentation
  • Handler Documentation

Handler - Expression

Contact Us

If you still have questions or prefer to get help directly from an agent, please submit a request.
We’ll get back to you as soon as possible.

Please fill out the contact form below and we will reply as soon as possible.

  • Service Management
    Matrix42 Professional Solution Matrix42 Core Solution Enterprise Service Management Matrix42 Intelligence
  • Identity Governance and Administration (IGA)
    IGA overview IGA solution library
  • Platform
    ESM ESS2 ESS Efecte Chat for Service Management Integrations Add-ons
  • Release Notes for M42 Professional, IGA, Conversational AI
    2026.1 2025.3 2025.2 2025.1 2024.2 2024.1 2023.4 2023.3 2023.2 2023.1 2022.4 2022.3 Release Information and Policies
  • Other Material
    Terms & Documentation Guidelines Accessibility Statements
  • Services
+ More
    • Service Management

    • Identity Governance and Administration (IGA)

    • Platform

    • Release Notes for M42 Professional, IGA, Conversational AI

    • Other Material

    • Services

Handler - Expression

Expression handler uses a Python expression in generating a value for the parent attribute. The handler evaluates the expression and returns the result automatically in the parent attribute's data field after the data card is saved. Note that HTML tags within the result are not escaped.

Custom modules can be saved to the directory defined as platform setting python.path. See an example below.

ExpressionHandler doesn't work on required attributes.

ExpressionHandler works on multivalue attributes. On multivalue attributes existing values are replaced by values created by ExpressionHandler. Note that if ExpressionHandler produces multiple values on a single value attribute saving of data card fails.

Default label for Expression handler's button is value of presentation text text_calculate. Label value can be overwritten in template's localization editor.

 

For information about Python, please visit https://www.python.org . In the following address https://wiki.python.org/moin/BeginnersGuide/ you can find Beginner's Guide to Python.

You can use the Expression handler, for example, to perform calculations on another attribute values denoted by their individual attribute codes in the parent attribute's metadata.

Expression handler can be used on reference attribute. If expression returns a PythonEntity that is used to set reference value. If expression returns String that is used to search target data card.

For example, to calculate an average from the attribute Q1, Q2, Q3, and Q4, attach the Expression handler to an attribute Average and denote the following Python expression in the Average 's metadata: ([attributeCodeQ1]+[attributeCodeQ2]+[attributeCodeQ3]+[attributeCodeQ4])/4 . Expression handler calculates the average of the denoted attribute values and indicates it as the value of the Average attribute as illustrated in following picture.

A value Average generated with Expression handler:

The following tables provide information on the attribute settings and metadata requirements for Expression handler. Compulsory metadata is provided in a Required attribute metadata table.

Configuration of Expression handler varies from other handlers. Needed metadata names are given, admin must give the values only.

Table 1. Attribute Settings

Handler name Datatype
Expression Any datatype, except embedded reference or back reference.

Table 2. Required Attribute Metadata

Name Value Description
expression [Python expression]

A valid Python expression (or script if isScript is enabled) for computing a value.

If the expression cannot be parsed, a referenced attribute value is empty or an error occurs, the result will be empty.

isScript [Checked | unchecked]

When this option is checked, expression is interpreted as a Python script.

Scripts are more powerful than expressions and can contain multiple lines, loops and other control structures. Also they are more complex to configure. Check examples of scripts below. If you want to interpret the expression as a script, check this box.

The result value must be set into a variable called _result . If you want to keep the attribute output empty, do not set anything to variable _result.

More example configurations available below.

Table 3. Optional Attribute Metadata

Name Value Description
debug true/false

By default, "null" results will not be shown. If this metadata is set to true, null values will be shown. With non-string/text attributes this also fails sorting of a data card.

Note: Do NOT use this in production environment. This may fail all data card stores such as multi edit, move, trashing and emptying trashcan if expression happens to be broken.

showButton true/false By default, count button is shown. If this metadata is set to false, the count button will not be shown. Button calculates values (stored in a _result) only for a current attribute.
alwaysExecute true/false If this is true, the expression will be executed (as root) always when the data card is saved. Default is false: expression will be executed (as current user) only if the user who saves the card has privileges for this attribute.
searchAttribute attributeCode

Attribute code of target template(s). Reference search is restricted to this attribute. This setting can be used when ExpressionHandler is used on reference attribute.

Note: This attribute has to be unique in target template(s).

Note: If createEmptyReferences is true, this attribute has to be primary attribute in target template(s).

createEmptyReferences true/false If this is true and reference target data card is not found, it will be created and saved into folder configured in referenceTargetFolder metadata. This setting can be used when ExpressionHandler is used on reference attribute and referenceTargetFolder has value.
referenceTargetFolder folderCode Code of folder were reference target data cards will be created. This setting can be used when ExpressionHandler is used on reference attribute and createEmptyReferences is true.
isHtmlOutput true/false

By default, the result of an expression is a regarded as string. If this metadata is set to true, it tells the ExpressionHandler to regard the outcome of the expression as HTML (NOT ESCAPED). If value is false, the outcome is regarded as plain string. The default is false.

Note: This setting is meaningful for string and text attributes only.

Note: This setting is not available in E6 series product family

executeEarly true/false

By default, the expression is run at the same time as other handlers after default values are set and conditional attributes ("Enable if" functionality) are applied but before delayed preSave handlers have run. If this metadata is set to true, the expression will be run before default values are set and conditional attributes ("Enable if" functionality) are applied. The default value is false.

Note: This metadata is not intended to be used with executeLate. Configurations where both are enabled are not supported.


This metadata allows the use case of enabling attributes with an expression based on imported data while also allowing to import of data to the enabled attributes during the same save operation. Current implementation supports importing data manually, using REST API, csv import task and WebAPI. More specifically, admins can create a configuration in which Self-service (ESS) imports data over WebAPI to attributes that are enabled by an expression and the conditional attributes functionality ("Enable if" functionality) based on the imported data or other conditions.

When the metadata is set to true, the following is made possible:

  1. Self-Service (ESS) creates a new data card or updates an existing data card over WebAPI and imports value(s) to "Enable if" child attribute(s).
  2. If "Execute early" is enabled, the expression is run. The expression sets a specific value in a parent attribute. The value set to the parent attribute must be the actual value that enables the child attribute(s).
  3. The conditional attributes functionality ("Enable if" functionality) is applied. Therefore, the child attributes are enabled, and the values imported to them remain.

Note: The metadata is designed for the use case described above; therefore, other use cases are not supported.

executeLate true/false

By default, the expression is run at the same time as other handlers after default values are set and conditional attributes ("Enable if" functionality) are applied but before delayed preSave handlers have run. If this metadata is set to true, the expression will be run after all other handlers, including delayed ones, have run and their values are applied. The default value is false.

Note: This metadata is not intended to be used with executeEarly. Configurations where both are enabled are not supported.


This metadata allows the use case of using the output of delayed preSave handlers (SLADeadline and AttributeCombiner) inside expressions. More specifically, admins can use, for example AttributeCombiner values in expressions, even when importing data cards from external sources (ESS, WebAPI, ...)

When the metadata is set to true, the following is made possible:

  1. Self-Service (ESS) creates a new data card or updates an existing data card over WebAPI and imports value(s) to attributes that are part of some AttributeCombiner value.
  2. If "Execute late" is enabled, the expression is run after the AttributeCombiner. The expression uses the value of AttributeCombiner in some operation. The value is present and up-to-date.
  3. The expression logic is done and the process moves on to other executeLate handlers or data card saving process.

Note: The metadata is designed for the use case described above; therefore, other use cases are not supported.

Expression handler also allows access to referenced data cards. The current card can be referred with this, and other data cards by their the class attribute code configured in the parent card. Currently supported methods for referred data cards are:

Table 4. Data Card Access Methods

Name Returns Example
get(attributecode) Single value found in the field with the given attribute code. If the attribute is multivalued, first value is returned. If attribute is a reference, a PythonEntity object is returned. this.get("$support_person:email$")
getAll(attributecode) Array containing values found in the field with the given attribute code. If attribute is a reference, an array of PythonEntity object is returned. max(getAll("product_prices"))
getTemplateName() Single String value containing the name of the template for the data card. this.getTemplateName()
getTemplateCode() Single String value containing the code of the template for the data card. this.getTemplateCode()
getFolderCode() Single String value containing the code of the folder to where the data card is saved. If imported data card xml contains value for this attribute, it will be recalculated to be correct. this.getFolderCode()
getFolderName() Single String value containing the name of the folder to where the data card is saved. If imported data card xml contains value for this attribute, it will be recalculated to be correct. this.getFolderName()
getFolderModuleCode() Single String value containing the module's code where this data card is stored. Possible values are: equipment - CMDB; contract - Contract; job - Service Desk; solution - Solution; change - Change Management; procurement - Procurement; client - Organization; admin - Users; system - internal system data cards only. Available modules are enabled by licensing. Some products may be obsolete and not available anymore. this.getFolderModuleCode()
getEntityId() Single String value containing the id of the data card. Return value of this method can be used to verify if the data card was saved or not. If the return value is equal to 'none' then data card was not saved yet. this.getEntityId()
getReferrers(templateCode) Array containing PythonEntities that are associated with a template specified by templateCode. If the parameter is left blank, then the method is returning an array containing PythonEntities that are associated with all templates. this.getReferrers('incident') this.getReferrers()
isHidden() Single true/false value. Return value of this method can be used to verify if the data card is hidden or not. this.isHidden()

Table 5. Data Card Manipulation Methods

Name Functionality Example
set(attributecode, value)

Changes the value of an attribute. Note: Do not change values of referred data cards or use reference paths.

Note: Do not change values of referred data cards or use reference paths.
If values for referred data cards are set, at least following features won't work:

  • Listeners/handlers are not executed.
  • History is not updated.
  • There may be other issues too.
this.set("priority", 1)
add(attributecode, value)

Adds a value to an attribute.

Note: Do not change values of referred data cards or use reference paths. Please check details from set-method.

this.add("keywords", "email")

Script Examples

Lets assume: 1) "car" is a multivalue reference of _this_ template 2) "limit" an integer attribute of _car_ template 3) Get a limit from single car reference:

car.get("car_limit")

Calculate total sum of cars' limits. This requires the isScript option:

_result=0
for i in car:
 _result+=i.get("car_limit")

Decide field value based on two others. Requires isScript option:

_result='No'
if client_status=='Accepted' and dealer_status=='Yes':
 _result='Yes'

Visibility of a data card (either this or data card found with data card access methods) can be checked with method isHidden. Note that if you check the visibility of the data card where the attribute belongs to, the attribute with the DatacardHiddenState handler has to be before the Expression attribute for method to work!

if this.isHidden():
 _result = 'This data card is hidden'
        
car = this.get("car")
if car.isHidden():
 _result = 'Car is hidden'
else:
 _result = 'Car is visible'

With equals function you can find out, e.g., if two references refer to the same data card.

ref1 = this.get("ref1")
ref2 = this.get("ref2")
if ref1 != None and ref2 != None:
if ref1.equals(ref2):
 _result = 'Ref1 and ref2 refer to the same data card'
else:
 _result = 'Ref1 and ref2 refer to different data cards'       

Attributes with No Values

The script below demonstrates the way of checking that a certain attribute has a value. If there is no attribute with code myDate1 or myDate2, or if this data card doesn't have a value for both of those attributes, the result will be 0. If both attributes exist and they have a value, 1 is returned.

date1 = this.get("myDate1")
date2 = this.get("myDate2")

if date1 is None or date2 is None:
 _result = 0
else:
 _result = 1      

To use a shorter form of checking if an attribute has a value, use this (here, attr_code is the attribute's code):

if attr_code:
 _result = '...'

To check if an attribute does not have a value, use this (here, attr_code is the attribute's code):

if not attr_code:
 _result = '...'

Handling Strings with Special Characters

To avoid producing illegal characters, instead of special characters, it is recommended to always use u prefix before unicode strings For example:

 _result = u'Text with some special characters like: ä, ö, ź, ć, ę, ð etc.'          

It is also essential to use u prefix when comparing strings. Following comparison will always return false value:

string_attribute_value == 'ää'  

The comparison above should be done like this:

 string_attribute_value == u'ää'    

Generating Random Numbers

Let's assume the code of the attribute is "random_figure" and we want to count the figure once. The script here will give you a number between 1 and 100. isScript option is needed to import modules.

import random
if random_figure is None:
 _result = random.randint(1, 100)
else:
 _result = random_figure        

Calculating with Dates

A special DateUtil class can be used to calculate with dates. DateUtil.daysBetween(date1, date2) calculates how many days there are between date1 and date2. Similar methods for all date ranges:

DateUtil.yearsBetween(date1, date2)
DateUtil.monthsBetween(date1, date2)
DateUtil.daysBetween(date1, date2)
DateUtil.hoursBetween(date1, date2)
DateUtil.minutesBetween(date1, date2)
DateUtil.secondsBetween(date1, date2)

DateUtil.addDays(date, number) adds given amount of days to the given date and returns the new date. If given number is negative, days will be subtracted from the given date. Similar methods exist for other date ranges too:

DateUtil.addYears(date, number)
DateUtil.addMonths(date, number)
DateUtil.addDays(date, number)
DateUtil.addHours(date, number)
DateUtil.addMinutes(date, number)
DateUtil.addSeconds(date, number)

DateUtil.currentDate() returns the current date and current time. This can be used with other methods, as for example in the expression below:

_result = DateUtil.addHours(DateUtil.currentDate(), this.get("priority_high")     

In this case the expression adds the amount of hours in field "priority_high" to current date.

References and Reference Paths

There are two ways to get values from references. Suggested way is to use reference paths. With this $code1:code2$ notation you don't need to check if the value for code1 really exist. If you're manipulating Company-value, you must add a None check for it. Naturally, all codes must be written correctly. You can use this.getAll("$person:company$") to get multiple values.

this.get("$person:company$")        

Following example is an old and obsolete way that is not suggested anymore. By getting each path item separately you need to add None-checks for each item (this.get("person") != None).

this.get("person").get("company")         

Changing Values of Other Attributes

Setting a single value

this.set("priority", 1)
this.set("description", (description or "") + "\n(For more information, contact service desk)")        

Setting multiple values

this.set("keywords", ["email", "communication"])

Adding values

this.add("keywords", "email")
---
this.add("keywords", ["email", "communication"])
---
if this.get("rollback_count") == None:
this.set("rollback_count", 0)
else:
 this.set("rollback_count", (this.get("rollback_count")+1))      

Copying values from reference paths

this.set("prices", this.getAll("$items:price$"))
this.set("total_price", sum(this.getAll("$items:price$") or []))

Emptying values

this.set("keywords", None)
this.set("keywords", [])
# Calling add with the same parameters doesn't do anything.

Attributes with CommentHandler

CommentHandler saves comments as data cards. For expressions comments are returned as PythonComments. PythonComment has methods for getting comment message, author and date. Author of a comment is reference to person data card. Author is returned as PythonEntity. Date is returned as date time values for any other entity data. Comments cannot be edited in expressions. Existing comments cannot be set as target values of any reference attribute (i.e. they cannot be moved). CommentUtil can be used to create a new comment. Comment message must be given when creating a comment. New comments can be added to a CommentHandler attribute (set method is not supported). Date is set to timestamp of comment creation. Author is set to be person data card of current user. If current user does not have a person data card, creation of comment fails.

Permissions to comments are given based permissions of CommentHandler attribute. Normally users don't have permissions to comment data cards themselves. Users might not have permissions to authors either. For these reasons it might be necessary to set alwaysExecute metadata in some cases to expressions handling comments.

 

Table 6. PythonComment Access Methods

Method Returns
getAuthor() PythonEntity
getComment() Comment message as String value.
getDate() Timestamp of comment creation as Date.
getType() The comment's type as String value. The value is 'file-attached' for comments that are created automatically when users attach files. Other possible types are 'user-written' and 'pythonapi-generated'.
setComment Sets comment's message. Can be used to change message of an existing comment. Message can be emptied but not set to null.

Table 7. CommentUtil Methods

Method Returns Example
createComment(message) Returns PythonComment that contains comment message given as parameter. Author will be current user's person data card and date the creation timestamp CommentUtil.createComment(message)
createComment(message, date, author, type)

Creates a PythonComment using the provided parameters.

 

The date parameter can be a string in the format YYYY-MM-DD or set to None to use the current timestamp. The expected format  for date is: 

%Y-%m-%dT%H:%M:%S

 

The author parameter should match the value in the attribute defined by platform settings 'ngss.person.uid.attribute.code' (primary) or 'servlet.auth.person.uid.attribute.code' (fallback) attached to the person, or None, in which case the current user will be used. 

 

The type parameter accepts either 'user-written' or 'pythonapi-generated' and defaults to 'user-written' if unspecified. Empty parameters can be passed using None. For example: CommentUtil.createComment("Sample message", None, None, "user-written").

CommentUtil.createComment(message)
deleteComment(comment) Deletes underlying comment entity represented by PythonComment given as parameter. Deletion makes PythonComment instance unusable (don't call its getters/setters, set it as value of a CommentHandler attribute or try to delete it again). CommentUtil.deleteComment(comment)


Table 8. Comment Related PythonEntity Methods

Method Returns Example
getAllCommentsOrdered(attribute_code) Returns comments as PythonComments ordered from latest to oldest from a comment handler attribute this.getAllCommentsOrdered("ngss_comments")
getLatestComment(attribute_code) Returns latest comment as PythonComment from a comment handler attribute this.getLatestComment("ngss_comments")

Below are some examples of comments used in expressions. 

Sets all non-null authors to another multivalue reference field.

_result = []
comments = this.getAll("ngss_comments")
for comment in comments:
    if comment.getAuthor() != None:
        _result.append(comment.getAuthor())

Creates a new comment and attaches it a CommentHandler attribute:

this.add("ngss_comments", CommentUtil.createComment("Added by expression"))

Creates a new comment with a specific date, author and type and attaches it a CommentHandler attribute:

this.add("ngss_comments", CommentUtil.createComment("Added by expression", "2020-01-01", "admin", "pythonapi-generated"))     

Deletes a comment based on value in comment message:

comments = this.getAll("ngss_comments")
for comment in comments:
   if comment.getComment() != None and 'secret' in comment.getComment():
      CommentUtil.deleteComment(comment)

Empties comment messages based on value in them:

comments = this.getAll("ngss_comments")
for comment in comments:
   if comment.getComment() != None and 'secret' in comment.getComment():
      comment.setComment('')  

Fetches all comments from this entity ordered by creation time in descending order:

comments = this.getAllCommentsOrdered("ngss_comments")
for comment in comments:
   if comment.getComment() != None:
      comment.getComment()  

Fetches the latest comment:

comment = this.getLatestComment("ngss_comments")
   if comment != None and comment.getComment() != None:
      comment.getComment()

Using Custom Modules

Defining a module: Create file stringutils.py with the following contents into the directory indicated by platform setting python.path:

def reverse(value):
   if value is None:
       return None
   else:
       return str(value)[::-1]

Importing and using a module. isScript option is needed to import modules.

 import stringutils
 _result = stringutils.reverse(attribute_to_be_reversed)

Importing and using functions form a module. Multiple functions can be imported by separating the function names by commas.

 from stringutils import reverse
 _result = reverse(attribute_to_be_reversed)

While developing modules, use reload(module) to apply changes in the module file. Reloading a module will decrease performance so remove the line when the module is ready to be used in production environment.

 import stringutils
 reload(stringutils) #remove this line when module is ready

Python Version

Python version can be controlled with platform setting python.version. Check current version with this.

 import sys
 _result = sys.version
expression handler

Was this article helpful?

Yes
No
Give feedback about this article

Table of Contents

Related Articles

  • Attribute Metadata - ReferenceSearchFilter
  • Attribute Metadata - ShowCode
  • Attribute Metadata - Related Data Card Search

Copyright 2026 – Matrix42 Professional.

Matrix42 homepage


Knowledge Base Software powered by Helpjuice

0
0
Expand