Shopware

Preisregeln in Shopware: welche gewinnt

Nicht die günstigste. Shopware nimmt die erste Regel, die auf den Kontext passt — und die Reihenfolge bestimmt die Priorität, die jemand einmal vergeben hat.

Pixup MediaVeröffentlicht am 8 Min. Lesezeit

„Der Kunde sieht den falschen Preis." Der Satz beginnt fast jedes Preis-Support-Ticket, und in den meisten Fällen ist der Preis nicht falsch, sondern das Ergebnis einer Regel, die jemand vor Monaten angelegt hat.

Dieser Text beschreibt, wie Shopware entscheidet — nachgelesen im Quelltext einer laufenden 6.7.13.1-Installation, nicht aus der Erinnerung.

Die Entscheidung in einer Schleife

Wenn mehrere Preisregeln auf einen Kontext passen, sieht die Auflösung so aus:

foreach ($context->getRuleIds() as $ruleId) {
    $filtered = $rules->filter(fn ($price) => $ruleId === $price->get('ruleId'));

    if (\count($filtered) > 0) {
        return $filtered;
    }
}

Drei Dinge stecken darin:

Erstens: Es gewinnt die erste Regel, die passt. Nicht die günstigste, nicht die zuletzt angelegte. Die erste in der Reihenfolge von getRuleIds().

Zweitens: Diese Reihenfolge kommt aus der Priorität. Die Regel-Entität hat ein Pflichtfeld dafür:

(new IntField('priority', 'priority'))->addFlags(new Required())

Drittens: Nach dem ersten Treffer wird nicht weitergesucht. Alle weiteren zutreffenden Regeln sind für diesen Preis bedeutungslos.

Das ist eine bewusste Entscheidung und in der Sache richtig: Eine B2B-Konditionsregel soll auch dann greifen, wenn gerade eine allgemeine Aktion günstiger wäre. Der Händler bestimmt die Rangfolge, nicht der Rechner.

Staffelpreise innerhalb einer Regel

Hat die gewonnene Regel mehrere Staffeln, sortiert Shopware sie nach dem Mengenbeginn:

$prices->sort(fn ($a, $b) => $a->get('quantityStart') <=> $b->get('quantityStart'));

Danach entscheidet die Menge im Warenkorb, welche Staffel greift. Das ist der unauffällige Teil — Fehler entstehen hier fast nur, wenn Staffeln Lücken haben oder sich überschneiden.

Der günstigste Preis ist vorberechnet

In Listen und Filtern verwendet Shopware nicht die Regelauflösung, sondern einen vorberechneten Wert. Er merkt sich unter anderem:

FeldBedeutung
variantIdvon welcher Variante der Preis stammt
ruleIdunter welcher Regel er zustande kam
hasRangeob es eine Spanne gibt — daraus wird das „ab“ in der Liste
purchaseder zugehörige Einkaufspreis

Gepflegt wird der Wert von einem eigenen Aktualisierer, also einem Indexer.

Und genau daraus entsteht der häufigste Support-Fall: Jemand ändert einen Preis im Backend, sieht ihn auf der Detailseite sofort — dort läuft die Regelauflösung im Kontext — und in der Liste weiterhin den alten Wert. Nichts ist kaputt; der Indexer ist noch nicht gelaufen.

Eine Prüfreihenfolge für den Ernstfall

  1. Welche Regeln treffen auf diesen Kontext zu? Kundengruppe, Land, Warenkorbwert, Kanal — die Bedingungen der Regel entscheiden das.
  2. Welche hat die höhere Priorität? Diese gewinnt, unabhängig vom Preis.
  3. Liegt der Unterschied zwischen Liste und Detailseite? Dann ist es der Indexer, nicht die Regel.
  4. Greift eine Staffel? Mengenbeginn und Warenkorbmenge vergleichen.
  5. Erst dann nach einer Erweiterung suchen, die in die Preisermittlung eingreift.

Punkt 3 ist die schnellste Unterscheidung und wird am häufigsten übersprungen.

Was das für die Regelpflege heisst

Prioritäten bewusst vergeben, nicht durchnummerieren. Wenn alle Regeln die gleiche Priorität haben, entscheidet eine Reihenfolge, die niemand gewählt hat.

Weniger Regeln sind besser. Jede zusätzliche Regel erhöht die Zahl der Kombinationen, die jemand im Kopf haben muss. Zwanzig Regeln sind keine Feinsteuerung, sondern eine Fehlerquelle.

Änderungen an einem Testsystem prüfen. Eine Regel, die im Backend richtig aussieht, kann im Kontext eines bestimmten Kunden anders greifen als gedacht. Ein Blick in die Storefront mit der passenden Kundengruppe klärt das in Minuten.

Wo es rechtlich wird

Preisangaben berühren die Preisangabenverordnung — etwa die Pflicht, bei Preisermässigungen den niedrigsten Preis der letzten 30 Tage anzugeben. Das ist eine rechtliche Frage, und wir geben dazu keine Rechtsauskunft.

Technisch lässt sich sagen: Shopware hält von sich aus keine Preishistorie in der Form vor, die dafür nötig ist. Wer die Angabe automatisiert braucht, braucht eine Erweiterung, die den Verlauf aufzeichnet und den Referenzpreis berechnet — wir haben eine dafür gebaut. Ob eine konkrete Umsetzung den rechtlichen Anforderungen genügt, gehört in eine juristische Prüfung, nicht in einen Fachartikel.

Wenn der Preis trotzdem nicht stimmt

Dann liegt es meist an einer Bedingung, die anders greift als gedacht — oder an Daten, die von aussen kommen. Warenwirtschaftssysteme legen Preisregeln beim Abgleich gelegentlich neu an, statt bestehende zu aktualisieren; danach existieren zwei Regeln mit unterschiedlicher Priorität, und die falsche gewinnt.

Wie wir solche Fälle eingrenzen, gehört zu Shopware-Support. Ob ein Wechsel auf 6.7 daran etwas ändert, steht in Auf Shopware 6.7 wechseln oder bei 6.6 bleiben.

Häufige Fragen

Warum gewinnt nicht der günstigste Preis?
Weil Shopware die Regeln als geordnete Liste behandelt und die erste zutreffende nimmt. Das ist beabsichtigt: Eine B2B-Regel soll auch dann greifen, wenn eine allgemeine Aktion gerade günstiger wäre.
Wo stelle ich die Reihenfolge ein?
Über die Priorität der Regel. Das Feld ist Pflicht und ganzzahlig; es bestimmt, in welcher Reihenfolge Regeln geprüft werden.
Warum zeigt die Liste einen anderen Preis als die Detailseite?
Weil die Liste den vorberechneten günstigsten Preis verwendet, die Detailseite die Regelauflösung im Kontext. Nach Preisänderungen ist das ein Hinweis auf einen ausstehenden Indexerlauf.
Gilt das auch für Varianten?
Der vorberechnete günstigste Preis merkt sich, von welcher Variante er stammt und ob es eine Spanne gibt. Deshalb steht in Listen „ab“ statt eines festen Preises.
WeiterführendShopware-Support