# Profimodus

{% hint style="danger" %}
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
{% endhint %}

#### Aufbau / Syntax

Die Formel im Profimodus ist ein JSON-Objekt, d.h. jegliche Operatoren werden als JSON-Objekt definiert.

#### Operatoren

Im einfachen Modus stehen die Logikoperatoren und boolesche Operatoren und arithmetische Operatoren zur Verfügung

#### Arithmetische Operatoren

<table><thead><tr><th>Name</th><th>Operator</th></tr></thead><tbody><tr><td>Multiplizieren</td><td><pre><code>{"*":[1,2]}
</code></pre></td></tr><tr><td>Didivdieren</td><td><pre><code>{"/":[1,2]}
</code></pre></td></tr><tr><td>Addieren</td><td><pre><code>{"+":[1,2]}
</code></pre></td></tr><tr><td>Subtrahieren</td><td><pre><code>{"-":[1,2]}
</code></pre></td></tr><tr><td>Quadratwurzel ziehen</td><td><pre><code>{"sqrt":16} 
{"sqrt":{"var":"fields.zahl.value"}
</code></pre></td></tr><tr><td>Potenzieren</td><td><pre><code>{"pow":[2,3]} -> 2 hoch 3 
{"pow":[{"var":"fields.zahl.value"},2]}
</code></pre></td></tr></tbody></table>

Alle Operatoren können durch die Angabe weiterer Argumente erweitert werden. Die Anzahl ist also nicht auf 2 beschränkt, z.B. {"\*":\[1,2,3,4]} = 1 \* 2 \* 3 \* 4 = 24

#### Vergleichsoperatoren &#x20;

<table><thead><tr><th>Name</th><th width="462.5688729874776">Operator</th></tr></thead><tbody><tr><td>if / else</td><td><pre><code>{"if" : [
  Bedingung,
  falls Bedingung wahr,
  sonst
]}
</code></pre></td></tr><tr><td>if /else if / if</td><td><pre><code>{"if" : [
  {"&#x3C;": [{"var":"fields.length.value"}, 100] }, 20,  
  {"&#x3C;": [{"var":"fields.length.value"}, 200] }, 30,  
  {"*":[{"var":"fields.length.value"},10]}
]}
</code></pre><p><strong>Ergibt</strong>: <br>Falls Länge &#x3C; 100: 20<br>Sonst falls Länge &#x3C; 200: 30,<br>sonst 10</p></td></tr><tr><td>Gleich</td><td><pre><code>{"==" : [2, 1]}
</code></pre></td></tr><tr><td>Ungleich</td><td><pre><code>{"!=" : [2, 1]}
</code></pre></td></tr><tr><td>Größer gleich / Größer</td><td><pre><code>{">" : [2, 1]}
{">=" : [2, 1]}
</code></pre></td></tr><tr><td>Kleiner gleich / Kleiner</td><td><pre><code>{"&#x3C; " : [1, 2]}
{"&#x3C; =" : [1, 2]}
</code></pre><p><strong>Nach dem &#x3C; Zeichen immer ein Leerzeichen lassen!</strong></p></td></tr></tbody></table>

#### Rundungen

Vor allem in der Preisberechnung können Rundungen sinnvoll sein.

<table><thead><tr><th>Name</th><th width="462.5688729874776">Operator</th></tr></thead><tbody><tr><td>Runden</td><td><pre><code>{"round" : [{"var":"fields.length.value"}, 2]}
{"round" : [7.999393, 2]}
</code></pre><p>Rundet den Wert aus dem Feld auf 2 Nachkommastellen</p></td></tr><tr><td>Aufrunden</td><td><pre><code>{"ceil" : 7.90}
</code></pre><p>Ergebnis: 8</p></td></tr><tr><td>Abrunden</td><td><pre><code>{"floor" : 7.90}
</code></pre><p>Ergebnis: 7</p></td></tr></tbody></table>

#### Bruttopreise / Nettopreise - steuersensitive Angaben je nach Kundengruppe

<table><thead><tr><th>Name</th><th width="462.5688729874776">Operator</th></tr></thead><tbody><tr><td>Preis als Brutto-Preis markieren</td><td><pre><code>{"brutto" : 2.40}
{"brutto" : {"var":"fields.auswahl.price"}}
</code></pre><p>Sowohl <strong>brutto</strong> als auch <strong>gross</strong> werden als Operator-Name unterstützt:</p><pre><code>{"gross" : 2.40}
{"gross" : {"var":"fields.auswahl.price"}}
</code></pre></td></tr><tr><td>Preis als Netto-Preis markieren</td><td><pre><code>{"netto" : 2.40}
{"netto" : {"var":"fields.auswahl.price"}}
</code></pre><p>Sowohl <strong>net</strong> als auch <strong>netto</strong> werden als Operator-Name unterstützt:</p><pre><code>{"net" : 2.40}
{"net" : {"var":"fields.auswahl.price"}}
</code></pre></td></tr></tbody></table>

#### Sonstiges

<table><thead><tr><th>Name</th><th width="462.5688729874776">Operator</th></tr></thead><tbody><tr><td>Matrix-Operator für Staffelpreise / Preistabellen</td><td><pre><code><strong>{"matrix":[
</strong>  550,
  [
    [500, 84.00],
    [600, 89.00],
    [700,94.00]
  ]
]}

{"matrix":\[
{"var":"fields.auflage.value"},
\[
\[100, 84.00],
\[200, 89.00],
\[300,94.00]
]
]}

{"matrix":\[
{"var":"fields.length.value"},{"var":"fields.width.value"},
\[
\[100, 20, 84.00],
\[200, 20, 89.00],
\[300, 20, 94.00]
]
]} </code></pre></td></tr><tr><td>Kleinster Wert</td><td><pre><code>{"min" : \[7.90,{"var":"fields.length.value"}]} </code></pre></td></tr><tr><td>Größter Wert</td><td><pre><code>{"max" : \[7.90,{"var":"fields.length.value"}]} </code></pre></td></tr><tr><td>Textlänge</td><td><pre><code>{"length" : "Hallo"}
{"length" : {"var":"fields.text.value"}} </code></pre></td></tr><tr><td>Texte verknüpfen</td><td><pre><code>{"cat" : \["Anzahl Felder: ", {"var:"fields.repeater.count"}]} </code></pre><p>--> Anzahl Felder: 3</p></td></tr><tr><td>Text ersetzen</td><td><p>Text kann ersetzt werden. In diesem Beispiel werden die mm entfernt, damit z.B. weiter mit der Zahl gerechnet werden kann, aus 29.7 mm wird 29.7</p><pre><code>{"replace" : \["29.7 mm", " mm", ""]} </code></pre><pre><code>{"replace" : \["Text", "Suche", "Ersetzung"]} </code></pre></td></tr></tbody></table>

### Beispiele

#### Formelbeispiel: Preis richtet sich nach der Anzahl der eingegebenen Buchstaben

```json5
{
  "if": [
    {">": [{"length": {"var": "fields.textfield.value"}}, 2]},
    {"*":[{"var":"product.price"}, 2.5]},
    {"*":[{"var":"product.price"}, 5.4]}
  ]
}
```

#### Formelbeispiel Validierung

Falls im Feld "Dicke" ein Wert kleiner als 6 eingetragen / gewählt wurde, ist der maximal gültige Wert 1400, sonst 2000.

```json5
{"or": [
{"and" : [{"< " : [{"var":"fields.dicke.value"}, 6]}, {"< " : [{"var":"value"}, 1400]}]},
{"and" : [{">=" : [{"var":"fields.dicke.value"}, 6]}, {"< " : [{"var":"value"}, 2000]}]}
]}
```

#### **Formelbeispiel Preis abhängig von Textlänge**

2 Euro pro Buchstabe siehe Beispiel im Demoshop:\
[Storefront](https://demoshop-shopware-6.neonlines.de/Konfigurator-einfacher-Variantenartikel-mit-Textfeld/SW10012.3#neonCfg=aufdruck:Happy%20Birthday) [Admin](https://demoshop-shopware-6.neonlines.de/admin#/neon/configurator/detail/27a28aa105474d799d1cf9887adf6d3c/pricecalculation) (demo demo)

```
{"*":[
    2,
    {"length":{"var":"fields.aufdruck.value"}}
]}
```

#### **Formelbeispiel: Mindestpreis**

Durch den min-Operator wird der jeweils kleinste Wert ausgewählt. Wenn die Berechnung im Ergebnis kleiner als 9,90 ist, wird 9,90 ausgegeben.&#x20;

<pre class="language-json"><code class="lang-json">{"max" : [
  9.90,
  {"if": [
    {">": [{"length": {"var": "fields.textfield.value"}}, 2]},
    {"*":[{"var":"product.price"}, 2.5]},
    {"*":[{"var":"product.price"}, 5.4]}
  ]}
<strong>]}
</strong></code></pre>

Auch mehrere Werte sind möglich, der größte Preis wird gewählt, durch die Angabe von 9.90 wird der Mindestpreis auf 9.90 Euro festgelegt.

<pre class="language-json"><code class="lang-json"><strong>{"max" : [
</strong>  9.90,
  {"*":[{"var":"product.price"}, {"var":"fields.length.value"}]},
  {"if": [
    {">": [{"length": {"var": "fields.textfield.value"}}, 2]},
    {"*":[{"var":"product.price"}, 2.5]},
    {"*":[{"var":"product.price"}, 5.4]}
  ]}
<strong>]}
</strong></code></pre>

#### **Formelbeispiel Preisstaffel mit dem Matrix-Operator**

Mit dem Matrix-Operator lassen sich Preisstaffeln / Staffelpreise einfach umsetzen. Statt mit verschachtelten if-gleich-Blöcken zu arbeiten, kann hier die Eingabe ganz einfach Zeile für Zeile erfolgen.\
\
In der ersten Zeile wird der zu prüfende Wert eingetragen, in den Folgezeilen die Abstufungen. Im folgenden Beispiel wird bei Auflage >= 100 und < 200 der Wert 10 gewählt, bei >=200 und < 300 der Wert 8.90 etc. Dieses Ergebnis lässt sich wieder mit anderen Operatoren weiterverarbeiten und kombinieren.

```
{"matrix":[
  {"var":"fields.auflage.value"},
  [
    [0, 10.00],
    [100, 9.90],
    [200, 8.90],
    [300, 8.70]
  ]
]}
```

Auch weitere Dimensionen sind möglich:

```
{"matrix":[
  {"var":"fields.laenge.value"},{"var":"fields.breite.value"},
  [
    [100, 10, 9.90],
    [200, 10, 18.90],
    [300, 10, 27.70],
    [100, 20, 11.90],
    [200, 20, 21.90],
    [300, 20, 31.70],
    [100, 30, 41.90],
    [200, 30, 54.90],
    [300, 30, 45.70],
  ]
]}
```

Dieses Beispiel würde in tabellarischer Form so aussehen:

<table data-header-hidden><thead><tr><th width="208">200</th><th></th><th></th><th></th><th data-hidden>Länge</th></tr></thead><tbody><tr><td><strong>Breite</strong> ↓ <strong>Länge -></strong></td><td>100</td><td>200</td><td>300</td><td></td></tr><tr><td>10</td><td>9,90</td><td>18,90</td><td>27,70</td><td></td></tr><tr><td>20</td><td>11,90</td><td>21,90</td><td>31,70</td><td></td></tr><tr><td>30</td><td>41,90</td><td>54,90</td><td>45,70</td><td></td></tr><tr><td></td><td></td><td></td><td></td><td></td></tr></tbody></table>

Das funktioniert auch mit Auswahlfeldern:

```
{"matrix":[
  {"var":"fields.auswahl.value"},{"var":"fields.breite.value"},
  [
    ["Variante A", 0, 10],
    ["Variante A", 100, 6],
    ["Variante B", 0, 10.50],
    ["Variante B", 100, 6.50]
  ]
]}

```

{% hint style="info" %}
Es sind beliebig viele Dimensionen damit abbildbar
{% endhint %}
