Beschreibung der STAR-Programmiersprache

Author:

docs 365 GmbH

Die Programmiersprache STAR ist die eingebaute Skriptsprache von docs365 documents und wird beispielsweise in Formular-Events verwendet.

STAR ist eine dynamisch typisierte Sprache, die die Python-Typen verwendet. Statements werden durch das Zeilenende oder ein Semikolon getrennt, Einrückungen sind nicht signifikant. Bei Schlüsselwörtern (if, null etc.) ist auch die Groß- und Kleinschreibung nicht signifikant.

Kommentare werden mit dem Zeichen # begonnen und mit dem Zeilenende abgeschlossen.

Typen

Es werden die Python-Typen verwendet:

  • Strings

  • Ganzzahlen

  • Dezimalzahlen

  • Boolean (true und false)

  • null (leer)

Strings können durch einfache oder auch doppelte Anführungszeichen definiert werden:

a = 'single'
b = "double"

Arithmetische Operatoren

Es gibt folgende Operatoren:

+
-
*
/
%
//

% ist der Modulo-Operator, // die Integer-Division.

Beispiele:

a = (b + 4) * 3
b = 1 + 2 + 3
c = 10 + datepart("year", today())

Index-Operator

Der Index-Operator extrahiert ein Element oder einen Slice (eine Teilsequenz) aus einem String.

Die Syntax ist wie folgt:

collection[0]

Gibt das erste Element der Sammlung zurück.

collection[start:stop]

Gibt eine Teilsequenz zurück, die bei start startet und alle Folge-Elemente bis (und exklusive) stop enthält.

collection[:stop]

Ist äquivalent zum Aufruf collection[0:stop].

collection[start:]

Ist äquivalent zum Aufruf collection[start:last_index+1]. Gibt alle Elemente von start bis zum Ende der Sammlung zurück.

collection[:]

Ist äquivalent zum Aufruf collection[0:last_index+1]. Gibt die gesamte Sammlung zurück.

  • Ein Aufruf der Form str[index] gibt das Zeichen an diesem Index zurück.

  • Ein Aufruf der Form str[start:stop] gibt den Teilstring von start bis stop-1 zurück.

Ausdrücke

Ein Ausdruck ist ein Konstrukt, das ausgewertet wird und beispielsweise aus einer Kombination von Vergleichsoperatoren einen Wert zurückliefert.

Es gibt folgende Vergleichsoperatoren:

==
!=
<
<=
>
>=

Darüber hinaus gibt es den in-Operator, der prüft, ob ein Wert in einem anderen enthalten ist.

Mehrere Ausdrücke können durch and, or und not miteinander kombiniert werden.

Beispiele:

a < 5 and not (b == 1 or c > 10)
'ab' in 'abc' # true
'ac' in 'abc' # false
# Ist der Nutzer Teil einer Gruppe mit diesem Namen?
'Vorgesetzte' in current.user.groups_names

Operatorrangfolge

Die Operatorrangfolge von niedrigster zu höchster Priorität ist wie folgt:

  1. or

  2. and

  3. not x

  4. == != < <= > >=

  5. + -

  6. * / % //

Durch Klammern kann die Rangfolge überschrieben werden.

Variablen

Variablen müssen mit einem Buchstaben beginnen und können anschließend Buchstaben, Ziffern oder Unterstriche enthalten:

a = 100
b1 = "String"
c_2 = false

Eine Variable kann erst verwendet werden, wenn ihr ein Wert zugewiesen wurde.

In Formular-Events gibt es darüber hinaus noch Variablen mit dem speziellen Präfix _, die die Werte eines Vorgang enthalten. Beispielsweise enthält _rechnr den Wert des Datenfeldes mit dem Kurznamen rechnr. Eine Zuweisung an diese Variable ändert den Wert des Datenfeldes.

Verzweigungen

In if-Verzweigungen kann es optional beliebig viele elseif-Blöcke und einen else-Block geben. Mit end wird die Verzweigung abgeschlossen:

if a > 0 then
    b = 1
elseif a < 0 then
    b = -1
else
    b = 0
end

Evaluierung von Variablen

In STAR werden, genau wie in Python, die Werte explizit zu true oder false evaluiert. Damit lassen sich vereinfachte Abfrage-Bedindungen aufstellen, wodurch Code und Komplexität reduziert und die Leserlichkeit intuitiver gemacht werden kann.

Für Variablen vom Typ string gilt:

text = "Buchungstext"

# Strenge Abfrage: Text ist nicht "" (leerer String) und nicht null (nicht zugewiesener Wert)
if text != "" and text != null then
    # Logik
end

# Einfache Abfrage, die beide Fälle der vorherigen Abfrage abdeckt
if text then
    # Logik
end

Weitere Anwendungsbeispiele für if-Abfragen mit vereinfachter Wahrheitsprüfung:

Es wird geprüft, ob Betragsteuer null (nicht zuwiesener Wert) oder 0 ist. Das Feld muss ausgefüllt sein, damit die Bedingung eintrifft. In diesem Fall wird sowohl null, als auch 0 zu einem false evaluiert.

# Implizit: Prüfung auf null oder 0
if (_betragsteuer_reg or 0) == 0 then
    _betragsteuer_reg = 1000
    # Logik
end

# Explizit: Vereinfachte Prüfung, analog zum Typ "string"
if not _betragsteuer_reg then
    _betragsteuer_reg = 1000
    # Logik
end

Kreditorname ist nicht null oder „“ und Rechnungsnummer ist nicht null oder „“. Beide Werte sind befüllt.

if _kreditorname and _rechnungsnummer then
    # Logik
end

Rechnungsdatum ist vorhanden, aber kein Leistungsdatum (nicht zugewiesener Wert).

if _rechdat and not _leistdat then
    _leistdat = date(<year>, <month>, <day>)
    # Logik
end

Schleifen

STAR bietet For-Schleifen an, mit der über Objekte iteriert werden kann, die dieses unterstützen. Die Syntax ist wie folgt:

for idx in _subtable.enumerate() do
    row_field = _subtable.get(idx, 'field_name')
    if row_field == 'secret' then
        continue
    elseif row_field == 'stop' then
        break
    end
    print(row_field)
end

In dem Beispiel wird über Reihenindizes einer Untertabelle iteriert. Falls der Wert des Feldes ‚secret‘ ist wird der Rest des Codes übersprungen und mit dem nächsten Index der Tabelle weitergemacht. Falls der Wert ‚stop‘ ist wird mit der Iteration aufgehört und aus der Schleife ausgebrochen.

Funktionen

Eigene Funktionen können mittels der folgenden Syntax definiert werden:

function add_mul (a, b, c=1)
    return (a + b) + c
end

Abbruch und Rückgabe

An einer bestimmten Zeile des Code kann wie folgt ausgestiegen werden:

betrag = lookup("test_tabelle", "netto_betrag", fallback=null, _name = "Mitarbeiter X")

if betrag > 1000 then
    print("Ende der Logik")
    return
end

print("Fortführende Logik")

Der Abbruch einer Logik (z.B. Archivierung im on_save Event) kann mit der folgenden Funktion ausgeführt werden:

name = lookup("firmen", "firma", fallback=null, _name="Meine Firma")

if not name then
    abort("Firma konnte nicht gefunden werden.")
else
    print("Führe Logik aus")
end

Der abort Funktion kann optional ein Parameter message übergeben werden, die beim Werfen der Meldung als Fehlertext angezeigt wird.

Es werden folgende Funktionen bereitgestellt:

abort(message)

Bricht das Skript sofort ab. Alle vorher durchgeführten Änderungen (z.B. Feldwert-Zuweisungen) werden rückgängig gemacht.

date(year, month, day)

Gibt das Datum definiert durch die drei int-Parameter zurück.

datepart(part, d)

Extrahiert das Jahr, das Quartal, den Monat oder den Tag aus einem Datumswert. part muss den Wert "year", "quarter", "month" oder "day" haben. d muss ein Datum sein.

decimal(value)

Konvertiert den String value in eine Dezimalzahl. Als Dezimal-Trennzeichen werden sowohl Punkt als auch Komma erkannt, Tausender-Trennzeichen werden hingegen nicht unterstützt. Wenn der String mit dem Zeichen % endet, wird der zurückgegebene Wert automatisch durch 100 geteilt.

getattr(object, "attribute_name", default=null)

Es wird versucht, auf das Attribut des Objekts mit dem angegebenen Namen zuzugreifen. Hat das Objekt kein Attribut mit diesem Namen, beispielsweise wenn es null ist, wird entweder ein Fehler ausgelöst oder, wenn default gesetzt ist, dessen Wert zurückgegeben.

int(value)

Konvertiert value (beispielsweise ein String, der eine Zahl enthält) in einen Integer.

is_table(object)

Prüft ob ein Objekt eine Tabelle ist.

len(collection)

Gibt die Länge einer Liste oder eines Strings zurück

print(value)

Gibt den aktuellen Wert von value aus.

round(n) oder round(n, d)

Rundet die Zahl n. Der optionale Parameter d gibt die Anzahl der Nachkommastellen an, ansonsten wird auf ganze Zahlen gerundet.

str(value)

Konvert value in einen String.

relativedelta

Eine Funktion zum Berechnenen von Datumswerten, die wie die Funktion relativedelta aus der dateutil-Python-Library funktioniert.

timedelta(num, unit="days")

Diese Funktion wird benötigt, um mit Datumwerten zu rechnen. Der optional Parameter unit kann folgende Werte enthalten: "day", "second", "minute", "hour", "week". Das folgende Beispiel berechnet das Datum eine Woche in der Zukunft: today() + timedelta(1, "week")

today()

Gibt das heutige Datum zurück.

user_message(text)

Sendet nach Ausführung des Events eine Info-Nachricht mit dem text an den Benutzer.

not_null(value_one, value_two, ..., value_n)

Iteriert durch alle an die Funktion übergebenen values und gibt für den ersten gefundenen null-Wert ein false zurück. Wenn es keine null-Werte gibt, wird abschließend ein true zurückgegeben.

String-Methoden

Es stehen die folgenden Methodenaufrufe für Strings zur Verfügung:

.startswith(prefix)

Gibt zurück, ob der String mit dem übergebenen Präfix beginnt.

.endswith(suffix)

Gibt zurück, ob der String mit dem übergebenen Suffix endet.

.removeprefix(prefix)

Gibt einen String zurück, bei dem das übergebene Präfix entfernt wurde.

.removesuffix(suffix)

Gibt einen String zurück, bei dem das übergebene Suffix entfernt wurde.

.isalnum()

Gibt true zurück, wenn alle Zeichen im String alphanumerisch sind, ansonsten false.

.isalpha()

Gibt true zurück, wenn alle Zeichen im String alphabetisch sind, ansonsten false.

.isdigit()

Gibt true zurück, wenn Zeichen im String Ziffern sind, ansonsten false.

.lower()

Gibt einen in Kleinbuchstaben umgewandelten String zurück.

.upper()

Gibt einen in Großbuchstaben umgewandelten String zurück.

.strip()

Entfernt Whitespace (z.B. Leerzeichen und Tabs) vom Anfang und Ende des Strings.

.find(sub)

Sucht das erste Vorkommen des Substring und gibt den Index an, an dem der Substring im durchsuchten String beginnt.

.replace(old, new)

Sucht im String nach dem Substring ´´old´´ und ersetzt alle Vorkommnisse mit ´´new´´.

Datums-Objekte

Datums-Objekte können mittels der Funktion date(year, month, day) erstellt werden. Werte eines bestehenden date-Objektes können mit der Funktion datepart(part, date_object) extrahiert werden.

Für Zeitdifferenzen zwischen zwei Datumsangaben gibt es zwei Möglichkeiten der Berechnung und Handhabung.

timedelta

Man kann ein timedelta entweder selbst mittels der Funktion timedelta(5, units="week") erstellen oder diese mittels arithmetischer Operationen auf date Objekten erzeugen. Ein timedelta-Objekt hat die Attribute .days und .seconds die man abfragen kann. Bei der Konstruktion kann man für units day|second|minute|hour|week als Wert wählen. Alle Einheiten, die man bei der Erzeugung angibt, werden auf .days und .seconds normalisiert.

date_1 = date(2020, 2, 03)
date_2 = date(2021, 10, 05)
time_delta = date_2 - date_1
print(time_delta.days)
print(time_delta.seconds)

Dieses Code-Snippet würde die Tagesdifferenz von 610 und Sekundendifferenz von 0 ausgeben. Weiter kann man timedelta-Objekte auch von date-Objekten subtrahieren oder auf diese addieren.

time_delta = timedelta(15, unit="days")
date_1 = date(2020, 2, 03)
date_2 = time_delta + date_1
print(date_2.days)

Dieses Code-Snippet würde die Anzahl der Tage von date_2 als 18 ausgeben.

relativedelta

Man kann ein relativedelta mittels der Funktion relativedelta(date_1, date_2) erzeugen, welche zwei date-Objekte als Parameter nimmt. Für ein relativedelta-Objekt kann man auf die Attribute .years, .weeks, .days, .hours, .minutes, .seconds und .microseconds zugreifen.

date_1 = date(2020, 2, 03)
date_2 = date(2021, 10, 05)
relative_delta = relativedelta(date_2, date_1)
print(relative_delta.years)
print(relative_delta.months)
print(relative_delta.days)

Dieses Code-Snippet würde 1, 8, 2 für die Jahres-, Monats und Tagesdifferenz ausgeben. Achtung! Es wird hier z. B. nicht für das Attribute .months die Differenz zwischen den Datumsangaben in Monaten zurückgegeben, die hier 20 wäre, sondern die Differenz der .months Attribute der beiden date Objekte. Um die Differenz zwischen den date Objekten in Monaten zu erhalten müsste man die Jahresdifferenz in Monate umwandeln und dazurechnen. Gleiches gilt für das .days.

Globale Variablen

current_user

Der aktuell angemeldete Benutzer als Benutzer-Objekt. Ist null, wenn kein Benutzer angemeldet ist (beispielsweise bei der Ausführung einer Hintergrundverarbeitung).

current_record

Stellt über die Attribute current_record.id, current_record.creation_date, current_record.modification_date, current_record.creator_id, current_record.expiration_date, current_record.deletion_date, current_record.release_id, current_record.release_version, current_record.release_date, current_record.status, current_record.postbox_users, current_record.hidden und current_record.postbox_groups Informationen über den aktuellen Vorgang bereit. Diese Daten sind nur lesbar. Man kann sie nicht durch Zuweisung ändern. Die Variable steht in den Events on_save, on_load, sowie während Workflow-Transitionen zur Verfügung.

event

Enthält Basis-Informationen über das aktuell ausgeführte Event. event.field enthält den (mit Unterstrich vorangestellten) Kurznamen des Datenfeldes, in dem das Event ausgelöst wurde. Bei Formular-Events ist der Wert null. event.row und event.column enthalten bei Events einer Untertabelle die Koordinaten der Tabelle-Zelle, in der das Event ausgelöst worden ist. row ist dabei die Zeilennummer (beginnend mit 0 für die erste Zeile) und column der Kurzname der Spalte.

Veränderbare Vorgangs-Variablen

Die folgenden Variablen unterstützen auch Zuweisungen, um Eigenschaften am Vorgang zu verändern:

$expiration_date

Das Ablaufdatum des Vorgangs.

$deletion_date

Das Löschdatum des Vorgangs.

Mandanten

Wenn in einem Archiv die Mandanten aktiviert sind, enthält die spezielle Variable $client den im Vorgang aktuell ausgewählten Mandanten. Über Attribut-Zugriff kann auf die Eigenschaften des Mandanten zugegriffen werden:

$client.identifier

Kürzel des Mandanten.

$client.name

Name des Mandanten.

$client.id

Interne ID des Mandanten.

Benutzer-Objekte

Ein Benutzer-Objekt repräsentiert einen Benutzer.

Benutzer-Objekte sind beispielsweise die globale Variable current_user, die den aktuell angemeldeten Benutzer zurückgibt, sowie die Rückgabewerte der Funktion lookup_user().

Ein Benutzer-Objekt hat folgende Attribute:

id

Die interne Benutzer-ID (die bespielsweise vom Key-Value-Feld „Benutzer“ gespeichert wird).

username

Login-Name.

fullname

Name.

email

Die E-Mail-Adresse.

language

Die Sprache, die der Benutzer in der Oberfläche eingestellt hat. Mögliche Werte sind de und en.

groups

Die Liste der Gruppen-IDs, in denen der Benutzer Mitglied ist.

groups_names

Die Liste der Gruppen-Namen, in denen der Benutzer Mitglied ist.

roles

Die Liste der Rollen-IDs, in denen der Benutzer Mitglied ist.

roles_names

Die Liste der Rollen-Namen, in denen der Benutzer Mitglied ist.

substitute_id

Die Benutzer-ID des Vertreters bzw. null, falls kein Vertreter eingestellt ist.

substitute_active

Ist true, falls ein Vertreter aktiv ist, andernfalls false.

Beispiel:

# Gibt aus, ob der aktuell angemeldete Benutzer Mitglied der Rolle mit dem Namen "Prüfer" ist.
print("Prüfer" in current_user.roles_names)

Status-Änderung im on_save-Event

Im on_save-Event werden zusätzliche Variablen bereitgestellt:

$status

Enthält den Status-Namen des Vorgangs. Durch Zuweisung eines anderen, gültigen Status-Namen kann man den neuen Status des Vorgangs überschreiben

$new

Ist true, wenn das on_save-Event für einen gerade neu angelegten Vorgang ausgeführt wird.

$update

Ist true, wenn das on_save-Event für einen existierenden Vorgang ausgeführt wird.

Änderung der Sichtbarkeit eines Datenfeldes

Möglich ist auch das Verstecken von Datenfeldern. Über Events können die Datenfelder im Formular versteckt, auf Read-Only gesetzt oder aber auch das Label verändert werden:

_feld1.visible = false
_feld2.editable = false
_feld2.label = 'Neues Label'

Zugriff auf den Anzeige-Text eines Datenfeldes

Für Felder eines Vorgangs, die ein Key-Value-Feld sind (wie beispielsweise vom Vorschlagstyp „Benutzer“ oder ein verlinkter Vorgang aus anderem Archiv) kann der Anzeige-Text abgefragt werden.

Beispiel:

if _user.text == current_user.fullname then
    _user_refer = "You"
else
    _user_refer = _user.text
end

Beim Aufruf von _user oder _user.value wird hier die Benutzer-ID zurückgegeben, da diese intern für das Feld gespeichert wird. Für _user.text wird hier der Name eines Benutzers zurückgegeben, da dies der Anzeige-Text für einen Benutzer-Vorschlag in einem Formular ist.

Untertabellen

Wenn in einem Archiv Untertabellen konfiguriert sind, enthalten die Tabellen-Objekte Funktionen, mit denen Informationen und Werte ausgelesen bzw. verändert werden können. Im Folgenden ist die Untertabelle im Archiv mit dem Kurznamen table konfiguriert:

_table.clear()

Leert die Tabelle.

_table.enumerate()

Gibt einen Iterator für die Indizes der Tabelle zurück. Dieser kann in einer For-Schleife benutzt werden um, alle Reihenindizes der Tabelle durchzugehen.

_table.extend(other, strict=false)

Fügt der Tabelle die Zeilen von other hinzu und überträgt alle vorhandenen Werte der Zeilen, die dem Schema der Tabelle (d.h. Spalten mit identischem Namen) entsprechen. Der optionale Parameter strict kann auf true gesetzt werden. Dann kommt es, falls das Schema der beiden Tabellen nicht gleich ist, zu einem Fehler.

_table.row_count

Enthält die aktuelle Anzahl der Tabelle-Zeilen.

_table.get(0, "ort")

Gibt den Wert aus der Zeile mit dem Index 0 und dem Datenfeld mit dem Kurznamen „ort“ zurück. Wie in den meisten Programmiersprachen beginnt der Index mit 0 und verweist somit auf die erste Zeile der Tabelle. Wenn es keine Zeile mit dem angegeben Index gibt, wird null zurückgegeben.

_table.delete_row(idx)

Entfernt die Zeile an der Stelle idx.

_table.set(0, "ort", "Berlin")

Schreibt den angegeben Wert in die Zeile mit dem Index und dem Kurznamen „ort“.

_table.set_row(0, clear=true, _ort="Berlin", _plz=11011)

Mit dieser Funktionen können mehrere Spaltenwerte auf einmal geändert werden, die Parameter mit Unterstrich enthalten dabei die zu verändernden Spaltenwerte. Mit dem optionalen Parameter clear können alle nicht explizit gesetzten Wert auf null zurückgesetzt werden.

_table.add_row()

Fügt eine neue Zeile in die Tabelle ein und gibt deren Index zurück.

_table.sum("betrag")

Berechnet die Summe aller Zahlenwerte in der Spalte mit dem Kurznamen „betrag“. Es wird null zurückgegeben, wenn die angegeben Spalte nicht existiert, keine Zahlenwerte oder auch gar keine Werte enthält.

Suche in Datentabellen und Archiven

Die Funktion lookup() sucht nach Werten in Datentabellen oder Archiven.

Das erste Argument der Funktion bestimmt, welche Tabelle durchsucht wird. Wenn direkt ein Kurzname angegeben wird, wird die Datentabelle mit dem angegebenen Kurzname durchsucht. Das Durchsuchen eines Archivs erfordert das Präfix archive: und den Kurznamen beispielsweise sind folgende Werte möglich:

zahlungsbedingungen

Durchsucht die Datentabelle mit dem Kurznamen zahlungsbedingungen.

datatable:zahlungsbedingungen

Durchsucht ebenfalls die Datentabelle mit dem Kurznamen zahlungsbedingungen.

archive:rechungen

Durchsucht das Archiv mit dem Kurznamen rechungen.

Das zweite Argument ist der Kurzname der Spalte, deren Wert man ermitteln möchte. Interne Felder eines Vorgangs lassen sich durch folgende Kriterien gezielt filtern: record_id, record_release_version und record_release_id.

Im folgenden Beispiel enthält ein Archiv ein Feld mit einem konfigurierten Vorschlagstyp „Vorgänge“, das einige Datenfelder eines Referenz-Archivs für die Darstellung verwendet.

# Ein Kriterium zum Wiederfinden eines bestimmten Vorgangs
rechnr = 1200001

# Vorgang im aktuellen Archiv finden und als Filterkriterium wiederverwenden
test_lookup = lookup("archive:test", "informationen", _rechnr=rechnr)

# Gezielt ein Datenfeld anhand der release_id extrahieren im Referenz-Archiv
referred_lookup = lookup("archive:test_referred", "anbieter", record_release_id=test_lookup)

Das Ergebnis des Beispiels ist eine ID oder None und kann fortführend als weiteres Kriterium verwendet werden.

Wenn ein internes Feld der Vorgangs zurückgegeben werden soll, muss der Name des Felds im zweiten Parameter mit dem Präfix record: angegeben werden, beispielsweise record:release_id.

Folgende Felder können hierbei zurückgegeben werden:

  • record:id

  • record:release_id

  • record:release_version

  • record:client_identifier

  • record:client_name

  • record:client_id

Beispiele:

# Extrahierte IDs als Filterkriterium
lookup("archive:test", "record:id", record_release_id=lookup_release_id)
lookup("archive:test", "record:client_identifier", record_id=lookup_record_id, client=$client)

Insbesondere das interne Feld release_id: Die Release-ID (die über mehrere Versionen eines Vorgangs hinweg stabil ist) wird vom Vorschlags-Typ Vorgänge für die Verlinkung von Vorgängen verwendet. Diese Funktionserweiterung bietet beispielsweise die Möglichkeit, über die lookup-Funktion Werte aus dem verlinkten Vorgang zu laden.

Durch Keyword-Argumente wird das weitere Verhalten der Funktion bestimmt:

  • Mit Unterstrich beginnende Parameter definieren Filter anhand des Kurznamen der Datentabellen-Spalten.

  • Im Parameter filter kann auch ein komplexerer Filter als String in der üblichen Filter-Syntax übergeben werden. Wenn dieser Filter dynamische Werte aus Variablen verwenden soll, wird empfohlen, diesen String mit der unten beschriebenen Funktion format_filter() zu erzeugen.

  • Durch wildcard=true wird nicht nach exakten Werten gesucht, sondern es kann beispielsweise mit "F*" nach allen Treffern gesucht werden, in dem der Wert mit einem F beginnt.

  • fallback=x bestimmt, dass der Wert x zurückgegeben wird, wenn es keinen Treffer gab.

  • Wenn man in Archiv-Lookup nach Mandanten filtern möchte, muss der ausgewählte Mandant mit dem Keyword-Argument client=$client an die lookup()-Funktion durchgereicht werden.

Es wird jeweils das erste gefundene Ergebnis zurückgegeben.

Beispiele:

a = lookup("zahlungsbedingungen", "nettotage", fallback=10, _name = "Firma")
b = lookup("archive:kunden", "strasse", wildcard=true, _name = "F*", _plz=54321)

Falls das Feld eine Untertabelle ist, wird hier ein Tabellen-Objekt zurückgegeben.

Die Funktion lookup_table() funktioniert ähnlich zur Funktion lookup. Es wird aber kein Feld für die Datentabelle oder das Archiv angeben, d.h. der zweite Parameter der lookup fehlt hier. Stattdessen werden alle gefundenen Zeilen als eine Tabelle zurückgegeben.

Beispiel:

a = lookup_table("archive:kunden", _name = "F*")

Die Funktion format_filter() ist eine Hilfsfunktion, um den filter-Parameter für die lookup()-Funktion zu erzeugen.

Das erste Argument ist ein Formatierungs-String, der in geschweiften Klammern angegebene Platzhalter enthält. Diese Parameter können dann durch Keyword-Argumente mit Werten aus Variablen befüllt werden. Dabei konvertiert die Funktion verschiedene Typen in das Format, das von der Filter-Syntax verlangt wird:

  • Beispielsweise wird ein Datumswert in das ISO-Format mit doppelten Anführungszeichen konvertiert.

  • Strings bekommen automatisch doppelte Anführungszeichen (aus diesem Grund müssen bei Filter-Werten hier auch keine doppelten Anführungszeichen angegeben werden), für in den Strings enthaltene Anführungszeichen wird Escaping durchgeführt.

Beispiel:

plz = 54321
name = 'Firma "Test"'
f = format_filter("_plz = {p} AND _name = {n} AND _date > {d}", p=plz, n=name, d=today())

Dabei wird folgender String erzeugt:

_plz = 54321 AND _name = "Firma \"Test\"" AND _date > "2022-06-02"

Suche von Benutzern

Zum Laden von Benutzern wird die Funktion lookup_user() bereitgestellt.

Die Funktion versucht, einen Benutzer nach den angegebenen Filter-Optionen zu finden. Mögliche Optionen sind:

  • user_username

  • user_fullname

  • user_email

  • user_id

Der Rückgabewert ist ein Benutzer-Objekt bzw. null, falls kein Benutzer gefunden wird.

Beispiel:

active = getattr(lookup_user(user_id=_freigeber), "substitute_active", false)

Hier wird nach einem Benutzer gesucht und dann versucht das Attribut substitute_active auszulesen. Sollte lookup_user einen null-Wert zurückgeben, wird hier dann der Standardwert false zurückgegeben.

Termine über STAR anlegen und bearbeiten

Im on_save-Event stehen drei Funktionen zur Verfügung, um Termine anzulegen, zu bearbeiten oder zu löschen.

Die Funktion create_schedule legt einen neuen Termin an:

create_schedule(
   start_date,
   escalation_rule=null,
   todo=null,
   recipient1=null,
   recipient2=null,
   recipient3=null,
   repeat_unit=null,
   repeat_count=null,
   from_user=null,
   inactive=false
)
start_date

Pflicht. Gibt das Start-Datum an, an dem der Termin ausgeführt wird. Muss der Funktion als Schlüsselwort start_date= übergeben werden.

escalation_rule

Optional. Gibt den Namen der zu verwendenden Eskalations-Regel an. Beim Fehlen dieses Parameters wird die Standard-Regel verwendet.

recipient1, recipient2, recipient3

Optional. Parameter sind erforderlich, wenn die Eskalations-Regel diese benötigt. Das kann z.B. der Fall sein, wenn ein Empfänger in der Terminplanung ausgewählt werden muss. Übergeben wird ein Benutzer-Objekt (z.B. current_user oder das Ergebnis eines Benutzer-Lookups mittels lookup_user).

repeat_unit

Optional. Der Parameter akzeptiert die Werte "day", "week", "month" und "year". Damit wird angegeben, in welchem zeitlichen Intervall der Termin wiederholt auslösen soll.

repeat_count

Optional. Gibt die Anzahl der Wiederholungen eines Termins an. Damit ein Termin sich in einem Intervall wiederholen kann, sind die beide optionalen Parameter repeat_unit und repeat_count notwendig.

from_user

Optional. Gibt den Absender des Termins an.

inactive

Optional. Standardmäßig auf false. Mit dieser Option lässt sich ein deaktivierter Termin anlegen.

Beispiel:

-- Erstellt einen Termin für den Vorgang, der ab heute eine Woche in der Zukunft liegt.
create_schedule(start_date=today() + timedelta(1, "week"))

Der Rückgabewert von create_schedule() ist der neu erzeugte Termin.

Die Funktion lookup_schedules lädt eine Liste von Terminen:

lookup_schedules(todo=null, wildcard=false)
todo

Optional. Gibt einen String an, der sich mit der Beschreibung des Termins abgleichen lässt.

wildcard

Optional. Standardmäßig false. Ermöglicht die Suche des todo in Kombination mit wildcards.

In den geladenen Schedule-Objekten können die Termin-Daten über Attribute verändert werden. So kann z.B. ein Start-Datum um eine Woche verschoben werden.

schedule.start_date = _date + timedelta(1, "week")
schedule.todo = "Invoice checking postponed"

Die Funktion delete_schedule löscht einen Termin:

delete_schedule(schedule)