> ## Documentation Index
> Fetch the complete documentation index at: https://dokumentation.websale.de/llms.txt
> Use this file to discover all available pages before exploring further.

# $wsDirectOrder - Direktbestellung

> Zustand einer Direktbestellung (Scan & Order, Bestellschein) im Frontend lesen: Eingabezeilen, erfasste Positionen und Validität der Eingaben.

Mit dem `$wsDirectOrder`-Modul lesen Sie den Zustand einer Direktbestellung. Bei der Direktbestellung legt der Kunde Produkte durch Eingabe ihrer Artikelnummern direkt in den Warenkorb, ohne sie einzeln im Shop zu suchen. Das Modul liefert die aktuelle Anzahl der Eingabezeilen und die bisher erfassten Positionen samt Gültigkeit.

Auf dieser Seite geht es um das Lesen des Direktbestell-Zustands. Das Hinzufügen und Löschen von Positionen erfolgt über die Aktionen `DirectOrderAdd` / `DirectOrderDelete`.

***

## Grundkonzept

Der Bestellschein ist ein Formular mit mehreren Eingabezeilen. In jede Zeile gibt der Kunde eine Artikelnummer (und eine Menge) ein. Beim Absenden prüft die Aktion `DirectOrderAdd`, ob die Nummer existiert, und legt das Produkt in den Warenkorb.

`$wsDirectOrder` stellt dabei den aktuellen Zustand bereit:

* [`currentLines`](#wsdirectorder-currentlines) – wie viele Eingabezeilen aktuell angezeigt werden. Der Wert stammt aus der Konfiguration ([`$wsConfig.directOrder`](/frontend/referenz/module/wsconfig#wsconfig-directorder): `initialNumber` bis `maximalNumber`).
* [`items`](#wsdirectorder-items) – die bereits erfassten Positionen, je mit `id`, `quantity` und `valid`.

### Gültigkeit

Das Feld [`valid`](#wsdirectorder-items) einer Position zeigt an, ob die eingegebene Artikelnummer im Shop existiert und bestellbar ist. Werten Sie es aus, um dem Kunden eine ungültige Eingabe direkt zurückzumelden.

***

## Modulübersicht

**Beispiel / Ausschnitt über** `$wsDirectOrder`

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $wsDirectOrder | json }}
```

**JSON-Ausgabe**

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
  "currentLines": 5,
  "items": [
    { "id": "123-45678", "quantity": 1, "valid": true },
    { "id": "910-111213", "quantity": 1, "valid": false }
  ]
}
```

**Variablen in der Übersicht**

| **Variable**   | **Typ** | **Beschreibung**                                   |
| -------------- | ------- | -------------------------------------------------- |
| `currentLines` | int     | Aktuelle Anzahl der angezeigten Eingabezeilen.     |
| `items`        | array   | Erfasste Bestellpositionen (Struktur siehe unten). |

**Eigenschaften einer Bestellposition (`items[]`)**

| **Eigenschaft** | **Typ** | **Beschreibung**                                             |
| --------------- | ------- | ------------------------------------------------------------ |
| `id`            | string  | Eingegebene Artikelnummer.                                   |
| `quantity`      | int     | Eingegebene Menge.                                           |
| `valid`         | bool    | `true`, wenn die Artikelnummer existiert und bestellbar ist. |

***

## Templates

Der Bestellschein liegt im Standard im Template `module/directOrder.htm`. Verlinken Sie ihn z. B. im Footer (siehe [Beispiel](#seite-im-footer-verlinken)).

***

## Variablen

### \$wsDirectOrder.currentLines

Gibt die aktuelle Anzahl der angezeigten Eingabezeilen aus. Der Wert wird über [`$wsConfig.directOrder`](/frontend/referenz/module/wsconfig#wsconfig-directorder) konfiguriert (`initialNumber` als Start, `maximalNumber` als Obergrenze). Nutzen Sie ihn beispielsweise, um genau so viele Zeilen zu erzeugen.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Aktuelle Zeilen: {{= $wsDirectOrder.currentLines }}
```

### \$wsDirectOrder.items

Gibt die erfassten Bestellpositionen aus. Über den Zeilenindex greifen Sie auf eine bestimmte Position zu (`items[$index]`).

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $item in $wsDirectOrder.items }}
  {{= $item.id }} – Menge: {{= $item.quantity }} – gültig: {{= $item.valid }}
{{ /foreach }}
```

#### Eigenschaften einer Bestellposition

| **Eigenschaft** | **Typ** | **Beschreibung**                                             |
| --------------- | ------- | ------------------------------------------------------------ |
| `id`            | string  | Eingegebene Artikelnummer.                                   |
| `quantity`      | int     | Eingegebene Menge.                                           |
| `valid`         | bool    | `true`, wenn die Artikelnummer existiert und bestellbar ist. |

***

## Methoden

Für `$wsDirectOrder` stehen keine Methoden zur Verfügung.

***

## Aktionen

`$wsDirectOrder` selbst stellt keine Aktionen bereit. Das Hinzufügen und Löschen von Positionen erfolgt über die [Aktionen](/frontend/referenz/aktionen/directorder).

***

## Beispiele

### Bestellschein-Template

Dieses Beispiel erzeugt für jede konfigurierte Zeile (`currentLines`) eine Eingabereihe. `range(0, currentLines - 1)` liefert die Indizes `0` bis `currentLines - 1`. Pro Zeile werden die Aktionen `DirectOrderAdd` und `DirectOrderDelete` mit dem Zeilenindex als `tag` erzeugt, damit Eingaben und Fehler der richtigen Zeile zugeordnet werden. Der Filter `ifNull('')` setzt einen leeren Wert, falls die Zeile noch nicht erfasst wurde.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ extends "layouts/layout.htm" }}
{{ block content_main }}
  <div id="wsBasketWrapper">
    <h1>Direktbestellung</h1>
    <table class="table">
      <tbody id="wsDirectOrderTableBody">
        {{ foreach $cProduct in range(0, $wsDirectOrder.currentLines - 1) }}
          {{ var $cActionDirectOrderAdd = $wsActions.create("DirectOrderAdd", tag=string($cProduct)) }}
          {{ var $cActionDirectOrderDelete = $wsActions.create("DirectOrderDelete", tag=string($cProduct)) }}
          <tr class="wsDirectOrderRow">
            <td class="wsTableCellMin">
              <!-- Produktsymbol (SVG) -->
            </td>
            <td>
              <form method="POST" action="{{= $wsViews.current.url() }}">
                <input type="hidden" name="wscsrf" value="{{= $cActionDirectOrderAdd.csrf }}">
                <input type="hidden" name="wstarget" value="{{= $wsViews.current.url() }}">
                <p>Bitte Artikelnummer eingeben</p>
                <input type="text" name="id" placeholder="Art.-Nr."
                       value="{{= $wsDirectOrder.items[$cProduct].id | ifNull('') }}">
                <label>Menge</label>
                <input type="text" name="quantity"
                       value="{{= $wsDirectOrder.items[$cProduct].quantity | ifNull('') }}">
                <button type="submit" name="wsact" value="{{= $cActionDirectOrderAdd.id }}">Suchen</button>
                <button type="submit" name="wsact" value="{{= $cActionDirectOrderDelete.id }}">Löschen</button>

                {{ foreach $field in $wsConfig.directOrder.itemNumberFields }}
                  {{ if $field.type == "field" }}
                    <input type="text" name="{{= $field.name }}">
                  {{ elseif $field.type == "separator" }}
                    {{= $field.sign }}
                  {{ /if }}
                {{ /foreach }}
              </form>
            </td>
          </tr>
        {{ /foreach }}
      </tbody>
    </table>
  </div>
{{ /block }}
```

**Ergebnis** \
Ein Bestellschein mit so vielen Eingabereihen, wie `currentLines` vorgibt. Bereits erfasste Zeilen haben ihre Artikelnummer und Menge vorbelegt.

### Fehlermeldungen anzeigen

Die Aktion `DirectOrderAdd` meldet Fehler feldbezogen über `errorsByField`. Dieses Beispiel zeigt die Fehler zur Artikelnummer (`id`) und zur Menge (`quantity`) je Zeile.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $cProduct in range(0, $wsDirectOrder.currentLines - 1) }}
  {{ var $cActionDirectOrderAdd = $wsActions.create("DirectOrderAdd", tag=string($cProduct)) }}

  {{ if $cActionDirectOrderAdd.errorsByField.id }}
    <div class="alert alert-danger">
      {{ foreach $err in $cActionDirectOrderAdd.errorsByField.id }}
        {{ if $err.text }}{{= $err.text }}{{ else }}{{= $err.code }}{{ /if }}
      {{ /foreach }}
    </div>
  {{ /if }}

  {{ if $cActionDirectOrderAdd.errorsByField.quantity }}
    <div class="alert alert-danger">
      {{ foreach $err in $cActionDirectOrderAdd.errorsByField.quantity }}
        {{ if $err.text }}{{= $err.text }}{{ else }}{{= $err.code }}{{ /if }}
      {{ /foreach }}
    </div>
  {{ /if }}
{{ /foreach }}
```

**Ergebnis** \
Bei fehlerhafter Eingabe (z. B. ungültige Artikelnummer oder Menge) erscheint die zugehörige Meldung in der betreffenden Zeile.

### Seite im Footer verlinken

Den Link zur Direktbestellung erzeugen Sie mit `viewUrl()`. Den Pfad zum Template als Argument übergeben.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<a href="{{= $wsViews.viewUrl('module/directOrder.htm') }}">Direktbestellung</a>
```

**Ergebnis** \
Ein Link, der zur Direktbestell-Seite führt.

***

## Weiterführende Links

* [\$wsActions](/frontend/referenz/module/wsactions) – stellt die Aktionen `DirectOrderAdd` / `DirectOrderDelete` und die Fehlerstruktur `errorsByField` bereit.
* [\$wsConfig.directOrder](/frontend/referenz/module/wsconfig#wsconfig-directorder) – konfiguriert Zeilenanzahl und zusätzliche Artikelnummer-Felder.
* [Online-Bestellschein](/frontend/praxisbeispiele/bestellablauf-bestellfunktionen/online-bestellschein) – ausführliches Praxisbeispiel.
* [checkout - Bestellablauf](/konfiguration/checkout-bestellablauf) – Konfiguration des Bestellablaufs.
