Alle Artikel
Shopware 65 min

Shopware 6 Rule Builder – Preisregeln und Conditions

Der Shopware 6 Rule Builder ist eines der mächtigsten Features im Shopware-Universum. Mit ihm lassen sich flexible Geschäftslogiken abbilden – von einfachen Rabatten bis zu komplexen Preisstrategien. In diesem Artikel zeige ich dir, wie du den Rule Builder effektiv einsetzt und eigene Custom Rules entwickelst.

Was ist der Shopware 6 Rule Builder?

Der Rule Builder in Shopware 6 ist ein Regelwerk-System, das Conditions (Bedingungen) mit Actions verknüpft. Anders als bei starren Konfigurationen kannst du damit dynamisch entscheiden, wann welche Logik greift.

Typische Anwendungsfälle:

  • Preisregeln nach Kundengruppe
  • Versandkosten-Berechnung
  • Zahlungsarten-Freischaltung
  • Promotion-Logik
  • Produktsichtbarkeit

Der Shopware 6 Rule Builder arbeitet mit einem Matching-System: Wenn alle definierten Conditions erfüllt sind, wird die Regel aktiv.

Rule Builder im Admin nutzen

Der einfachste Einstieg erfolgt über das Backend:

Navigation: Einstellungen → Regelwerk → Regel erstellen

Eine typische Regel besteht aus:

  1. Name und Priorität – Je höher die Priorität, desto früher wird sie evaluiert
  2. Conditions – Die Bedingungen (UND/ODER-Verknüpfung möglich)
  3. Zuordnung – Wo wird die Regel verwendet? (Preise, Versand, Promotion)

Praktisches Beispiel: B2B-Preisregel

Angenommen, B2B-Kunden sollen 15% Rabatt auf alle Produkte erhalten:

  1. Neue Regel erstellen: "B2B Rabatt"
  2. Condition hinzufügen: "Kundengruppe" → "B2B Kunden"
  3. Bei Preisen: Erweiterte Preise → Regel zuweisen → -15%

Der Shopware 6 Rule Builder evaluiert diese Regel bei jedem Cart-Vorgang automatisch.

Custom Rules programmieren

Für spezifische Anforderungen kommst du um eigene Rules nicht herum. Die Architektur ist sauber: Jede Rule ist eine PHP-Klasse, die gegen den Cart oder Context prüft.

Struktur einer Custom Rule

<?php declare(strict_types=1);

namespace Custom\Rules\Rule;

use Shopware\Core\Framework\Rule\Rule;
use Shopware\Core\Framework\Rule\RuleScope;

class MinimumOrderCountRule extends Rule
{
    protected int $minimumCount;

    public function __construct(int $minimumCount = 1)
    {
        parent::__construct();
        $this->minimumCount = $minimumCount;
    }

    public function match(RuleScope $scope): bool
    {
        if (!$scope instanceof CartRuleScope) {
            return false;
        }

        $lineItems = $scope->getCart()->getLineItems();
        $totalCount = 0;

        foreach ($lineItems as $lineItem) {
            $totalCount += $lineItem->getQuantity();
        }

        return $totalCount >= $this->minimumCount;
    }

    public function getConstraints(): array
    {
        return [
            'minimumCount' => [new NotBlank(), new Type('int')],
        ];
    }

    public function getName(): string
    {
        return 'custom_minimum_order_count';
    }
}

Diese Rule prüft, ob mindestens X Artikel im Warenkorb liegen. Der Shopware 6 Rule Builder integriert sie automatisch, sobald sie registriert ist.

Rule registrieren

In der services.xml deines Plugins:

<service id="Custom\Rules\Rule\MinimumOrderCountRule">
    <tag name="shopware.rule.definition"/>
</service>

Nach bin/console cache:clear erscheint die Rule im Admin-Dropdown.

Fortgeschrittene Techniken

1. Kombination mit LineItem-Conditions

Für produktspezifische Regeln nutzt du LineItemScope:

public function match(RuleScope $scope): bool
{
    if ($scope instanceof LineItemScope) {
        $lineItem = $scope->getLineItem();
        
        // Beispiel: Nur auf Kategorie prüfen
        $categoryIds = $lineItem->getPayloadValue('categoryIds') ?? [];
        return in_array('SPECIFIC_CATEGORY_ID', $categoryIds);
    }
    
    return false;
}

2. Container-Rules für komplexe Logik

Der Shopware 6 Rule Builder unterstützt verschachtelte Rules:

use Shopware\Core\Framework\Rule\Container\AndRule;
use Shopware\Core\Framework\Rule\Container\OrRule;

$complexRule = new AndRule([
    new CustomerGroupRule(['B2B_GROUP_ID']),
    new OrRule([
        new LineItemOfTypeRule(['product']),
        new LineItemOfTypeRule(['promotion'])
    ])
]);

So baust du "Wenn B2B UND (Produkt ODER Promotion)"-Logik.

3. Performance-Optimierung

Bei vielen Rules wird Performance wichtig:

public function match(RuleScope $scope): bool
{
    // Early return bei falschen Scopes
    if (!$scope instanceof CartRuleScope) {
        return false;
    }

    // Caching wo möglich
    $cart = $scope->getCart();
    if ($cart->getExtension('myCustomCheck')) {
        return true;
    }

    // Teure Operationen nur wenn nötig
    $result = $this->expensiveCheck($cart);
    $cart->addExtension('myCustomCheck', new ArrayStruct(['result' => $result]));
    
    return $result;
}

Rule Builder API: Programmatische Erstellung

Für Multi-Store-Setups oder Migrations brauchst du manchmal automatisierte Rule-Erstellung:

use Shopware\Core\Framework\Context;
use Shopware\Core\Content\Rule\RuleEntity;

$ruleRepository = $this->container->get('rule.repository');

$ruleRepository->create([
    [
        'name' => 'Automatische B2B Regel',
        'priority' => 100,
        'conditions' => [
            [
                'type' => 'customerGroup',
                'value' => [
                    'customerGroupIds' => ['b2b-group-id'],
                    'operator' => '='
                ]
            ]
        ]
    ]
], Context::createDefaultContext());

Nützlich für Deployment-Scripte oder Setup-Wizards.

Debugging von Rules

Rules debuggen kann tricky sein. Mein Workflow:

1. Logging aktivieren:

public function match(RuleScope $scope): bool
{
    $this->logger->info('MinimumOrderCountRule evaluated', [
        'minimumCount' => $this->minimumCount,
        'actualCount' => $this->getActualCount($scope)
    ]);
    
    return $this->getActualCount($scope) >= $this->minimumCount;
}

2. Shopware Profiler nutzen:

Der Symfony Profiler zeigt alle evaluierten Rules. In config/packages/dev/framework.yaml:

framework:
    profiler: { only_exceptions: false }

3. Unit Tests schreiben:

public function testMinimumCountMatches(): void
{
    $rule = new MinimumOrderCountRule(5);
    $cart = $this->createCartWithItems(6);
    $scope = new CartRuleScope($cart, $this->createMock(SalesChannelContext::class));
    
    static::assertTrue($rule->match($scope));
}

Best Practices

1. Sprechende Namen: "B2B 15% Rabatt" statt "Regel 1"

2. Prioritäten sinnvoll setzen: Allgemeine Rules niedrig (1-10), spezifische hoch (90-100)

3. Nicht zu viele Conditions: Mehr als 5-6 verkettete Conditions werden unübersichtlich

4. Custom Rules dokumentieren: Code-Kommentare + Admin-Description

5. Versionierung: Rules in Setup-Klassen definieren, nicht manuell im Admin für Production

Typische Fehler vermeiden

Problem: Rule greift nicht, obwohl Bedingungen erfüllt scheinen

Lösung: Context prüfen – match() bekommt verschiedene Scopes je nach Situation (Cart, LineItem, Customer). Typ-Check ist Pflicht.

Problem: Performance-Einbruch bei vielen Rules

Lösung: Prioritäten nutzen + Rules mit hoher Match-Wahrscheinlichkeit zuerst. Der Shopware 6 Rule Builder cached evaluierte Rules teilweise, aber nicht alle Conditions sind gleich performant.

Problem: Deployment überschreibt Rules

Lösung: Rules via RuleRepository in Migrations/Setup verwalten, nicht händisch im Admin pflegen.

Fazit

Der Shopware 6 Rule Builder ist extrem flexibel – von simplen Rabatten bis zu komplexen Business-Rules. Mit Custom Rules bist du technisch komplett frei, die API ist sauber designed.

Wichtigste Takeaways:

  • Admin-Interface für Standard-Cases nutzen
  • Custom Rules für spezifische Logik
  • Performance im Blick behalten
  • Debugging-Tools einsetzen
  • Code-basierte Verwaltung für Production

Du arbeitest an einem Shopware-Projekt mit komplexen Preisregeln? Ich helfe dir gerne bei der Implementierung von Custom Rules und Performance-Optimierung im Shopware 6 Rule Builder.

Shopware 6 Rule BuilderShopware 6FreelancerWebentwicklungDüsseldorf