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:
- Eine Beschäftigte stellt den Antrag und unterschreibt.
- Die Personalstelle prüft, ob ein Anspruch besteht, und legt den Zuschuss fest.
- 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.

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.

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.

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:

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
63eintragen und Nachkommastellen auf2setzen. - Reiter Sichtbarkeit: Schreibgeschützt auf
ein— den Preis soll niemand im Antrag ändern.

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 |

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.

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.

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.

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:

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.
- Setze den Haken Workflow aktiv.
- Lege mit + Stufe fünf Stufen an und trage Nr. und Bezeichnung ein.
- 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 |
☑ |

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".

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.

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:
$beginnist der Wert des Feldes mit der Feld-IDbeginn. 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..isEmptyfragt: 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;
}
.boolliest ein Ankreuzfeld: wahr, wenn der Haken gesetzt ist..numliest ein Zahlenfeld als Zahl, mit der man rechnen kann.var preis = …merkt sich einen Wert unter einem Namen.Math.round(… * 100) / 100rundet 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.subjectundwf.mail.textgibst du dieser Mail deinen eigenen Betreff und Text.\nist 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.

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 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.

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 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.