Zum Inhalt

Beispiel zum Nachbauen: Jobticket-Antrag

In diesem Kapitel bauen wir gemeinsam einen Antrag auf ein Jobticket — so, wie ihn viele Städte, Gemeinden und Behörden für ihre Beschäftigten haben. Der Antrag wandert dabei von Person zu Person:

  1. Eine Beschäftigte stellt den Antrag und unterschreibt.
  2. Die Personalstelle prüft, ob ein Anspruch besteht, und legt den Zuschuss fest.
  3. Die Bezügestelle bestellt das Ticket und trägt ein, ab wann der Eigenanteil vom Gehalt einbehalten wird.

Am Ende hast du ein Formular mit drei Seiten, einem Feld, das selbst rechnet, einer Unterschrift und einem Workflow mit fünf Stufen.

Die Seite „Antrag" des fertigen Formulars: Angaben zur Person, das Ticket und der ausgerechnete Eigenanteil

Zusammenklicken reicht — bis auf Schritt 7

Das Formular, die Felder und der Workflow entstehen in den Schritten 1 bis 6 ohne eine Zeile Programmcode. Erst in Schritt 7 kommen kurze Skripte dazu. Sie prüfen Dinge, die sich nicht anklicken lassen — zum Beispiel, ob das Ticket an einem Monatsersten beginnt. Du kannst sie kopieren. Nach Schritt 6 läuft der Antrag schon; Schritt 7 macht ihn nur strenger.

Erst ansehen, dann bauen

Das fertige Formular gibt es als Demo. Du installierst es unter System-Administration → Formular-Bausteine → Beispiele („Jobticket-Antrag (Workflow-Demo)"). Danach steht es im Katalog Demo, Ordner Workflow. Dort kannst du bei jedem Schritt nachsehen, wie es aussehen soll.

Du hast noch nie ein Formular gebaut? Dann lies zuerst Wir bauen ein einfaches Formular. Das dauert eine Viertelstunde, und danach kennst du alle Handgriffe, die hier vorkommen.

So läuft ein Jobticket-Antrag in der Praxis

Das Verfahren ist nicht überall gleich. Der Kern ist aber fast immer derselbe:

Wer Was passiert
Beschäftigte füllen den Antrag aus: Wer bin ich, ab wann will ich das Ticket. Sie stimmen zu, dass ihr Anteil vom Gehalt einbehalten wird.
Personalstelle prüft das Beschäftigungsverhältnis (besteht es? ist es befristet?) und bestätigt den Zuschuss des Arbeitgebers.
Bezügestelle bestellt das Ticket beim Verkehrsunternehmen und richtet den monatlichen Einbehalt ein.

Die Zahlen im Beispiel (Stand 2026): Das Ticket kostet 63,00 € im Monat. Gibt der Arbeitgeber mindestens ein Viertel dazu (15,75 €), gewährt der Verkehrsverbund 5 % Rabatt (3,15 €). Die Beschäftigten zahlen dann 63,00 − 3,15 − 15,75 = 44,10 €.

Die Zahlen sind ein Beispiel

Preis, Rabatt und Zuschuss ändern sich und sind bei jedem Arbeitgeber anders geregelt. Trage für ein echtes Formular die Werte ein, die bei euch gelten — die Personalstelle kennt sie.

Was am Ende dasteht

Drei Seiten:

Seite Wer füllt sie aus Inhalt
Antrag Beschäftigte Angaben zur Person, Beginn, Preis und Eigenanteil
Einwilligung Beschäftigte zwei Zustimmungen und die Unterschrift
Bearbeitung Personalstelle, Bezügestelle Prüfvermerk, Abo-Nummer, Verlauf

Fünf Stufen:

Nr. Stufe Was passiert dort
1 Antrag Die Beschäftigte füllt aus und unterschreibt.
2 Personalstelle prüft und leitet weiter. Sie kann zurückgeben (zurück zu 1) oder endgültig ablehnen (98).
3 Bezügestelle bestellt und schließt ab. Sie kann zurückgeben (zurück zu 2).
98 Abgelehnt Endstufe: Der Antrag ist abgelehnt.
99 Abgeschlossen Endstufe: Das Ticket ist bestellt.

Schritt 1: Das Formular anlegen

Öffne Administration → Formular-Editor und klicke auf + Neu. Es öffnet sich der Formular-Assistent.

Trage ein:

Feld Wert
Titel Jobticket-Antrag
ID jobticket_antrag — der Assistent schlägt sie vor, lass sie stehen
Katalog Tutorial
Spalten 2 — zweispaltig
Seiten 3, und darunter die Namen Antrag, Einwilligung, Bearbeitung

Klappe Mehr Einstellungen auf und setze den Haken bei Seiten als Seitenleiste. Dann stehen die drei Seiten später links neben dem Formular.

Der Formular-Assistent mit den Angaben aus diesem Schritt

Klicke auf Formular anlegen.

Heißt bei dir schon ein Formular so?

Hast du die Demo installiert, gibt es die ID jobticket-antrag schon. Dein eigenes Formular bekommt mit dem Unterstrich eine andere ID (jobticket_antrag) — beide vertragen sich.

Schritt 2: Die Seite „Antrag"

Über der Vorschau stehen drei kleine Marken: 01, 02 und 03. Das sind deine Seiten. Ein neues Feld landet immer auf der Seite, deren Marke gerade dunkel ist. Achte darauf, dass 01 gewählt ist.

Lege nun in der Spalte FELDER mit + Neu diese Felder an — in dieser Reihenfolge. Den Titel tippst du, die Feld-ID überschreibst du mit dem kurzen Namen aus der Tabelle.

Titel Feld-ID Typ
Wer beantragt? sec_person section (Trenn-Überschrift)
Was möchten Sie? art string
Personalnummer personalnummer string
Vorname vorname string
Nachname nachname string
Amt / Dienststelle dienststelle string
E-Mail für Rückfragen email string
Beschäftigungsverhältnis beschaeftigung string
Befristet bis befristet_bis date (Datum)
Das Ticket sec_ticket section (Trenn-Überschrift)
Gewünschter Beginn (immer der 1. eines Monats) beginn date (Datum)
Preis des Tickets pro Monat ticketpreis number
Rabatt des Verkehrsverbunds (5 %) rabatt number
Zuschuss des Arbeitgebers zuschuss number
Ihr Eigenanteil pro Monat eigenanteil number

Jetzt bekommen einige Felder ihre Besonderheiten. Du öffnest ein Feld jeweils mit einem Doppelklick in der Felder-Spalte; es erscheint der Feld-Dialog mit seinen Reitern.

2a) Eine Auswahlliste statt freiem Text

Öffne art und wechsle in den Reiter Auswahl. Wähle Feste Werteliste und trage mit + Eintrag drei Werte ein: Neubestellung, Änderung, Kündigung.

Reiter „Auswahl": feste Werteliste mit drei Einträgen

Setze darunter den Haken Nur Werte aus Liste. Ohne ihn ist die Liste nur ein Vorschlag, und man kann auch etwas anderes eintippen.

Mach dasselbe bei beschaeftigung mit den Werten unbefristet, befristet, Ausbildung, ebenfalls mit Nur Werte aus Liste.

2b) Pflichtfelder

Ohne Namen und Personalnummer kann niemand den Antrag bearbeiten. Öffne nacheinander art, personalnummer, vorname, nachname und beginn. Stelle im Reiter Sichtbarkeit jeweils Pflichtfeld auf ein.

2c) Ein Feld nur zeigen, wenn es gebraucht wird

„Befristet bis" ist nur sinnvoll, wenn der Vertrag befristet ist. Öffne befristet_bis, Reiter Sichtbarkeit. Stelle Sichtbarkeit auf bedingt und trage darunter ein:

beschaeftigung === 'befristet'

Reiter „Sichtbarkeit": das Feld erscheint nur bei einem befristeten Vertrag

Das liest sich so: Zeige das Feld, wenn im Feld beschaeftigung der Wert befristet steht. Die drei Gleichheitszeichen bedeuten „ist genau gleich".

Etwas weiter unten im selben Reiter steht Im PDF erscheinen. Stelle auch das auf bedingt und trage dieselbe Bedingung ein. Bildschirm und Ausdruck sind zwei getrennte Einstellungen — ohne diesen Schritt stünde auf dem Ausdruck ein leeres Feld „Befristet bis".

2d) Geldbeträge mit Vorgabe

Die drei Beträge sollen schon ausgefüllt sein, wenn jemand den Antrag öffnet. Öffne ticketpreis:

  • Reiter Format: bei Suffix € eintragen (mit Leerzeichen davor).
  • Reiter Erweitert, Bereich Elementeigenschaften: bei Vorbelegung den Wert 63 eintragen und Nachkommastellen auf 2 setzen.
  • Reiter Sichtbarkeit: Schreibgeschützt auf ein — den Preis soll niemand im Antrag ändern.

Reiter „Erweitert": Vorbelegung mit dem Wert 63

Bei den anderen Beträgen gehst du genauso vor:

Feld Suffix Vorbelegung Nachkommastellen Schreibgeschützt
ticketpreis € 63 2 ein
rabatt € 3.15 2 ein
zuschuss € 15.75 2 kommt in Schritt 4
eigenanteil € — 2 rechnet selbst, siehe unten

Punkt statt Komma

In die Vorbelegung tippst du die Zahl mit Punkt: 3.15. Im Formular steht sie später trotzdem als 3,15 €.

2e) Ein Feld, das selbst rechnet

Der Eigenanteil ist Preis minus Rabatt minus Zuschuss. Das rechnet KCForms selbst. Öffne eigenanteil und wechsle in den Reiter Berechnung:

Einstellung Wert
Art der Berechnung Rechnung aus Feldern (+ − × ÷)
Rechenart Differenz (a − b − …)
Operanden Preis des Tickets pro Monat, Rabatt des Verkehrsverbunds (5 %), Zuschuss des Arbeitgebers — in dieser Reihenfolge
Nachkommastellen 2

Reiter „Berechnung": Differenz aus drei Feldern

Die Reihenfolge zählt: Vom ersten Feld werden alle weiteren abgezogen.

In der Vorschau steht jetzt unter „Ihr Eigenanteil pro Monat" der Betrag 44,10 €. Mehr dazu: Berechnungsfelder.

Die Vorschau der fertigen Seite „Antrag"

Schritt 3: Die Seite „Einwilligung"

Klicke über der Vorschau auf die Marke 02. Lege diese Felder an:

Titel Feld-ID Typ
Einwilligung sec_einwilligung section (Trenn-Überschrift)
(leer lassen) hinweis_einbehalt Leittext (kc:text)
Ich bin einverstanden, dass mein Eigenanteil monatlich von meinen Bezügen einbehalten wird. einbehalt_ok boolean
Ich bin einverstanden, dass meine Angaben an das Verkehrsunternehmen weitergegeben werden. datenschutz_ok boolean

In den Leittext hinweis_einbehalt trägst du den Erklärtext ein, zum Beispiel:

Ihr Eigenanteil wird jeden Monat von Ihren Bezügen einbehalten. Das Ticket läuft, bis Sie es kündigen. Endet Ihr Beschäftigungsverhältnis, endet auch das Jobticket.

Stelle bei den drei Feldern unter der Überschrift im Reiter Allgemein die Spaltenbreite auf volle Breite — die langen Sätze brauchen den Platz.

3a) Ein Haken, der gesetzt sein muss

Ein gewöhnliches Ankreuzfeld darf leer bleiben. Bei einer Einwilligung soll das nicht gehen. Öffne einbehalt_ok, Reiter Sichtbarkeit, und setze den Haken bei Zustimmung erzwingen. Dasselbe bei datenschutz_ok.

Reiter „Sichtbarkeit": Zustimmung erzwingen

Jetzt lässt sich der Antrag ohne beide Haken nicht speichern.

3b) Die Unterschrift

Die Unterschrift kommt aus dem Baukasten: Klicke rechts auf den Reiter Baukasten und mach einen Doppelklick auf Unterschriftsfeld. Im kleinen Dialog trägst du den Titel Unterschrift ein; als Feld-ID lässt du unterschrift stehen.

Öffne das neue Feld. Im Reiter Allgemein stellst du ein:

  • Geschützte Felder — setze die Haken bei allen Angaben der Antragstellerin: art, personalnummer, vorname, nachname, dienststelle, beschaeftigung, befristet_bis, beginn, einbehalt_ok, datenschutz_ok. Diese Felder sind nach der Unterschrift gesperrt.
  • Button-Beschriftung — ✍ Antrag unterschreiben.
  • Bestätigungstext — zum Beispiel: Mit der Unterschrift bestätige ich, dass meine Angaben stimmen. Danach sind die Angaben im Antrag gesperrt.

Der Dialog des Unterschriftsfelds: geschützte Felder, Beschriftung und Bestätigungstext

Die Unterschrift ist hier ein Klick mit Namen und Uhrzeit — KCForms hält fest, wer wann unterschrieben hat. Soll jemand wirklich mit Maus oder Finger zeichnen, setzt du den Haken Handschriftliche Unterschrift (Bild). Mehr dazu: Unterschriften.

Schritt 4: Die Seite „Bearbeitung"

Klicke auf die Marke 03 und lege an:

Titel Feld-ID Typ Spaltenbreite
Personalstelle sec_personal section (Trenn-Überschrift)
Anspruch geprüft: Das Beschäftigungsverhältnis besteht. anspruch_geprueft boolean volle Breite
Bemerkung der Personalstelle bemerkung_personal string volle Breite
Bezügestelle sec_bezuege section (Trenn-Überschrift)
Einbehalt ab einbehalt_ab date (Datum)
Abo-Nummer des Verkehrsunternehmens abo_nummer string
Verlauf sec_verlauf section (Trenn-Überschrift)
Abgeschlossen am abgeschlossen_am string
Was bisher geschah verlauf string volle Breite

Die letzten beiden Felder füllt später ein Skript. Stelle bei beiden im Reiter Sichtbarkeit den Schalter Schreibgeschützt auf ein. Bei verlauf wählst du zusätzlich im Reiter Format unter Darstellung mehrzeilig.

4a) Zwei unsichtbare Felder für den Workflow

Der Workflow muss sich merken, auf welcher Stufe der Antrag steht. Dafür braucht er zwei Felder. Lege sie auf einer beliebigen Seite an:

Titel Feld-ID Typ
Workflow-Status (technisch) wf_status number
Status wf_status_label string

Stelle bei beiden im Reiter Sichtbarkeit die Sichtbarkeit auf aus. Bei wf_status stellst du zusätzlich Im PDF erscheinen auf aus — die nackte Stufennummer hat auf dem Ausdruck nichts verloren. wf_status_label darf gedruckt werden: Dann steht auf dem Papier, wie weit der Antrag ist. In wf_status steht später die Nummer der Stufe (1, 2, 3, 98 oder 99), in wf_status_label ihr Name.

4b) Jede Stelle darf nur ihre eigenen Felder ändern

Die Personalstelle soll nur schreiben können, solange der Antrag bei ihr liegt — also auf Stufe 2. Öffne anspruch_geprueft, Reiter Sichtbarkeit. Stelle Schreibgeschützt auf bedingt und trage ein:

Number(wf_status) !== 2

Reiter „Sichtbarkeit": schreibgeschützt, solange der Antrag nicht auf Stufe 2 steht

Das liest sich so: Sperre das Feld, wenn die Stufe nicht 2 ist. Das Zeichen !== bedeutet „ist ungleich".

Trage dieselbe Bedingung bei diesen Feldern ein:

Feld Schreibgeschützt, wenn … Wer darf also schreiben
zuschuss (Seite 1) Number(wf_status) !== 2 Personalstelle
anspruch_geprueft Number(wf_status) !== 2 Personalstelle
bemerkung_personal Number(wf_status) !== 2 Personalstelle
einbehalt_ab Number(wf_status) !== 3 Bezügestelle
abo_nummer Number(wf_status) !== 3 Bezügestelle

Die Angaben der Antragstellerin brauchst du nicht einzeln zu sperren — das erledigt die Unterschrift aus Schritt 3.

Schritt 5: Den Workflow einrichten

Klicke über der Vorschau auf Formulareigenschaften bearbeiten und klappe den Abschnitt Workflow (mehrstufige Freigabe) auf.

  1. Setze den Haken Workflow aktiv.
  2. Lege mit + Stufe fünf Stufen an und trage Nr. und Bezeichnung ein.
  3. Wähle bei den ersten drei Stufen, wohin es weitergeht:
Nr. Bezeichnung Bei Zustimmung → Bei Zurückgabe → Endstufe
1 Antrag 2 · Personalstelle — (keine)
2 Personalstelle 3 · Bezügestelle 1 · Antrag
3 Bezügestelle 99 · Abgeschlossen 2 · Personalstelle
98 Abgelehnt ☑
99 Abgeschlossen ☑

Der Workflow-Block: die drei Arbeitsstufen mit ihren Zielen

Darunter stellst du noch drei Dinge ein:

  • Statusfeld — wf_status (das Feld aus Schritt 4a).
  • Abgeschlossene Vorgänge sperren — Haken setzen. Ein bestelltes Ticket soll niemand mehr ändern.
  • Stufe für „Endgültig ablehnen" — 98 · Abgelehnt. Damit bekommt die Bearbeitung neben „Zurückgeben" auch den Knopf „Endgültig ablehnen".

Die beiden Endstufen und die Einstellungen darunter

Das Feld Feste Empfänger-Adresse bleibt leer. Dann wählt beim Versenden jeweils ein Mensch aus, an wen der Antrag geht. Wie du stattdessen ein festes Postfach oder eine Gruppe einträgst, steht im Workflow-Workshop, Teil 3.

Schritt 6: Speichern und zum ersten Mal ausprobieren

Schließe den Dialog und klicke oben rechts auf Speichern. KCForms legt jetzt die Tabelle für die Anträge an.

Klicke auf Im Formular öffnen und fülle einen Antrag aus. Unter dem Formular erscheint der Bereich Workflow — er zeigt die fünf Stufen und den Knopf zum Versenden. Der Antrag läuft jetzt schon von Stufe zu Stufe.

Was noch fehlt: Niemand prüft, ob der Beginn wirklich ein Monatserster ist, ob unterschrieben wurde oder ob die Abo-Nummer eingetragen ist. Das kommt jetzt.

Schritt 7: Prüfungen und Aktionen

Ein Skript ist eine kurze Anleitung, die KCForms Zeile für Zeile ausführt. Im Workflow gibt es zwei Sorten:

Sorte Wann sie läuft Wofür
Prüfung bevor der Antrag die Stufe wechselt etwas verlangen: „Ohne Unterschrift geht es nicht weiter."
Aktion nachdem er gewechselt hat etwas erledigen: ein Feld füllen, einen Text für die Mail schreiben

Du legst sie dort an, wo sie wirken: Öffne wieder Formulareigenschaften bearbeiten → Workflow. Unter jeder Stufe steht eine Zeile Skripte mit kleinen Knöpfen. Ein Klick auf einen Knopf öffnet den Editor. Dort löschst du die Vorlage, fügst das Skript von dieser Seite ein und klickst auf Speichern.

Der Skript-Editor mit der Prüfung an Stufe 1; links alle Skripte des Formulars

Achte auf die Anführungszeichen

Ein Text steht im Skript zwischen zwei geraden Anführungszeichen: "so". Schreibst du in diesem Text ein deutsches Anführungszeichen unten und schließt es mit einem geraden oben — „Einwilligung" —, dann hält KCForms das gerade Zeichen für das Ende des Textes. Das Skript bricht mit der Meldung Missing close quote ab. Lass die Anführungszeichen im Text einfach weg, oder nimm einfache: 'Einwilligung'.

7a) Stufe 1: Der Antrag muss vollständig sein

Knopf: Stufe 1, hinter „Zustimmung → 2:" auf + Prüfung.

// 1) Ein Jobticket beginnt immer am 1. eines Monats.
//    Ein Datum steht im Skript als Text: Jahr-Monat-Tag, zum Beispiel 2027-03-01.
//    Die Zeichen 9 und 10 sind der Tag.
if (String($beginn).substring(8, 10) !== "01") {
  ctx.cancel("Ein Jobticket beginnt immer am 1. eines Monats. Bitte wählen Sie einen Monatsersten.");
  return;
}

// 2) Bei einem befristeten Vertrag muss das Ende nach dem Beginn liegen.
//    Zwei Daten in dieser Schreibweise lassen sich wie Text vergleichen.
if ($beschaeftigung === "befristet") {
  if ($befristet_bis.isEmpty) {
    ctx.cancel("Bitte tragen Sie ein, bis wann Ihr Vertrag läuft.");
    return;
  }
  if (String($befristet_bis) <= String($beginn)) {
    ctx.cancel("Ihr Vertrag endet vor dem Beginn des Tickets. Ein Jobticket ist dann nicht möglich.");
    return;
  }
}

// 3) Ohne Unterschrift geht der Antrag nicht weiter.
//    (Die Pflichtfelder und die beiden Haken prüft KCForms schon beim Speichern.)
if ($unterschrift.isEmpty) {
  ctx.cancel("Bitte unterschreiben Sie den Antrag auf der Seite Einwilligung.");
  return;
}

Was hier steht, in einfachen Worten:

  • $beginn ist der Wert des Feldes mit der Feld-ID beginn. Vor jede Feld-ID setzt du ein Dollarzeichen.
  • ctx.cancel("…") hält den Antrag an. Der Text in der Klammer erscheint rot unter dem Knopf zum Versenden.
  • return; beendet das Skript an dieser Stelle.
  • .isEmpty fragt: Ist das Feld leer?

7b) Alle Stufen: Wer zurückgibt oder ablehnt, sagt warum

Knopf: ganz unten in der Zeile Bei jedem Wechsel auf + Prüfung.

if (wf.returned && !wf.comment) {
  ctx.cancel("Bitte schreiben Sie in den Kommentar, was geändert werden soll.");
  return;
}
if (wf.declined && !wf.comment) {
  ctx.cancel("Bitte schreiben Sie in den Kommentar, warum der Antrag abgelehnt wird.");
  return;
}

wf ist der gerade laufende Wechsel. wf.returned ist wahr, wenn jemand auf Zurückgeben geklickt hat, wf.declined bei Endgültig ablehnen. In wf.comment steht, was die Person in das Feld „Kommentar" geschrieben hat. Das Ausrufezeichen davor bedeutet „nicht": !wf.comment heißt es gibt keinen Kommentar.

7c) Stufe 2: Anspruch bestätigt, Zuschuss in den Grenzen

Knopf: Stufe 2, hinter „Zustimmung → 3:" auf + Prüfung.

// 1) Der Haken „Anspruch geprüft" muss gesetzt sein.
if (!$anspruch_geprueft.bool) {
  ctx.cancel("Bitte bestätigen Sie mit dem Haken, dass der Anspruch geprüft ist.");
  return;
}

// 2) Der Zuschuss hat zwei Grenzen:
//    - mindestens ein Viertel des Ticketpreises, sonst gibt der Verkehrsverbund keinen Rabatt,
//    - höchstens so viel, wie das Ticket nach dem Rabatt kostet.
var preis      = $ticketpreis.num;
var mindestens = Math.round(preis * 25) / 100;
var hoechstens = Math.round((preis - $rabatt.num) * 100) / 100;

if ($zuschuss.num < mindestens) {
  ctx.cancel("Der Zuschuss muss mindestens " + kc.numFormat(mindestens, "", "€", 12, 2, ",", ".", 3)
           + " betragen (ein Viertel des Ticketpreises).");
  return;
}
if ($zuschuss.num > hoechstens) {
  ctx.cancel("Der Zuschuss darf höchstens " + kc.numFormat(hoechstens, "", "€", 12, 2, ",", ".", 3)
           + " betragen (mehr kostet das Ticket nicht).");
  return;
}
  • .bool liest ein Ankreuzfeld: wahr, wenn der Haken gesetzt ist.
  • .num liest ein Zahlenfeld als Zahl, mit der man rechnen kann.
  • var preis = … merkt sich einen Wert unter einem Namen.
  • Math.round(… * 100) / 100 rundet auf zwei Stellen nach dem Komma.
  • kc.numFormat(…) schreibt eine Zahl so, wie man sie liest: 15,75 €.

7d) Stufe 3: Erst bestellen, dann abschließen

Knopf: Stufe 3, hinter „Zustimmung → 99:" auf + Prüfung.

if ($abo_nummer.isEmpty) {
  ctx.cancel("Bitte tragen Sie die Abo-Nummer des Verkehrsunternehmens ein.");
  return;
}
if ($einbehalt_ab.isEmpty) {
  ctx.cancel("Bitte tragen Sie ein, ab wann der Eigenanteil einbehalten wird.");
  return;
}

7e) Stufe 99: Abschluss festhalten und die Mail anpassen

Knopf: Stufe 99, + Beim Erreichen. Das ist eine Aktion: Sie läuft, wenn der Antrag auf „Abgeschlossen" angekommen ist.

// 1) Eigenanteil ausrechnen. In der Maske macht das ein Berechnungsfeld;
//    hier rechnen wir noch einmal, damit die Zahl in der Mail sicher stimmt.
var eigenanteil = Math.round(($ticketpreis.num - $rabatt.num - $zuschuss.num) * 100) / 100;
ctx.form.eigenanteil = eigenanteil;

// 2) Abschluss festhalten.
ctx.form.abgeschlossen_am = new Date().format("dd.MM.yyyy");

// 3) Die Standard-Mail dieses Wechsels anpassen.
//    Aus 2027-03-01 wird 01.03.2027: Tag, Monat und Jahr einzeln herausschneiden.
var t  = String($einbehalt_ab);
var ab = t.substring(8, 10) + "." + t.substring(5, 7) + "." + t.substring(0, 4);
wf.mail.subject = "Ihr Jobticket ist bestellt";
wf.mail.text = "Guten Tag " + $vorname + " " + $nachname + ",\n\n"
             + "Ihr Jobticket ist bestellt (Abo-Nummer " + $abo_nummer + ").\n"
             + "Ihr Eigenanteil beträgt " + kc.numFormat(eigenanteil, "", "€", 12, 2, ",", ".", 3) + " im Monat.\n"
             + "Er wird ab dem " + ab + " von Ihren Bezügen einbehalten.\n\n"
             + "Ihre Personalstelle";
  • ctx.form.abgeschlossen_am = … schreibt einen Wert in ein Feld. KCForms speichert ihn von selbst.
  • Erreicht ein Antrag eine Endstufe, bekommt die Antragstellerin eine Mail. Mit wf.mail.subject und wf.mail.text gibst du dieser Mail deinen eigenen Betreff und Text. \n ist ein Zeilenumbruch.

7f) Alle Stufen: Mitschreiben, was geschah

Knopf: in der Zeile Bei jedem Wechsel auf + Aktion.

var weg = wf.approve ? "weitergeleitet" : wf.returned ? "zurückgegeben" : "abgelehnt";
var zeile = new Date().format("dd.MM.yyyy HH:mm") + "  " + wf.fromLabel + " -> " + wf.toLabel
          + "  (" + weg + " von " + (ctx.user.name || wf.actingLogin) + ")"
          + (wf.comment ? "  – " + wf.comment : "");

ctx.form.verlauf = (ctx.form.verlauf ? ctx.form.verlauf + "\n" : "") + zeile;

// Dieselbe Zeile ins Skript-Protokoll — dort sieht sie auch der Administrator.
log.info("Jobticket #" + ctx.instanceId + ": " + zeile);

Jeder Wechsel hängt eine Zeile an das Feld „Was bisher geschah" an. So sieht jede Stelle auf einen Blick, wo der Antrag schon war.

Welche Uhrzeit steht im Verlauf?

Die Uhr stellt der Administrator ein: System-Einstellungen → Zeitzone für Datums- und Zeitangaben. Ohne Einstellung gilt die Uhr des Servers.

Speichere das Formular. Mehr Beispiele für solche Skripte — eine zusätzliche Mail, die Ablage als PDF, die Meldung an ein anderes Programm — findest du unter Workflow: Skripte am Stufenwechsel.

Schritt 8: Den Antrag durchspielen

Öffne das Formular mit Im Formular öffnen.

Als Antragstellerin

Fülle die Seite Antrag aus. Wähle beim Beginn zuerst absichtlich den 15. eines Monats. Wechsle links auf Einwilligung, setze beide Haken und klicke auf ✍ Antrag unterschreiben. Speichere.

Die Seite „Einwilligung" nach der Unterschrift: Die Angaben sind gesperrt

Unter dem Formular steht der Bereich Workflow. Klicke auf Empfänger auswählen und suche die Person, die den Antrag prüfen soll — zum Ausprobieren kannst du dich selbst nehmen. Klicke dann auf Versenden an: Personalstelle.

Die Prüfung aus Schritt 7a meldet sich:

Der Workflow-Bereich: Die Prüfung hält den Antrag an und sagt, warum

Der Antrag ist auf Stufe 1 geblieben. Um den Beginn zu ändern, hebst du die Unterschrift mit Aufheben auf — erst dann sind die Angaben wieder frei. Wähle einen Monatsersten, unterschreibe neu, speichere und versende.

Als Personalstelle

Öffne den Antrag und wechsle auf die Seite Bearbeitung. Nur die Felder der Personalstelle sind jetzt beschreibbar. Setze den Haken Anspruch geprüft.

Stufe „Personalstelle": Der Prüfvermerk ist offen, die Felder der Bezügestelle sind gesperrt

Im Bereich Workflow hast du drei Knöpfe:

Knopf Was passiert
Zustimmen Der Antrag geht an die Bezügestelle.
Zurückgeben Der Antrag geht zurück an die Antragstellerin. Ohne Kommentar geht das nicht (Schritt 7b).
Endgültig ablehnen Der Antrag endet auf „Abgelehnt". Auch das braucht einen Kommentar.

Probiere aus, den Zuschuss auf der Seite Antrag auf 10 zu setzen und zuzustimmen: Die Prüfung aus Schritt 7c hält dich auf.

Als Bezügestelle

Trage auf der Seite Bearbeitung die Abo-Nummer und Einbehalt ab ein und klicke auf Abschließen.

Der abgeschlossene Antrag: Abo-Nummer, Abschlussdatum und der Verlauf aller Stufen

Der Antrag steht jetzt auf Abgeschlossen und ist gesperrt. Im Feld „Was bisher geschah" steht jeder Schritt. Über Drucken bekommst du ihn als PDF — mit der Unterschrift.

Zum Ausprobieren reicht ein Konto

Als Administrator darfst du jede Stufe bearbeiten. So kannst du den ganzen Weg allein durchspielen. Im echten Betrieb bearbeitet eine Stufe nur, wer den Antrag bekommen hat. Mehr dazu: Wer darf weiterleiten?

Wenn etwas nicht klappt

Was du siehst Woran es liegt
Ein neues Feld steht auf der falschen Seite. Beim Anlegen war eine andere Marke (01/02/03) gewählt. Öffne das Feld und ordne es über ⚙ Seite oben im Dialog neu zu.
Der Bereich Workflow erscheint nicht. Der Antrag ist noch nicht gespeichert — oder der Haken Workflow aktiv fehlt.
„Ihr Eigenanteil" bleibt leer. Eines der drei Felder aus der Berechnung ist leer. Prüfe die Vorbelegungen aus Schritt 2d.
Ein Skript meldet Missing close quote. Ein deutsches Anführungszeichen im Text, siehe den Warnkasten in Schritt 7.
Ein Skript meldet $… is not defined. Die Feld-ID im Skript stimmt nicht mit der im Formular überein. Vergleiche Buchstabe für Buchstabe.
Ein Knopf zeigt + Prüfung, obwohl du ein Skript eingefügt hast. Das Skript ist noch nicht gespeichert. Ein Punkt (●) am Knopf heißt: Skript vorhanden.
Die Personalstelle kann ihre Felder nicht ausfüllen. Die Bedingung aus Schritt 4b ist vertauscht (=== statt !==) oder nennt die falsche Stufe.

Wie geht es weiter?

Wunsch Wo
Anträge automatisch an ein Postfach oder eine Gruppe schicken Workflow-Workshop, Teil 3
Den Text der Benachrichtigungen ohne Skript ändern Workflow-Workshop, Teil 5
Preis und Zuschuss an einer Stelle pflegen statt in jedem Feld Properties
Den fertigen Antrag als PDF ablegen oder ein anderes Programm benachrichtigen Workflow: Skripte am Stufenwechsel
Eine Liste aller Anträge mit ihrem Status Formular-Eigenschaften → Listenansichten
Die Unterschrift zeichnen lassen Unterschriften

Aufräumen

Dein Übungsformular brauchst du nicht zu behalten. Öffne es im Editor, klicke auf Formulareigenschaften bearbeiten, scrolle ganz nach unten und wähle Formular „jobticket_antrag" löschen. Die Anträge darin werden mitgelöscht.