Ausdrücke
An mehreren Stellen im Admin-Panel lassen sich Felder nicht nur mit festen Werten, sondern mit Ausdrücken befüllen. Ein Ausdruck ist eine kleine Formel, die zum Zeitpunkt der Auswertung anhand der Daten einer Entität berechnet wird. Dadurch lässt sich das Verhalten von Certiflow dynamisch und ohne Programmierung an die jeweilige Situation anpassen.
Certiflow schreibt alle Ausdrücke in der Common Expression Language (CEL), einer weit verbreiteten, bewusst schlicht gehaltenen Ausdruckssprache. Eine Auswahl zwischen mehreren Sprachen gibt es nicht. Eine vollständige Beschreibung der Sprache finden Sie in der CEL-Dokumentation. Dieser Artikel erklärt, was Sie für die Arbeit in Certiflow davon brauchen. Er richtet sich an Administratoren, die solche Felder konfigurieren, und setzt ein gewisses technisches Verständnis voraus.
Wo Ausdrücke verwendet werden
Section titled “Wo Ausdrücke verwendet werden”Die folgende Tabelle nennt die Felder, in denen Ausdrücke stehen, jeweils mit der Bezeichnung aus der Oberfläche.
| Ort | Ergebnistyp | Wirkung |
|---|---|---|
| Regelset: Ausdruck | Wahrheitswert | Bestimmt, welche Entitäten von einer Checkliste oder einem Prüfplan erfasst werden. |
| Checklistenpunkt: Erfüllungstyp-Ausdruck | Text | Legt fest, wie der Punkt erfüllt wird (siehe unten). |
| Checklistenpunkt: Karenzzeit-Ausdruck (Sekunden) | Ganze Zahl | Legt fest, wie lange ein neu erforderlicher Punkt unerfüllt bleiben darf, bevor er die Entität blockiert. |
| Checklistenpunkt: Auto-Genehmigungsrate-Ausdruck | Zahl von 0 bis 100 | Wahrscheinlichkeit in Prozent, mit der ein hochgeladenes Dokument automatisch genehmigt wird. |
| Checklistenpunkt: Auto-Genehmigungsablaufzeit-Ausdruck | Ganze Zahl | Legt in Sekunden fest, wie lange eine automatische Genehmigung gültig bleibt. |
| Spezifikationsvorlage: Filter | Wahrheitswert | Bestimmt, ob ein Eintrag im erzeugten Dokument erscheint. Bearbeitung im Baukasten oder im Textmodus. |
| Formularelement: Sichtbarkeits-Ausdruck und Validierungs-Ausdruck | Wahrheitswert bzw. Text | Steuern, ob ein Feld im Formular angezeigt wird und ob eine Antwort zulässig ist. |
| Auswahlfeld: Optionsfilter-Ausdruck | Liste von Texten | Schränkt die angebotenen Optionen eines Auswahlfelds je Entität ein. |
| Einstellungen: Wert | je nach Schlüssel | Jeder Wert in den Einstellungen ist selbst ein Ausdruck. |
| Automatisierungsregel: Vorfilter | Wahrheitswert | Bestimmt, ob ein Ereignis eine Regel auslöst. |
| Kampagnen: Platzhalter in Betreff und Text | Text | Fügt Werte in den Text einer Kampagnen-Nachricht ein. |
Welche Daten ein Ausdruck an der jeweiligen Stelle lesen kann und wie sich ein Fehler auswirkt, beschreibt die Referenz Ausdruck-Kontexte.
Der Ausdruckseditor
Section titled “Der Ausdruckseditor”In den Dialogen, in denen ein Ausdruck eingegeben wird, steht ein gemeinsamer Editor zur Verfügung.
Textmodus
Section titled “Textmodus”Im Textmodus schreiben Sie den Ausdruck von Hand. Der Editor zeigt Zeilennummern und hebt die Bestandteile des Ausdrucks farbig hervor. Beim Tippen schlägt er passende Namen und Funktionen vor. Mit den Pfeiltasten wählen Sie einen Vorschlag aus, mit der Eingabe- oder der Tabulatortaste übernehmen Sie ihn, mit der Escape-Taste schließen Sie die Liste.
Certiflow prüft den Ausdruck während der Eingabe. Ist er syntaktisch fehlerhaft, erscheint unter dem Feld der Hinweis „Ungültiger Ausdruck” mit einer Beschreibung des Fehlers, und der Dialog lässt sich nicht speichern. Das gilt auch für eine Konstante, deren Ergebnistyp nicht zum Feld passt, etwa ein Text in einem Feld, das einen Wahrheitswert erwartet. In den Dialogen mit Auswahl einer Testentität (siehe unten) steht bei einem fehlerfreien Ausdruck zusätzlich „Fehlerfrei geparst” mit der Zahl der gelesenen Felder.
Baukasten
Section titled “Baukasten”Bei Regelsets und beim Filter einer Spezifikationsvorlage lässt sich der Ausdruck alternativ im Baukasten zusammenklicken, ohne die Schreibweise zu kennen. Der Baukasten arbeitet mit Bedingungen, die in Zeilen angeordnet sind. Jede Zeile besteht aus:
- dem Feld, das geprüft wird. Das kann ein Attribut der Entität sein, ihre Tags, ihre Entitätsart oder ein Feld einer verknüpften Entität (Vorgänger oder Nachfolger),
- dem Operator, etwa „ist gleich” oder „enthält”,
- den Werten, mit denen verglichen wird. Mehrere Werte trennen Sie mit Komma.
Mehrere Zeilen werden zu Gruppen zusammengefasst. Eine Gruppe verknüpft ihre Bedingungen entweder mit ALLE (alle müssen zutreffen) oder EINE (mindestens eine muss zutreffen). Mit NICHT (Gruppe negieren) kehren Sie das Ergebnis einer Gruppe um. Der Baukasten zeigt den erzeugten Ausdruck darunter an und bietet die Schaltfläche Kopieren. Enthält der Baukasten keine Bedingung, ergibt sich der Ausdruck true. Bei einem Regelset bedeutet das, dass es für alle Entitäten gilt. Ein leeres Textfeld zählt dagegen als false.
Welche Operatoren zur Auswahl stehen, richtet sich nach der Art des Feldes:
| Feldart | Operatoren |
|---|---|
| Text | ist gleich, ist ungleich, enthält, enthält nicht, beginnt mit, beginnt nicht mit, endet mit, endet nicht mit, ist eines von, ist keines von, ist gesetzt, ist nicht gesetzt |
| Zahl | ist gleich, ist ungleich, ist größer als, ist mindestens, ist kleiner als, ist höchstens, ist gesetzt, ist nicht gesetzt |
| Ja/Nein | ist wahr, ist falsch, ist gesetzt, ist nicht gesetzt |
| Auswahlliste | ist gleich, ist ungleich, ist eines von, ist keines von, enthält, enthält nicht, beginnt mit, beginnt nicht mit, endet mit, endet nicht mit, ist gesetzt, ist nicht gesetzt |
| Attribut mit mehreren Werten | hat, hat nicht, ist gesetzt, ist nicht gesetzt |
| Tags | hat, hat nicht |
| Bereich | ist gesetzt, ist nicht gesetzt |
| Verknüpfte Entität als Ganzes | ist gesetzt, ist nicht gesetzt |
Datei-Attribute stehen in Ausdrücken nicht zur Verfügung.
Unter den Bedingungen zeigt der Baukasten den Stand an: Sind Zeilen unvollständig, nennt er deren Zahl mit dem Hinweis „Der Ausdruck kann nie zutreffen.“, sonst erscheint „Keine Probleme”.
Wenn Sie im Textmodus einen Ausdruck schreiben, den der Baukasten nicht abbilden kann, bleibt dieser im Textmodus, und der Umschalter zum Baukasten ist nicht verfügbar. Solange der Baukasten den Ausdruck darstellen kann, formatiert die Schaltfläche Format den Text übersichtlich.
Ausdruck testen
Section titled “Ausdruck testen”In den Dialogen für Regelsets, Checklistenpunkte, Formularelemente und Spezifikationseinträge können Sie unter Testen gegen eine Entität auswählen. Der Ausdruck wird dann live gegen deren echte Daten ausgewertet:
- Bei einem Wahrheitswert zeigt der Editor Treffer oder Kein Treffer.
- Bei anderen Ergebnissen erscheint das Ergebnis mit seinem Typ.
- Aufklappbar ist der vollständige Kontext, also die Daten, die der Ausdruck an dieser Stelle lesen kann.
Nach der Auswahl bietet die Autovervollständigung zusätzlich die Namen aus den Daten dieser Entität an. Beim Spezifikationseintrag hat das Feld eine eigene Auswahl, die auf Entitäten des Typs der Vorlage beschränkt ist, und der Kontext ist auf die Zielgruppe der Vorlage gefiltert. In den Dialogen für Regelsets und Checklistenpunkte gilt die gewählte Entität für alle Ausdrucksfelder des Dialogs gemeinsam.
Beim Regelset gibt es außerdem die Schaltfläche Ausdruck testen. Sie wertet den eingegebenen, noch nicht gespeicherten Ausdruck gegen alle Entitäten aus und zeigt im Dialog Testergebnis die Zahl der Treffer sowie die ersten zehn Treffer mit externer ID, Hauptname und Entitätsart. Dabei wird nichts gespeichert. Ohne Ausdruck ist die Schaltfläche deaktiviert.
Grundlagen der Syntax
Section titled “Grundlagen der Syntax”Die Sprache unterstützt die üblichen Bausteine:
- Logik:
&&(und),||(oder) und!(nicht). - Vergleiche:
==,!=,>,<,>=,<=. - Rechnen:
+,-,*,/,%. Die Division zweier ganzer Zahlen rundet ab:7 / 2ergibt3. - Bedingung (wenn/dann/sonst):
bedingung ? wert_wenn_wahr : wert_wenn_falsch. - Zugehörigkeit:
x in listeprüft, ob ein Wert in einer Liste vorkommt, und"Name" in entityprüft, ob ein Attribut einen Wert hat. - Texte stehen in doppelten oder einfachen Anführungszeichen, zum Beispiel
"DE". - Textfunktionen werden als Methode aufgerufen:
x.contains("a"),x.startsWith("a"),x.endsWith("a")undx.matches("regulärer Ausdruck"). - Weitere Funktionen:
size(x)liefert die Länge eines Textes oder einer Liste,string(x),int(x)unddouble(x)wandeln Werte um,max(...)undmin(...)liefern den größten bzw. kleinsten Wert. - Datum und Zeit:
timestamp("2024-01-15T00:00:00Z")erzeugt einen Zeitpunkt,duration("1h")eine Zeitspanne. Aus einem Zeitpunkt lassen sich Teile mitgetFullYear(),getMonth(),getDayOfMonth(),getDate(),getDayOfWeek(),getDayOfYear(),getHours(),getMinutes(),getSeconds()undgetMilliseconds()lesen.
Listen durchsuchen
Section titled “Listen durchsuchen”Listen werden mit einer selbst gewählten Variablen durchsucht, die für das jeweils betrachtete Element steht. Im Beispiel unter der Tabelle steht t für jedes einzelne Tag.
| Schreibweise | Bedeutung |
|---|---|
liste.exists(x, bedingung) |
Mindestens ein Element erfüllt die Bedingung. |
liste.all(x, bedingung) |
Alle Elemente erfüllen die Bedingung. |
liste.exists_one(x, bedingung) |
Genau ein Element erfüllt die Bedingung. |
liste.filter(x, bedingung) |
Liefert die Elemente, die die Bedingung erfüllen. |
liste.map(x, ausdruck) |
Liefert eine neue Liste mit dem berechneten Ausdruck. |
tags.exists(t, t == "kritisch")Was es nicht gibt
Section titled “Was es nicht gibt”Einige Funktionen anderer Ausdruckssprachen stehen nicht zur Verfügung: Text-Vorlagen mit Backticks, das Ausschneiden von Textteilen, fuzzyMatch, extract, sum, avg, median und mode sowie Datumsrechnung mit add, diff oder startOf und Zeitzonen. Eine nicht vorhandene Funktion meldet der Editor bereits beim Tippen.
Werte lesen
Section titled “Werte lesen”Attribute der Entität
Section titled “Attribute der Entität”Die Attributwerte einer Entität stehen unter entity und werden über den Attributnamen angesprochen. Weil Attributnamen meist Leerzeichen enthalten, verwenden Sie die Index-Schreibweise:
entity["Primary Name"]Die Punkt-Schreibweise entity.Name funktioniert nur bei Namen ohne Leerzeichen und führt zu einem Fehler, wenn das Attribut keinen Wert hat. Verwenden Sie deshalb möglichst immer die Index-Schreibweise.
Der Entitätstyp steht nicht in entity, sondern in entity_type, zum Beispiel entity_type == "supplier". Attribute, die mehrere Werte aufnehmen können, liefern immer eine Liste, auch wenn nur ein Wert hinterlegt ist. Die Elemente prüfen Sie mit exists oder all.
Die Tags einer Entität stehen als Liste unter tags:
tags.exists(t, t == "no_requirements")Verknüpfte Entitäten
Section titled “Verknüpfte Entitäten”Die direkt verknüpften Entitäten stehen unter predecessors (übergeordnet) und successors (untergeordnet), jeweils nach Entitätstyp gruppiert. Es sind nur die Typen enthalten, die tatsächlich verknüpft sind. Prüfen Sie daher zuerst, ob der Typ vorhanden ist, bevor Sie die Liste durchsuchen:
"supplier" in predecessors && predecessors["supplier"].exists(p, p.entity["Land"] == "DE")Die Tags verknüpfter Entitäten sind ebenfalls lesbar. Verknüpfte Entitäten sind nur eine Ebene tief enthalten: Innerhalb einer verknüpften Entität sind predecessors und successors immer leer.
Einstellungen
Section titled “Einstellungen”Werte aus den Einstellungen lesen Sie mit der Variablen config, immer in der Index-Schreibweise mit dem vollständigen Schlüssel, zum Beispiel config["message.reminder.interval_days"]. Eigene Werte lesen Sie mit config["custom.<name>"]. Die Einzelheiten beschreibt die Referenz Ausdruck-Kontexte.
Konfigurationswerte sind Ausdrücke
Section titled “Konfigurationswerte sind Ausdrücke”In den Einstellungen geben Sie nie den Wert selbst ein, sondern einen Ausdruck, der den Wert liefert. Ein Text steht daher in Anführungszeichen ("Beispiel"), ein Wahrheitswert wird als true oder false geschrieben, und ein JSON-Wert steht als Text in Anführungszeichen. Ein fehlerhafter Ausdruck wird im Dialog als „Ungültiger Ausdruck” mit einer Fehlerbeschreibung markiert und lässt sich nicht speichern. Die Einzelheiten und Ausnahmen beschreibt der Artikel Einstellungen.
Fehlende Werte
Section titled “Fehlende Werte”Ein Attribut ohne Wert fehlt in den Daten der Entität. Der Zugriff in der Index-Schreibweise liefert dafür null, ohne dass ein Fehler entsteht. Wie sich null verhält, ist für die Zuverlässigkeit eines Ausdrucks entscheidend:
- Ein Gleichheitsvergleich ergibt
false. Der Ausdruckentity["Land"] == "DE"ist für eine Entität ohne Land schlicht nicht erfüllt. - Ein Größenvergleich (
>,<,>=,<=) gegennullist dagegen ein Fehler und nichtfalse.
Sichern Sie Größenvergleiche deshalb mit der Zugehörigkeitsprüfung ab:
"Umsatz" in entity && entity["Umsatz"] > 1000000Wie sich ein Fehler auswirkt, hängt von der Stelle ab, an der der Ausdruck steht:
| Ort | Wirkung eines Fehlers |
|---|---|
| Regelset | Der Ausdruck zählt als false. Die Entität wird nicht erfasst. |
| Erfüllungstyp-Ausdruck | Es gilt always, der Punkt ist also optional. |
| Karenzzeit-Ausdruck | Es gilt der Standardwert aus den Einstellungen. |
| Filter einer Spezifikation | Das gesamte Dokument wird nicht erzeugt. |
| Sichtbarkeits-Ausdruck | Das Feld bleibt sichtbar. |
Beim Speichern prüft Certiflow jeden Ausdruck: Er muss fehlerfrei sein und den passenden Ergebnistyp liefern, also zum Beispiel einen Wahrheitswert beim Regelset, einen der drei Texte beim Erfüllungstyp oder ganze Sekunden bei der Karenzzeit. Diese Prüfung läuft gegen die erste aktive Entität des Systems, also nicht unbedingt gegen eine Entität des Typs, für den der Ausdruck gedacht ist. Ein sachlich richtiger Ausdruck kann deshalb abgelehnt werden, wenn diese Beispielentität ein gelesenes Attribut nicht hat und der Ausdruck dadurch einen Fehler ergibt, etwa bei einem ungesicherten Größenvergleich. Mit der Absicherung durch in und einer Prüfung des Entitätstyps wie in entity_type == "supplier" && entity["Land"] == "DE" vermeiden Sie das.
Der Erfüllungstyp-Ausdruck von Checklistenpunkten
Section titled “Der Erfüllungstyp-Ausdruck von Checklistenpunkten”Ein Sonderfall ist der Erfüllungstyp-Ausdruck eines Checklistenpunkts. Hier muss der Ausdruck zu einem von drei festen Texten ausgewertet werden, die in Anführungszeichen stehen. Jeder dieser Werte entspricht einem der Dokument-Fristentypen:
| Ergebnis | Bedeutung | Entspricht |
|---|---|---|
expiration_date |
Es muss ein Dokument mit gültigem, in der Zukunft liegendem Ablaufdatum vorhanden sein. | Kritische Datei (verbindliche Frist) |
file_assigned |
Es muss mindestens ein Dokument zugewiesen sein; das Ablaufdatum spielt keine Rolle. | Unkritische Datei (unverbindliche Frist) |
always |
Der Punkt gilt immer als erfüllt; es ist kein Dokument erforderlich. | Optionale Datei |
Weil das Ergebnis über einen Ausdruck berechnet wird, kann der Fristentyp eines Punkts auch von den Daten der Entität abhängen. Das folgende Beispiel verlangt nur dann ein Ablaufdatum, wenn das Ja/Nein-Attribut „Ablaufdatum erforderlich” gesetzt ist:
"Ablaufdatum erforderlich" in entity && entity["Ablaufdatum erforderlich"] ? "expiration_date" : "file_assigned"Liefert der Ausdruck einen Fehler oder einen anderen Text, gilt always. Beim Speichern wird ein ungültiges Ergebnis abgelehnt.
Beispiele
Section titled “Beispiele”// Regelset: nur deutsche Lieferanten mit hohem Umsatzentity_type == "supplier" && entity["Land"] == "DE" && "Umsatz" in entity && entity["Umsatz"] > 1000000// Regelset: Produkte, deren Lieferant das Tag "kritisch" trägtentity_type == "product" && "supplier" in predecessors && predecessors["supplier"].exists(p, p.tags.exists(t, t == "kritisch"))// Filter einer Spezifikationsvorlage: Eintrag nur, wenn Allergene hinterlegt sind"Allergene" in entity// Filter einer Spezifikationsvorlage: Eintrag nur für Lebensmittelentity["Produktkategorie"] == "lebensmittel"// Karenzzeit-Ausdruck: 14 Tage in Sekunden14 * 24 * 60 * 60// Karenzzeit-Ausdruck mit eigenem Wert aus den Einstellungen, Rückfall auf 0 Sekundenconfig["custom.grace_days"] != null ? config["custom.grace_days"] * 24 * 60 * 60 : 0// Auto-Genehmigungsrate: 50 % der Uploads automatisch genehmigen50// Auto-Genehmigungsablaufzeit: 90 Tage in Sekunden90 * 24 * 60 * 60// Blindkopie nur bei Sperrnachrichten (Wert in den Einstellungen)message.type == "lock" ? "compliance@example.com" : ""Die Auto-Genehmigungsausdrücke erhalten weder Entitätsdaten noch config. Hier sind nur Konstanten und Rechnungen möglich.
Umstieg von der früheren Schreibweise
Section titled “Umstieg von der früheren Schreibweise”Wenn Sie Ausdrücke aus der früheren Schreibweise übernehmen, hilft die folgende Gegenüberstellung:
| Früher | Jetzt |
|---|---|
a and b, a or b, not a |
a && b, a || b, !a |
entity.umsatz |
entity["Umsatz"], zusammen mit "Umsatz" in entity bei Vergleichen |
some(tags, # == "kritisch") |
tags.exists(t, t == "kritisch") |
| Texte in Backticks mit Platzhaltern | Texte mit + verketten, Zahlen vorher mit string(x) umwandeln |
fuzzyMatch, extract, sum, avg |
nicht verfügbar |
Datumsrechnung mit add, diff |
nicht verfügbar, stattdessen timestamp(...) und duration(...) |