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:
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.
workflowApi.addRelation(TicketRelationType.REFERENCE, "This is a very important relation", pSourceTicketId, pTargetTicketId)
Code example 65: Creating a ticket relation of type REFERENCE using workflowAPI
List<Ticket> mytickets = workflowApi.getReferencedTickets()
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.
//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
// 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)
List<Ticket> mytickets = workflowApi.getSlaveTickets()
Code example 69: Finding all slave tickets of the current ticket
def mticket = workflowApi.getMasterTicket()
Code example 70: Finding the master ticket of the current ticket
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.
// 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
def my_parent = workflowAPI.getParentTicket()
Code example 72: Finding the parent ticket of a ticket
// only works for current ticket:
List<Ticket> my_childtickets = workflowApi.getChildTickets()
Code example 73: Finding all child tickets of a ticket
// only works for current ticket:
List<Ticket> my_brothers = workflowApi.getBrotherTickets()
Code example 74: Finding all brother tickets of a (child) ticket
Note the following rules for the work with ticket relations:
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
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
// 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