Workflow Components: Activities

Introduction to Activities

An activity represents an action in a workflow. An activity is located within a scope and is of one of the following types:

Using manual and automatic activities, you can model a rather strict business process where the engineer has to follow one of the provided pathes for the ticket. Using scope activities you can model more flexible processes and prepare the CM system for case management where an engineer can react in a rather dynamic way, depending on the required circumstances.

A manual activity has to be performed by a manual action of the engineer using the Web Client GUI. The activity is displayed as Workflow activity in the Web Client, provided at least one of the roles of the engineer has the Execute permission (please refer to the ConSol CM Administrator Manual, section Role Administration, for a detailed explanation). In the Process Designer, the activity is marked by the red hand/manual icon.

Figure 40: ConSol CM Process Designer - Manual activity in workflow

Figure 41: ConSol CM Web Client - Manual activity

An automatic activity is performed automatically by the system and is not displayed in the Web Client. In the Process Designer, an automatic activity is not marked by any special icon.

Figure 42: ConSol CM Process Designer - Automatic activities

A scope activity is located within a scope and does not have any incoming connections from other activities. In the Web Client, a scope activity is available as long as the ticket is placed within the scope. This holds true for all subordinate scopes. A scope activity might have subsequent activities (then is causes a process exception) but it can also be an activity without any connections (then it causes an interrupt). See section Interrupts and Exceptions to learn more about interrupts and exceptions.

Please note that a ticket does not necessarily leave a scope when the "last" activity within the scope has been performed. See section Activities about this topic.

Figure 43: ConSol CM Process Designer - a scope activity (available in the scopes "Work in Progress" and "Ticket on hold")

Properties of an Activity

In order to display and edit the properties of an activity, mark the activity in the Process Designer.

The Properties Editor is opened for the element which has been selected in the main editing panel and contains component-specific parameters. Some general parameters are present for all components, some are present only for a certain type of component.

Figure 44: ConSol CM Process Designer - Selected activity in workflow

Figure 45: ConSol CM Process Designer - Properties editor

Properties:

Process Logic of Activities

This is the process logic of activities:

  1. When a ticket has passed through an activity it always waits behind this activity (and not before the next one!).
  2. When a ticket has passed through an activity, it checks if one of the potential subsequent activities is an automatic activity. If yes, the ticket passes through this automatic activity as well. This is why there can only be one automatic activity in a process step.
  3. The ticket passes automatically through (automatic) activities as long as there are new automatic activities. It comes to a halt as soon as there is/are one or more manual activities where engineer interaction is required.
  4. If one or more of the following manual activities have a precondition script, this script is executed in order to decide if the activity has to be displayed in the Web Client GUI or not.
  5. If the engineer selects the activity in the Web Client GUI, the script of the activity is executed.
  6. If there is a postActivityScript, this script is executed immediately after the execution of the activity script.
  7. The ticket waits behind the manual activity. If the following activity is located in a new scope, the ticket will not enter the new scope. It always waits behind the old activity and not before the new one!

In case the activity has an ACF, the Business Logic of ACFs also has to be considered.

Remark on Scope Activities

A scope activity does not have any incoming connections, but it can have

When a scope activity has been executed, the subsequent position of the ticket depends on the workflow topology: 

A ticket always waits behind the last activity which has been executed and not before the new one!
This is relevant, for example, when a view is defined: it is important to know that the ticket might not have entered the next scope, because it is still waiting behind the previous activity in the current scope.

If the ticket temporarily leaves its scope due to the execution of a scope activity, triggers are restored when the ticket reenters the scope afterwards.

Examples of Activities

Example 1: Precondition for Displaying Activity "Inform team lead"

In case the ticket has been opened by a VIP contact, i.e. a contact where the boolean field vip is true, the team lead should be informed. If it is no VIP, the activity should not be offered. The customer field vip which is part of the customer data model is checked for this purpose.

Figure 54: ConSol CM Process Designer - Workflow activities (one with precondition script)

import com.consol.cmas.core.server.service.*

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

def ticket = workflowApi.ticket

// fetch main contatc of the ticket

def maincontact = ticket.getMainContact()

def unit_type = maincontact.definition.type

log.info 'vipCheck: Unittype is ' + unit_type

log.info 'vipCheck: Unittype class is ' + unit_type.getClass()

if(unit_type == UnitDefinitionType.COMPANY) {

log.info 'No vipCheck for comapnies possible! Returning false ... '

return false

} else if (unit_type == UnitDefinitionType.CONTACT){

 

// fetch e-mail address of the man contact. The data object group field has to be addressed using data object group name:data object group field name

def vip_field

def custgroup = maincontact.customerGroup.name

println 'vipCheck: Customergroup is now ' + custgroup

switch(custgroup) {

case "Reseller": vip_field = "vip_person";

break;

case "DirectCustomers": vip_field = "vip_dircust"

break;

case "MyCustomerGroup": vip_field = "vip"

break;

case "OurPartnerCompanies": vip_field = "vip_partners"

break;

case "RetailCustomers": vip_field = "retail_vip"

break;

}

def vip_value = maincontact.get(vip_field)

log.info 'VIP is now ' + vip_value

 

if (vip_value){

return true

} else {

return false

}

}

Code example 2: Precondition script: activity should only be displayed for VIP customers

Figure 55: ConSol CM Admin Tool - Customer field "vip" (CM version 6.9)

Figure 56: ConSol CM Web Client - Precondition: Return value TRUE

Figure 57: ConSol CM Web Client - Precondition: Return value FALSE

Example 2: Send an Email to the Main Contact When a Ticket Has Been Opened

When a ticket has been opened, an email should be sent automatically to the main contact of the ticket.

Figure 58: ConSol CM Process Designer - Automatic activity where receipt note is sent

Script in workflow activity Send notice of receipt

log.info'Calling SendReceiptNotice script ...'

scriptExecutionService.execute("SendReceiptNotice.groovy")

Script SendReceiptNotice.groovy in Admin Tool:

import com.consol.cmas.common.model.mail.Mail

import com.consol.cmas.common.util.MailHeadersUtil;

import com.consol.cmas.core.server.service.*;

import static com.consol.cmas.common.util.TemplateUtil.TICKET_SUBJECT_TEMPLATE_NAME;

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

// create new mail object

def mail = new Mail()

def ticket = workflowApi.getTicket()

 

// fetch main contatc of the ticket

def maincontact = ticket.getMainContact()

def unit_type = maincontact.definition.type

log.info 'Mailscript: Unittype is ' + unit_type

log.info 'Mailscript: Unittype class is ' + unit_type.getClass()

 

if(unit_type == UnitDefinitionType.COMPANY) {

println 'No email address for company; no receipt notice sent.'

return

} else if (unit_type == UnitDefinitionType.CONTACT){

 

// fetch e-mail address of the man contact. The data object group field has to be addressed using data object group name:data object group field name

def toaddress_field

def custgroup = maincontact.customerGroup.name

 

switch(custgroup) {

case "Reseller": toaddress_field = "email";

break;

case "DirectCustomers": toaddress_field = "dir_cust_email"

break;

case "MyCustomerGroup": toaddress_field = "email"

break;

case "OurPartnerCompanies": toaddress_field = "email"

break;

case "RetailCustomers": toaddress_field = "retail_customer_email"

break;

}

def toaddress = maincontact.get(toaddress_field)

if (!toaddress){

log.info 'No email address found for contact, no receipt notice sent.'

} else {

// put the e-mail TO address into the Mail object

mail.setTo(toaddress)

 

// fetch the REPLY TO address, theis is stored in a system property

def replyaddress = configurationService.getValue("cmweb-server-adapter","mail.reply.to")

// put the e-mail REPLY TO address into the Mail object

mail.setReplyTo(replyaddress)

 

// build e-mail text using a template which is stored in the Template Designer

def text = workflowApi.renderTemplate("Acknowledgement_of_receipt")

// put the e-mail text into the Mail object

mail.setText(text)

 

// create the subject of the e-mail, the ticket number with the correct Regular Expression

// has to be set for correct recognition of incoming e-mails for the ticket

// ****** alternative solutions for PD manual! *****

// solution 1:

// def ticketname = ticket.getName()

// def subject = "Your case has been registered as Ticket (" + ticketname + ")"

// solution 2: (needs import of TemplateUtil.TICKET_SUBJECT_TEMPLATE_NAME

def subject = templateService.merge(TICKET_SUBJECT_TEMPLATE_NAME, [ticketName:ticket.name])

// put the subject into the Mail object

mail.setSubject(subject)

// Mail should use the e-mail script which is configured for the queue

mail.useDefaultScript()

// send out the e-mail and register status

def attList = new ArrayList<AttachmentEntry>()

def collection = new HashSet<MailEntry>()

def mailStatus = true;

 

try {

mail.send();

} catch (Exception e){

mailStatus = false;

}

 

} // end if (!toaddress){

} // end of else if (unit_type.equals('COMPANY')){

Code example 3: Scripts for automatic activity where receipt note is sent, variant 1

// lines of code alost identical to variant 1 except for the sending of the mail:

 

new Mail().setSubject( subj ).setTo( contact_e ).setReplyTo( replyto ).setText( text ).setTicketAttachments( null ).send()

Code example 4: Script for automatic activity where receipt note is sent, variant 2

Example 3: Assign the Ticket to the Current Engineer

The ticket should be assigned to the engineer who executes the activity New IT ticket.

Figure 59: ConSol CM Process Designer - Workflow activity where engineer should be assigned

Figure 60: ConSol CM Web Client - Ticket passed through activity where engineer was assigned

// Get the engineer who is executing the activity:

// Java Style is possible: def curr_eng = workflowApi.getCurrentEngineer()

// we use Groovy style here:

def curr_eng = workflowApi.currentEngineer

// alternative would be:

// def curr_eng = engineerService.current

 

// Assign the ticket to the current engineer

// Java style is possible: 

ticket.setEngineer(curr_eng)

// groovy alternative would be: 

// ticket.engineer = curr_eng

Code example 5: Script for assigning ticket to current engineer

Make sure that you always use the correct engineer object!

The current engineer is the engineer who is logged in, who is executing the current activity. You can get the object by using one of the following methods.

Using workflowApi: 

// Java notation

def curr_eng = workflowApi.getCurrentEngineer()

// Groovy notation

def curr_eng = workflowApi.currentEngineer

Using engineerService :

// Java notation:

def curr_eng = engineerService.getCurrent()

//Groovy notation

def curr_eng = engineerService.current

The ticket engineer is the person who is (at this point of time) the ticket owner and responsible for the ticket. You can get the object by using the following method:

//Java notation

def tic_eng = ticket.getEngineer()

//Groovy notation

def tic_eng = ticket.engineer

Example 4: Using a Scope Activity

The scope activity Forward problem to supervizor should be present for the entire life cycle of the ticket. For really problematic tickets, the engineer can use a "shortcut": the ticket does not have to be moved through the entire process but can be directly sent to a special management queue where a supervisor takes care of it.

Figure 61: A scope activity which will be available throughout the entire life cycle of the ticket, because the activity is placed in the global scope