In diesem Kapitel werden folgende Themen behandelt:
In ConSol CM können Sie die Datenbank nach Tickets oder Units (Kontakten und Firmen) durchsuchen. Wenn Ihr CM-System das Modul CM.ResourcePool enthält, können Sie die Datenbank auch nach Ressourcen durchsuchen. Alle Suchmodi basieren auf dem gleichen Prinzip:
Die Felder, die als Parameter für die Criteria-Objekte gesetzt sind, müssen indiziert sein, d. h. die Annotationen field-indexed muss gesetzt sein.
Um nach Tickets zu suchen, müssen Sie das Objekt TicketCriteria erstellen. Es können zum Beispiel folgende Felder gesetzt werden (siehe auch entsprechende setter-Methoden in der folgenden Abbildung):
Abbildung 158: Setter-Methoden der Klasse TicketCriteria, Java API Doc, CM-Version 6.10.5.2
Das Objekt TicketCriteria muss an den TicketService übergeben werden, der implizit in jedem Skript als Singleton ticketService verfügbar ist. Details über die Klassen und Methoden finden Sie in der Dokumentation zur ConSol CM Workflow Java API.
def ticketCrit = new TicketCriteria()
ticketCrit.subject = "TICKET_SUBJECT"
ticketCrit.setQueueIds([new Long(workflowApi.getQueueByName("QUEUE_NAME").id)] as Set)
ticketCrit.setFields([new StringField(new FieldKey("FIELD_GROUP", "FIELD_NAME"), "SEARCH_VALUE")] as Set)
List<Ticket> foundTickets = ticketService getByCriteria(ticketCrit)
def firstTicket = foundTickets?.first()
Code-Beispiel 83: Suche nach Tickets (Pseudocode)
Das folgende Beispiel stammt aus einem Workflow einer ServiceDesk-Umgebung. Wenn das Ticket erstellt wurde und das Modul aus einer Liste gesetzt wurde, soll der Workflow automatisch überprüfen, ob es andere offene Tickets mit dem gleichen Modul gibt. Für das Modul wird ein enum verwendet.
Abbildung 159: Web Client: Auswählen des Moduls für ein ServiceDesk-Ticket
def mod = ticket.getField("helpdesk_standard", "module")
def crit = new TicketCriteria()
crit.setStatus(TicketCriteria.Status.OPEN)
Set<AbstractField> myfields = [mod]
crit.setFields(myfields)
List<Ticket> tics = ticketService.getByCriteria(crit)
tics.each() { tic ->
println 'Next Ticket subject is now ' + tic.subject
// do whatever is required with the tickets
}
Code-Beispiel 84: Suchen nach Tickets mit dem gleichen Modul wie das aktuelle Ticket
In diesem Beispiel suchen wir das AccountManagement-Ticket für eine Firma.
import com.consol.cmas.common.model.scripting.unit.PostActionType
import com.consol.cmas.common.model.scripting.unit.PostActionParameter
import com.consol.cmas.common.model.customfield.Unit
import com.consol.cmas.common.model.ticket.TicketCriteria
import com.consol.cmas.common.model.customfield.ListField
import com.consol.cmas.common.model.customfield.ContactReferenceField
import com.consol.cmas.common.model.customfield.UnitReferenceSearchField
import com.consol.cmas.common.model.customfield.ContactReferenceSearchField
import com.consol.cmas.common.model.customfield.meta.FieldKey
import com.consol.cmas.common.model.ticket.Ticket
import com.consol.cmas.common.model.ContactTicketRole
import com.consol.cmas.common.model.customfield.StringField
import com.consol.cmas.common.model.scripting.unit.UnitActionScriptResult
//get AM queue for search
def q_id = (workflowApi.getQueueByName("AccountManagement")).id
def q_ids = new HashSet()
q_ids.add(q_id)
//find AM ticket for the company
def crit = new TicketCriteria()
crit.setQueueIds(q_ids)
// Create List Field Key
def contactSearchListFieldKey = new FieldKey("queue_fields","contacts")
// Prepare List Field
def contactsListField = new ListField(contactSearchListFieldKey )
// Create Memberfield Key
def contactSearchFieldKey = new FieldKey("queue_fields","contacts_member")
// Create Unit Memberfield with Unit and Ticket-Main Role
def contactsMember = new ContactReferenceSearchField(contactSearchFieldKey, unit, ContactTicketRole.MAIN_ROLE)
// Put Member Field in Unit List Field
contactsListField.addChild(contactsMember)
// Put prepared fields into TicketCriteria
crit.setFields([contactsListField] as Set)
// Search ... and Result
def foundTickets = ticketService.getByCriteria(crit)
println "Found tickets: ${foundTickets}"
if ( foundTickets ) {
def AM_tic = foundTickets.first()
def AM_tic_id = AM_tic.id
}
Code-Beispiel 85: Suche nach Tickets nach Unit
In diesem Beispiel kann ein Bearbeiter die Workflow-Aktivität Neues Ticket (Ticket annehmen) nur aufrufen, wenn er noch nicht zu viele Tickets hat. Die maximal zulässige Anzahl an Tickets ist in der kundenspezifischen System-Property custom-servicedesk,engineer.max.open.tickets gespeichert. Auf diese Weise kann die Anzahl von einem CM-Administrator ohne Beteiligung eines Workflow-Entwicklers geändert werden.
Abbildung 160: Workflow-Aktivität, die das Skript zur Kontrolle der Ticketanzahl enthält
// Engineer can only accept ticket if he does not have too many tickets already
def curr_eng = workflowApi.currentEngineer
def max_tics = configurationService.getValue("custom-servicedesk","engineer.max.open.tickets")
// look for open tickets of current engineer
def engs = []
engs.add(curr_eng.id)
TicketCriteria tic_crit = new TicketCriteria()
tic_crit.engineerCriteria = TicketCriteria.EngineerCriteria.assigned(engs as Set)
tic_crit.status = TicketCriteria.Status.OPEN
List<Ticket> open_eng_tics = ticketService.getByCriteria(tic_crit)
def tic_number = open_eng_tics.size
if (tic_number > max_tics) {
workflowApi.addValidationError("INFO","You have too many tickets (" + tic_number + ") already, so you cannot accept another ticket. Maximum allowed number is " + max_tics)
} else {
ticket.setEngineer(curr_eng)
}
Code-Beispiel 86: Skript der Aktivität "Neues Ticket (Ticket annehmen)"
Abbildung 161: Web Client: Kontrolle der Anzahl der Tickets, die einem Bearbeiter zugewiesen sein können
Um nach Units (d. h. Kontakten und/oder Firmen) zu suchen, müssen Sie ein Objekt UnitCriteria erstellen. Es können zum Beispiel folgende Felder gesetzt werden (siehe auch entsprechende setter-Methoden in der folgenden Abbildung):
Verwenden Sie dann unitService, um das Suchergebnis abzurufen.
Abbildung 162: Setter-Methoden der Klasse UnitCriteria, Java API Doc, CM-Version 6.10.5.2
def unitCrit = new UnitCriteria()
unitCrit.setFields([new StringField(new FieldKey("UNIT_GROUP_NAME", "firstname"), "Max"),
new StringField(new FieldKey("UNIT_GROUP_NAME", "lastname"), "Mustermann")] as Set)
def foundContacts = unitService.getByCriteria(unitCrit)
def firstContact = foundContacts?.first()
Code-Beispiel 87: Suche nach Kontakten nach Vornamen und Nachnamen
import com.consol.cmas.common.model.customfield.UnitCriteria
import com.consol.cmas.common.model.customfield.EnumSearchField
import com.consol.cmas.common.model.customfield.meta.FieldKey
def unitCrit = new UnitCriteria()
def companyEnumField = new EnumSearchField(new FieldKey("customer", "company"), [enumService.getValueByName("ENUM_GROUP_NAME",ENUM_VALUE_NAME)] as Set)
unitCrit.setFields([companyEnumField] as Set)
unitService.getByCriteria(unitCrit).each { foundContact ->
println "Processing found contact: "+foundContact.get("name")
}
Code-Beispiel 88: Suche nach Units nach Enum-Wert (allgemeine Syntax)
def unitCrit = new UnitCriteria()
//all other UnitCriteria init operations skipped
// this is the requested value inside the list:
def secLvl = ticket.get("transportEntryData.securityLevel")
//ShipperData/securityLevel is the path of the EnumField inside the list
def secLvlEnumFieldKey = new FieldKey("ShipperData","securityLevel")
//create the template field with FieldKey and our value to search for
def secLvlTemplateField = new EnumField(secLvlEnumFieldKey, secLvl)
//ShipperData/securityLevels is the path of the list itself
def secLvlListTemplateFieldKey = new FieldKey("ShipperData","securityLevels")
//init the template list with the value to be searched for
def secLvlListTemplateField = new ListField(secLvlListTemplateFieldKey,[secLvlTemplateField])
// put the template list into the UnitCriteria object
def unitCrit.setFields([secLvlListTemplateField] as Set)
// Search ... and Result
def shippers = unitService.getByCriteria(unitCrit)
Code-Beispiel 89: Suche nach Units nach Enum-Wert (Beispiel)
Um nach Ressourcen zu suchen, müssen Sie das Objekt ResourceCriteria erstellen. Es können zum Beispiel folgende Felder gesetzt werden (siehe auch entsprechende setter-Methoden in der folgenden Abbildung):
Verwenden Sie dann resourceService, um das Suchergebnis abzurufen.
Abbildung 163: Setter-Methoden der Klasse ResourceCriteria, Java API Doc, CM-Version 6.10.5.2
Im folgenden Beispiel wird eine Liste aller IT-Assets, die als Ressourcen eines bestimmten Ressourcentyps abgebildet sind, in das aktuelle Ticket geschrieben.
Abbildung 164: Web Client: Aufrufen einer Workflow-Aktivität, die die Liste der IT-Assets in einen Kommentar im Ticket schreibt (Skript: siehe folgendes Code-Beispiel)
// Make an inventory of the asset base (CM.Resource Pool) and write the info into the current ticket
// Asset base contains Hardware and Software resources
import com.consol.cmas.common.model.resource.*
import java.util.Arrays
import com.consol.cmas.common.model.ticket.Ticket
import com.consol.cmas.common.model.content.TextEntry
ticket = workflowApi.getTicket()
def crit = new ResourceCriteria()
// only three resource groups are required:
Set<String> res_groups = ["Printers","OfficeSoftware","PCs"]
crit.setResourceGroupsTechnicalNames(res_groups)
List<Resource> res_list = resourceService.getByCriteria(crit)
def desc_name def printout_list = []
res_list.each(){res ->
def res_tname = res.getResourceType().getName()
// println 'Resource type is ' + res_tname
// find the field which is used for description of a single resource
// this depends on the resource fields of the resource field group
switch (res_tname){
case "HP_Printer": desc_name = "HP_Printer_Fields_basic.name"
break;
case "MS_Word2013": desc_name = "MS_Word2013_Fields.OrderNumber"
break;
case "PC_Desktops": desc_name = "PC_Desktop_Fields_basic.name"
break;
case "PC_Laptops": desc_name = "PC_Laptop_Fields_basic.laptopname"
break;
}
def res_final = res.get(desc_name) + '(' + res_tname + ')<br>'
printout_list += res_final
}
printout_list = printout_list.sort{it}
TextEntry new_te = new TextEntry("Asset Base contains the following assets",printout_list.toString()
.replace('[','')
.replace(']','')
.replace(',',''))
ticketContentService.createContentEntry(ticket,new_te)
Code-Beispiel 90: Schreiben einer Liste mit IT-Assets (Ressourcen) ins Ticket