Report templates

The reports (and PDF variants generated from them) are based on MS Word templates that you can modify. Here we explain the essential configuration options that are available to you in the report engine.

What general adjustments to the manual template are possible?

The fixed formatting and layouts, as well as the logos and texts that you can see in the headers and footers, for example, can be changed using the Word on-board resources. Simply open your template, edit it, for example by changing the logo at the desired position, and save the change in the file.

Pay attention to possible section changes between portrait or landscape pages in the document, as it is possible that after such a section change, repeated changes are needed in the headers and footers.

Note

If you want to change the font of your report template be aware that in the process of generating a .pdf file only certain fonts are supported by the report engine. The usage of not supported fonts can lead to formatting losses and a change in the total number of pages in your .pdf file. Therefore note the possibility to embed the used fonts in your document. Here you will find a detailed list of the fonts, which are supported by the report engine.

How do I output properties of a document?

In the context of a template, you have a diagram available by using the method content.getSelection(). If you have queried the diagram, you can, for example, output the properties of a document.

For example, if you want to have the author of your template, proceed as follows:

<<[content.getSelection().getDocument().getBuiltInProperty("Author").getValue()]>>
  • content.getSelection() returns the graph. Then you can access and output certain information from the diagram.

  • content.getDocument() returns the document. Then you can access and output information about default and custom properties from the document.

  • getBuiltInProperty() gives you the possibility to access all default properties of the template file. The example above is about the property “Author” of the template.

The method getBuiltInProperty() returns an attribute. Then, there are other methods available to you:

  • getValue() returns the formatted value of the property in the current content language.

  • getRawValue() returns the value of the property in the current content language.

  • getName() returns the name of the property in the current content language.

  • getType() returns the type of the attribute in the current content language.

If you want to output custom property of your template, proceed as follows:

<<[content.getSelection().getDocument().getCustomProperty("Some name").getValue()]>>
  • content.getSelection() returns the graph. Then you can access and output certain information from the diagram.

  • getCustomProperty() gives you the possibility to access all custom properties for template file.

How do I output the diagram graphic in the template?

You have two possibilities to output a diagram as a graphic in reports. The method getImage() renders the diagram in a single graphic. Write this method into a text field to specify the size and position of the graphic. The tag image has to be set ahead of the method:

<<image [content.getSelection().getImage()]>>

The above code line should be inserted into a text field as follows:

The screenshot shows a text field containing tha command to output a diagram in the template.

Alternatively, you can use the method getImageWithPrintSettings() to output the diagram in multiple graphics. This method cuts the diagram in parts as defined in the print settings and outputs each part as a single graphic. It is recommended to use the getImageWithPrintSettings() method for larger diagrams to guarantee the readability in the report. You can include the method in your report template as follows. Note that the required tag is doc and the method must not be inserted into a text field.

<<doc [content.getSelection().getImageWithPrintSettings()]>>

How do I output attributes of a diagram?

In the context of a template, you have a diagram available, that you get with the method content.getSelection(). If you have queried the diagram, you can, for example, output the maintained attributes. For a list of the identifiers of these attributes, see the appendix.

For example, if you want to have the name of your selected diagram written on the title page, proceed as follows:

<<[content.getSelection().getAttribute("AT_NAME").getValue()]>>
  • content.getSelection() returns the graph. Then you can access and output certain information from the diagram.

  • getAttribute() gives you the possibility to access a concrete attribute. The example above is about the attribute Name of the diagram.

When you request an attribute with getAttribute(), there are other methods available to you:

  • getName() returns the name of the attribute in the current content language.

  • getValue() returns the value of the attribute in the current content language.

  • getRawValue() returns the value of the attribute in the raw form.

If you like to output the description of the diagram (AT_DESCRIPTION), you need to add the tag -html at the end. This ensures that the text of the description is formatted correctly.

<<[content.getSelection().getAttribute("AT_DESCRIPTION").getValue()]-html>>

Additionally, you can also output the title of an attachment by using the tag -html. Doing this, the title of the attachment will be put out instead of the full URL. This is also possible, if more than one file or URL is attached.

Proceed as follows to output the titles:

<<foreach [title in content.getSelection().getAttribute(“AT_ATTACHMENT”).getValuesAsList()]>><<[title]-html>><</foreach>>

Note

You can put the current name (getName()) of an attribute next to the value (getValue()). An advantage would be that even a changed attribute name remains up-to-date in the report. A disadvantage would be that the name can not be returned if the value was not maintained. Not maintained attributes are not made available to the report in their entirety. Alternatively, you can write the name of the desired attribute directly and thus statically into the template.

How can I specify the format of a date?

If you output the value of an attribute which is a date, you can specify the format. The attribute value has to be accessed via the getRawValue() method. Then you can add the format template by combining the special characters /, . or - and the abbreviations for the different time units. The following abbreviations can be used:

Character

Meaning (time unit)

YYYY or yyyy

year

yy oder YY

year in abbreviated format, e.g. “22” instead of “2022”

MM

month as a number

MMM

month as an abbreviation (first 3 English letters)

MMMM

month as string

dd

day in the month

EE

abbreviation of the week day (first 3 English letters)

EEEE

week day as string

In the following, some example formats are presented. Here, the governance attribute “Valid to” (“AT_VALID_TO”) is output and its value will be the 24th August 2022.

<<[content.getSelection().getAttribute("AT_VALID_TO").getRawValue()]:"yyyy.MM.dd">>

results in 2022.08.24,

<<[content.getSelection().getAttribute("AT_VALID_TO").getRawValue()]:"dd/MM/YYYY">>

results in 24/08/2022. If the month should be output as a text, you could use

<<[content.getSelection().getAttribute("AT_VALID_TO").getRawValue()]:"dd. MMMM yyyy">>

which gives 24. August 2022. The day of the week can be templated by

<<[content.getSelection().getAttribute("AT_VALID_TO").getRawValue()]:"EEEE, d MMM yyyy">>

to get Wednesday, 24 Aug 2022.

Dates that are output via the getValue() method are always written in the format 24. August 2022 UTC.

The format of system attribute values (e.g., lastModifiedDate) cannot be changed and displays the date and time by default. However, if you want to display the date without the time in your application, you can use the following command:

<<var [dateTime = content.getSelection().getLastModifiedDate()]>><<var [date = dateTime.substring(0, dateTime.lastIndexOf(“,”))]>><<[date]>>

This command extracts the date, for example, from the system attribute lastModifiedDate and formats it accordingly for the German date format.

Hint

Please note that this example is only suitable for the German date format.

How can I specify the format of the time?

If you output the value of an attribute which is a date, you can specify the format. The attribute value has to be accessed via the getRawValue() method. Then you can add the format template by combining the special character : and the abbreviations for the different time units. The following abbreviations can be used:

Character

Meaning (time unit)

h

hours (1-12)

HH or hh

hours (0-23)

mm

minutes

ss

seconds

SS

milliseconds

a

AM/PM marker

z

time zone

Z

ISO 8601 time zone (e.g., +0100)

In the following, some example formats are presented. Here, the governance attribute “Valid to” (“AT_VALID_TO”) is output and its value will be 4:34 PM.

<<[content.getSelection().getAttribute("AT_VALID_TO").getRawValue()]:”h:mm">>

results in 4:34,

<<[content.getSelection().getAttribute("AT_VALID_TO").getRawValue()]:”h:mm:ss:SS">>

results in 4:34:22:03, while the seconds and milliseconds are fictitious. The according AM/PM marker will be templated as

<<[content.getSelection().getAttribute("AT_VALID_TO").getRawValue()]:”h:mm a">>

which results in 4:34 PM. For the time zone, you can use

<<[content.getSelection().getAttribute("AT_VALID_TO").getRawValue()]:”h:mm a Z z">>

which results in 4:34 PM +0000 UTC.

Note

Please note that you cannot change the format of system attribute values (e.g., the lastModifiedDate).

How do I output objects of a diagram in a list?

There are two different operations on the diagram to access its the elements:

  • getEntities() returns the used objects of the diagram exactly once. If, for example, you have used the risk “completeness” multiple times, you only receive it once for output. Note that occurrence attributes on entities (“objects or catalog entries”) are not available.

  • getNodes() returns the occurrences in a diagram. These may be redundant or contain occurrence attributes. This means, the previous example risk “completeness” may be issued multiple times and the particular risk score (an occurrence attribute) may vary from use to use.

Of course, you can now decide which objects you want to view. This can be, for example, all objects of a certain type. In the following example, all risks of the diagram are considered and the maintained names are listed one below the other. This can be done using a foreach loop and inserting a line break before the closing foreach to have a line break after each object name.

<<foreach [in content.getSelection().getEntities("ET_RISK")]>><<[getAttribute("AT_NAME").getValue()]>>

<</foreach>>

If a diagram contains the risks A, B and C, the output generated from the above template code would be:

risk A
risk B
risk C

Alternatively, you can write a comma-separated list in one line.

  • indexOf() allows the listing under consideration of a separator symbol (here ,). In addition, the first (or zeroth) element is not preceded by a comma.

<<foreach [in content.getSelection().getEntities("ET_RISK")]>><<[indexOf() != 0 ? ", " : ""]>><<[getAttribute("AT_NAME").getValue()]>><</foreach>>

Here, the following output is generated:

risk A, risk B, risk C

If you want to make an enumeration, you have to choose the first enumeration point yourself in Word. Then the foreach loop follows. Write the closing <</foreach>> in the next line, but without bullets. Then no bullet will be output additionally when your list has reached the end.

• <<foreach [in content.getSelection().getEntities("ET_RISK")]>><<[getAttribute("AT_NAME").getValue()]>>

<</foreach>>

For example, the result would look like this:

  • risk A

  • risk B

  • risk C

Alternatively, the enumeration can be templated as a numbered MS Word list via:

1. <<foreach [in content.getSelection().getEntities("ET_RISK")]>><<[getAttribute("AT_NAME").getValue()]>>

<</foreach>>

Then, the result of the example diagram would look like this:

  1. risk A

  2. risk B

  3. risk C

Furthermore, you can determine the order of the returned objects of the getNodes()-operation by adding the parameter Sort.with(...). For example, an alphabetical sorting of all documents is generated by

content.getSelection().getNodes("ET_DOCUMENTS", Sort.with("byName")).

Analogically, the indication “byCoords” results in a sorting by the coordinates in the diagram and “byPath” in a sorting by their occurrence in the process flow.

How do I output connected nodes?

On a node in a set of getNodes() you can execute getRelatedNodes(). The nodes represent the occurrences of the objects in the diagram. These are typically connected to other nodes. The connections are usually a condition for output in separate lists or contexts.

  • getRelatedNodes() returns the associated values. As a condition, you can filter the object type and/or the link type that you want to output or evaluate.

In the first example, all activities are written to a variable named activity. This is necessary to buffer the values, since a loop runs over this set. As the loop passes, the name of each activity is output. In addition, the system checks for each activity whether associated symbols of the type role and the connection Responsible exist. The output of the text Responsible for Implementation: and the maintained name of the role follows.

<<foreach [activity in content.getSelection().getNodes("ET_ACTIVITY")]>>

<<[activity.getAttribute("AT_NAME").getValue()]>>

<<foreach [in activity.getRelatedNodes("ET_ROLE","AST_RESPONSIBLE")]>>Responsible for Implementation: <<[getAttribute("AT_NAME").getValue()]>>

<</foreach>><</foreach>>

The next example uses the method getRelatedNodes() twice. First, the same iteration as above is done for all activities of the diagram. Then, the associated risks are output. For the risks, a second variable risk is introduced. At last, the associated controls for each risk (resp. the name) are issued.

<<foreach [activity in content.getSelection().getNodes("ET_ACTIVITY")]>>

<<foreach [risk in activity.getRelatedNodes("ET_RISK")]>><<[risk.getAttribute("AT_NAME").getValue()]>>

<<foreach [in risk.getNodeAccess().getRelatedNodes("ET_CONTROL")]>><<[getAttribute("AT_NAME").getValue()]>>

<</foreach>><</foreach>><</foreach>>

How do I output all attributes of an element?

The method getAttributes() can be executed on objects, nodes and just on the diagram.

  • getAttributes() returns the set of available, maintained attributes. You could simply output or filter them further.

The following code contains a loop in a loop that outputs all the objects of the diagram with all their attributes:

<<foreach [entity in content.getSelection ().getEntities (".*")]>>

<<[entity.getAttribute("AT_NAME").getValue()]>>

<<foreach [attribute in entity.getAttributes()]>><<[attribute.getName()]>>

<<[attribute.getValue()] -html>>

<</foreach>><</foreach>>

Here a variable named entity is created, which contains all objects of the diagram. The name of each object is output. Then a new variable named attribute is created, in which all attributes of the object are written. The name and value of each attribute are then displayed below each other.

How do I output multivalued attributes of a diagram in a list?

The method getAttributes().getValue() returns the set of available, maintained attributes as a comma-separated list. The code

<<[content.getSelection().getAttribute(“AT_EXAMINER”).getValue()>>

generates the following output, for example:

Examiner 1, Examiner 2, Examiner 3

Using the .replace(", ", "\n") method, you can display the list with line breaks.

<<[content.getSelection().getAttribute(“AT_EXAMINER”).getValue().replace(“, “, “\n”)]>>

Here, the following output is generated, for example:

Examiner 1
Examiner 2
Examiner 3

Note

Use a bullet point “•” or a numbering “1.” before the code for enumeration.

How do I output my data in tables?

If you integrate tables into your template, the report engine will fill in objects and/ or attributes according to your definition. Simply use the Word tables and - for example - write the desired loop with methods that return the diagram attributes, contained objects or object attributes into the first row. The data will be formatted in the chosen table.

In the following example, one table row is created for each activity. The entire loop per activity covers the entire line. This is important because otherwise empty rows are not removed by the report engine if they are not needed. The rows are numbered and contain the risks, controls and KPIs.

Process step

Risk

KPI

  1. <<foreach [activity in content.getSelection().getNodes(“ET_ACTIVITY”)]>>

<<[activity.getAttribute(“AT_NAME”).getValue()]>>

• <<foreach [risk in activity.getRelatedNodes(“ET_RISK”)]>><<[risk.getAttribute(“AT_NAME”).getValue()]>>
• <<foreach [in risk.getNodeAccess().getRelatedNodes(“ET_CONTROL”)]>><<[getAttribute(“AT_NAME”).getValue()]>>
<</foreach>>
<</foreach>>
  • <<foreach [in activity.getRelatedNodes(“ET_KPI”)]>><<[getAttribute(“AT_NAME”).getValue()]>> <</foreach>><</foreach>>

You can combine the loops described above and execute them in a table. In the following example, a header line is inserted for each group. A row is created for each entry in the group:

<<foreach [group in content.getSelection().getEntities(“.*”).where(p => !”ET_ACTIVITY,ET_EVENT,ET_XOR,ET_OR,ET_AND”.contains(p.getStereotypeName())).groupBy(p => p.getStereotypeName())]>><<[first().getStereotypeName()]>>

<<foreach [in group]>><<[getAttribute(“AT_NAME”).getValue()]>><<if [getAttribute(“AT_ATTACHMENT”).getValue().toString().length()!=0]>> (<<[getAttribute(“AT_ATTACHMENT”).getValue()]-html>>)<</if>>

<<[getAttribute(“AT_DESCRIPTION”).getValue()]-html>><</foreach>><</foreach>>

Here, all the objects of the diagram are first written to a variable called group. They are filtered so that no activities, events or rules are included. Then they are grouped by the stereotype designation. After that, names and descriptions will be displayed. If there is an attachment, it is also output.

  • getStereotypeName() returns the name of the stereotype of the element.

  • contains() defines the contained elements as a condition.

  • first() selects the first object from the list.

Condition for table

In addition, you can set entire tables in conditions so that a header of the table may not be displayed without additional content. This can be done using the methode any().

  • In the following example, any() compares whether elements of the type role (ET_ROLE) or application (ET_APP_COMPONENT) exist. Otherwise (<<else>>) the text No more information. is output instead of an empty table.

You could structure such a table as follows:

<<if [content.getSelection().getEntities(".*").any(p => "ET_RISK,ET_APP_COMPONENT".contains(p.getStereotype()))]>>Here are the IT systems:

Process step

IT system

<<foreach [activity in content.getSelection().getNodes(”ET_ACTIVITY”)]>><<[activity.getAttribute(„AT_NAME“).getValue()]>>

• <<foreach [in activity.getRelatedNodes(“ET_APP_COMPONENT”)]>><<[getAttribute(“AT_NAME”).getValue()]>>
<</foreach>><</foreach>>
<<else>>No more information.<</if>>

Note

foreach loops only work within the same table or e.g. starting before and ending after a table. If the loop surrounds a table, a new table is created for each element in the foreach loop. However, if you start the loop outside a table and end it inside it, or vice versa, the loop does not work.

How do I output sorted lists with certain conditions?

You can configure the template in such a way that only objects satisfying certain conditions are read out. The following methods can be useful:

  • where() selects all objects, that fulfill the condition.

  • orderBy() sorts the nodes by the desired value. In this example, activities are sorted by their probability. To be able to sort these values, they must be converted into comparable numbers.

In the first example, the activities with an execution probability (attribute AT_PROBABILITY) higher than 75% are identified and displayed. At first, the activities are sorted by probabilities whereas the values are converted to the data type double. The double values can also be used for calculations, for example. Secondly, the condition for a probability greater than 75% is checked. Only corresponding activities are output in this loop.

<<foreach [in content.getSelection().getNodes("ET_ACTIVITY").orderBy(p => ((Double)(p.getAttribute("AT_PROBABILITY").getRawValue())).where(p => ((Double)p.getAttribute("AT_PROBABILITY").getRawValue()) > 75)]>><<[getAttribute("AT_NAME").getValue()]>><</foreach>>

Similarly, you can search for the longest processing times and output only these activities. In the next example, all activities are displayed that have a maintained processing time of more than 20 minutes.

<<foreach [in content.getSelection().getNodes("ET_ACTIVITY").orderBy(p => (Double)(p.getAttribute("AT_PROCESS_TIME").getRawValue())).where(p => ((Double)p.getAttribute("AT_PROCESS_TIME").getRawValue()) > 20)]>><<[getAttribute("AT_NAME").getValue()]>><</foreach>>

Note

Java code is generally possible in the report engine. Examples can be found here and in the report template of the system.

How can I change the output language in the template?

If you want to output another content language than the current one, the system needs a corresponding note. To do this, a value with the corresponding language abbreviation must be entered at getValue(). You can use the language abbreviations defined by the standard ISO-639-1.

The example returns the value of the diagram name which has been maintained in the content language English.

<<[content.getSelection().getAttribute("AT_NAME").getValue("en")]>>

The following list is an extract from the ISO standard.

Language code

Language

ar

Arabic

zh

Chinese

en

English

fr

French

de

German

it

Italian

es

Spanish

How do I use variables to store data?

The <<var [...]>>-tag is used to store data or objects in a variable. Any data type can be stored in variables. The name of the variables and the data type cannot be changed afterwards.

The following line declares the variable i. Initially, it holds the value “0”.

<<var [i = 0]>>

If you want to change the value of an existing variable, use the same tag as in the definition of the variable. In the next code block, the new value “1” is assigned to the variable i. Then, the variable is increased by 1.

<<var [i = 1]>>
<<var [i = i+1]>>

Variables may store objects like an activity analogically:

<<var [activities = content.getSelection().getEntities("ET_ACTIVITY")]>>
<<var [activities = activities.concat(content.getSelection.getEntities("ET_ACTIVITY"))]>>

A variable has the same functionality as the corresponding normal object.

How do I use diagrams to visualize data?

The report also supports visual representation via a diagram. Simply use the Word diagrams and - for example - write the desired methods that return the diagram attributes, contained objects or object attributes into the first row. The data will be formatted in the chosen diagram.

To do that, please note the following:

  • Diagram header needs to start with a <<foreach[...]>> tag like any other loop.

  • The <<foreach[...]>> tag can stay open.

  • Diagram header needs to contain a <<x[...]>> tag to specify the x-axis marking.

  • Diagram header needs to contain a <<y[...]>> tag to specify the y-axis marking.

The following example shows the template of a bar chart that compares the organizational units contained in a process diagram. In the title, the command content.getSelection().getNodes("ET_ORG_UNIT") gathers the categories of the bar chart (the organizational units) and they are sorted via orderBy(). For each category, the number of roles, positions and persons are visualized by different bars.

Here a sample diagram including its source code is displayed.

In a report of a BIC Process Design diagram containing the organizational units “Development”, “Human Resources”, “Management” and “Sales”, this leads to the following result:

The screenshot shows the visual representation of report data in the form of a diagram.

How do I use numbers in my template?

Using the method getValue(), you can display the value of an attribute as a text in the current content language. getRawValue() gets the value as a number, but they need to be casted into the right type. This is possible by adding the data type in parentheses before the method call. In the example, the attributes are read out as (Long) resp. (Double).

<<[(Long) content.getSelection().getNodes("ET_RISK").first().getAttribute("AT_RISK_CATEGORY").getRawValue()]>>
<<[(Double) content.getSelection().getNodes("ET_ACTIVITY").first().getAttribute("ET_PROCESS_TIME").getRawValue()]>>

Attributes can be casted in the following types:

Attribute type ID

Data type

AT_ACTUAL_VALUE

Long

AT_AT_CONFIDENTIALITY_REASON

String

AT_AT_CONFIDENTIALITY_REASON

String

AT_ATTACHMENT

String

AT_AVAILABILITY

Long

AT_AVAILABILITY_REASON

String

AT_CALL_ACTIVITY

Boolean

AT_CALL_CONVERSATION

Boolean

AT_CAPACITY

Long

AT_COLLECTION

Boolean

AT_COMPENSATION_TASK

Boolean

AT_CONFIDENTIALITY

Long

AT_CONTROL_EFFECT

Long

AT_DAMAGE_CONTROL_MEASURES

String (<<[...]-html>>)

AT_DATA_SOURCE

String

AT_DATA_STATE

String

AT_DATA_UNIT

String

AT_DATATYPE

Long

AT_DEFAULT_VALUE

String

AT_DESCRIPTION

String (<<[...]-html>>)

AT_DEVELOPMENT_COSTS

Double

AT_EMAIL

String

AT_END_EVENT_TYPE

Long

AT_EVENT_GATEWAY_TYPE

Long

AT_EVENT_TYPE

Long

AT_EXECUTION_INTERVAL

Long

AT_EXECUTION_TYPE

Long

AT_EXTERNAL

Boolean

AT_FOCUS_ON_TARGET

String (<<[...]-html>>)

AT_GATEWAY_INSTANTIATE

Boolean

AT_GROUP

Boolean

AT_HEADCOUNT

Long

AT_IDENTIFIER

String

AT_IDENTIFYING

Boolean

AT_IDLE_TIME

Double

AT_IMPACT_ON_OCCURRENCE

Long

AT_INPUT_OUTPUT

Long

AT_INSTANCES

String

AT_INTEGRITY

Long

AT_INTEGRITY_REASON

String

AT_INTERMEDIATE_EVENT_TYPE

Long

AT_IS_WEAK

Boolean

AT_ITEM_COLLECTION

Boolean

AT_KEYWORDS

String

AT_LIFE_CYCLE

Long

AT_MANUFACTURER

String

AT_MATERIAL_COSTS

Double

AT_MULTIPLE_INSTANCE_TYPE

Long

AT_MULTIPLE_INSTANCES

Boolean

AT_NAME

String

AT_NON_INTERRUPTING

Boolean

AT_OCCURRENCE_PROBABILITY

Long

AT_OPERATION_REFERENCE

String

AT_OPERATIONAL_TIME_END

Long

AT_OPERATIONAL_TIME_START

Long

AT_ORG_RES_CAPACITY

Double

AT_PERSONAL_DATA

Long

AT_PHONE

String

AT_PRIMARY_KEY

Boolean

AT_PRIORITY

Long

AT_PRIVACY_BY_DEFAULT

Boolean

AT_PRIVACY_BY_DESIGN

Boolean

AT_PROBABILITY

Double

AT_PROCESS_TIME

Double

AT_PROCESS_TYPE

Long

AT_PROCESSING_CRITICAL_DATA

Boolean

AT_PROCESSING_PURPOSE

String

AT_RELEASE

String

AT_RES_COST_RATE

Double

AT_RISK_CATEGORY

Long

AT_RISK_MITIGATION_MEASURES

String (<<[...]-html>>)

AT_RISK_PROBABILITY

Double

AT_RISK_PROBABILITY_CLASSIFICATION

Long

AT_ROOT_CAUSE

String (<<[...]-html>>)

AT_SETUP_TIME

Double

AT_STAFF_CAPACITY

Double

AT_START_EVENT_TYPE

Long

AT_STATE

Long

AT_STRUCTURE_REFERENCE

String

AT_TARGET_VALUE

Double

AT_TASK_TYPE

Long

AT_TEMPORAL_BINDING

Double

AT_TRANSFER_THIRD_COUNTRY

Boolean

AT_TRANSPORT_TIME

Double

AT_UNIT_COSTS

Double

AT_VALID_FROM

Long

AT_VALID_TO

Long

AT_VERSION

String

How can I access the case data when I create a report?

As part of a template, you have the option to output the maintained process variables of a case.

For example, if you want to display the name of the selected case, you can proceed as follows:

<<[case.getName()]>>
  • case.getName() returns the name of the case.

  • case.getCreationDate() returns the creation date of the case.

  • case.getDueDate() returns the due date of the case.

  • case.getCreator() returns information about the creator.

You receive the following information about the creator as follows:

  • case.getCreator().getType() returns who created the case (e.g. user, timer, etc.).

  • case.getCreator().getId() returns the ID of the creator.

  • case.getCreator().getName() returns the name of the creator.

  • case.getCreator().getEmail() returns the e-mail address of the creator.

Hint

If you use case.getCreator() without accessing a specific field, the name of the creator is used as a placeholder: case.getCreator() ~ case.getCreator().getName()

How can I access process variables in a form field for a case?

In the context of a template, you have the option to access process variables in a form field for a case by using the method case.getVariable().

If you want to output the ID and value of a variable, for example, you can proceed as follows:

<<[case.getVariable(“customer”).getName()]>>: <<[case.getVariable(“customer”).getValue()]>>
  • getName() returns the ID of the process variable.

  • getValue() returns the value of the process variable.

  • getRawValue() returns the value of the variable without any formatting.

In your template, you also have the option of accessing process variables of the type array.

To get a comma-separated list of the values in the array, you can use the following procedure:

<<[case.getVariable(“myArray”).getValue()]>>

To get a list that returns the entire collection of arrays, so that you can iterate over it directly, you can proceed as follows:

<<[case.getVariable(“myArray”).asList()]>>

Alternatively, you can also have the variables displayed one below the other. This can be done using a foreach loop and inserting a line break before the closing foreach to have a line break after each object name.

<<foreach [field in case.getVariables()]>><<[field.getName()]>>: <<[field.getValue()]>><</foreach>>

Hint

If you access a value of a non-existing variable, for example with case.getVariable("nonExistingVariable").getValue(), the template will still be created. In this case, the following message is displayed instead of the value of the non-existing variable: The variable “nonExistingVariable” is not available.

Warning

Only the case object is available. Attempts to use other undefined objects are not taken into consideration. Either nothing is displayed in the resulting template, or a corresponding error message appears.

How can I access the tasks within a case?

In the context of a template, you have the option to access the tasks within a case. The provided information includes both user tasks and automated tasks. Additionally, it contains both open tasks, which are pending and require editing, and completed tasks that have been successfully finished.

You can use the following code to output all information related to the tasks of a case:

<<foreach [task in case.getTasks()]>><<[task.getStatus()]>> <<[task.getName()]>><<[task.getDescription()]>> <<[task.getStartDate()]>> <<[task.getEndDate()]>> <<[task.getAssignee()]>><<[task.getDueDate()]>><</foreach>>

If a line break is used before the closing foreach, you can display the information one below the other. The tasks are displayed sorted by start date.

The following information is included:

  • task.getStatus() returns the status of the task.

  • task.getName() returns the name of the task in your configured default language.

  • task.getDescription() returns the description of the task in your configured default language.

  • task.getStartDate() returns the start date of the task.

  • task.getEndDate() returns the end date of the task.

  • task.getAssignee() returns the assignee for the task.

  • task.getDueDate() returns the due date of the task.

What other options do I have with the report engine?

Further options are listed below:

  • all(Predicate) outputs all objects that fulfill the condition.

<<foreach [in content.getSelection().getEntities("ET_ROLE").all(p => ((Boolean)p.getAttribute("AT_EXTERNAL").getRawValue())]>><<[getAttribute("AT_NAME").getValue()]>>
<</foreach>>

In this example, all external roles involved are output.

  • any() checks whether an objects exists in the list and can be used as a condition.

<<[content.getSelection().getEntities("ET_ROLE").any()]>>

This example checks if there are any involved persons.

  • any(Predicate) checks if an object exists in the list, that satisfies the condition.

<<[content.getSelection().getEntities("ET_ROLE").any(p => ((Boolean) p.getAttribute("AT_EXTERNAL").getRawValue()))]>>

The example checks whether an external person is involved.

  • average(Selector) calculates the mean value of the transferred property.

<<[content.getSelection().getNodes("ET_ACTIVITY").average(p => ((Double)p.getAttribute("AT_MATERIAL_COSTS").getRawValue()))]>>

In this example, the average of all costs of the process is calculated.

  • concat(Iterable) combines two lists by appending the second list to the first one.

<<[content.getSelection().getEntities("ET_ROLE").concat(content.getSelection().getEntities("ET_DOCUMENT")).count()]>>

In this example, the list of persons is linked to the list of documents.

  • union(Iterable) concatenates two lists into one by appending the second one at the end of the first one.

<<[content.getSelection().getEntities("ET_ROLE").union(content.getSelection().getEntities("ET_DOCUMENT")).count()]>>

In this example, a list of persons are connected with a list of documents.

  • count() counts the items of a list.

<<[content.getSelection().getEntities("ET_ROLE").count()]>>

In this example, the persons involved are counted.

  • count(Predicate) counts the objects in a list that fulfill the condition.

<<[content.getSelection().getEntities("ET_ROLE").count(p => ((Boolean)p.getAttribute("AT_EXTERNAL").getRawValue()))]>>

In this example, all external employees are counted.

  • first() selects the first object from the list.

<<[content.getSelection().getEntities("ET_ROLE").first().getAttribute("AT_NAME").getValue()]>>

In this example, the name of the first employee involved is displayed.

  • first(Predicate) selects the first object that satisfies the condition from the list.

<<[content.getSelection().getEntities("ET_ROLE")first(p => ((Boolean)p.getAttribute("AT_EXTERNAL").getRawValue())).getAttribute("AT_NAME").getValue()]>>

In this example, the name of the first external employee is displayed.

  • groupBy(Selector) sorts the objects into groups according to their properties.

<<foreach [type in content.getSelection().getEntities(".*").groupBy(p => p.getStereotype())]>><<[first().getStereotype()]>>

<<foreach [in type]>><<[getAttribute("AT_NAME").getValue()]>>

<</foreach>><</foreach>>

In this example, an enumeration is created in which all entities are listed sorted by stereotype.

  • last() outputs the last object.

<<[content.getSelection().getEntities("ET_ROLE").last().getAttribute("AT_NAME").getValue()]>>

In this example, the name of the last employee is displayed.

  • last(Predicate) returns the last object with the property.

<<[content.getSelection().getEntities("ET_ROLE").last(p => ((Boolean)p.getAttribute("AT_EXTERNAL").getRawValue())).getAttribute("AT_NAME").getValue()]>>

In this example, the name of the last external employee is displayed.

  • max(ComparableSelector) returns maximum value.

<<[content.getSelection().getNodes("ET_ACTIVITY").max(p => (Double)p.getAttribute("AT_PROCESS_TIME").getRawValue())]>>

In this example, the longest process time is output.

  • min(ComparableSelector) returns the minimum value.

<<[content.getSelection().getNodes("ET_ACTIVITY").min(p => (Double)p.getAttribute("AT_PROCESS_TIME").getRawValue())]>>

In this example, the shortest process time is output.

  • orderBy(ComparableSelector) sorts the objects in the list according to the parameter.

<<foreach [in content.getSelection().getEntities("ET_ROLE").orderBy(p => ((String) p.getAttribute("AT_NAME").getValue()))]>><<[getAttribute("AT_NAME").getValue()]>><</foreach>>

In this example, all employees are returned sorted by name.

  • skip(int) skips n items in the list.

<<foreach[in content.getSelection().getNodes("ET_ACTIVITY").orderBy(p => ((Double)p.getAttribute("AT_PROCESS_TIME").getRawValue())).skip(5)]>>

<<[getAttribute("AT_NAME").getValue()]>><</foreach>>

In this example, all activities except the first five are displayed.

<<[content.getSelection().getNodes("ET_ACTIVITY").orderBy(p => p.getAttribute("AT_MATERIAL_COSTS").getValue().toString()).skip(2).first().getAttribute("AT_NAME").getValue()]>>

In this example, the third most expensive activity in the process is output.

  • skipWhile(Predicate) skips objects until the condition is no longer fulfilled.

<<foreach[in content.getSelection().getNodes("ET_ACTIVITY").orderBy(p => p.getAttribute("AT_PROCESS_TIME").getValue().toString()).skipWhile(p => ((Double)p.getAttribute("AT_PROCESS_TIME").getRawValue()) < 5)]>>

<<[getAttribute("AT_NAME").getValue()]>><</foreach>>

In this example, all activities are displayed that take at least 5 minutes to process.

  • sum(Selector) sums the attributes of the objects in the list.

<<[content.getSelection().getNodes("ET_ACTIVITY").sum(p => ((Double)p.getAttribute("AT_PROCESS_TIME").getRawValue()))]>>

In this example, the total processing time is output.

  • take(int) selects the first n objects from the list.

<<foreach [in content.getSelection().getNodes("ET_ACTIVITY").orderBy(p => ((Double)(p.getAttribute("AT_PROCESS_TIME").getRawValue())).take(5)]>><<[getAttribute("AT_NAME").getValue()]>><</foreach>>

In this example, the five activities with the shortest processing time are output.

  • takeWhile(Predicate) selects objects until the condition is no longer fulfilled.

<<foreach [in content.getSelection().getNodes("ET_ACTIVITY").orderBy(p => ((Double)(p.getAttribute("AT_PROCESS_TIME").getRawValue())).takeWhile(p => ((Double)p.getAttribute("AT_PROCESS_TIME").getRawValue()) < 5)]>><<[getAttribute("AT_NAME").getValue()]>><</foreach>>

In this example, all activities that have a processing time of less than 5 minutes are displayed.

  • where(Predicate) selects all objects that satisfy the condition.

<<foreach [in content.getSelection().getNodes("ET_ACTIVITY").orderBy(p => ((Double)(p.getAttribute("AT_PROCESS_TIME").getRawValue())).where(p => ((Double)p.getAttribute("AT_PROCESS_TIME").getRawValue()) < 5)]>><<[getAttribute("AT_NAME").getValue()]>><</foreach>>

In this example, all activities are displayed that have a processing time of less than 5 minutes.

  • AT_PROCESS_TIME, AT_SETUP_TIME and AT_TRANSPORT_TIME are needed to calculate the cycle time.

<<foreach [activity in content.getSelection().getEntities(”ET_ACTIVITY”)]>>

<<var[process = activity.getAttribute(“AT_PROCESS_TIME”).getRawValue().getClass().getSimpleName().equals(“Double”)? (double) activity.getAttribute(“AT_PROCESS_TIME”).getRawValue():0]>>

<<var[setup = activity.getAttribute(“AT_SETUP_TIME”).getRawValue().getClass().getSimpleName().equals(“Double”)? (double) activity.getAttribute(“AT_SETUP_TIME”).getRawValue():0]>>

<<var[transport = activity.getAttribute(“AT_TRANSPORT_TIME”).getRawValue().getClass().getSimpleName().equals(“Double”)? (double) activity.getAttribute(“AT_TRANSPORT_TIME”).getRawValue():0]>>

<<var[cycle =(double)process+(double)setup+(double)transport]>>

<<[activity.getAttribute(“AT_NAME”).getValue()]>>

<<[cycle]>>

<</foreach>>

In this example, the cycle time of an activity for each activity in a process is calculated.

  • <<if […]>><</if>> checks if a condition is true.

<<if [content.getSelection().getEntities("ET_ROLE").any(p => ((Boolean)p.getAttribute("AT_EXTERNAL").getRawValue()))]>>Process with external involvement.<<else>>No external involvement.<</if>>

In this example, the system checks whether external roles occur. In this case, a corresponding message is output. Otherwise (<<else>>) the system displays that “No external involvement” was found.

  • equals(...) checks if a boolean attribute was set.

<<foreach [activity in content.getSelection().getEntities(”ET_ACTIVITY”)]>>

<<[activity.getAttribute(“AT_NAME”).getValue()]>>

<<if [activity.getAttribute(“AT_COMPENSATION_TASK”).getRawValue().equals(true)]>>YES<<else>>NO<</if>>

<</foreach>>

This example checks whether a boolean value has been set or not. Hence, a text (YES/NO) is displayed.

  • <<foreach [in …]>><</foreach>> applies the method to all objects in the data collection.

<<foreach [in content.getSelection().getEntities("ET_ROLE")]>><<[getAttribute("AT_NAME").getValue()]>>

<</foreach>>

In this example, the names of all roles in the diagram are listed.

Hint

Please note that the use of the <<doc>> tag and access to content from other files within report templates is not supported.

Cast necessity

Since the attributes of the objects from BIC Process Design are exported as an object and previously all data types are formatted as strings, which are then formatted in objects, it is necessary for predicates to parse the attributes back into strings. To do this, a (<data type>) must be used. This reformats the objects back to the desired data type, making the comparison possible again.