Zum Inhalt

Workshop: Workflow-Formulare bauen (von einfach bis Profi)

Dieser Workshop führt Schritt für Schritt vom kleinsten mehrstufigen Freigabe-Workflow bis zu Mail-Schablonen, allen Skript-Varianten, Gruppen-Postfächern und dem Kopieren abgeschlossener Vorgänge.

Referenz statt Theorie: Alles hier ist an den mitgelieferten Demo-Formularen (Katalog Demo → Workflow) nachvollziehbar:

Demo Zeigt
Urlaubsantrag mit Workflow Grundlagen, Verzweigung, feste Adresse, Gruppen-Postfach, onCopy
Begutachtung mit Workflow Seitenleiste + Änderungsprotokoll, Mail-Schablonen für jeden Schritt
Bestellfreigabe mit Workflow Skripte je Stufe und Übergang (prüfen, rechnen, ablegen), Abschluss-Sperre
Jobticket-Antrag ein ganzer Antrag mit Berechnung, Einwilligung, Unterschrift und Ablehnungs-Stufe — Schritt für Schritt zum Nachbauen

Die reine Referenz (Feldtabelle der <form>_wf, Laufzeit-Ablauf) steht in Workflow (mehrstufige Freigabe). Dieser Workshop baut darauf auf.

Zusammenklicken reicht — das JSON ist zum Nachschauen da

Stufen, Übergänge, Empfänger, Seitenleiste und Änderungsprotokoll richtest du vollständig im Formular-Editor ein, ohne eine Zeile zu tippen; die Mail-Schablonen aus Teil 5 entstehen in der System-Administration. Die eingeklappten Kästen „Hinter den Kulissen" zeigen dir, was dabei in das Formular geschrieben wird. Aufklappen lohnt sich, wenn du einen fertigen Workflow in ein anderes Formular übernehmen willst oder suchst, warum ein Übergang nicht greift — zum Bauen brauchst du es nicht. Nur Teil 6 (Skript-Hooks) verlangt wirklich getippten Code.


Teil 1 — Ein Workflow mit zwei Stufen

Ein Workflow ist reine Konfiguration — kein Skript nötig. Er lebt im Formular-Schema unter dem Schlüssel kc:workflow.

1.1 Ein Status-Feld anlegen

Der Workflow merkt sich seinen Stand in einem Zahlenfeld. Konvention: wf_status (technisch, unsichtbar). Für lesbare Listen/PDF legt man zusätzlich wf_status_label an (String, das System pflegt es automatisch mit dem Stufennamen). Zwei Felder, beide unsichtbar:

"wf_status":       { "type": "number", "title": "Workflow-Status (technisch)", "kc:visible": false },
"wf_status_label": { "type": "string", "title": "Status", "kc:visible": false, "kc:readonly": true }

1.2 Workflow aktivieren (Formular-Editor)

Im Formular-Editor unter Formular-Eigenschaften → Workflow (mehrstufige Freigabe):

  1. Workflow aktiv anhaken.
  2. Stufen anlegen (Nummer + Bezeichnung). Nummern frei wählbar — Konvention: 99 = Endstufe.
  3. Übergänge je Stufe: „Bei Zustimmung → Stufe X".

So sieht der Block aus — hier am Demo-Formular Urlaubsantrag, dessen erste beide Stufen zu sehen sind:

Der Workflow-Block im Formular-Editor: „Workflow aktiv" und die ersten beiden Stufen

Der kleinste sinnvolle Fall: Entwurf → Abgeschlossen. Zwei Stufen, ein Übergang — mehr braucht es nicht, damit der Vorgang laufen kann.

Hinter den Kulissen: zwei Stufen und ein Übergang (kc:workflow)
"kc:workflow": {
  "enabled": true,
  "statusField": "wf_status",
  "stages": [
    { "no": 1,  "label": "Entwurf",       "link": "general" },
    { "no": 99, "label": "Abgeschlossen", "link": "general", "terminal": true }
  ],
  "transitions": {
    "1": { "approve": 99 }
  }
}

statusField zeigt auf das Zahlenfeld aus 1.1, stages listet die Stufen in der Reihenfolge der Stufen-Leiste, und transitions ordnet jeder Stufe ihr Ziel zu. terminal: true markiert die Endstufe.

Sobald ein Datensatz gespeichert ist, erscheint darunter die Workflow-Seite mit Stufen-Leiste, Verlauf und den Buttons Zustimmen / Ablehnen.


Teil 2 — Mehrere Stufen mit Verzweigung (Rücksprung)

Echte Freigaben haben Zwischenstufen und einen Rücklauf bei Ablehnung. Das steuern die transitions: je Stufe ein Ziel für approve und optional reject.

Stufen mit Zustimmung (vorwärts) und Ablehnung (Rücksprung)

Im Beispiel unten geht es von Entwurf über Prüfung und Freigabe zum Abschluss — und bei Ablehnung jeweils eine Stufe zurück:

  • Zustimmung in Stufe 2 → Stufe 3. Ablehnung in Stufe 2 → zurück auf 1.
  • Bei einem Rücksprung merkt sich der Workflow den vorherigen Bearbeiter der Ziel-Stufe und benachrichtigt ihn erneut — der Vorgang „kehrt zurück", statt ins Leere zu laufen.
Hinter den Kulissen: vier Stufen mit Rücksprung
"kc:workflow": {
  "enabled": true,
  "statusField": "wf_status",
  "stages": [
    { "no": 1,  "label": "Entwurf",      "link": "general" },
    { "no": 2,  "label": "Prüfung",      "link": "general" },
    { "no": 3,  "label": "Freigabe",     "link": "general" },
    { "no": 99, "label": "Abgeschlossen","link": "general", "terminal": true }
  ],
  "transitions": {
    "1": { "approve": 2 },
    "2": { "approve": 3, "reject": 1 },
    "3": { "approve": 99, "reject": 2 }
  }
}

Jeder Eintrag unter transitions trägt den Schlüssel der Ausgangsstufe; approve und reject nennen die jeweilige Zielstufe. Fehlt reject, gibt es in dieser Stufe keinen Rücklauf.

optional: true an einer Stufe markiert sie als überspringbar (z. B. eine Vertretungs-Bestätigung, die nicht immer nötig ist).

Beim Bearbeiter sieht eine Stufe mit Rücklauf so aus: oben die Stufen-Leiste, in der Mitte der Verlauf, unten die Entscheidung. Zurückgeben folgt dem reject-Übergang der Stufe, Endgültig ablehnen der Ablehnungs-Stufe (Teil 7).

Workflow-Bereich bei „Genehmigung Vorgesetzter": Verlauf und die drei Entscheidungs-Knöpfe


Teil 3 — Empfänger: Person, feste Adresse, Gruppen-Postfach

Beim Weiterleiten wählt der Bearbeiter, an wen die nächste Stufe geht. Es gibt drei Muster.

3.1 Person auswählen (Picker)

Standard: der Bearbeiter wählt den Empfänger über den Empfänger-Picker (dieselbe Auswahl wie in der Vorlage Empfängerauswahl). Vor-/Nachname, Personal-Nr., Benutzerkennung und E-Mail werden übernommen.

Der Dialog „Empfänger auswählen" mit zwei Treffern

Ein Klick auf die Zeile übernimmt die Person; erst dann wird der Knopf „Versenden" aktiv:

Workflow-Bereich mit gewähltem Empfänger, der Knopf „Versenden" ist aktiv

3.2 Feste Adresse (Sammelpostfach)

Soll eine Stufe immer an dieselbe Adresse gehen (z. B. personalabteilung@…), trägt man an der Stufe eine feste Empfänger-Adresse ein:

{ "no": 4, "label": "Personalabteilung", "link": "general",
  "fixedRecipient": "personalabteilung@kehrmann-consulting.com" }

Der Empfänger-Picker entfällt dann für diese Stufe. Im Verlauf erscheint das Postfach als Empfänger; wer den Schritt tatsächlich bearbeitet hat, wird zusätzlich als „bearbeitet von …" ausgewiesen.

3.3 Gruppen-Postfach (mehrere Personen sehen den Vorgang)

Eine feste Adresse ist ein Postfach — aber wer darf es bearbeiten? Dazu dient das Gruppen-Sammelpostfach: Alle Mitglieder einer Gruppe sehen die im Umlauf befindlichen Vorgänge in einer eigenen Liste und dürfen die Feststufe bearbeiten.

Das konfigurierst du an einer Liste: Neben der Standard-Liste legst du eine zweite Liste „Personalabteilung (im Umlauf)" an und weist sie der Gruppe zu. Zwei Schalter stehen dafür zur Verfügung:

  • includeWorkflowAssigned: true — die persönliche Inbox: „mir gerade zugewiesene" Vorgänge tauchen in dieser Liste auf.
  • workflowGroupInbox: "<Gruppe>" — die Gruppen-Inbox: alle Mitglieder der Gruppe Personalabteilung sehen jeden umlaufenden Vorgang.
Hinter den Kulissen: persönliche Inbox und Gruppen-Inbox (kc:lists)
"kc:lists": [
  { "id": "liste", "title": "Urlaubsanträge",
    "columns": ["antragsteller", "wf_status_label", "wf_status"],
    "default": true, "includeWorkflowAssigned": true },

  { "id": "personalabteilung", "title": "Personalabteilung (im Umlauf)",
    "columns": ["antragsteller", "wf_status_label", "wf_status"],
    "workflowGroupInbox": "Personalabteilung" }
]

Beide Listen zeigen dieselben Spalten — der Unterschied steckt allein im letzten Schlüssel je Eintrag.

3.4 Wer darf weiterleiten? (Autorisierung)

Der „Zustimmen / Ablehnen"-Schritt ist serverseitig abgesichert:

Berechtigungsmatrix: wer darf weiterleiten


Teil 4 — Seitenleiste + Status + Änderungsprotokoll

Zwei Chrome-Bausteine, die jedes Workflow-Formular aufwerten.

4.1 Linke Seitenleiste mit Live-Status

Setzt Seiten (kc:pages) voraus. Statt der Reiter oben bekommt das Formular dann eine Navigation an der linken Seite, die oben den aktuellen Workflow-Status anzeigt — der Bearbeiter sieht auf jeder Seite, wo der Vorgang gerade steht. Breite und Anfangszustand (auf- oder zugeklappt) sind einstellbar.

Hinter den Kulissen: Seitenleiste mit Status (kc:sidebar)
"kc:pageNavStyle": "sidebar",
"kc:sidebar": { "defaultExpanded": true, "showStatus": true, "widthPx": 260 },
"kc:pages": [
  { "id": "antrag",    "title": "Antrag",    "icon": "01" },
  { "id": "bemerkung", "title": "Bemerkung", "icon": "02" }
]

Jedes Feld bekommt "kc:page": "<seiten-id>", um es einer Seite zuzuordnen. kc:pageNavStyle schaltet von Reitern auf die Seitenleiste um; showStatus blendet den Workflow-Status darüber ein.

4.2 Änderungsprotokoll (Audit-Log)

kc:auditLog protokolliert jede gespeicherte Änderung und jeden Workflow-Schritt (Statuswechsel + per Skript gesetzte Werte). Es erscheint als eigene Seite „Änderungsprotokoll". Eingeschaltet ist das ein Schalter:

"kc:auditLog": { "enabled": true }

Optional feiner justierbar:

Option Wirkung
onlyAfterFirstSave: true die Erst-Anlage nicht protokollieren
onlyForeignEditor: true nur protokollieren, wenn NICHT der Ersteller bearbeitet

Teil 5 — Mail-Schablonen (ohne Skript)

Standardmäßig verschickt jeder Stufenwechsel eine schlichte Benachrichtigung mit Datensatz-Link. Über die Property-Mechanik lässt sich pro Statuswechsel Betreff und Text frei gestalten — komplett ohne Skript.

5.1 Welcher Schlüssel wann greift

Eine Property mit einem dieser Schlüssel greift (erster Treffer gewinnt). Wert = Betreff, Zusatzwert (langer Text) = Body.

Auflösungsreihenfolge der Mail-Schablonen

5.2 Beispiel

Für begutachtung-workflow, Übergang Stufe 1 → 2:

  • Schlüssel: begutachtung-workflow.msgText.1.2
  • Wert (Betreff): Sichtung angefordert: ${person_name}
  • Zusatzwert (Body):
    Hallo ${recipient.firstName},
    
    ${sender.firstName} ${sender.lastName} bittet um Sichtung des Vorgangs
    „${person_name}". Bitte öffnen und bearbeiten:
    
    ${url}
    

Angelegt werden Schablonen am bequemsten im Formular-Editor unter … Mehr → Properties … (nur die Einträge dieses Formulars). Alternativ unter System-Administration → Formular-Konfiguration → Properties (alle Formulare, mit Excel-Import) — siehe Properties.

5.3 Mailtexte per Knopfdruck erzeugen

Sie müssen die Schlüssel nicht von Hand zusammensetzen. Ein Knopf legt für jeden Stufenwechsel einen fertigen Mailtext an. Danach passen Sie nur noch die Formulierung an. So geht es:

Schritt 1 — Workflow speichern. Richten Sie die Stufen ein (Teil 1 und 2) und speichern Sie das Formular. Der Knopf arbeitet mit dem gespeicherten Stand.

Schritt 2 — Properties öffnen. Klicken Sie im Formular-Editor oben auf „⋯ Mehr" → „🔧 Properties …". Ein Fenster zeigt die Properties dieses Formulars (Bilder dazu unter Properties → Pflege im Formular-Editor).

Schritt 3 — Knopf drücken. Klicken Sie auf „✉ Workflow-Mailtexte erzeugen". Der Knopf erscheint nur bei Formularen mit eingeschaltetem Workflow. Über der Liste steht danach, was passiert ist, und die neuen Einträge stehen in der Liste.

Der Properties-Dialog nach dem Klick: Meldung „4 Mailtexte angelegt, 1 vorhanden und unverändert", darunter die fünf Einträge msgText.1.2 bis msgText.3.99

Im Bild gab es den Eintrag msgText.1.2 schon vorher, mit einem eigenen Betreff („Bitte um Sichtung …"). Er ist unverändert geblieben; nur die vier fehlenden sind dazugekommen.

Schritt 4 — Text anpassen. Klicken Sie auf eine Zeile. Im Feld Wert steht der Betreff, im Feld Zusatzwert der Mailtext. Ändern Sie, was Sie möchten, und klicken Sie auf Speichern. Die Platzhalter in ${…} füllt KCForms beim Versenden aus, zum Beispiel ${url} mit dem Link zum Vorgang.

Ein erzeugter Eintrag: Schlüssel msgText.2.3, im Wert der Betreff, im Zusatzwert der vollständige Mailtext mit Platzhaltern

Zeilen, die nur bei Bedarf erscheinen: ${comment?}

${comment} ist der Text, den die bearbeitende Person beim Weiterleiten eingibt. Oft schreibt sie nichts. Damit dann kein leeres „Hinweis des Absenders:" in der Mail steht, schreiben die erzeugten Texte ${comment?} — mit Fragezeichen.

Das Fragezeichen bedeutet: Ist der Wert leer, entfällt die ganze Zeile. Ist er gefüllt, steht er wie gewohnt da.

Im Mailtext Mit Kommentar „Bitte bis Freitag" Ohne Kommentar
Hinweis des Absenders: ${comment?} Hinweis des Absenders: Bitte bis Freitag (Zeile fehlt)
Hinweis des Absenders: ${comment} Hinweis des Absenders: Bitte bis Freitag Hinweis des Absenders:

Das Fragezeichen geht an jedem Platzhalter, auch an Feldnamen, zum Beispiel Kostenstelle: ${kostenstelle?}. Ohne Fragezeichen bleibt die Zeile immer stehen — so verschwindet die Anrede nicht, nur weil ein Vorname fehlt.

Schritt 5 — später nachgenerieren. Haben Sie eine Stufe dazugenommen, klicken Sie einfach noch einmal auf den Knopf. Es kommen nur die fehlenden Einträge dazu. Ist schon alles da, sagt die Meldung das, und nichts wird geändert:

Nach einem zweiten Klick: „0 Mailtexte angelegt, 5 vorhanden und unverändert."

Mehrsprachige Formulare bekommen je Sprache eine eigene Fassung: die Basissprache ohne Zusatz, jede weitere mit @sv bzw. @en am Schlüssel (siehe 5.4). Welche Sprachen das sind, bestimmen die Sprachen des Formulars (Reiter „Sprachen") und die eingestellte Sprache der Workflow-Mails. Die schwedische Fassung beginnt mit „Hej", die englische mit „Hello", und Formulartitel sowie Stufennamen stehen in der Übersetzung — soweit Sie sie im Reiter „Sprachen" eingetragen haben. Ein deutsches Formular ohne weitere Sprachen bekommt weiterhin nur deutsche Einträge.

Ein Eintrag entsteht für genau die Wechsel, die eine Mail auslösen:

Wechsel Woher Mail geht an
Weiterleiten „Zustimmung → n" einer Stufe den nächsten Bearbeiter
Abschließen „Zustimmung" auf eine Endstufe den Antragsteller
Zurückgeben „Zurückgabe → n" einer Stufe den Bearbeiter der früheren Stufe
Endgültig ablehnen Ablehnungs-Stufe, an jeder Stufe mit „Zurückgabe" den Antragsteller

Für die Begutachtungs-Demo entstehen so genau die fünf Einträge 1.2, 2.1, 2.3, 3.2 und 3.99.

Drei Dinge, auf die Sie sich verlassen können:

  • Vorhandenes bleibt, wie es ist. Steht ein Eintrag schon da, wird er nicht angefasst. Klicken Sie nach einer neuen Stufe einfach noch einmal — es kommen nur die fehlenden dazu.
  • Eine Kurzform wird nicht ausgehebelt. Gibt es schon <formId>.msgText.<nach> (ohne Von-Stufe), legt der Knopf für diesen Wechsel nichts an. Der längere Schlüssel würde sonst vorgehen und Ihren Text still ersetzen. Die Meldung nennt den betroffenen Eintrag.
  • Es zählt der gespeicherte Stand. Haben Sie gerade Stufen geändert und noch nicht gespeichert, fragt der Editor nach. Speichern Sie im Zweifel zuerst.

Eine global.msgText.*-Schablone gilt weiter für alle anderen Formulare. Für dieses Formular gehen die neuen Einträge vor; die Meldung nennt dann die abgelöste Schablone.

Hinter den Kulissen: ein erzeugter Eintrag

Für die Begutachtungs-Demo, Stufe 1 → 2:

Feld Inhalt
Schlüssel begutachtung-workflow.msgText.1.2
Wert Begutachtung mit Workflow (Demo) – Sichtung zu beurteilende Person
Zusatzwert Guten Tag ${recipient.firstName} ${recipient.lastName}, …
Bemerkung E-Mail-Schablone 1→2 Entwurf → Sichtung zu beurteilende Person (Weiterleitung, erzeugt)

Die Texte benutzen nur Platzhalter, die die Engine auch füllt: ${url}, ${comment}, ${recipient.*}, ${sender.*} und Feldnamen. Der Kommentar steht als ${comment?} darin, die Zeile entfällt also ohne Kommentar. Abschluss- und Ablehnungs-Mails beginnen mit „Guten Tag," ohne Namen — der Antragsteller hat keinen Empfänger-Datensatz, ${recipient.*} wäre leer.

5.4 Mails in einer anderen Sprache

Ein Formular verschickt seine Workflow-Mails in einer festen Sprache. Sie stellen sie in den Formular-Eigenschaften im Workflow-Block ein, unter „Sprache der Workflow-Mails". Ohne Auswahl gilt die Basissprache des Formulars.

Die Einstellung wirkt auf drei Dinge:

  • Den Standardtext, wenn es keine Schablone gibt. Er liegt für Deutsch, Schwedisch und Englisch bei.
  • Den Formulartitel im Betreff. Er kommt aus der Übersetzung des Formulars (Reiter „Sprachen" im Editor). Fehlt sie, steht der Titel in der Basissprache da.
  • Die Schablonen. Eine Schablone in einer anderen Sprache bekommt den Sprachcode mit @ hinten an den Schlüssel:
Schlüssel Sprache
begutachtung-workflow.msgText.1.2 Basissprache des Formulars
begutachtung-workflow.msgText.1.2@sv Schwedisch
begutachtung-workflow.msgText.1.2@en Englisch

Gesucht wird erst die Variante in der Mail-Sprache, dann der Eintrag ohne @. Ein genauerer Schlüssel geht dabei immer vor: Gibt es für das Formular nur die deutsche Fassung …msgText.1.2, wird sie genommen — auch wenn es eine schwedische global.msgText.2@sv gäbe. So kann eine globale Übersetzung nie still den Text eines einzelnen Formulars verdrängen.

Die Namen der Stufen übersetzen Sie im Editor im Reiter „Sprachen". Dort steht jede Stufe als eigene Zeile „Workflow-Stufe · 2". Die Übersetzung gilt überall: in der Mail („Steg: Granskning"), in der Workflow-Leiste unter dem Formular und in den Knöpfen („✓ Godkänn → Granskning"). Fehlt sie, steht der Name in der Basissprache da.

Eingegebene Daten wie ${person_name} bleiben, wie sie sind — sie werden nie übersetzt.

Stufennamen im Verlauf

In einer anderen Sprache als der Basissprache zeigt die Tabelle „Verlauf" die Stufennamen in dieser Sprache — so wie die Stufenleiste darüber.

In der Basissprache steht dagegen der Name, der beim Weiterleiten gespeichert wurde. Benennen Sie eine Stufe später um, bleibt der Verlauf dort, wie er war: Er ist ein Protokoll.

5.5 Die Workflow-Leiste in der Sprache des Formulars

Die Leiste unter dem Formular — Stufen, Knöpfe, Verlauf, Empfängerauswahl, Bestätigungen und Fehlermeldungen — spricht dieselbe Sprache wie das Formular darüber. Schaltet jemand das Formular oben auf Svenska um, wechselt auch die Leiste. Das gilt auch für die Meldungen des Servers, etwa „Vidarebefordrat till steg 2 (Granskning)." oder den Hinweis, dass ein Skript den Wechsel verhindert hat. Den Grund, den Ihr Skript dabei nennt (ctx.cancel("…")), zeigt KCForms unverändert — schreiben Sie ihn bei Bedarf selbst mehrsprachig, etwa mit ctx.lang.

Die Sprache der Mail richtet sich noch nicht nach dem Empfänger. Ein Team, in dem Deutsch und Schwedisch gemischt gelesen wird, wählt am besten die Sprache, die alle verstehen.


Teil 6 — Rechnen und Eingreifen per Skript

Für alles jenseits der zusammengeklickten Verzweigung stehen Skripte bereit: Werte setzen, ein Fremdsystem benachrichtigen, den Vorgang für ein DMS exportieren, eine zusätzliche Mail verschicken — oder einen Schritt verhindern.

Hinweis Log: Meldungen aus log.info(...) landen NICHT auf der Docker- Konsole, sondern in /app/logs/script.log (+ by-user/<user>.log) und werden automatisch mit [form:<id>] präfixt — so findet man sie im Betrieb wieder.

6.1 Skripte am Stufenwechsel

Ein Workflow-Skript hängt an dem Ort, an dem es wirkt. Angelegt wird es deshalb nicht in der Skriptliste, sondern direkt im Workflow-Block: Formular-Eigenschaften → Workflow, Zeile Skripte an der jeweiligen Stufe. Ein Klick öffnet den Editor mit einer passenden Vorlage; ein gefüllter Punkt (●) am Knopf zeigt, dass dort schon ein Skript liegt.

Knopf Läuft Typischer Einsatz
Beim Erreichen (an der Stufe) sobald der Vorgang die Stufe erreicht, egal woher Export bei „Abgeschlossen", Mitteilung bei „Abgelehnt"
Prüfung (am Übergang) vor dem Wechsel — kann ihn verhindern Pflichtangaben je Schritt, Rückfrage an ein Fremdsystem
Aktion (am Übergang) nach dem Wechsel Meldung an ein Fremdsystem nur bei Zustimmung
Bei jedem Wechsel (unter den Stufen) bei jedem Stufenwechsel Zeitstempel, Verlauf fortschreiben

Eine Stufe im Workflow-Block mit der Zeile „Skripte"

Im Editor steht über dem Code „Baustein einfügen". Die Bausteine sind lauffähiger Code für die üblichen Aufgaben — Werte setzen, Meldung an ein Fremdsystem (REST), Export fürs DMS, zusätzliche E-Mail, Standard-Mail anpassen, Wechsel verhindern. Anzupassen sind nur die Stellen, die im Baustein mit ANPASSEN markiert sind.

Der Skript-Editor mit Vorlage und dem Menü „Baustein einfügen"

Fertig eingebaut: die Demo „Bestellfreigabe“

Das Demo-Formular Bestellfreigabe mit Workflow (Skript-Demo) trägt an jeder Stufe Skripte — öffne es im Formular-Editor und sieh unter Formulareigenschaften → Workflow nach, wo ein Punkt (●) steht:

Stelle Skript Was es tut
Stufe 1, Zustimmung Prüfung verlangt Bezeichnung und Betrag
Stufe 1, Zustimmung Aktion merkt sich, wer eingereicht hat
Stufe 2, Zustimmung Prüfung verlangt die Kostenstelle
Stufe 2, Zustimmung Aktion gibt der Benachrichtigung einen eigenen Betreff
Stufe 2, Zurückgabe Prüfung verlangt einen Kommentar
Stufe 3, Zustimmung Prüfung Vier-Augen-Prinzip ab 1.000 € brutto
Stufe 99 Beim Erreichen legt die Bestellung als PDF ab; meldet sie optional an ein anderes Programm
Bei jedem Wechsel Aktion rechnet Brutto, zählt Schritte, schreibt den Verlauf fort

Zum Ausprobieren: Mit einem Netto-Betrag unter 840 € kommst du allein bis zum Abschluss. Darüber greift an Stufe 3 das Vier-Augen-Prinzip — dann muss eine andere Person freigeben.

27 Beispiele zum Kopieren

Die Seite Workflow: Skripte am Stufenwechsel erklärt dasselbe Schritt für Schritt in einfachen Worten — von „Feld setzen" bis „Buchhaltung benachrichtigen und PDF ins Archiv legen". Jedes Beispiel dort wird automatisch gegen ein echtes KCForms ausgeführt.

Adressen gehören in die Properties

Die Bausteine lesen Ziel-Adressen aus ctx.params (zum Beispiel ctx.params.sapUrl). Lege den Wert unter Administration → Properties an (<formular-id>.sapUrl). So zeigt das Testsystem auf das Test-SAP und die Produktion auf das echte, ohne dass jemand das Skript anfasst.

Vorher: eine Prüfung kann den Wechsel verhindern

Die Prüfung läuft, bevor etwas geschrieben wird. ctx.cancel('Grund') lässt den Vorgang auf der alten Stufe; der Bearbeiter liest den Grund im Workflow-Bereich.

// Prüfung vor „3 · Genehmigung" → „4 · Personalabteilung"
if (wf.approve && !$begruendung) {
  ctx.cancel('Bitte zuerst eine Begründung eintragen.');
  return;
}

ctx.form zeigt in der Prüfung, was der Bearbeiter gerade im Formular stehen hat. Änderungen an ctx.form werden hier nicht gespeichert — eine Prüfung prüft nur.

Nachher: Aktionen

Aktionen laufen nach dem Statuswechsel und vor der Benachrichtigung. Was das Skript in ctx.form setzt, wird gespeichert und steht schon in der Mail-Schablone bereit.

// Aktion nach „3 · Genehmigung" → „4 · Personalabteilung"
// 1. Fremdsystem melden — steht vorn, weil es scheitern kann
var sap = http.post(ctx.params.sapUrl, {
  vorgang: ctx.instanceId,
  status:  wf.toStage,
  von:     wf.actingLogin
}, { timeout: 15000, retries: 2 });
if (!sap.ok) {
  throw new Error('Fremdsystem meldet HTTP ' + sap.status);
}

// 2. Werte setzen — werden automatisch gespeichert
ctx.form.sap_belegnr        = sap.json().belegnummer;
ctx.form.letzter_bearbeiter = ctx.user.name || wf.actingLogin;

Scheitert eine Aktion, wird der Wechsel zurückgenommen

Wirft ein Aktions-Skript einen Fehler (oder ruft es ctx.cancel(...)), steht der Vorgang danach wieder auf der alten Stufe — Status, Verlauf und Feldwerte wie vor dem Klick. Der Bearbeiter sieht die Meldung und kann es erneut versuchen.

Was sich nicht zurückholen lässt, ist alles außerhalb des Vorgangs: eine bereits verschickte Mail, eine geschriebene Datei, ein Aufruf, der im Fremdsystem schon gebucht hat. Deshalb die Reihenfolge im Skript: erst, was scheitern kann — zuletzt, was sich nicht zurückholen lässt.

Soll eine Aktion den Vorgang nicht aufhalten (eine Zusatz-Mail etwa), fängst du ihren Fehler selbst ab:

try {
  mail.send({ to: ctx.params.mailExtern, subject: 'Info', body: wf.toLabel });
} catch (e) {
  log.warn('Zusatz-Mail nicht verschickt: ' + e.message);
}

Reihenfolge

Bei einem Wechsel von Stufe A nach B laufen die Skripte in dieser Reihenfolge — erst allgemein, dann speziell:

  1. Prüfung „bei jedem Wechsel", dann Prüfung am Übergang A → B
  2. der Statuswechsel
  3. Aktion „bei jedem Wechsel", dann Aktion am Übergang A → B, dann „Beim Erreichen" von B
  4. die Benachrichtigung

Das wf-Objekt

Feld Inhalt
fromStage / toStage Nummer der alten und der neuen Stufe
fromLabel / toLabel deren Bezeichnung
action "approve" (Zustimmen), "return" (Zurückgeben) oder "decline" (endgültig ablehnen)
approve / returned / declined dasselbe als true/false
terminal true, wenn die neue Stufe eine Endstufe ist
comment Kommentar des Bearbeiters
recipient.email / .login / .firstName / .lastName Empfänger der neuen Stufe
initiatorEmail Adresse des Antragstellers
actingLogin, now wer entschieden hat und wann
url Link zum Vorgang für den Empfänger (nur in Aktionen)
mail.skip auf true setzen: die Standard-Benachrichtigung dieses Wechsels entfällt
mail.subject / mail.text setzen: ersetzt Betreff bzw. Text der Standard-Benachrichtigung

wf.decision ("approve"/"reject") gibt es weiterhin; es unterscheidet aber nicht zwischen Zurückgeben und endgültigem Ablehnen — dafür ist wf.action da.

In allen Workflow-Skripten stehen dieselben Bausteine bereit wie in jedem anderen Hook: mail, http, fs, pdf, db, log, ctx.params, ctx.attachments, die Bibliotheken und die Hilfsfunktionen des Formulars.

Hinter den Kulissen: wie die Skripte heißen

Die Zuordnung steckt im Namen des Skripts — in der Skriptliste steht darunter jeweils der Klartext mit den Stufennamen.

Name Bedeutung
onWorkflowCheck Prüfung vor jedem Wechsel
onWorkflowCheck_3_4 Prüfung vor dem Wechsel 3 → 4
onWorkflowStep Aktion nach jedem Wechsel
onWorkflowStep_3_4 Aktion nach dem Wechsel 3 → 4
onWorkflowEnter_99 Aktion beim Erreichen der Stufe 99

Ändert jemand die Nummer einer Stufe oder das Ziel eines Übergangs, bleibt das Skript unter seinem alten Namen in der Skriptliste stehen und läuft nicht mehr mit. Es wird nicht still gelöscht: benenne es um oder übernimm den Code in das Skript des neuen Übergangs.

6.2 onCopy — die Kopie vorbereiten

Läuft beim „Als neuen Satz kopieren". Der zurückgegebene ctx.form wird der neue Entwurf — ideal, um Unterschriften zu löschen, Vorgabewerte zurückzusetzen oder den Workflow-Status zu leeren.

// onCopy – frischer Entwurf statt Erbe des abgeschlossenen Originals
ctx.form.wf_status = null;          // Workflow zurück auf Anfang
ctx.form.wf_status_label = null;
ctx.form.unterschrift = null;       // Signatur-Feld leeren
ctx.form.bemerkung = "";            // Vorgabewert zurücksetzen
// ctx.isNew === true, copy.sourceInstanceId === ID des Quell-Satzes

6.3 Weitere Hooks im Workflow-Kontext

Die allgemeinen Lebenszyklus-Hooks greifen auch bei Workflow-Formularen:

Hook Typischer Workflow-Einsatz
onLoad Vorbelegen (Antragsteller = angemeldeter Nutzer, Datum = heute).
onValidate Pflichtfelder/Plausibilität prüfen — ctx.addError(feld, meldung).
onBeforeSave Vetoable: ctx.cancel(grund) verhindert das Speichern.
onSubmit Nach dem Speichern: eigene Mail/WebService-Aufrufe (mail, http, ws).
onAfterSave Abschluss der Save-Pipeline; ctx.isNew unterscheidet Neuanlage/Update.
canEdit Versionierung: entscheidet, ob ein geladener Satz bearbeitbar ist.

Details: Lebenszyklus-Hooks.


Teil 7 — Abschluss-Sperre & Kopieren

7.1 Abgeschlossene Vorgänge sperren

Erreicht ein Vorgang die Endstufe (terminal: true), ist er standardmäßig schreibgeschützt — serverseitig durchgesetzt. Diese Sperre kannst du ganz abschalten oder für einzelne Gruppen lockern:

  • lockAfterTerminal: false — Sperre ganz aus.
  • editAfterTerminalRoles: [...] — benannte Gruppen/Berechtigungen, die auch danach noch bearbeiten dürfen (Admin darf immer).

Im Formular-Editor stehen beide Einstellungen unter den Stufen — zusammen mit der Position des Workflow-Bereichs und der Stufe für „Endgültig ablehnen":

Einstellungen unter den Stufen: Sperre nach Abschluss, Position, Stufe für „Endgültig ablehnen"

Hinter den Kulissen: Sperre lockern (lockAfterTerminal)
"kc:workflow": {
  "…": "…",
  "lockAfterTerminal": true,
  "editAfterTerminalRoles": ["Buchhaltung"]
}

Beide Schlüssel stehen direkt in kc:workflow, neben stages und transitions — die Zeile "…": "…" steht hier nur für den übrigen Inhalt.

Ein gesperrter Vorgang zeigt einen Hinweis samt Button „Als neuen Satz kopieren".

7.2 Kopieren

„Als neuen Satz kopieren" übernimmt die Werte des (ggf. schreibgeschützten) Vorgangs in einen neuen Entwurf der aktuellen Formularversion. Mit dem onCopy-Hook (Teil 6.2) bereitet man diesen Entwurf gezielt vor — im urlaub-workflow-Demo wird so der Status auf „Entwurf" zurückgesetzt, während der Antragsteller erhalten bleibt.


Kurz-Referenz

kc:workflow-Schlüssel

Schlüssel Bedeutung
enabled Workflow an/aus
statusField Status-Zahlenfeld (Standard wf_status)
stages[].no / label Stufennummer + Bezeichnung
stages[].link general (Vertreter ok) / personal (nur Empfänger 🔒)
stages[].terminal Endstufe
stages[].fixedRecipient feste Empfänger-Adresse (Postfach-Stufe)
stages[].optional überspringbare Stufe
transitions.<no>.approve/reject Zielstufen der Verzweigung
lockAfterTerminal Abschluss-Sperre (Default true)
editAfterTerminalRoles[] Ausnahme-Gruppen/-Berechtigungen

Verwandte Schlüssel

Schlüssel Zweck
kc:lists[].includeWorkflowAssigned persönliche Inbox in einer Liste
kc:lists[].workflowGroupInbox Gruppen-Sammelpostfach
kc:sidebar.showStatus + kc:pageNavStyle:"sidebar" Seitenleiste mit Status
kc:auditLog.enabled Änderungsprotokoll
<formId>.msgText.[<von>.]<ziel> (Property) Mail-Schablone

Skript-Hooks

onWorkflowCheck / onWorkflowStep / onWorkflowEnter (Stufenwechsel, wf-Objekt — Teil 6) · onCopy (copy.sourceInstanceId) · onLoad · onValidate · onBeforeSave · onSubmit · onAfterSave · canEdit