> 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/en/plugins/product-configurator/admin-dashboard/formula.md).

# Formula

Formulas are the configurator's most powerful tool. With them you calculate **prices, dimensions, weight, a product number** or **display values** dynamically from your customers' input – such as "price = area × square-metre price" or "10% discount from 100 units".

This chapter explains formulas from the ground up. You need no programming knowledge – just a bit of logical thinking. You can use all examples directly.

{% hint style="info" %}
**Premium feature:** "Expert calculation" (all formula inputs) is part of the **Premium** version. In other versions the formula fields are visible but disabled – see [Advanced & Premium version](/en/plugins/product-configurator/versions.md).
{% endhint %}

## What is a formula?

A formula is a small calculation expression that produces a result. In the simplest case it is pure maths:

```twig
price + 10
```

This formula means: take the product price and add 10. Instead of fixed numbers you can use **variables** – placeholders that are filled with the real values of the customer input at runtime.

{% hint style="info" %}
Technical background: formulas use the template language **Twig** in a secured environment. Only the variables, functions and filters documented here are allowed – this keeps formulas safe.
{% endhint %}

## Where do I enter formulas?

There are two places:

**1. Configurator calculations** (the configurator's *Calculation* tab). Each calculation has a switch and a formula field:

| Calculation                          | Result                     | Variable type |
| ------------------------------------ | -------------------------- | ------------- |
| **Price**                            | Final unit price           | Number        |
| **Width / Height / Length / Weight** | New dimension/weight value | Number        |
| **Product number**                   | Generated product number   | Text          |

**2. Field calculations** (the *Calculation* tab of an individual field):

| Calculation                                           | Result                | Variable type |
| ----------------------------------------------------- | --------------------- | ------------- |
| **Default value**                                     | Pre-fill of the field | Number/Text   |
| **Result formula** (only field type *Interim result*) | Live displayed value  | Text          |

## Available variables

In every formula you have these variables available:

| Variable                              | Meaning                                                              |
| ------------------------------------- | -------------------------------------------------------------------- |
| `price`                               | Base unit price of the product                                       |
| `width`, `height`, `length`, `weight` | Dimensions and weight of the product                                 |
| `fields.<identifier>`                 | The current value of a field, e.g. `fields.quantity`                 |
| `options.<identifier>.price`          | Surcharge of the selected option of that field                       |
| `options.<identifier>.width`          | Width of the selected option (likewise `height`, `length`, `weight`) |
| `options.<identifier>.value`          | Technical value of the selected option                               |

* `<identifier>` is the **technical identifier** of the field (see [Elements & field types](/en/plugins/product-configurator/admin-dashboard/elements-and-field-types.md)).
* For multiple choice, `options.<identifier>` refers to the **first** selected option.
* Fields without input return an empty value – use the `default` filter for those (see below).

## Calculating: operators

| Operator                    | Meaning              | Example                    |
| --------------------------- | -------------------- | -------------------------- |
| `+` `-` `*` `/`             | Basic arithmetic     | `price * 2`                |
| `%`                         | Remainder (modulo)   | `fields.quantity % 2`      |
| `**`                        | Power                | `width ** 2`               |
| `~`                         | **Concatenate text** | `'NR-' ~ fields.colour`    |
| `==` `!=` `>` `<` `>=` `<=` | Comparisons          | `fields.quantity >= 100`   |
| `and` `or` `not`            | Logical combination  | `width > 0 and height > 0` |

{% hint style="warning" %}
**Important:** To **join text** use `~`, not `+`. When calculating, use the **dot** as the decimal separator (`1.5`, not `1,5`).
{% endhint %}

## Functions & filters

**Functions** (called with parentheses):

| Function               | Meaning        | Example           |
| ---------------------- | -------------- | ----------------- |
| `max(a, b, …)`         | largest value  | `max(price, 25)`  |
| `min(a, b, …)`         | smallest value | `min(price, 500)` |
| `round(value, digits)` | round          | `round(price, 2)` |

**Filters** (applied with `|`):

| Filter          | Meaning                   | Example                       |
| --------------- | ------------------------- | ----------------------------- |
| `round`         | round                     | `price\|round(2)`             |
| `ceil`          | round up                  | `(price)\|ceil`               |
| `floor`         | round down                | `(price)\|floor`              |
| `abs`           | absolute (positive) value | `price\|abs`                  |
| `number_format` | format                    | `price\|number_format(2)`     |
| `default`       | fallback when empty       | `fields.quantity\|default(1)` |
| `length`        | count/length              | `fields.lines\|length`        |

> `abs`, `ceil` and `floor` exist **only as filters** (`value|abs`), not as functions.

## Conditions and intermediate variables

You can use case distinctions and your own intermediate values:

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

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

The blocks `{% if %}`, `{% elseif %}`, `{% else %}`, `{% set %}` and `{% for %}` are allowed.

## Important: how the price formula works

The **price formula replaces the entire unit price** – it is not a surcharge.

* If the price calculation is **active**, the formula alone determines the price. Option surcharges are **not** added automatically – if you need them, include them via `options.<identifier>.price` in the formula.
* If the price calculation is **off**, the rule is: product price **+ the sum of the selected option surcharges**.

More about the interaction with cart and display under [Price & cart](/en/plugins/product-configurator/storefront/pricing-and-cart.md).

## Examples

### Fixed surcharge

```twig
price + 15
```

### Include an option's surcharge

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

### Area price (width × height)

Dimensions from customer input in centimetres, price per square metre = €40:

```twig
price + (fields.width * fields.height / 10000) * 40
```

### Quantity tiers (discount from a number of units)

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

### Enforce a minimum price

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

### Price per unit × quantity

```twig
(price + options.engraving.price) * fields.quantity|default(1)
```

### Surcharge by material choice

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

### Round cleanly to two decimals

```twig
round(price + (fields.width * fields.height / 10000) * 40, 2)
```

### Calculate a dimension (width formula)

Final width = base width + surcharge from input:

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

### Calculate weight (weight formula)

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

### Generate a product number (text formula)

```twig
'SIGN-' ~ fields.colour ~ '-' ~ fields.width ~ 'x' ~ fields.height
```

Result e.g.: `SIGN-gold-30x20`

### Show an interim result (result formula)

For a field of type *Interim result*:

```twig
'Area: ' ~ (fields.width * fields.height / 10000)|round(2) ~ ' m²'
```

Shows the customer live, e.g.: `Area: 0.06 m²`

### Pre-fill a default value (default value formula)

```twig
width
```

## Checking & error behaviour

* **Check the formula:** While editing you can have a formula validated for correct syntax directly in the backend. Unknown variables or disallowed constructs are reported.
* **Robustness in the shop:** If a formula does not produce a sensible result at runtime (e.g. due to a division by zero), the configurator automatically falls back to the **base value** (base price or base dimension). So your shop never shows an error, but in case of doubt the unchanged price.

## Tips & pitfalls

* **Concatenate text** with `~`, **calculate** with `+ - * /`. `'A' + 'B'` does not work as expected.
* Use the **decimal point**: `0.5`, not `0,5`.
* **Safeguard empty fields:** `fields.quantity|default(1)` prevents calculating with an empty value.
* **Mind the units:** convert lengths deliberately (e.g. cm → m² by dividing by 10000) so your square-metre price is correct.
* **`abs`, `ceil`, `floor`** only as filters: `value|ceil`.
* Start small: test a simple formula, check the result in the shop, then extend it step by step.


---

# 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/en/plugins/product-configurator/admin-dashboard/formula.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.
