> For the complete documentation index, see [llms.txt](https://docs.premsoft.de/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.premsoft.de/plugins/produkt-konfigurator/verwaltungs-dashboard/formeln.md).

# Formeln

Formeln sind das mächtigste Werkzeug des Konfigurators. Mit ihnen berechnest du **Preise, Maße, Gewicht, eine Artikelnummer** oder **Anzeigewerte** dynamisch aus den Eingaben deiner Kunden – etwa „Preis = Fläche × Quadratmeterpreis" oder „ab 100 Stück 10 % Rabatt".

Dieses Kapitel erklärt Formeln von Grund auf. Du brauchst keine Programmierkenntnisse – nur ein wenig logisches Denken. Alle Beispiele kannst du direkt übernehmen.

{% hint style="info" %}
**Premium-Funktion:** Die „Kalkulation für Experten" (alle Formel-Eingaben) ist Teil der **Premium**-Version. In anderen Versionen sind die Formelfelder sichtbar, aber deaktiviert – siehe [Versionen](/plugins/produkt-konfigurator/versionen.md).
{% endhint %}

## Was ist eine Formel?

Eine Formel ist ein kleiner Rechenausdruck, der ein Ergebnis liefert. Im einfachsten Fall ist das reine Mathematik:

```twig
price + 10
```

Diese Formel bedeutet: nimm den Produktpreis und addiere 10. Anstelle fester Zahlen kannst du **Variablen** verwenden – Platzhalter, die zur Laufzeit mit den echten Werten der Kundeneingaben gefüllt werden.

{% hint style="info" %}
Technischer Hintergrund: Formeln nutzen die Template-Sprache **Twig** in einer abgesicherten Umgebung. Es sind nur die hier dokumentierten Variablen, Funktionen und Filter erlaubt – das hält Formeln sicher.
{% endhint %}

## Wo gebe ich Formeln ein?

Es gibt zwei Orte:

**1. Konfigurator-Berechnungen** (Reiter *Berechnung* des Konfigurators). Jede Berechnung hat einen Schalter und ein Formelfeld:

| Berechnung                          | Ergebnis                 | Variablen-Typ |
| ----------------------------------- | ------------------------ | ------------- |
| **Preis**                           | Endgültiger Stückpreis   | Zahl          |
| **Breite / Höhe / Länge / Gewicht** | Neuer Maß-/Gewichtswert  | Zahl          |
| **Artikelnummer**                   | Generierte Artikelnummer | Text          |

**2. Feld-Berechnungen** (Reiter *Berechnung* eines einzelnen Feldes):

| Berechnung                                           | Ergebnis               | Variablen-Typ |
| ---------------------------------------------------- | ---------------------- | ------------- |
| **Standardwert**                                     | Vorbelegung des Feldes | Zahl/Text     |
| **Ergebnis-Formel** (nur Feldtyp *Zwischenergebnis*) | Live angezeigter Wert  | Text          |

## Verfügbare Variablen

In jeder Formel stehen dir diese Variablen zur Verfügung:

| Variable                              | Bedeutung                                                         |
| ------------------------------------- | ----------------------------------------------------------------- |
| `price`                               | Basis-Stückpreis des Produkts                                     |
| `width`, `height`, `length`, `weight` | Maße und Gewicht des Produkts                                     |
| `fields.<bezeichner>`                 | Der aktuelle Wert eines Feldes, z. B. `fields.menge`              |
| `options.<bezeichner>.price`          | Aufpreis der gewählten Option dieses Feldes                       |
| `options.<bezeichner>.width`          | Breite der gewählten Option (analog `height`, `length`, `weight`) |
| `options.<bezeichner>.value`          | Technischer Wert der gewählten Option                             |

* `<bezeichner>` ist der **technische Bezeichner** des Feldes (siehe [Elemente und Feld Typen](/plugins/produkt-konfigurator/verwaltungs-dashboard/elemente-und-feld-typen.md)).
* Bei Mehrfachauswahl bezieht sich `options.<bezeichner>` auf die **erste** gewählte Option.
* Felder ohne Eingabe liefern einen leeren Wert – nutze dafür den Filter `default` (siehe unten).

## Rechnen: Operatoren

| Operator                    | Bedeutung            | Beispiel                   |
| --------------------------- | -------------------- | -------------------------- |
| `+` `-` `*` `/`             | Grundrechenarten     | `price * 2`                |
| `%`                         | Rest (Modulo)        | `fields.menge % 2`         |
| `**`                        | Potenz               | `width ** 2`               |
| `~`                         | **Texte verketten**  | `'NR-' ~ fields.farbe`     |
| `==` `!=` `>` `<` `>=` `<=` | Vergleiche           | `fields.menge >= 100`      |
| `and` `or` `not`            | Logische Verknüpfung | `width > 0 and height > 0` |

{% hint style="warning" %}
**Wichtig:** Zum **Verbinden von Texten** nutzt du `~`, nicht `+`. Beim Rechnen verwendest du als Dezimaltrennzeichen den **Punkt** (`1.5`, nicht `1,5`).
{% endhint %}

## Funktionen & Filter

**Funktionen** (Aufruf mit Klammern):

| Funktion               | Bedeutung      | Beispiel          |
| ---------------------- | -------------- | ----------------- |
| `max(a, b, …)`         | größter Wert   | `max(price, 25)`  |
| `min(a, b, …)`         | kleinster Wert | `min(price, 500)` |
| `round(wert, stellen)` | runden         | `round(price, 2)` |

**Filter** (angewendet mit `|`):

| Filter          | Bedeutung               | Beispiel                   |
| --------------- | ----------------------- | -------------------------- |
| `round`         | runden                  | `price\|round(2)`          |
| `ceil`          | aufrunden               | `(price)\|ceil`            |
| `floor`         | abrunden                | `(price)\|floor`           |
| `abs`           | Betrag (positiver Wert) | `price\|abs`               |
| `number_format` | formatieren             | `price\|number_format(2)`  |
| `default`       | Ersatzwert bei leer     | `fields.menge\|default(1)` |
| `length`        | Anzahl/Länge            | `fields.zeilen\|length`    |

> `abs`, `ceil` und `floor` gibt es **nur als Filter** (`wert|abs`), nicht als Funktion.

## Bedingungen und Zwischenvariablen

Du kannst Fallunterscheidungen und eigene Zwischenwerte nutzen:

```twig
{% if fields.menge >= 100 %}
    price * 0.9
{% elseif fields.menge >= 50 %}
    price * 0.95
{% else %}
    price
{% endif %}
```

```twig
{% set flaeche = width * height %}
price + flaeche * 0.5
```

Erlaubt sind die Blöcke `{% if %}`, `{% elseif %}`, `{% else %}`, `{% set %}` und `{% for %}`.

## Wichtig: So wirkt die Preis-Formel

Die **Preis-Formel ersetzt den kompletten Stückpreis** – sie ist kein Aufschlag.

* Ist die Preis-Berechnung **aktiv**, bestimmt allein die Formel den Preis. Options-Aufpreise werden **nicht** automatisch addiert – wenn du sie brauchst, nimm sie über `options.<bezeichner>.price` in die Formel auf.
* Ist die Preis-Berechnung **aus**, gilt: Produktpreis **+ Summe der gewählten Options-Aufpreise**.

Mehr zum Zusammenspiel mit Warenkorb und Anzeige unter [Preis und Warenkorb](/plugins/produkt-konfigurator/storefront/preis-und-warenkorb.md).

## Beispiele

### Fester Aufschlag

```twig
price + 15
```

### Aufpreis einer Option einbeziehen

```twig
price + options.material.price
```

### Flächenpreis (Breite × Höhe)

Maße aus Kundeneingaben in Zentimetern, Preis pro Quadratmeter = 40 €:

```twig
price + (fields.breite * fields.hoehe / 10000) * 40
```

### Mengenstaffel (Rabatt ab Stückzahl)

```twig
{% if fields.menge >= 100 %}
    price * 0.85
{% elseif fields.menge >= 50 %}
    price * 0.9
{% else %}
    price
{% endif %}
```

### Mindestpreis sicherstellen

```twig
max(price + options.zubehoer.price, 19.90)
```

### Preis pro Stück × Menge

```twig
(price + options.gravur.price) * fields.menge|default(1)
```

### Aufpreis nach Materialwahl

```twig
{% if fields.material == 'eiche' %}
    price + 80
{% elseif fields.material == 'nuss' %}
    price + 120
{% else %}
    price
{% endif %}
```

### Sauber auf zwei Nachkommastellen runden

```twig
round(price + (fields.breite * fields.hoehe / 10000) * 40, 2)
```

### Maß berechnen (Breiten-Formel)

Endbreite = Grundbreite + Zuschlag aus Eingabe:

```twig
width + fields.zusatzbreite|default(0)
```

### Gewicht berechnen (Gewicht-Formel)

```twig
weight + options.material.weight
```

### Artikelnummer generieren (Text-Formel)

```twig
'SCHILD-' ~ fields.farbe ~ '-' ~ fields.breite ~ 'x' ~ fields.hoehe
```

Ergebnis z. B.: `SCHILD-gold-30x20`

### Zwischenergebnis anzeigen (Ergebnis-Formel)

Für ein Feld vom Typ *Zwischenergebnis*:

```twig
'Fläche: ' ~ (fields.breite * fields.hoehe / 10000)|round(2) ~ ' m²'
```

Zeigt dem Kunden live z. B.: `Fläche: 0,06 m²`

### Standardwert vorbelegen (Standardwert-Formel)

```twig
width
```

## Prüfen & Fehlerverhalten

* **Formel prüfen:** Beim Bearbeiten kannst du eine Formel direkt im Backend auf gültige Syntax prüfen lassen. Unbekannte Variablen oder nicht erlaubte Konstrukte werden gemeldet.
* **Robustheit im Shop:** Führt eine Formel zur Laufzeit nicht zu einem sinnvollen Ergebnis (z. B. wegen einer Division durch Null), fällt der Konfigurator automatisch auf den **Basiswert** zurück (Basispreis bzw. Grundmaß). Dein Shop zeigt also nie einen Fehler an, sondern im Zweifel den unveränderten Preis.

## Tipps & Stolperfallen

* **Texte verketten** mit `~`, **rechnen** mit `+ - * /`. `'A' + 'B'` funktioniert nicht wie erwartet.
* **Dezimalpunkt** verwenden: `0.5`, nicht `0,5`.
* **Leere Felder absichern:** `fields.menge|default(1)` verhindert Rechnen mit einem leeren Wert.
* **Einheiten beachten:** Rechne Längen bewusst um (z. B. cm → m² durch Teilen durch 10000), damit dein Quadratmeterpreis stimmt.
* **`abs`, `ceil`, `floor`** nur als Filter schreiben: `wert|ceil`.
* Klein anfangen: Teste eine einfache Formel, prüfe das Ergebnis im Shop, und erweitere sie dann Schritt für Schritt.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.premsoft.de/plugins/produkt-konfigurator/verwaltungs-dashboard/formeln.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
