Operatoren
Bei der Preis- und Gewichtsberechnung muss das Ergebnis einer Formel immer ein numerischer Wert sein. Bei der Validierung muss das Ergebnis immer ein Wahrheitswert / boolescher Wert sein
Die Formeln im Profimodus basieren auf JSONLogic. Jeder Operator wird als JSON-Objekt definiert.
Im Profimodus stehen Logikoperatoren, boolesche Operatoren und arithmetische Operatoren zur Verfügung.
Arithmetische Operatoren
| Name | Beschreibung |
|---|---|
| Multiplizieren | Multipliziert zwei oder mehr Werte |
| Dividieren | Dividiert den ersten Wert durch den zweiten |
| Addieren | Addiert zwei oder mehr Werte |
| Subtrahieren | Subtrahiert den zweiten Wert vom ersten |
| Modulo | Berechnet den Rest der Division |
| Quadratwurzel ziehen | Berechnet die Quadratwurzel eines Wertes |
| Potenzieren | Potenziert den ersten Wert mit dem zweiten |
Multiplizieren
Zwei Werte:
{"*": [2, 3]}
Ergebnis: 6
Mit mehreren Werten:
{"*": [2, 3, 4]}
Ergebnis: 24
Mit Feldvariable:
{"*": [{"var": "fields.laenge.value"}, 10]}
Ergebnis: Länge-Wert * 10
Dividieren
{"/": [10, 2]}
Ergebnis: 5
Addieren
{"+": [5, 3, 2]}
Ergebnis: 10
Subtrahieren
{"-": [10, 3]}
Ergebnis: 7
Modulo
{"%": [10, 3]}
Ergebnis: 1 (Rest der Division 10 ÷ 3)
Quadratwurzel
{"sqrt": 16}
Ergebnis: 4
Mit Feldvariable:
{"sqrt": {"var": "fields.zahl.value"}}
Potenzieren
{"pow": [2, 3]}
Ergebnis: 8 (2 hoch 3)
Alle Operatoren können durch die Angabe weiterer Argumente erweitert werden. Die Anzahl ist nicht auf 2 beschränkt, z.B. {"*":[1,2,3,4]} = 1 * 2 * 3 * 4 = 24
Vergleichsoperatoren
| Name | Beschreibung |
|---|---|
| if / else | Einfache Bedingung mit zwei möglichen Ergebnissen |
| if / else if / else | Mehrfach-Bedingungen mit verschiedenen Ergebnissen |
| and | Logisches UND - alle Bedingungen müssen wahr sein |
| or | Logisches ODER - mindestens eine Bedingung muss wahr sein |
| ! (not) | Logisches NICHT - kehrt Wahrheitswert um |
| !! (boolean) | Wandelt Wert in Boolean um |
| Gleich | Prüft auf Gleichheit zweier Werte |
| Strikte Gleichheit | Prüft auf Gleichheit ohne Typkonvertierung |
| Ungleich | Prüft auf Ungleichheit zweier Werte |
| Strikte Ungleichheit | Prüft auf Ungleichheit ohne Typkonvertierung |
| Größer / Größer gleich | Vergleicht ob erster Wert größer (gleich) als zweiter |
| Kleiner / Kleiner gleich | Vergleicht ob erster Wert kleiner (gleich) als zweiter |
Beispiele für Vergleichsoperatoren:
if/else Bedingung
{"if": [
{">": [{"var": "fields.alter.value"}, 18]},
"Erwachsen",
"Minderjährig"
]}
Falls Alter > 18: "Erwachsen", sonst: "Minderjährig"
if/else if/else Struktur:
{"if": [
{"<": [{"var": "fields.length.value"}, 100]}, 20,
{"<": [{"var": "fields.length.value"}, 200]}, 30,
{"*": [{"var": "fields.length.value"}, 10]}
]}
- Falls Länge < 100: Ergebnis ist 20
- Sonst falls Länge < 200: Ergebnis ist 30
- Sonst: Ergebnis ist Länge * 10
Logisches UND (and)
{"and": [
{">": [{"var": "fields.alter.value"}, 18]},
{"==": [{"var": "fields.status.value"}, "aktiv"]}
]}
Ergebnis: true nur wenn beide Bedingungen wahr sind
Logisches ODER (or)
{"or": [
{"==": [{"var": "fields.typ.value"}, "premium"]},
{">": [{"var": "fields.punkte.value"}, 100]}
]}
Ergebnis: true wenn mindestens eine Bedingung wahr ist
Größer-Vergleich
{">": [{"var": "fields.preis.value"}, 100]}
Ergebnis: true wenn Preis > 100
Größer-gleich-Vergleich
{">=": [{"var": "fields.alter.value"}, 18]}
Ergebnis: true wenn Alter >= 18
Kleiner-Vergleich
{"<": [{"var": "fields.wert.value"}, 50]}
Ergebnis: true wenn Wert < 50
Kleiner-gleich-Vergleich
{"<=": [{"var": "fields.menge.value"}, 100]}
Ergebnis: true wenn Menge <= 100
Logisches NICHT (!)
{"!": [{"var": "fields.deaktiviert.value"}]}
Kehrt den Wahrheitswert um
Boolean-Konvertierung (!!)
{"!!": [{"var": "fields.text.value"}]}
Wandelt leeren Text in false, gefüllten Text in true um
Gleichheit prüfen
{"==": [{"var": "fields.farbe.value"}, "rot"]}
Ergebnis: true wenn Farbe gleich "rot"
Strikte Gleichheit
{"===": [{"var": "fields.zahl.value"}, 42]}
Prüft Gleichheit ohne Typkonvertierung (42 !== "42")
Ungleichheit prüfen
{"!=": [{"var": "fields.groesse.value"}, "XL"]}
Ergebnis: true wenn Größe nicht gleich "XL"
Strikte Ungleichheit
{"!==": [{"var": "fields.wert.value"}, "0"]}
Prüft Ungleichheit ohne Typkonvertierung (0 !== "0")
Rundungen
Vor allem in der Preisberechnung können Rundungen sinnvoll sein.
| Name | Beschreibung |
|---|---|
| Runden | Rundet auf die angegebene Anzahl Nachkommastellen |
| Aufrunden | Rundet immer auf zur nächsten ganzen Zahl |
| Abrunden | Rundet immer ab zur nächsten ganzen Zahl |
| Nachkommastellen festlegen (pad) | Formatiert eine Zahl mit fester Anzahl Nachkommastellen |
Beispiele für Rundungen:
Auf 2 Nachkommastellen runden
{"round": [{"var": "fields.preis.value"}, 2]}
Festen Wert runden
{"round": [7.999393, 2]}
Ergebnis: 8.00
Aufrunden
{"ceil": 7.20}
Ergebnis: 8
Abrunden
{"floor": 7.90}
Ergebnis: 7
Nachkommastellen festlegen (pad)
{"pad": [{"var": "fields.preis.value"}, 2]}
Formatiert den Wert mit fester Nachkommastellen-Anzahl, z. B. wird aus 8 der Text "8.00". Ohne zweites Argument werden 2 Nachkommastellen verwendet.
Bruttopreise / Nettopreise
Steuersensitive Angaben je nach Kundengruppe.
| Name | Beschreibung |
|---|---|
| Brutto-Preis markieren | Markiert einen Preis als Bruttopreis |
| Netto-Preis markieren | Markiert einen Preis als Nettopreis |
Beispiele für Preis-Markierungen:
Brutto-Preis
{"brutto": 2.40}
Mit Feldvariable:
{"brutto": {"var": "fields.auswahl.price"}}
Alternative Schreibweise:
{"gross": 2.40}
Netto-Preis
{"netto": 2.40}
Alternative Schreibweisen:
{"net": 2.40}
Weitere Operatoren
| Name | Beschreibung |
|---|---|
| Matrix-Operator | Für Staffelpreise und Preistabellen |
| Kleinster Wert | Gibt den kleinsten Wert aus mehreren zurück |
| Größter Wert | Gibt den größten Wert aus mehreren zurück |
| Textlänge | Ermittelt die Anzahl Zeichen eines Textes |
| Texte verknüpfen | Verbindet mehrere Texte zu einem |
| Text ersetzen | Ersetzt Textteile durch andere |
| Teilstring extrahieren | Extrahiert Zeichen aus einem Text |
| Datenzugriff (var) | Zugriff auf Feldwerte und Produktdaten |
| Array transformieren (map) | Wendet Operation auf alle Array-Elemente an |
| Array filtern (filter) | Filtert Array nach Bedingung |
| Array-Test (all/some/none) | Testet alle/einige/keine Array-Elemente |
| Arrays zusammenführen (merge) | Verbindet mehrere Arrays |
| Element in Array suchen (in) | Prüft ob Element in Array vorhanden ist |
| Schrittweite prüfen (stepsize) | Prüft, ob ein Wert ein Vielfaches einer Schrittweite ist (Validierung) |
| Eindeutigkeit prüfen (unique) | Prüft, ob ein Array keine Duplikate enthält (Validierung) |
| Datum (date / datum) | Wandelt einen Datumsausdruck in einen Zeitstempel um |
| Regex-Suche (regexFind) | Sucht per regulärem Ausdruck in einem Text |
| Vorlage anwenden (replaceApply) | Ersetzt Platzhalter in einer Formelvorlage und wertet sie aus |
Beispiele für weitere Operatoren:
Matrix-Operator für einfache Staffelpreise
{"matrix": [
{"var": "fields.auflage.value"},
[
[0, 10.00],
[100, 9.90],
[200, 8.90],
[300, 8.70]
]
]}
Matrix-Operator für zwei Dimensionen
{"matrix": [
{"var": "fields.laenge.value"},
{"var": "fields.breite.value"},
[
[100, 20, 84.00],
[200, 20, 89.00],
[300, 20, 94.00],
[100, 30, 91.00],
[200, 30, 96.00],
[300, 30, 101.00]
]
]}
Matrix mit Auswahlfeldern
{"matrix": [
{"var": "fields.material.value"},
{"var": "fields.groesse.value"},
[
["Holz", 100, 25.00],
["Holz", 200, 45.00],
["Metall", 100, 35.00],
["Metall", 200, 65.00]
]
]}
Kleinster Wert
{"min": [7.90, {"var": "fields.preis.value"}, 15.50]}
Größter Wert (für Mindestpreis)
{"max": [9.90, {"*": [{"var": "fields.laenge.value"}, 0.50]}]}
Mindestpreis 9.90, sonst Länge * 0.50
Textlänge
{"length": {"var": "fields.text.value"}}
Feste Textlänge
{"length": "Hallo Welt"}
Ergebnis: 10
Texte verknüpfen
{"cat": ["Preis: ", {"var": "fields.preis.value"}, " Euro"]}
Ergebnis: "Preis: 25.50 Euro"
Text ersetzen (Einheiten entfernen)
{"replace": [{"var": "fields.masse.value"}, " mm", ""]}
Aus "25.5 mm" wird "25.5"
Text ersetzen (allgemein)
{"replace": ["Originaltext", "Alt", "Neu"]}
Teilstring extrahieren (substr)
{"substr": [{"var": "fields.text.value"}, 0, 10]}
Extrahiert die ersten 10 Zeichen
{"substr": ["Hallo Welt", 6]}
Ergebnis: "Welt" (ab Position 6)
Datenzugriff (var)
{"var": "fields.preis.value"}
Zugriff auf Feldwert
{"var": "product.price"}
Zugriff auf Produktpreis
{"var": ["fields.farbe.value", "blau"]}
Mit Standardwert falls Feld leer
Array transformieren (map)
{"map": [
{"var": "fields.preisliste.value"},
{"*": [{"var": ""}, 1.19]}
]}
Alle Preise mit 19% MwSt. multiplizieren
Array filtern (filter)
{"filter": [
{"var": "fields.artikel.value"},
{">": [{"var": ".preis"}, 50]}
]}
Nur Artikel über 50€ behalten
Array-Tests (all/some/none)
{"some": [
{"var": "fields.kategorien.value"},
{"==": [{"var": ""}, "premium"]}
]}
Prüft ob mindestens eine Kategorie "premium" ist
{"all": [
{"var": "fields.bewertungen.value"},
{">": [{"var": ""}, 3]}
]}
Prüft ob alle Bewertungen über 3 sind
{"none": [
{"var": "fields.bewertungen.value"},
{"<": [{"var": ""}, 3]}
]}
Prüft ob KEINE Bewertung unter 3 liegt
Arrays zusammenführen (merge)
{"merge": [
{"var": "fields.grundausstattung.value"},
{"var": "fields.extras.value"}
]}
Verbindet zwei Arrays
Element in Array suchen (in)
{"in": [
{"var": "fields.farbe.value"},
["rot", "blau", "grün"]
]}
Prüft ob gewählte Farbe in erlaubten Farben enthalten ist
Schrittweite prüfen (stepsize)
{"stepsize": [0.5, {"var": "fields.laenge.value"}]}
Ergebnis: true, wenn der Längen-Wert ein ganzzahliges Vielfaches von 0.5 ist (z. B. 1.0, 1.5, 2.0), sonst false. Das eignet sich für die Validierung, um nur bestimmte Schrittweiten zuzulassen.
Eindeutigkeit prüfen (unique)
{"unique": [{"var": "fields.werte.value"}]}
Ergebnis: true, wenn das Array keine Duplikate enthält. Beispiele: {"unique": [1, 2, 3]} → true, {"unique": [2, 2]} → false.
Datum (date / datum)
{"datum": {"var": "fields.liefertermin.value"}}
Wandelt einen Datumsausdruck in einen Unix-Zeitstempel um. Neben Datumsfeldern werden auch "today" / "heute" und "now" (aktuelles Datum) sowie Datumstexte unterstützt. date ist die alternative Schreibweise. So lassen sich z. B. Zeitspannen berechnen:
{"-": [
{"datum": {"var": "fields.liefertermin.value"}},
{"datum": "today"}
]}
Ergebnis: Differenz in Sekunden zwischen Liefertermin und heute.
Regex-Suche (regexFind)
{"regexFind": [{"var": "fields.text.value"}, "[0-9]+"]}
Findet die erste Zahlenfolge im Text. Optionale weitere Argumente: 3. = Treffer-Nummer (1-basiert), 4. = Flags (z. B. "g" oder "i"), 5. = Ersatzwert, falls kein Treffer gefunden wird.
Vorlage anwenden (replaceApply)
{"replaceApply": ["$i", {"var": "index"}, {"var": "calculationFormulas.template"}]}
Ersetzt Platzhalter (z. B. $i) in einer als Vorlage gespeicherten Formel und wertet die Formel anschließend aus. Das ist vor allem für dynamische Formeln in Wiederholfeldern nützlich. Mehrere Ersetzungen sind ebenfalls möglich:
{"replaceApply": [[["$suffix", "a"], ["$i", 0]], {"var": "calculationFormulas.template"}]}