Working with Ticket-Ticket Relations

Introduction

Relations between tickets can help to model your business processes in a very efficient way.

ConSol CM offers three types of relations:

Figure 144: ConSol CM relation types

In this section, we will not explain how to set-up ticket relations using the Web Client, this is explained in detail in the ConSol CM User Manual. In the current section, we will show you how to establish relations using the programming interface, namely workflow scripts.

In the ConSol CM Workflow API, the reference type is represented by the class (enum) com.consol.cmas.common.model.ticket.TicketRelationType. This offers three values:

Simple Ticket Relation without a Hierarchy

This relation type can be helpful when you want to create references which help to find the tickets related to one ticket easier than using the search function.

Example use cases are:

This relation type can be built and manipulated using either the Web Client or the programming interface. Thus, a relation of type REFERENCE can be built within a workflow script and can then be manipulated by an engineer using the Web Client, provided he/she has the required access rights.

Example: Creating a Simple Relation between Two Tickets

workflowApi.addRelation(TicketRelationType.REFERENCE, "This is a very important relation", pSourceTicketId, pTargetTicketId)

Code example 65: Creating a ticket relation of type REFERENCE using workflowAPI

Syntax: Find all Referenced Tickets

ConSol CM versions 6.10.4.0 and up

List<Ticket> mytickets = workflowApi.getReferencedTickets()

Master-Slave Relations

This relation type can be helpful when you want to create a hierarchy between a certain number of existing tickets. Remember that this relation type can be established using either the Web Client or using the programming interface. However, here, only the programming approach will be explained.

Example use cases are:

A Master-Slave relation can be built and manipulated using either the Web Client or the programming interface. Thus, a relation of type MASTER_SLAVE can be built within a workflow script and can then be manipulated by an engineer using the Web Client, provided the engineer has the required access rights. Use the Parent-Child construct when you want to make sure that no engineer can manipulate the ticket hierarchy.

Example: Creating a Master-Slave Relation between Two Tickets

//in this script the project ticket (= current ticket) is set as slave ticket to

// the program ticket which becomes the master

 

// fetch the program ticket ID. The ID of the program ticket is already stored

// in a CF in the project (=current) ticket

def progTicketId = ticket.get("ReferencesFields.ProgramTicketId")

 

// fetch ID of current ticket (which will become the slave)

def mySlaveProjectId = ticket.id

 

workflowApi.addRelation(TicketRelationType.MASTER_SLAVE, "Slave Ticket: This project is part of the program indicated in the master ticket", progTicketId, mySlaveProjectId)

Code example 66: Creating a ticket relation of type MASTER_SLAVE using workflowAPI

Syntax: Finding All Slave Tickets

ConSol CM versions 6.10.3.x and below

// the ticket can be set, might be current ticket or another ticket

List<Ticket> mytickets = workflowApi.getTargetTickets(myTicket.getId(), TicketRelationType.MASTER_SLAVE)

Code example 67: Version A: Finding all target tickets (here: all slave tickets)

// used for current ticket

List<Ticket> mytickets = workflowApi.getTargetTickets(TicketRelationType.MASTER_SLAVE)

Code example 68: Version B: Finding all target tickets (here: all slave tickets)

ConSol CM versions 6.10.4.0 and up

List<Ticket> mytickets = workflowApi.getSlaveTickets()

Code example 69: Finding all slave tickets of the current ticket

Syntax: Finding the Master Ticket

ConSol CM versions 6.10.4.0 and up

def mticket = workflowApi.getMasterTicket()

Code example 70: Finding the master ticket of the current ticket

Parent-Child Relations

This relation type can be helpful when you want to create a hierarchy between a certain number of tickets which should not be manipulated manually.

Example use cases are:

The relation type PARENT_CHILD can only be built and manipulated using the programming interface. Thus, a relation of this type can be built within a workflow script and can then only be manipulated by other scripts.

Example 1: Creating a New Child Ticket as Child of Current Ticket

// this script creates a ticket for a task which will be child ticket

// of a project ticket (which will be the parent)

 

// create a new ticket, which will become the task (=child) ticket

Ticket newTask = new Ticket()

 

// fetch the subject of the parent-to-be ticket, i.e. of the current ticket

def subj = ticket.subject

// or longer: def subj = ticket.getSubject()

 

// set the subject of the new task (= child) ticket

newTask.setSubject("New Task for project " + subj)

 

// put the task (= child) ticket into the tasks queue

def tasksQueue = queueService.getByName("Tasks")

newTask.setQueue(tasksQueue)

 

// Initially, the new task ticket will not have an engineer

newTask.setEngineer(null)

 

// define the ticket text, i.e. the first comment in the new task ticket

def taskTicketText = "Please work on this task asap"

 

// the contact for the new task ticket should be the same as the one for the project ticket:

def taskContact = workflowApi.getPrimaryContact()

 

//create PARENT_CHILD relation between project (parent) and task (child)

workflowApi.createChildTicket(newTask, taskTicketText, taskContact)

Code example 71: Creating a child ticket

Example 2: Finding the Parent Ticket of a Ticket

def my_parent = workflowAPI.getParentTicket()

Code example 72: Finding the parent ticket of a ticket

Example 3: Finding All Child Tickets of a Ticket

// only works for current ticket:

List<Ticket> my_childtickets = workflowApi.getChildTickets()

Code example 73: Finding all child tickets of a ticket

Example 4: Finding All Brother Tickets (Other Child Tickets) of the Same Parent Ticket

// only works for current ticket:

List<Ticket> my_brothers = workflowApi.getBrotherTickets()

Code example 74: Finding all brother tickets of a (child) ticket

Important Methods for the Work with Ticket Relations

Note the following rules for the work with ticket relations:

WorkflowApi Methods

The following methods are methods of the class WorkflowContextService which is implicitly available as workflowApi object in workflow scripts.

Method of workflowApi (workflowContextService)

Explanation

Ticket createChildTicket(Ticket pTicket, String pTicketText, Unit pCustomer)

Creates a new child ticket. Queue and ticket fields have to be set correctly.

List<Ticket> getChildTickets()

IntSet containing the ticket objects of the child tickets of the current ticket.

List<Ticket> getBrotherTickets()

IntSet containing the ticket objects of the brother tickets of the current ticket.

Ticket getParentTicket()

Ticket object of the parent ticket or null if the current ticket does not have a parent ticket.

List<Ticket> getTargetTickets(TicketRelationType pType)

Get list of ticket objects that current ticket has relations of certain type to. For those relations, the current ticket is the source ticket.

List<Ticket> getTargetTickets(long pTicketId, TicketRelationType pType)

Get list of ticket objects that current ticket has relations of certain type to. For those relations, the ticket given with pTicketId is the source ticket.

List<Ticket> getSourceTickets(TicketRelationType pType)

Get list of ticket objects that current ticket has relations of certain type from. For those relations, the current ticket is the destination ticket.

List<Ticket> getSourceTickets(long pTicketId, TicketRelationType pType)

Get list of ticket objects that current ticket has relations of certain type from. For those relations, the given ticket is the destination ticket.

boolean hasTargetTickets(TicketRelationType pType)

Check if ticket has target tickets. Check if relations exist that have this ticket as source ticket.

boolean hasTargetTickets(long pTicketId, TicketRelationType pType)

Check if given ticket has target tickets. Check if relations exist that have this ticket as source ticket.

boolean hasSourceTickets(TicketRelationType pType)

Check if ticket has source tickets. Check if relations exist that have this ticket as target ticket.

boolean hasSourceTickets(long pTicketId, TicketRelationType pType)

Check if given ticket has source tickets. Check if relations exist that have this ticket as target ticket.

void changeSourceTickets(TicketRelationType pType, long pTargetTicketId, List<Long> pSourceTicketIds)

For the target ticket (e.g. a child ticket) the relations of a given type (e.g. PARENT_CHILD) are removed. For the same relation type a new relation is created with the provided source tickets.

void changeTargetTickets(TicketRelationType pType, long pSourceTicketId, List<Long> pTargetTicketsIds)

For the given source ticket all relations of the given type are removed. For the list of provided target tickets new relations of the given type are created.

void removeRelation(TicketRelationType pType, long pSourceTicketId, long pTargetTicketId)

Remove ticket relation between two tickets with specified type.

void addRelation(TicketRelationType pType, String pComment, long pSourceTicketId, long pTargetTicketId)

Add relation of the specified type between ticket sourceTicketId and targetTicketId.

Ticket getMasterTicket()

Available starting with CM version 6.10.4.0

Return the master ticket of the current ticket.

List<Ticket> getSlaveTickets()

Available starting with CM version 6.10.4.0

Returns a list of all slave tickets of the current ticket

List<Ticket> getReferencedTickets()

Available starting with CM version 6.10.4.0

Returns a list of all tickets which have a simple reference to the current ticket.

Table 1: Important methods of workflowApi for the work with ticket relations

TicketRelationService Methods

If you work with scripts in the Admin Tool (which are then called from a workflow script), the workflowApi is not available. You can use methods of the class TicketRelationService which is available as singleton ticketRelationService.

Method of ticketRelationService Explanation
List<TicketRelation> getByTicket(Ticket pTicket, TicketRelationDirection pTicketRelationEnd, TicketRelationType... pRelationType) Get a list of all ticket relations for a given ticket constrained by the relation direction (ANY|SOURCE|TARGET) and the relation type (MASTER_SLAVE|PARENT_CHILD|REFERENCE )
Set<TicketRelation> getByTickets(Set<Ticket> pTickets, TicketRelationDirection pTicketRelationEnd, TicketRelationType... pRelationType) Get set of all tickets relations for a given set of tickets constrained by the relation direction (ANY|SOURCE|TARGET) and the relation type (MASTER_SLAVE|PARENT_CHILD|REFERENCE )

Table 2: Important methods of TicketRelationService for the work with ticket relations

Example with workflowApi and ticketRelationService Methods

// use wflApi:

println 'Displaying slave tickets from wfl script ...'

List<Ticket> slave_tics = workflowApi.getSlaveTickets()

slave_tics?.each(){ st ->

log.info ' Slave Ticket is now ' + st.getId() + ' -- ' + st.getSubject()

}

Code example 75: Example Script, display IDs and names of slave tickets workflow version

// DisplaySlaveTickets.groovy

// use in AT:

import com.consol.cmas.common.service.*

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

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

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

println 'Displaying slave tickets from AT script ...'

def ticket = workflowApi.getTicket()

 

List<TicketRelation> t_rel = ticketRelationService.getByTicket(ticket, TicketRelationDirection.ANY, TicketRelationType.MASTER_SLAVE)

t_rel?.each(){ tr ->

log.info 'Source ticket is now ' + tr.sourceTicket.id + ' -- ' + tr.sourceTicket.subject

log.info 'Target ticket is now ' + tr.targetTicket.id + ' -- ' + tr.targetTicket.subject

}

Code example 76: Example Script, display IDs and names of slave tickets Admin Tool script version

scriptExecutionService.execute("DisplaySlaveTickets.groovy")

Code example 77: Calling previous AT script from workflow activity