> ## 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.

# OFFER- (Customer-specific offers)

> Display offers made to an individual customer: loop through the offers, output header data and totals, and list the offer products with their special prices and discounts.

A customer-specific offer is a price list that applies only to a single customer: certain products at certain quantities and prices, limited until a validity date. The offers are imported into the shop and assigned to the customer via their customer number. If they view them in the shop, they buy at these prices.

There are two tag families for this. `OFFER-` returns the header data of an offer, that is, number, date, costs and totals. `OPR-` returns the products in it, that is, name, quantity, offer price and discount. Both are held together by two nested loops.

Guide: Customer-specific offers · Reference: Offers section

## The structure of an offer page

The shop system stores a customer's offers and an offer's products in two separate lists. The outer loop `{@WS-OffersList}` runs over the offers and each time reloads the products of the offer currently reached. Only then does the inner loop `{@OPR-Data}` operate on filled data.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{WS-OffersList}
   {@WS-OffersList}

      <h2>Angebot ~OFFER-ID~ vom ~OFFER-Date~</h2>
      <p>gültig bis ~OFFER-ExpireDate~</p>

      {CAT-AdvData($Offers,99)}
         <table>
            {@OPR-Data}
               <tr>
                  <td>~OPR-Number~</td>
                  <td>~OPR-Name~</td>
                  <td>~OPR-Quantity~ ~OPR-Unit~</td>
                  <td>~OPR-Price~</td>
               </tr>
            {/@OPR-Data}
         </table>
      {/CAT-AdvData($Offers,99)}

      <p>Gesamtsumme: ~OFFER-TotalSumGross~</p>

   {/@WS-OffersList}
{/WS-OffersList}

{!WS-OffersList}
   <p>Für Sie liegen derzeit keine Angebote vor.</p>
{/!WS-OffersList}
```

> [!WARNING]
>
> The order is mandatory. Outside `{@WS-OffersList}`, no offer is selected, and all `OFFER-` tags are then treated as an invalid tag. The `OPR-` tags in turn additionally need the area tag `{CAT-AdvData($Offers,99)}`, because only that provides the product list of the offer.

> [!NOTE]
>
> The outer loop recalculates the offer totals on each pass. The tags `OFFER-TotalSumNet`, `OFFER-TotalSumGross` and `OFFER-TotalSumVAT` are therefore only reliable within the loop.

> [!NOTE]
>
> The number in the argument of `CAT-AdvData` otherwise limits the number of listed products. For `$Offers`, the shop system does not evaluate it; the loop always runs over all products of the offer. Write the number anyway so that the notation matches all other `CAT-AdvData` areas.

`WS-OffersList` is described under WS- (General tags), `CAT-AdvData` under CAT- (Categories and product lists).

## The header data of an offer

| Tag | Returns |
| - | - |
| `OFFER-ID` | the offer number |
| `OFFER-Date` | the offer date |
| `OFFER-ExpireDate` | the validity date |
| `OFFER-Descr` | the description of the offer |

> [!NOTE]
>
> All four also work as area tags and take effect if a value is available. This is worthwhile for `OFFER-Descr` and `OFFER-ExpireDate`, because both fields are not mandatory in the import.

## Payment method, shipping method and totals

Each offer has a payment method, a shipping method and the resulting costs. Each is available in three variants: net, gross and as a VAT amount.

| Tag | Returns |
| - | - |
| `OFFER-PaymentCostNet` | the net costs of the payment method |
| `OFFER-PaymentCostGross` | the gross costs of the payment method |
| `OFFER-PaymentCostVAT` | the VAT amount of the payment method |
| `OFFER-DeliveryCostNet` | the net costs of the shipping method |
| `OFFER-DeliveryCostGross` | the gross costs of the shipping method |
| `OFFER-DeliveryCostVAT` | the VAT amount of the shipping method |
| `OFFER-TotalSumNet` | the net total of the offer |
| `OFFER-TotalSumGross` | the gross total of the offer |
| `OFFER-TotalSumVAT` | the VAT amount of the total |

In addition, there are the names of the two methods and three older tags without a breakdown.

| Tag | Returns |
| - | - |
| `OFFER-PaymentName` | the name of the payment method |
| `OFFER-DeliveryName` | the name of the shipping method |
| `OFFER-PaymentCost` | the costs of the payment method |
| `OFFER-DeliveryCost` | the costs of the shipping method |
| `OFFER-TotalSum` | the total of the offer |

> [!NOTE]
>
> These five tags are not described in the previous documentation. `OFFER-PaymentName` and `OFFER-DeliveryName` are the only way to show the customer at all which payment and shipping method are stored for their offer. The three cost tags without a suffix date from the time before the split into net and gross. In new templates, use the variants with `Net`, `Gross` and `VAT`, because it is clear there what is output.

> [!NOTE]
>
> All amounts are output in the shop's number format, that is, with the configured decimal separator and thousands separator. The shop system does not append a currency; you add it yourself with `WS-Currency` or `WS-CurrencySymbol`.

## The products of an offer

`OPR-Data` is exclusively a loop tag. As a single tag or area tag, it outputs nothing. The check whether any products exist at all is handled by the area tag `{CAT-AdvData($Offers,99)}` above it, which hides itself automatically for an empty offer.

| Tag | Returns |
| - | - |
| `OPR-Name` | the product name |
| `OPR-Number` | the product number |
| `OPR-Insert` | the additional text of the product |
| `OPR-Quantity` | the order quantity |
| `OPR-Unit` | the unit |
| `OPR-Image` | the address of the product image |
| `OPR-Variations` | the permanently assigned variants |

> [!NOTE]
>
> `OPR-Insert` and `OPR-Image` are not described in the previous documentation. `OPR-Image` returns a complete address to the product image, not just the file name. If there is no image, the output remains empty and the area tag does not take effect, so you can cleanly omit the image column.

> [!WARNING]
>
> `OPR-Quantity` outputs the quantity without decimal places. For products ordered in fractions, for example goods sold by the meter, you see the truncated number in the template. Internally, the full value is used for calculation.

### Displaying variants

`OPR-Variations` has two tasks. As a single tag, it outputs the permanently assigned variants of the offer product, for example size and color. As an area tag, it takes effect if variants or text input fields are present.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{OPR-Variations}
   <p class="varianten">~OPR-Variations~</p>
{/OPR-Variations}
```

### The prices

| Tag | Returns |
| - | - |
| `OPR-Price` | the offer price as stored in the offer |
| `OPR-NetPrice` | the net offer price |
| `OPR-GrossPrice` | the gross offer price |
| `OPR-VAT` | the VAT amount of the offer price |

> [!WARNING]
>
> All four prices refer to the **order quantity**, not to the individual item. With a quantity of 10, `OPR-GrossPrice` contains the price for all ten. If you want to show a unit price, you must state it yourself or store a quantity of 1 in the offer.

### The discount

| Tag | Returns |
| - | - |
| `OPR-DiscountRate` | the discount as a percentage |
| `OPR-Discount` | the discount as an amount |

In the offer, you specify only one of the two values. The shop system calculates the other. If you specify the percentage, the amount results from it; if you specify the amount, the percentage results from it.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{OPR-DiscountRate}
   <span class="rabatt">~OPR-DiscountRate~ % gespart</span>
{/OPR-DiscountRate}
```

> [!NOTE]
>
> Both tags output an empty string for a value of zero. The area tag then does not take effect, and the discount notice disappears automatically. So you don't need a separate check for "no discount".

## Selecting an offer

If a customer has several offers, there are two ways to show them.

The first is a selection list. For this, you place `WS-OffersList` as a single tag. The shop system builds a complete select box from it with all of the customer's offers, and the customer only ever sees the selected one.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<form action="~FORM-Offers~" method="post">
   ~WS-OffersList~
</form>
```

The second way is the loop from above, which places all offers one below the other on a page. Then each offer needs its own form, and it must state which offer it is about. `WS-PrintHiddenOfferInput` takes care of this.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{@WS-OffersList}
   <form action="~FORM-Offers~" method="post">
      ~WS-PrintHiddenOfferInput~
      ...
   </form>
{/@WS-OffersList}
```

> [!NOTE]
>
> `WS-PrintHiddenOfferInput` generates a complete hidden input field with the index of the current loop pass. So you don't write an `input` element around it. Only place it within the loop, because outside it the index is zero.

`WS-OffersCount` outputs the number of offers and is suitable for a heading above the list.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<p>Für Sie liegen ~WS-OffersCount~ Angebote vor.</p>
```

## Messages

`MSG-Offers_Notify` outputs notice texts related to the offers, for example if an offer has expired.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{MSG-Offers_Notify}
   <p class="hinweis">~MSG-Offers_Notify~</p>
{/MSG-Offers_Notify}
```

Reference: MSG- (Messages)

## The tags at a glance

| Tag | Single tag | Area tag | Negative area tag | Loop tag |
| - | - | - | - | - |
| `OFFER-ID` | yes | yes | yes | – |
| `OFFER-Date` | yes | yes | yes | – |
| `OFFER-ExpireDate` | yes | yes | yes | – |
| `OFFER-Descr` | yes | yes | yes | – |
| `OFFER-PaymentName` | yes | yes | yes | – |
| `OFFER-PaymentCost` | yes | yes | yes | – |
| `OFFER-PaymentCostNet` | yes | yes | yes | – |
| `OFFER-PaymentCostGross` | yes | yes | yes | – |
| `OFFER-PaymentCostVAT` | yes | yes | yes | – |
| `OFFER-DeliveryName` | yes | yes | yes | – |
| `OFFER-DeliveryCost` | yes | yes | yes | – |
| `OFFER-DeliveryCostNet` | yes | yes | yes | – |
| `OFFER-DeliveryCostGross` | yes | yes | yes | – |
| `OFFER-DeliveryCostVAT` | yes | yes | yes | – |
| `OFFER-TotalSum` | yes | yes | yes | – |
| `OFFER-TotalSumNet` | yes | yes | yes | – |
| `OFFER-TotalSumGross` | yes | yes | yes | – |
| `OFFER-TotalSumVAT` | yes | yes | yes | – |
| `OPR-Data` | – | – | – | yes |
| `OPR-Name` | yes | yes | yes | – |
| `OPR-Number` | yes | yes | yes | – |
| `OPR-Insert` | yes | yes | yes | – |
| `OPR-Quantity` | yes | yes | yes | – |
| `OPR-Unit` | yes | yes | yes | – |
| `OPR-Image` | yes | yes | yes | – |
| `OPR-Variations` | yes | yes | yes | – |
| `OPR-Price` | yes | yes | yes | – |
| `OPR-NetPrice` | yes | yes | yes | – |
| `OPR-GrossPrice` | yes | yes | yes | – |
| `OPR-VAT` | yes | yes | yes | – |
| `OPR-DiscountRate` | yes | yes | yes | – |
| `OPR-Discount` | yes | yes | yes | – |

All `OFFER-` tags only apply within the `{@WS-OffersList}` loop, and all `OPR-` tags additionally only within `{@OPR-Data}`. The shop system evaluates the tag names regardless of capitalization.

## Related topics

* Guide: Customer-specific offers
* Reference: Offers section
* Reference: WS- (General tags)
* Reference: CAT- (Categories and product lists)


## Related topics

- [Customer-specific offers](https://dokumentation.websale.de/en/v8s/marketing-funktionen/kundenspezifische-angebote.md)
- [Shopping basket and order process](https://dokumentation.websale.de/en/v8s/referenz/konfigurationen/shopkonfiguration-shop-config/warenkorb-und-bestellprozess.md)
- [New customer vouchers](https://dokumentation.websale.de/en/v8s/gutscheine-anbieten/neukunden-gutscheine.md)
- [Shop configuration global.config](https://dokumentation.websale.de/en/v8s/referenz/konfigurationen/shopkonfiguration-global-config.md)
- [Texts and messages](https://dokumentation.websale.de/en/v8s/referenz/konfigurationen/shopkonfiguration-shop-config/texte-und-meldungen.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.