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

# Configuration product_alternatives.cfg

> All parameters of product_alternatives.cfg: entries, types, validity periods, price rules, and conditions, plus the rule that determines which entry wins when several match.

The `product_alternatives.cfg` configuration controls the alternative product data. It lets the shop show certain buyers different prices or different product data without changing anything in the regular data set.

The file consists of a list of entries. Each entry describes three things: how the deviation comes about, who it applies to, and when it applies. If more than one entry matches, the priority decides.

> [!NOTE]
>
> Alternative product data must be enabled for your shop. Without this activation, the shop doesn't read the file at all. Contact your WEBSALE representative about this.

Guide: Alternative product data · Reference: Alternative product data, tags · Basics: Configuration basics

## Where the file is located

The file is located directly in the shop's configuration directory:

```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
konfiguration/product_alternatives.cfg
```

It therefore applies to all subshops and all languages together. That's exactly why the `ValidInSubShops-List` parameter exists, which lets you restrict a single entry to specific subshops.

The shop treats lines that start with `#` as comments.

## Basic structure

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<+Entry>
   ID                                  =
   Type                                =
   PriceRuleUseFileExtension           =
   AlternativeProductDataFileExtension =
   UsePriceShadowingVariables          =
   ValidFrom                           =
   ValidUntil                          =
   ValidInSubShops-List                =
   Test                                =
   PriceRule                           =
   PriceRuleParameter1                 =
   Priority                            =
   <Conditions>
      <+ConditionSet>
         <+Condition>
            Type                       =
            Name                       =
            Value                      =
         </+Condition>
      </+ConditionSet>
   </Conditions>
</+Entry>
```

The `+Entry` section can occur any number of times.

## Identity and mode

| Parameter | Purpose | Values |
| - | - | - |
| `ID` | unique identifier of the entry. It ends up in the order data and makes it traceable which alternative product data was applied to an order | free text, for example `secondPAentry` |
| `Type` | the mode of the entry | `PriceRule`, `AlternativeProductDataFields-Replacement`, `AlternativeProductDataFields-Complementary` |

The three modes differ in where the deviating data comes from:

| Value of `Type` | Effect |
| - | - |
| `PriceRule` | the shop recalculates the price using a formula |
| `AlternativeProductDataFields-Replacement` | a second product data file **replaces** the regular fields |
| `AlternativeProductDataFields-Complementary` | a second product data file **supplements** the regular fields |

> [!WARNING]
>
> Any value other than these three makes the entry ineffective. The shop doesn't report this as an error; the entry simply never applies. Pay particular attention to the hyphens in the two long values. This isn't documented and has been added here.

## The alternative product data file

In all three modes, the deviating data is stored in a second file next to the regular product data file. Here you enter only the additional characters of the file name.

If the original product data is in `1234.prd` and the alternative data is in `1234.prd-apd`, the entry is `-apd`.

| Parameter | Purpose | Values |
| - | - | - |
| `PriceRuleUseFileExtension` | optional, only with `Type = PriceRule`. The price formula is then applied to this price list instead of the regular product data | for example `-apd` |
| `AlternativeProductDataFileExtension` | only with the two `AlternativeProductDataFields` modes. The file with the replacing or supplementary fields | for example `-apd` |

> [!NOTE]
>
> The shop doesn't even read the other of the two parameters. An `AlternativeProductDataFileExtension` in a `PriceRule` entry therefore has no effect, and the same applies the other way around.

## Strikethrough prices

| Parameter | Purpose | Values |
| - | - | - |
| `UsePriceShadowingVariables` | whether the tags for the original price are populated, that is `PR-PriceShadow`, `PR-SetPriceShadow`, `BASKET-PR-PriceShadow`, and `BASKET-PR-SetPriceShadow` | `yes`, `no`. Default: `no` |

> [!WARNING]
>
> With `Type = AlternativeProductDataFields-Replacement`, the strikethrough price tags aren't available. In this case, the original price is completely replaced and therefore no longer known.

## Validity

| Parameter | Purpose | Values |
| - | - | - |
| `ValidFrom` | optional. Point in time from which the entry is active | `YYYYMMDD[-HH[:MM[:SS]]]`, for example `20210101` |
| `ValidUntil` | optional. Point in time until which the entry is active | `YYYYMMDD[-HH[:MM[:SS]]]`, for example `20251224-12:00:00` |
| `ValidInSubShops-List` | optional. Comma-separated list of the subshops in which the entry applies. If omitted, it applies in all subshops | for example `Deutsch` |
| `Test` | whether the entry applies only in the shop's test mode | `yes`, `no`. Default: `no` |

> [!WARNING]
>
> A timestamp in any other format makes the entry invalid. The shop doesn't fall back to "always valid" in that case; it skips the entry entirely.
>
> Check the notation carefully. Allowed formats are `20251224`, `20251224-12`, `20251224-12:00`, and `20251224-12:00:00`. This behavior isn't documented and has been added here.

## Price rule

These parameters apply only with `Type = PriceRule`.

| Parameter | Purpose | Values |
| - | - | - |
| `PriceRule` | whether a discount or a surcharge is calculated | `discount` for a discount, `surcharge` for a surcharge |
| `PriceRuleParameter1` | the percentage applied as a discount or surcharge | for example `5` |

The shop then calculates `price minus price times percentage divided by 100` or `price plus price times percentage divided by 100`.

> [!NOTE]
>
> Without a percentage in `PriceRuleParameter1`, the price remains unchanged, even if `PriceRule` is set. The same applies to a percentage of `0` or less.
>
> The parameters `PriceRuleParameter2` and `PriceRuleParameter3` also appear in the file. The shop reads them but currently doesn't evaluate them when calculating prices. They're intended for future calculation rules. This isn't documented and has been added here.

## Conditions

In the `Conditions` subsection, you define who the entry applies to.

The logical combination results from the nesting:

* Multiple `+ConditionSet` blocks are combined with **or**. It's enough for one set to match.
* Multiple `+Condition` blocks within a set are combined with **and**. All of them must match.

| Parameter | Purpose | Values |
| - | - | - |
| `Type` | whether a URL parameter or a suffix field of the billing address is checked | `ActivateWithURLParameter`, `ActivateWithUserAccountSuffixField` |
| `Name` | name of the URL parameter or suffix field to check | for example `Suffix5` |
| `Value` | value to check against | for example `aktiv` |

> [!WARNING]
>
> For URL parameters, choose a combination of name and value that can't be guessed. Anyone who knows the link gets the deviating prices.
>
> Also choose a name that's unique enough not to collide with the shop's functional call parameters.

> [!NOTE]
>
> If multiple valid URL parameters are used during a session, the shop remembers the most recently found valid combination of name and value.

## Which entry wins

On every request, the shop checks all entries in the file in order and keeps the winner for the duration of the request. An entry is only considered if it passes the test mode, the validity period, and the subshop restriction **and** its conditions match.

If several entries remain after that, `Priority` decides.

| Parameter | Purpose | Values |
| - | - | - |
| `Priority` | ranking when there are several valid entries | integer |

> [!WARNING]
>
> **The lower numeric value wins.** An entry with `Priority = 1` prevails over one with `Priority = 3`.
>
> This leads to a pitfall: an entry without `Priority` counts as `0` and therefore beats every entry with a set priority. So either assign a priority to all entries or to none.
>
> If the numeric values are equal, the entry that appears higher up in the file wins.
>
> The previous documentation only said that the entry "with the higher priority" is applied, without specifying the numeric direction. This has been clarified here.

> [!WARNING]
>
> Exactly one entry wins, and that's final. If no matching alternative product data file exists for a product, that product gets its regular data. The shop does **not** fall back to the entry with the next priority.

## When an entry doesn't apply

The following causes all result in a seemingly correct entry having no effect. None of them produces a visible error message.

**The feature isn't enabled for the shop.** In that case, the shop doesn't read the file, regardless of its content.

**The file is missing or in the wrong location.** The shop expects it directly under `konfiguration/`, not in a subshop subdirectory.

**The value of `Type` isn't one of the three allowed values.** A typo in `AlternativeProductDataFields-Complementary` is enough.

**The timestamp is formatted incorrectly.** This makes the entry invalid, not valid indefinitely.

**Another entry has the lower `Priority`.** See above.

**The alternative product data file doesn't exist.** For each product, the shop checks whether the file with the configured extension actually exists in the product data directory. If it's missing, that product keeps its regular data.

> [!NOTE]
>
> For troubleshooting in the shop itself, there are tags with the prefix `APD-`. In test mode, you can use them to output which entry has currently won, with which mode, file extension, and validity.

Reference: Alternative product data, tags


## Related topics

- [Alternative product data](https://dokumentation.websale.de/en/v8s/produkte/alternative-produktdaten.md)
- [Alternative product data: tags](https://dokumentation.websale.de/en/v8s/referenz/tags/alternative-produktdaten-tags.md)
- [Configuration wsautoexpdelcost.cfg](https://dokumentation.websale.de/en/v8s/referenz/konfigurationen/konfiguration-wsautoexpdelcost-cfg.md)
- [Import file prod.cfg](https://dokumentation.websale.de/en/v8s/referenz/konfigurationen/importdatei-prod-cfg.md)
- [content - Catalogue (categories & products)](https://dokumentation.websale.de/en/konfiguration/content-katalog-kategorien-produkte.md)


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