> ## 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 - Direct order

> Read the state of a direct order (Scan & Order, order form) in the frontend: input lines, recorded order items, and validity of customer input.

With the `$wsDirectOrder` module, you read the state of a direct order. In a direct order, the customer places products into the basket directly by entering their item numbers, without searching for them individually in the shop. The module returns the current number of input lines and the items recorded so far, including their validity.

This page covers reading the direct-order state. Adding and deleting items happens via the `DirectOrderAdd` / `DirectOrderDelete` actions.

***

## Basic concept

The order form is a form with several input lines. In each line, the customer enters an item number (and a quantity). When submitted, the `DirectOrderAdd` action checks whether the number exists and adds the product to the basket.

`$wsDirectOrder` provides the current state for this:

* [`currentLines`](#wsdirectorder-currentlines) – how many input lines are currently displayed. The value comes from the configuration ([`$wsConfig.directOrder`](/en/frontend/referenz/module/wsconfig#wsconfig-directorder): `initialNumber` to `maximalNumber`).
* [`items`](#wsdirectorder-items) – the items already recorded, each with `id`, `quantity`, and `valid`.

### Validity

The [`valid`](#wsdirectorder-items) field of an item indicates whether the entered item number exists in the shop and can be ordered. Evaluate it to give the customer immediate feedback on an invalid entry.

***

## Module overview

**Example / excerpt of** `$wsDirectOrder`

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

**JSON output**

```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 }
  ]
}
```

**Variables overview**

| **Variable**   | **Type** | **Description**                             |
| -------------- | -------- | ------------------------------------------- |
| `currentLines` | int      | Current number of displayed input lines.    |
| `items`        | array    | Recorded order items (structure see below). |

**Properties of an order item (`items[]`)**

| **Property** | **Type** | **Description**                                      |
| ------------ | -------- | ---------------------------------------------------- |
| `id`         | string   | Entered item number.                                 |
| `quantity`   | int      | Entered quantity.                                    |
| `valid`      | bool     | `true` if the item number exists and can be ordered. |

***

## Templates

By default, the order form is located in the template `module/directOrder.htm`. Link it, e.g. in the footer (see [example](#link-the-page-in-the-footer)).

***

## Variables

### \$wsDirectOrder.currentLines

Returns the current number of displayed input lines. The value is configured via [`$wsConfig.directOrder`](/en/frontend/referenz/module/wsconfig#wsconfig-directorder) (`initialNumber` as the start, `maximalNumber` as the upper limit). Use it, for example, to generate exactly that many lines.

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

### \$wsDirectOrder.items

Returns the recorded order items. Use the line index to access a specific item (`items[$index]`).

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

#### Properties of an order item

| **Property** | **Type** | **Description**                                      |
| ------------ | -------- | ---------------------------------------------------- |
| `id`         | string   | Entered item number.                                 |
| `quantity`   | int      | Entered quantity.                                    |
| `valid`      | bool     | `true` if the item number exists and can be ordered. |

***

## Methods

No methods are available for `$wsDirectOrder`.

***

## Actions

`$wsDirectOrder` itself does not provide any actions. Adding and deleting items happens via the [actions](/en/frontend/referenz/aktionen/directorder).

***

## Examples

### Order form template

This example generates an input row for every configured line (`currentLines`). `range(0, currentLines - 1)` returns the indexes `0` to `currentLines - 1`. For each line, the actions `DirectOrderAdd` and `DirectOrderDelete` are created with the line index as `tag`, so that inputs and errors are assigned to the correct line. The `ifNull('')` filter sets an empty value if the line has not yet been filled in.

```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>Direct order</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">
              <!-- Product icon (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>Please enter item number</p>
                <input type="text" name="id" placeholder="Item no."
                       value="{{= $wsDirectOrder.items[$cProduct].id | ifNull('') }}">
                <label>Quantity</label>
                <input type="text" name="quantity"
                       value="{{= $wsDirectOrder.items[$cProduct].quantity | ifNull('') }}">
                <button type="submit" name="wsact" value="{{= $cActionDirectOrderAdd.id }}">Search</button>
                <button type="submit" name="wsact" value="{{= $cActionDirectOrderDelete.id }}">Delete</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 }}
```

**Result** \
An order form with as many input rows as `currentLines` specifies. Rows that have already been filled in are pre-populated with their item number and quantity.

### Display error messages

The `DirectOrderAdd` action reports errors per field via `errorsByField`. This example shows the errors for the item number (`id`) and the quantity (`quantity`) per line.

```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 }}
```

**Result** \
On invalid input (e.g. an invalid item number or quantity), the corresponding message appears in the affected line.

### Link the page in the footer

You generate the link to the direct order with `viewUrl()`. Pass the path to the template as the argument.

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

**Result** \
A link that leads to the direct-order page.

***

## Related links

* [\$wsActions](/en/frontend/referenz/module/wsactions) – provides the actions `DirectOrderAdd` / `DirectOrderDelete` and the error structure `errorsByField`.
* [\$wsConfig.directOrder](/en/frontend/referenz/module/wsconfig#wsconfig-directorder) – configures the number of lines and additional item-number fields.
* [Online order form](/en/frontend/praxisbeispiele/bestellablauf-bestellfunktionen/online-bestellschein) – detailed practical example.
* [checkout - Order process](/en/konfiguration/checkout-bestellablauf) – configuration of the order process.
