Skripte im Workflow
Skripte werden dazu verwendet, automatische Aktionen auszuführen und das Verhalten des Workflows anzupassen. Es gibt zwei grundlegende Skripttypen:
-
Sichtbarkeitsskripte werden ausgeführt, um die Verfügbarkeit der Aktivität zu steuern.
-
Reguläre Skripte werden ausgeführt, wenn eine bestimmte Aktion ausgeführt wird oder ein bestimmtes Ereignis eintritt.
Einige Elemente und Adornments haben zusätzlich Skripte für bestimmte Zwecke, wie zum Beispiel das Entscheidungsskript, das festlegt, welchen Ausgang ein Vorgang nimmt, wenn er durch einen Entscheidungsknoten läuft.
Sie können Skripte auf zwei Arten verwalten:
-
Verwenden von eingebetteten Skripten:
Eingebettete Skripte stehen direkt im Workflow-Editor zur Verfügung, d. h. Sie öffnen den Skripteditor für das gewünschte Element, schreiben den Inhalt des Skripts und speichern das Skript.
-
Verwenden von Skripten des Typs Workflow:
Workflow-Skripte werden auf der Seite Skripte der Web Admin Suite gespeichert, siehe Skripte des Typs Workflow. Sie können in einem eingebetteten Skript referenziert werden, d. h. Sie erstellen ein eingebettetes Skript, das ein Workflow-Skript ausführt:
scriptExecutionService.execute("myscript.groovy")
Die folgende Tabelle zeigt einen Vergleich der beiden Arten:
Art |
Beschreibung |
Vorteile |
Nachteile |
---|---|---|---|
Eingebettetes Skript |
Der gesamte Inhalt des Skripts steht im Workflow-Editor zur Verfügung. |
|
|
Workflow-Skript |
Das Skript wird als Skript des Typs Workflow auf der Seite Skripte gespeichert. Das eingebettete Skript referenziert dieses Workflow-Skript. |
|
|
Skripte werden in Groovy geschrieben. Da der Groovy-Code auf einer Java Virtual Machine ausgeführt wird, können Sie auch Java-Code schreiben. Mit Groovy-Code können Sie dynamische Typisierung verwenden und getter- und setter-Methoden auslassen, wodurch die Syntax kürzer wird. Die folgende Tabelle zeigt Beispiele für die Unterschiede zwischen Groovy und Java:
Ziel |
Groovy |
Java |
---|---|---|
Thema eines Vorgangs abrufen |
def mysubject = ticket.subject |
String mysubject = ticket.getSubject(); |
Hauptkontakt eines Vorgangs abrufen |
def mymaincontact = ticket.mainContact |
Unit mymaincontact = ticket.getMainContact(); |
Wert eines bestimmten Vorgangsfeldes aus einem Vorgang abrufen |
def myprio = ticket.get("helpdesk_fields.prio") |
String myprio = ticket.get("helpdesk_fields", "prio"); |
Thema eines Vorgangs setzen |
ticket.subject = "asd" |
ticket.setSubject("asd"); |
ConSol CM-API-Methoden
Die ConSol CM-API stellt verschiedene Convenience-Schnittstellen und -Methoden zur Verfügung, die den Zugriff auf häufig verwendete Objekte erleichtern. Die meisten dieser Convenience-Schnittstellen gehören zum Paket com.consol.cmas.common.service und dessen Unterpaketen.
Die implementierende Instanz der Schnittstelle ist immer verfügbar, indem Sie den Anfangsbuchstaben im Klassennamen, der ein Großbuchstabe ist, durch einen Kleinbuchstaben ersetzen. Verwenden Sie z. B. engineerService, wenn Sie Methoden der Schnittstelle EngineerService aufrufen möchten. Die einzige Ausnahme zu dieser Regel bildet die Klasse WorkflowContextService, deren Objekt workflowApi viele nützliche Methoden bietet.
Weitere Informationen zu den verfügbaren Klassen und Methoden finden Sie in der ConSol CM-API-Dokumentation.
Funktionen des Skripteditors
Der Skripteditor bietet die folgenden Funktionen:
-
Syntax-Hervorhebung
Der Editor verwendet Syntax-Hervorhebung für Groovy. -
Code-Vervollständigung
Sobald Sie einen Punkt tippen, werden Methoden für das aktuelle Objekt vorgeschlagen. Tippen Sie weiter, um die Ergebnisse einzuschränken. Es werden nur Methoden für explizit deklarierte Variablen angezeigt.Sie können STRG + LEERTASTE drücken, um Vorschläge für Service-Klassen anzuzeigen.
Wenn Sie in Ihrem Skript mit Code wie def utilityScript = scriptExecutionService.execute("utilityScript") oder def utilityScript = workflowApi.runScript("utilityScript") ein anderes Skript aufrufen, werden die öffentlichen Methoden, die in der obersten Ebene des Utility-Skripts definiert sind, vorgeschlagen, wenn Sie utilityScript gefolgt von einem Punkt eingeben.
Das Utility-Skript muss den Aufruf return this enhalten.
-
Code-Prüfung
Die Ergebnisse der Code-Prüfung werden unterhalb des Quellcodes angezeigt. Es gibt drei Arten:- Keine Prüfung: Die Code-Prüfungsfunktion ist ausgeschaltet.
- Einfache Prüfung: Es wird eine einfache Code-Prüfung durchgeführt.
- Strenge Prüfung: Es wird eine detailliertere Code-Prüfung durchgeführt, die auch überprüft, ob die aufgerufenen Methoden für das Objekt existieren.
-
Liste der Methoden und Variablen
Sie können auf das Icon Navigator anzeigen klicken, um auf der rechten Seite einen Bereich zu öffnen, der eine Liste der im Haupt-Scope des Skriptes definierten Methoden und globalen Variablen enthält. Klicken Sie auf eine Methode oder Variable, um im Skript zur entsprechenden Definition zu springen. -
Referenzierte Skripte
Skripte, die von einem Skript aufgerufen werden, sind unterstrichen. Sie können ein Skript öffnen, indem Sie auf den Skriptnamen klicken. -
Code-Fragmente
Sie können Code-Fragmente, die zu den folgenden Objekten gehören, in Ihre Skripte einfügen:- Skriptgeneratoren: Code für E-Mail- oder Suche-Skripte auf Basis der in einem Modalfenster vorgenommenen Einstellungen generieren und einfügen
- Datenfelder: Vorgangs-, Kontakt- und Ressourcenfelddaten abrufen und setzen, technischen und lokalisierten Wert von Feldern des Typs enum abrufen, über Listenfelder iterieren, Zeilen zu Listenfeldern hinzufügen
- Bezeichnungen: Bezeichnung mit oder ohne Lokalisierung einfügen
- Queues: Queue einfügen
- Skripte: Skript ausführen
- System-Properties: System-Property einfügen
- Templates: Template mit oder ohne Lokalisierung einfügen
Sie können auf Code-Fragmente zugreifen, indem Sie die Option >> Code-Fragment einsetzen aus den Autocomplete-Vorschlägen auswählen, auf den Button Code-Fragment einsetzen in der Symbolleiste klicken oder die Tastenkombination STRG + J verwenden.
Das Fenster Code-Fragmente enthält ein Suchfeld, über das Sie das gewünschte Code-Fragment suchen können. Sie können z. B. nach einem Kontaktfeld suchen, um die verfügbaren Fragmente anzuzeigen. Sie können weitere Filter anwenden, indem Sie den Objekttyp gefolgt von einem Doppelpunkt in das Suchfeld eingeben:
- label: sucht nach Bezeichnungen
- property: sucht nach System-Properties
- queue: sucht nach Queues
- resource: sucht nach Ressourcenfeldern
- script: sucht nach Skripten
- template: sucht nach Templates
- ticket: sucht nach Vorgangsfeldern
- unit: sucht nach Kontaktfeldern
-
Tastenkombinationen
Es gibt Tastenkombinationen für häufige Tätigkeiten. Beispiele:- Speichern: STRG + S
- Rückgängig machen: STRG + Z
- Suchen: STRG + F
- Code-Snippet einfügen: STRG + J
- Autovervollständigung: STRG + Leertaste
- Zu Zeile springen: STRG + L
- Zum referenziertem Skript springen: STRG + Klick
- Vorschau des referenzierten Skripts öffnen: STRG + ALT + Klick
- Vorschau des Skript-Templates anzeigen: ALT + T
- Code formatieren: ALT + F
Die Tastenkombinationen zu den referenzierten Skripten sind nur dann verfügbar, wenn der Benutzer den Skriptnamen im Code ausgewählt hat.
-
Texthervorhebung
Sie können auf ein Wort doppelklicken oder Text markieren, um alle Vorkommen im Skript hervorzuheben.
Skript-Beispiele
Die folgenden Abschnitte enthalten kurze Beschreibungen der wichtigsten Aspekte beim Schreiben von Skripten. Größere Themen werden auf Unterseiten behandelt:
Referenzieren von Workflow-Elementen
Workflow-Elemente werden immer durch ihren Pfad referenziert. Der Pfad spiegelt die hierarchische Struktur des Workflows wieder. Er beginnt mit defaultScope und enthält die technischen Namen der Bereiche, in denen das Element liegt, sowie den technischen Namen des Elements.
Beispiel: Aktivität information_received im Unterbereich on_hold des Bereichs work_in_progress:
defaultScope/work_in_progress/on_hold/information_received
Sie können den Pfad über den Button Kopieren im Detailbereich des entsprechenden Elements kopieren.
Arbeiten mit Datenfeldern
Datenfelder werden immer über ihre technischen Namen nach dem folgenden Muster referenziert:
<ticket|unit|resource>.<get|set|add|remove>("<technischer Name der Feldgruppe>.<technischer Name des Feldes>")
Der Inhalt eines Datenfeldes hängt vom Datentyp ab. Er kann sowohl ein Wert als auch ein Objekt sein.
Details zu den verfügbaren Methoden für verschiedene Objekte und Feldtypen finden Sie in Verwenden von Datenfeldern in Skripten.
Verwenden von Datenfeldern als Variablen
Manchmal benötigen Sie Variablen, die für die Workflow-Programmierung erforderlich sind, aber nicht auf der Oberfläche des Web Clients und von CM/Track sichtbar sein sollen. Abhängig vom Objekt, für welches sie benötigt werden, können Sie Vorgangs-, Kontakt- oder Ressourcenfelder für diese Variablen verwenden.
-
Erstellen Sie ein Datenfeld mit dem erforderlichen Datentyp.
-
Setzen Sie Sichtbarkeit auf Nie, um das Feld auf der Oberfläche zu verbergen.
Arbeiten mit Benutzerdaten
Bei der Arbeit mit Benutzerdaten ist es oft nötig, zwischen dem aktuellen Benutzer, d. h. dem Benutzer, der angemeldet ist und die Aktion durchführt, die zur Ausführung des Skripts führt, und dem zugewiesenen Bearbeiter eines Vorgangs zu unterscheiden.
-
Aktuellen Benutzer abrufen:
workflowApi.getCurrentEngineer()
engineerService.getCurrent()
-
Zugewiesenen Bearbeiter des aktuellen Vorgangs abrufen:
ticket.getEngineer()
-
Aktuellen Vorgang dem aktuellen Benutzer zuweisen:
ticket.engineer = engineerService.current
-
Benutzer mit einer bestimmten Rolle abrufen:
engineerRoleRelationService.getEngineersWithRoles(roleService.getByName("Supervisor"))
-
Rollen des aktuellen Benutzers abrufen:
engineerRoleRelationService.getRolesForEngineer(engineerService.current)
Anzeigen von Meldungen
Über Meldungen kann der Benutzer dynamische Informationen zum Prozess oder zu den eingegebenen Daten erhalten. Sie können in einer roten Box unterhalb der Menüleiste oder neben einem Vorgangsfeld in einem Aktivitätsformular angezeigt werden. Wenn die Meldung lokalisiert werden soll, ist es empfehlenswert, Bezeichnungen zu verwenden, siehe Bezeichnungen.
-
Lokalisierte Meldung in einer roten Box anzeigen. Der Meldungstext basiert auf der Bezeichnung, die für die Sprache des aktuellen Benutzers definiert ist.
workflowApi.addValidationError("INFO", messageProviderService.getMessage("label key", engineerService.currentLocale))
-
Einfache Meldung neben einem Vorgangsfeld anzeigen.
workflowApi.addValidationError(ticket.getField("field group", "field"), "Message text")
Arbeiten mit Overlays
Overlays bleiben während der gewählten Overlay-Gültigkeit am Vorgangs-Icon. Mit folgendem Code können Sie ein Overlay in einem Skript entfernen:
def si = ticket.scopeInfo
for (ov in si.getActivatedOverlays().toArray() ) {
if (ov.parent.name == "defaultScope/ServiceDeskTicketInProgressScope/Email_received") {
si.removeOverlay(ov)
}
}
Das Overlay wird mithilfe des Pfads der Aktivität, durch die es angehängt wurde, identifiziert.
Arbeiten mit System-Properties
Sie können Methoden der Klasse ConfigurationService verwenden, um den Wert von System-Properties abzurufen.
configurationService.getValue("module name","property name")
Arbeiten mit Textklassen
Für Protokolleinträge von Vorgängen können Sie Textklassen abrufen oder setzen.
-
Textklasse eines Protokolleintrags abrufen:
ContentEntry.getContentEntryClass()
-
Textklasse eines Protokolleintrags ändern:
ticketContentService.updateContentEntryClass(ContentEntry pContentEntry, ContentEntryClass pContentEntryClass)
Arbeiten mit Attachments
Mit den folgenden Methoden können Sie Attachments abrufen oder hinzufügen:
-
Alle Attachments abrufen:
workflowApi.getAttachmentList()
-
Attachments aus eingehenden E-Mails abrufen:
ticketContentService.getAttachmentEntries(ticket, ContentEntryCategory.INCOMING_MAIL)
-
Attachments aus ausgehenden E-Mails abrufen:
ticketContentService.getAttachmentEntries(ticket, ContentEntryCategory.OUTGOING_MAIL)
-
Attachment hinzufügen:
def filePath = "/home/hotline/fileToAdd.xml"
def file = new File(filePath)
def stream = new ByteArrayInputStream(file.readBytes() );
def content = new ContentFile("newFileName.xml", "application/xml", stream, file.length());
def attachment = new AttachmentEntry();
attachment.setMimeType ("application/xml")
attachment.setFile(content)
// in workflow context
workflowApi.addAttachment(attachment);
// in non-workflow context
ticketContentService.createContentEntry(ticket, attachment)
Ändern der Sichtbarkeit von Datenfeldgruppen
Sie können die Anzeige von Datenfeldgruppen mit der Einstellung Sichtbar steuern. Ein häufiger Anwendungsfall ist, Feldgruppen anfangs durch Setzen auf false zu verbergen, Aktivitätsformulare zu implementieren, in denen die Daten gefüllt werden, und die Feldgruppen danach auf der Oberfläche anzuzeigen. Indem bestimmte Feldern, nur dann angezeigt werden, wenn sie im Prozess benötigt werden, können die Vorgangsdaten kompakt gehalten werden.
Mit den folgenden Methoden können Sie die Sichtbarkeit von Vorgangsfeldgruppen steuern:
-
Vorgangsfeldgruppe anzeigen:
workflowApi.setGroupProperty("ticket field group",GroupPropertyType.VISIBLE,"true")
-
Vorgangsfeldgruppe verbergen:
workflowApi.setGroupProperty("ticket field group",GroupPropertyType.VISIBLE,"false")
-
Kontaktfeldgruppe anzeigen:
def fieldGroupDefinition = fieldDefinitionService.getGroupByName("field group")
unit.getGroupsConfiguration().setProperty(fieldGroupDefinition, GroupPropertyType.VISIBLE, "true")
-
Ressourcenfeldgruppe anzeigen:
def fieldGroupDefinition = fieldDefinitionService.getGroupByName("field group")
resource.getGroupsConfiguration().setProperty(fieldGroupDefinition, GroupPropertyType.VISIBLE, "true")
Suchen nach Objekten
Mit criteria-Objekte können Sie nach Vorgängen, Kontakten und Ressourcen suchen.
-
Nach Vorgängen suchen:
ticketService.getByCriteria(TicketCriteria pTicketCriteria)
-
Nach Kontakten suchen:
unit.Service.getByCriteria(UnitCriteria pUnitCriteria)
-
Nach Ressourcen suchen:
resourceService.getByCriteria(ResourceCriteria pResourceCriteria)
Das criteria-Objekt wird durch die verfügbaren Methoden zum Hinzufügen von einem oder mehreren Kriterien konfiguriert. Wenn Sie ein Datenfeld als Suchkriterium verwenden, muss das entsprechende Datenfeld indiziert sein.
Die Suchmethoden geben die kompletten Objekte zurück. Sie können daher sehr viel Speicherplatz verbrauchen, wenn Sie eine Suche durchführen. Wenn Sie lediglich die Anzahl der Objekte, die bestimmte Kriterien erfüllen, benötigen, können Sie stattdessen mit den Methoden getCountByCriteria() der gleichen Klassen arbeiten. Mit den Methoden getIdsByCriteria() können Sie auch nur die IDs der passenden Objekte abrufen.
Berücksichtigen von Vorgangs-Update-Events
Bestimmte Methoden führen zu sogenannten Update-Events (Klasse TicketUpdateEvent). Diese Update-Events können die System-Performance verringern. Daher sollten sie vermieden werden, wenn sie nicht unbedingt für den Geschäftsprozess nötig sind.
Beispiel: Benutzer einem Vorgang zuweisen
-
workflowApi.assignEngineer(workflowApi.currentEngineer) verursacht ein Update-Event.
-
ticket.setEngineer(workflowApi.currentEngineer) verursacht kein Update-Event.
Update-Events treten außerdem auf, wenn ein Workflow-Element ausgeführt wird. Wenn Elemente verkettet sind, sollten Sie vermeiden, dass ein Update-Event nach jedem einzelnen Element ausgeführt wird. Markieren Sie die Checkbox Kein Update-Event für alle Elemente mit Ausnahme des letzten, damit der Vorgang nur einmal nach dem letzten Workflow-Element aktualisiert wird.
Hinzufügen von Log-Informationen
Mit folgender Syntax können Sie Log-Informationen zu Ihren Skripten hinzufügen:
log.info "This is my debug message."
Sie können Meldungen auch auf anderen Log-Leveln protokollieren, indem Sie log.debug, log.warn oder log.error verwenden. Die Log-Meldungen werden in die Datei server.log geschrieben.
Details zu den verfügbaren Log-Dateien und ihrer Konfiguration finden Sie in Log-Dateien.
Ändern des Ausführungsablaufs
Mit der Methode skipInterruptRestore() der Klasse ScopeInfo können Sie eine Trigger-Ausführung mit automatischen Aktivitäten als Exception statt als Interrupt behandeln. Diese Methode kann nur in automatischen Aktivitäten, die mit Triggern verbunden sind, verwendet werden. Wenn Sie sie zum Skript solch einer Aktivität hinzufügen, kehrt der Vorgang nicht zur ursprünglichen Aktivität, an der er sich vor dem Feuern des Triggers befand, zurück, sondern verbleibt im Ablauf der Aktivität, in der die Methode aufgerufen wird.
Damit können beispielsweise Workflows implementiert werden, bei denen der Vorgang von einem Trigger in einen Wartebereich verschoben wird, und dort verbleibt, bis ein anderer Trigger feuert.