Wiederkehrende Bestelllisten technisch verstehen
Requisition Lists sind das B2B-Werkzeug für Stammkunden, die regelmäßig dieselben Positionen bestellen, mit eigenem Datenmodell, eigener API und einer klaren fachlichen Abgrenzung zur Wishlist. Wer eine eigene Frontend-Integration bauen will, muss wissen, wie das Datenmodell aufgebaut ist, welche API-Operationen zur Verfügung stehen und wo die Grenzen des Standardfeatures liegen.
Inhaltsverzeichnis
- 1. Requisition Lists im B2B-Modul einordnen
- 2. Das Datenmodell: requisition_list und requisition_list_item
- 3. Requisition List vs. Wishlist: der fachliche Unterschied
- 4. API-Zugriff für eigene Frontend-Integrationen
- 5. Eigene Mengenregeln per Plugin ergänzen
- 6. Typische Anwendungsfälle für Stammkunden
- 7. Berechtigungen: kein Team-Sharing ab Werk
- 8. Performance bei großen Listen
- 9. Pflege veralteter Listen
- 10. Zusammenfassung
- 11. FAQ
1. Requisition Lists im B2B-Modul einordnen
Requisition Lists sind Teil des Moduls Magento_RequisitionList aus der B2B-Suite und lösen ein sehr konkretes Problem: Firmenkunden bestellen häufig immer wieder dieselben oder sehr ähnliche Positionen, etwa Verbrauchsmaterial oder Ersatzteile, und wollen dafür nicht jedes Mal erneut im Katalog suchen. Eine Requisition List ist im Kern eine benannte, wiederverwendbare Sammlung von SKUs mit fest hinterlegten Mengen, die sich als Ganzes oder teilweise in den Warenkorb übernehmen lässt.
Anders als viele andere B2B-Features ist eine Requisition List nicht an eine Company gebunden, sondern an den einzelnen Kunden. Zwei Mitarbeiter derselben Firma sehen also standardmäßig nicht dieselben Listen, auch wenn sie über dieselbe Company verbunden sind, was für viele Projekte eine relevante Design-Entscheidung ist, sobald es um geteilte Bestellvorlagen im Team geht.
2. Das Datenmodell: requisition_list und requisition_list_item
Technisch besteht eine Requisition List aus zwei Tabellen: requisition_list mit den Feldern requisition_list_id, customer_id, name und description, sowie requisition_list_item mit sku, qty, requisition_list_id als Fremdschlüssel und einem serialisierten additional_options-Feld für Produktoptionen wie konfigurierbare Attribute oder individuelle Textfelder. Die eigentliche Produktreferenz erfolgt über die SKU, nicht über die interne Produkt-ID, was bei SKU-Änderungen im Katalog zu beachten ist.
Weil additional_options serialisiert gespeichert wird, lässt sich eine gespeicherte Position nicht einfach per einfachem SQL-Filter nach einer bestimmten Produktoption durchsuchen. Für eigene Auswertungen, etwa ein Report über die am häufigsten in Listen gespeicherten Konfigurationen, muss man die serialisierten Daten zunächst über die entsprechenden Serializer-Klassen deserialisieren, bevor man sie strukturiert auswerten kann.
3. Requisition List vs. Wishlist: der fachliche Unterschied
Auf den ersten Blick wirken Requisition Lists und Wishlists ähnlich, beide speichern eine benannte Liste von Produkten für einen Kunden. Der zentrale Unterschied liegt im Zweck: Eine Wishlist ist auf Merken und gegebenenfalls Teilen ausgelegt, mit optionalen Kommentaren und einer Sharing-Funktion über einen öffentlichen Link. Eine Requisition List hat dagegen einen rein operativen Zweck: schnelles, wiederholtes Bestellen mit fest hinterlegter Menge pro Position.
Praktisch zeigt sich das in den verfügbaren Aktionen. Requisition Lists erlauben das direkte Hinzufügen der gesamten Liste zum Warenkorb inklusive Mengenanpassung in einem Schritt, während eine Wishlist eher für das einzelne Hinzufügen einzelner Produkte gedacht ist. Zudem unterstützt eine Requisition List von Haus aus keine öffentliche Sichtbarkeit oder Freigabe an andere Nutzer, sie bleibt strikt an den anlegenden Kunden gebunden.
4. API-Zugriff für eigene Frontend-Integrationen
Für Custom-Frontends stehen sowohl Service Contracts wie RequisitionListRepositoryInterface und RequisitionListItemRepositoryInterface als auch eine GraphQL-Schicht zur Verfügung. Über die GraphQL-Query requisitionLists lassen sich die Listen eines eingeloggten Kunden inklusive ihrer Positionen abrufen, während Mutations wie createRequisitionList und addProductsToRequisitionList das Anlegen und Befüllen übernehmen.
Für das eigentliche Bestellen ist die Mutation addRequisitionListToCart relevant, die die komplette Liste oder eine ausgewählte Teilmenge an Positionen validiert und in den aktiven Warenkorb überführt. Die Validierung läuft dabei pro Position getrennt, sodass eine einzelne fehlerhafte Position, etwa ein inzwischen deaktiviertes Produkt, nicht zwangsläufig die gesamte Aktion blockiert, sondern als einzelner Fehler im Ergebnis zurückgemeldet wird.
mutation AddRequisitionListToCart {
addRequisitionListToCart(
cartId: "abc123cartid"
requisitionListId: "42"
requisitionListItemIds: ["101", "102", "103"]
) {
cart {
id
total_quantity
}
userErrors {
requisition_list_item_id
message
code
}
}
}
5. Eigene Mengenregeln per Plugin ergänzen
Ein häufiger Erweiterungsfall ist eine zusätzliche Mengenvalidierung, etwa wenn ein Produkt nur in Vielfachen einer Verpackungseinheit bestellt werden darf. Dafür bietet sich ein Plugin auf RequisitionListItemRepositoryInterface::save an, das vor dem eigentlichen Speichern prüft, ob die eingetragene Menge zur hinterlegten Packungsgröße des Produkts passt, und andernfalls eine LocalizedException wirft.
Diese Prüfung sollte konsequent an derselben Stelle greifen wie später beim Hinzufügen zum Warenkorb, da sonst ungültige Mengen zwar nicht in der Liste gespeichert, aber möglicherweise über einen anderen Pfad wie den direkten Produkt-Detailseiten-Zugriff dennoch bestellt werden könnten. Eine konsistente Regel gehört daher eher in einen zentralen, wiederverwendbaren Validator als in ein einzelnes Plugin.
<?php
declare(strict_types=1);
namespace Mironsoft\RequisitionListExtension\Plugin;
use Magento\Framework\Exception\LocalizedException;
use Magento\RequisitionList\Api\Data\RequisitionListItemInterface;
use Magento\RequisitionList\Api\RequisitionListItemRepositoryInterface;
use Mironsoft\RequisitionListExtension\Model\PackSizeValidator;
/**
* Stellt sicher, dass Mengen in Requisition-List-Positionen ein Vielfaches
* der hinterlegten Packungsgröße des Produkts sind.
*/
class ValidatePackSizePlugin
{
/**
* @param PackSizeValidator $packSizeValidator
*/
public function __construct(private readonly PackSizeValidator $packSizeValidator)
{
}
/**
* @param RequisitionListItemRepositoryInterface $subject
* @param RequisitionListItemInterface $item
* @return array{RequisitionListItemInterface}
* @throws LocalizedException
*/
public function beforeSave(
RequisitionListItemRepositoryInterface $subject,
RequisitionListItemInterface $item,
): array {
if (!$this->packSizeValidator->isValidQty($item->getSku(), (float) $item->getQty())) {
throw new LocalizedException(__('Die Menge muss ein Vielfaches der Packungsgröße sein.'));
}
return [$item];
}
}
6. Typische Anwendungsfälle für Stammkunden
In der Praxis lohnen sich Requisition Lists vor allem dort, wo Bestellungen regelmäßig und mit hoher Vorhersehbarkeit anfallen. Ein klassisches Beispiel sind Wartungsteams, die monatlich dieselben Ersatzteile für eine bestimmte Maschine bestellen, oder Filialen, die eine standardisierte Grundausstattung an Verbrauchsmaterial in festgelegten Mengen regelmäßig nachbestellen, ohne jedes Mal die passenden Produkte neu zusammensuchen zu müssen.
Ein weiterer verbreiteter Anwendungsfall ist die schnelle Wiederholung einer früheren Bestellung: Statt eine vergangene Order manuell zu duplizieren, legt der Kunde die relevanten Positionen einmalig als Requisition List an und passt bei jeder weiteren Bestellung nur noch die Mengen an, was den Bestellprozess spürbar beschleunigt und Tippfehler bei SKUs reduziert, die bei manueller Suche im Katalog leichter passieren.
7. Berechtigungen: kein Team-Sharing ab Werk
Eine wichtige Einschränkung, die bei der Planung eigener Erweiterungen oft übersehen wird: Requisition Lists sind im Standardfunktionsumfang strikt an den anlegenden Kunden gebunden und nicht automatisch für andere Mitglieder derselben Company sichtbar. Wer eine geteilte Bestellvorlage im Team möchte, muss diese Funktionalität explizit ergänzen, etwa über ein zusätzliches Attribut für Sichtbarkeit auf Company-Ebene und eine entsprechend erweiterte Repository-Abfrage.
Für eine solche Erweiterung bietet sich an, die bestehende Tabelle requisition_list um eine Spalte für die Sichtbarkeit zu ergänzen und die Standard-Collection über ein Plugin um einen zusätzlichen Filter zu ergänzen, statt die komplette Repository-Implementierung zu ersetzen. So bleiben Kompatibilität mit zukünftigen Magento-Updates und die vorhandene GraphQL-Schicht weitgehend erhalten.
8. Performance bei großen Listen
Bei Listen mit mehreren hundert Positionen wirkt sich die Validierung beim Hinzufügen zum Warenkorb spürbar auf die Antwortzeit aus, weil für jede Position Preis, Verfügbarkeit und Konfigurationsoptionen einzeln geprüft werden. Für sehr große Listen empfiehlt sich, die addRequisitionListToCart-Operation nicht mit der kompletten Liste auf einmal, sondern in kleineren Chargen aufzurufen, um sowohl die Antwortzeit als auch das Risiko eines Timeouts bei langsamen externen Preisquellen zu begrenzen.
Für wiederkehrende, planbare Nutzung, etwa eine automatisierte nächtliche Übernahme bestimmter Requisition Lists in Bestellungen über ein externes Beschaffungssystem, ist außerdem sinnvoll, denselben Validierungspfad wie im Frontend zu verwenden, statt eine eigene, abweichende Logik zu implementieren, damit sich Frontend- und Automatisierungsverhalten nicht auseinanderentwickeln.
9. Pflege veralteter Listen
Da Requisition Lists dauerhaft gespeichert bleiben und nicht automatisch ablaufen, sammeln sich über Jahre hinweg Listen an, die Positionen mit inzwischen deaktivierten oder aus dem Sortiment genommenen Produkten enthalten. Ohne eigene Pflege bleiben solche verwaisten Einträge unbegrenzt bestehen und führen beim Versuch, die Liste zum Warenkorb hinzuzufügen, zu Validierungsfehlern, die für den Kunden ohne Kontext schwer nachvollziehbar sind.
Eine sinnvolle Ergänzung ist ein regelmäßiger Batch-Job, der Positionen mit nicht mehr existierenden oder dauerhaft deaktivierten SKUs identifiziert und entweder automatisch entfernt oder dem Kunden beim nächsten Login als veraltete Position markiert, damit die Liste ihren praktischen Nutzen als verlässliche Bestellvorlage behält.
| Merkmal | Wishlist | Requisition List |
|---|---|---|
| Primärer Zweck | Merken und Teilen | Wiederholtes, schnelles Bestellen |
| Team-Sharing | Öffentlicher Link möglich | Nicht ohne eigene Erweiterung |
| Menge pro Position | Meist 1, editierbar | Fest hinterlegt, für Wiederbestellung gedacht |
| Kompletter Warenkorb-Übernahme | Nicht standardmäßig vorgesehen | Über addRequisitionListToCart |
| Bindung | An den Kunden | An den Kunden, nicht an die Company |
| Typischer Nutzer | Endkunde im B2C-Kontext | Firmenkunde mit wiederkehrendem Bedarf |
Mironsoft
Magento-Entwicklung, Modul-Beratung und Systemarchitektur
Magento-Projekt, das eine zweite Meinung oder erfahrene Umsetzung braucht?
Wir entwickeln individuelle Magento-Module, beraten bei Architekturentscheidungen und übernehmen komplexe Umsetzungen, von der Service-Contract-Planung bis zum produktionsreifen Deployment.
Architektur-Beratung
Modul- und Systemarchitektur vor der Umsetzung fundiert durchdenken lassen.
Custom-Modul-Entwicklung
Individuelle Magento-Module nach Best Practices sauber umsetzen.
Code-Review & Audit
Bestehende Module auf Performance, Sicherheit und Wartbarkeit prüfen lassen.
10. Zusammenfassung
Requisition Lists
Datenmodell
requisition_list und requisition_list_item speichern Name, Kunde, SKU, Menge und serialisierte Produktoptionen.
Abgrenzung
Anders als die Wishlist ist die Requisition List auf schnelles Wiederbestellen statt auf Merken und Teilen ausgelegt.
API
GraphQL-Mutations wie addRequisitionListToCart validieren jede Position einzeln und melden Fehler granular zurück.
Grenzen
Kein Team-Sharing ab Werk, keine automatische Bereinigung veralteter Positionen ohne eigene Erweiterung.