Distance- und Priority-Algorithmus bei Multi-Source-Inventory im Detail
AI generated
M2
di.xml
Magento 2 · MSI
Distance- und Priority-Algorithmus im Detail
Wie Magento MSI geografische Entfernung und Priorität bei mehreren Lagern kombiniert

Wer mehrere Lager in unterschiedlichen Regionen betreibt, steht bei MSI vor der Frage, ob Distance oder Priority die passende Auswahl trifft. Beide Algorithmen sind Standard, funktionieren aber grundlegend unterschiedlich: Der eine rechnet, der andere zählt eine feste Liste ab. Dieser Artikel zeigt, wie das Geocoding der Sources tatsächlich funktioniert, wie die Prioritäts-Konfiguration pro Source wirkt und wie ein realistisches Setup mit mehreren regionalen Lagern aussieht.

12 Min. Lesezeit Distance Algorithmus Priority Geocoding Multi-Region MSI Setup

1. Zwei unterschiedliche Philosophien der Source-Auswahl

Priority arbeitet komplett ohne Berechnung: Jede Source erhält in der Stock-Source-Zuordnung eine ganzzahlige Priorität, und der Algorithmus geht diese Liste streng der Reihe nach durch, bis die angefragte Menge gedeckt ist. Es gibt keine Rücksicht auf die Lieferadresse, keine Distanzberechnung und keine Laufzeitkosten für Geo-Lookups, was Priority zum performantesten der beiden Standardalgorithmen macht.

Distance hingegen berechnet für jede Bestellung die tatsächliche Entfernung zwischen der Lieferadresse des Kunden und der Adresse jeder Source und sortiert danach. Das ist näher an dem, was Kunden intuitiv erwarten, nämlich dass aus dem nächstgelegenen Lager versendet wird, kostet aber bei jeder Anfrage zusätzliche Rechenzeit für das Geocoding und die Distanzberechnung.

2. Wie das Geocoding der Sources funktioniert

Damit Distance überhaupt rechnen kann, benötigt jede Source geografische Koordinaten. Diese werden nicht automatisch beim Speichern einer Source ermittelt, sondern müssen über den Geocoding-Provider aufgelöst werden, den Magento standardmäßig über einen Google-Maps-API-Key anbindet. Beim Speichern einer Source-Adresse im Backend wird im Hintergrund ein API-Aufruf ausgelöst, der Strasse, Postleitzahl, Stadt und Land in Latitude und Longitude übersetzt und diese Werte in der Tabelle inventory_source persistiert.

Schlägt dieser Aufruf fehl, etwa wegen einer ungültigen Adresse, eines fehlenden API-Keys oder eines Kontingent-Limits bei Google, bleibt die Source ohne Koordinaten. Der Distance-Algorithmus behandelt eine solche Source dann als nicht bewertbar und schließt sie faktisch von der Auswahl aus, auch wenn dort ausreichend Bestand vorhanden wäre. Dieser stille Ausschluss ist eine der häufigsten Fehlerquellen bei Distance-Setups und fällt oft erst auf, wenn eine neue Source angelegt, aber nie beliefert wird.


<?php
declare(strict_types=1);

namespace Mironsoft\InventoryGeocodingCheck\Console\Command;

use Magento\InventoryApi\Api\SourceRepositoryInterface;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
 * Lists all active sources missing geocoded coordinates, which would
 * silently exclude them from the Distance algorithm.
 */
class ListUngeocodedSourcesCommand extends Command
{
    /**
     * @param SourceRepositoryInterface $sourceRepository
     * @param SearchCriteriaBuilder $searchCriteriaBuilder
     */
    public function __construct(
        private readonly SourceRepositoryInterface $sourceRepository,
        private readonly SearchCriteriaBuilder $searchCriteriaBuilder
    ) {
        parent::__construct();
    }

    /**
     * Configures the command name.
     *
     * @return void
     */
    protected function configure(): void
    {
        $this->setName('mironsoft:source:list-ungeocoded');
    }

    /**
     * Iterates all active sources and prints those without valid coordinates.
     *
     * @param InputInterface $input
     * @param OutputInterface $output
     * @return int
     */
    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $criteria = $this->searchCriteriaBuilder->addFilter('enabled', 1)->create();
        $sources = $this->sourceRepository->getList($criteria)->getItems();
        foreach ($sources as $source) {
            if ($source->getLatitude() === null || $source->getLongitude() === null) {
                $output->writeln(sprintf(
                    '%s (%s) has no geocoded coordinates and is excluded from Distance selection.',
                    $source->getSourceCode(),
                    $source->getName()
                ));
            }
        }
        return Command::SUCCESS;
    }
}

3. Die eigentliche Distanzberechnung

Für die Distanzberechnung selbst nutzt Magento standardmäßig die Haversine-Formel, die die kürzeste Entfernung zwischen zwei Punkten auf einer Kugeloberfläche berechnet, also die Luftlinie und nicht die tatsächliche Fahrstrecke. Das ist ein bewusster Kompromiss: Eine echte Routenberechnung über eine Kartendienst-API wäre für jede Bestellung deutlich teurer und langsamer, während die Luftlinie für die meisten Fälle eine ausreichend gute Näherung liefert, besonders bei Lagern, die mehrere hundert Kilometer auseinanderliegen.

In Regionen mit stark unterschiedlicher Verkehrsinfrastruktur kann die Luftlinien-Näherung allerdings zu falschen Ergebnissen führen, etwa wenn zwei Lager durch ein Gebirge getrennt sind und die tatsächliche Fahrstrecke deutlich länger ist als die direkte Distanz. Für solche Fälle müsste ein eigener Algorithmus die Distance-Grundlogik um eine echte Routing-API erweitern, was für die meisten Betriebe jedoch unverhältnismäßig aufwendig ist.

4. Prioritäts-Konfiguration pro Source im Priority-Algorithmus

Die Priorität einer Source wird nicht global, sondern pro Stock-Source-Zuordnung gepflegt, im Backend unter Inventory Stocks bei der Bearbeitung eines Stocks. Jede zugeordnete Source erhält dort eine ganzzahlige Priorität, wobei ein niedrigerer Wert eine höhere Priorität bedeutet. Dieselbe Source kann in unterschiedlichen Stocks unterschiedliche Prioritäten haben, was für Betriebe mit mehreren, sich überschneidenden Absatzkanälen relevant ist, etwa wenn ein B2B-Stock ein anderes Hauptlager bevorzugt als der B2C-Stock desselben Unternehmens.

Wichtig ist, dass zwei Sources im selben Stock dieselbe Priorität erhalten können. In diesem Fall entscheidet die interne Sortierreihenfolge, in der die Source-Item-Datensätze aus der Datenbank geladen werden, was ohne explizite Sekundärsortierung faktisch undefiniert ist. Für produktive Setups sollte deshalb jede Source in einem Stock eine eindeutige Priorität erhalten, um dieses Verhalten vorhersehbar zu machen.


<!-- Ausschnitt: Stock-Source-Zuordnung über den ResourceModel, illustriert die
     Datenstruktur hinter der Backend-Konfiguration von Inventory Stocks -->
<config>
    <stock_source_links>
        <link stock_id="10" source_code="warehouse-north" priority="1" />
        <link stock_id="10" source_code="warehouse-central" priority="2" />
        <link stock_id="10" source_code="warehouse-south" priority="3" />
    </stock_source_links>
</config>

5. Praktisches Beispiel: Drei Lager in unterschiedlichen Regionen

Ein realistisches Setup für ein Unternehmen mit Kunden in Nord-, Mittel- und Süddeutschland besteht aus drei Sources: warehouse-north in Hamburg, warehouse-central in Frankfurt und warehouse-south in München, alle demselben Stock zugeordnet. Wird Priority gewählt, muss eine bewusste Reihenfolge festgelegt werden, etwa Frankfurt als zentrales Hauptlager mit höchster Priorität und die beiden Randlager als Ergänzung. Das funktioniert gut, solange die meisten Kunden geografisch verteilt sind, sorgt aber dafür, dass ein Kunde aus Hamburg trotzdem primär aus Frankfurt beliefert wird.

Wird stattdessen Distance gewählt, liefert derselbe Kunde aus Hamburg automatisch aus warehouse-north, ein Kunde aus München aus warehouse-south, ohne dass eine explizite Reihenfolge gepflegt werden muss. Der Vorteil zeigt sich vor allem in kürzeren Versandzeiten, der Nachteil liegt darin, dass Lagerauslastung und Bestandsverteilung nicht berücksichtigt werden. Ist warehouse-north knapp an Bestand, wählt Distance trotzdem konsequent das nächstgelegene Lager, auch wenn ein anderes Lager mit mehr Puffer geografisch weiter entfernt liegt.

6. Kombinierte Strategie für wachsende Lagernetze

In der Praxis wächst ein Multi-Source-Setup oft organisch: Zunächst gibt es ein Hauptlager mit Priority, später kommen regionale Außenlager hinzu, und die Frage nach Distance stellt sich erst dann. Ein sauberer Übergang gelingt, indem zunächst nur zwei oder drei geografisch klar getrennte Sources mit Distance getestet werden, bevor das gesamte Lagernetz umgestellt wird. So lassen sich Geocoding-Probleme und unerwartete Verteilungsmuster früh erkennen, ohne gleich das komplette Fulfillment umzustellen.

Für Betriebe, die sowohl geografische Nähe als auch Lagerauslastung berücksichtigen wollen, ist wie im vorherigen Artikel zum eigenen Source Selection Algorithmus beschrieben eine Kombination sinnvoll: Distance als grobe Vorauswahl der nächstgelegenen Sources, innerhalb dieser Vorauswahl dann eine Sortierung nach Auslastung. Das ist mit den Standardalgorithmen allein nicht abbildbar und erfordert eine eigene Implementierung des SourceSelectionInterface.

7. Häufige Fehlerquellen bei Distance-Setups

Der häufigste Fehler ist eine unvollständig gepflegte Source-Adresse, etwa ein fehlendes Land oder eine falsch formatierte Postleitzahl, die das Geocoding fehlschlagen lässt, ohne dass im Backend eine deutliche Fehlermeldung erscheint. Ein regelmäßiger Check aller aktiven Sources auf fehlende Koordinaten, wie im Beispiel oben gezeigt, verhindert, dass eine neue Source unbemerkt von der Auswahl ausgeschlossen bleibt.

Ein zweiter Fehler betrifft den API-Key selbst: Wird das Kontingent des Geocoding-Providers überschritten oder der Key ablaufen gelassen, schlagen neue Geocoding-Anfragen fehl, während bereits geocodete Sources weiterhin funktionieren. Das führt zu einem trügerischen Verhalten, bei dem bestehende Sources normal arbeiten, während jede neu angelegte Source stillschweigend nicht in der Distance-Berechnung berücksichtigt wird, bis das Kontingent-Problem behoben ist.

8. Performance-Überlegungen bei vielen Sources

Bei Stocks mit einer zweistelligen Anzahl an Sources berechnet Distance für jede Bestellung eine Haversine-Distanz zu jeder einzelnen Source, was bei sehr großen Lagernetzen spürbar wird. Die Berechnung selbst ist zwar mathematisch günstig, das eigentliche Kostenrisiko liegt eher darin, dass Distance häufiger als Priority im Checkout zur Live-Anzeige der voraussichtlichen Lieferzeit aufgerufen wird und dadurch pro Seitenaufruf mehrfach ausgeführt werden kann.

Für sehr große Lagernetze lohnt sich deshalb ein Caching der berechneten Distanzen pro Postleitzahlgebiet statt einer exakten Neuberechnung bei jeder Anfrage, da sich die Distanz zwischen einer Source und einem Postleitzahlgebiet praktisch nie ändert. Das reduziert die Rechenlast bei stark frequentierten Checkouts deutlich, ohne die Genauigkeit relevant zu verschlechtern.

9. Konfigurierbarkeit der Algorithmus-Wahl

Welcher Algorithmus verwendet wird, ist eine reine Stock-Konfiguration im Backend und erfordert keinen eigenen Code, solange die Standardalgorithmen genügen. Wichtig ist, dass diese Entscheidung dokumentiert und im Team bekannt ist, da sie direkten Einfluss auf Versandzeiten und Lagerauslastung hat und bei einem Wechsel spürbare Auswirkungen auf das operative Fulfillment haben kann.

Für eigene Erweiterungen, etwa eine konfigurierbare maximale Distanz, ab der eine Source gar nicht mehr in Frage kommt, gilt dasselbe Prinzip wie bei jedem anderen Mironsoft-Modul: eine eigene system.xml-Sektion mit acl.xml und Menüpunkt statt hartkodierter Schwellenwerte im Code, damit das Fulfillment-Team die Konfiguration selbstständig anpassen kann.

Kriterium Priority Distance Auswirkung
Berechnungsaufwand Keiner, feste Liste Haversine-Distanz je Source und Anfrage Priority ist performanter bei vielen Sources
Voraussetzung Prioritätswert je Stock-Source-Link Geocoding-Koordinaten je Source Fehlendes Geocoding schließt Sources still aus
Kundenerlebnis Unabhängig vom Wohnort des Kunden Nähestes Lager wird bevorzugt Distance verkürzt tendenziell die Versanddauer
Lagerauslastung Nicht berücksichtigt Nicht berücksichtigt Beide Algorithmen ignorieren aktuelle Kapazität
Geeignet für Ein klar priorisiertes Hauptlager plus Backup Mehrere regional verteilte, gleichwertige Lager Wahl hängt von der Lagerstruktur ab

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

Distance und Priority: Das Wichtigste auf einen Blick

Priority ist statisch

Feste, konfigurierte Reihenfolge ohne Bezug zur Lieferadresse oder Bestandssituation.

Distance rechnet live

Haversine-Luftlinie zwischen Kundenadresse und geocodeten Source-Koordinaten je Bestellung.

Geocoding ist Voraussetzung

Ohne gültige Koordinaten wird eine Source von Distance still von der Auswahl ausgeschlossen.

Kombination möglich

Distance als Vorauswahl, eigene Kriterien wie Auslastung als Tiebreaker innerhalb der Vorauswahl.

11. FAQ: Distance und Priority: Das Wichtigste auf einen Blick

1Was ist der Hauptunterschied zwischen Priority und Distance?
Priority nutzt eine feste, im Backend konfigurierte Reihenfolge ohne Bezug zur Lieferadresse. Distance berechnet für jede Bestellung die tatsächliche Luftlinie zwischen Kundenadresse und Source und bevorzugt die nächstgelegene Source.
2Wie werden Source-Koordinaten ermittelt?
Über einen Geocoding-Provider, standardmäßig die Google-Maps-API, der beim Speichern einer Source-Adresse im Hintergrund aufgerufen wird und die Adresse in Latitude und Longitude umwandelt.
3Was passiert, wenn das Geocoding einer Source fehlschlägt?
Die Source bleibt ohne Koordinaten und wird vom Distance-Algorithmus als nicht bewertbar behandelt, also faktisch von der Auswahl ausgeschlossen, selbst wenn ausreichend Bestand vorhanden ist.
4Berechnet Distance die tatsächliche Fahrstrecke?
Nein, standardmäßig wird die Haversine-Formel für die Luftlinie zwischen zwei Punkten verwendet, nicht die reale Route. Das ist deutlich günstiger zu berechnen, kann aber bei Gebirgen oder Wasserflächen zwischen zwei Lagern ungenau sein.
5Wie wird die Priorität einer Source konfiguriert?
Pro Stock-Source-Zuordnung im Backend unter Inventory Stocks, als ganzzahliger Wert, wobei ein niedrigerer Wert eine höhere Priorität bedeutet. Dieselbe Source kann in unterschiedlichen Stocks unterschiedliche Prioritäten haben.
6Was passiert bei gleicher Priorität zweier Sources?
Die Reihenfolge ist dann faktisch undefiniert und hängt von der internen Ladereihenfolge der Datensätze ab. Für produktive Setups sollte deshalb jede Source im selben Stock eine eindeutige Priorität erhalten.
7Berücksichtigt Distance die aktuelle Lagerauslastung?
Nein, weder Distance noch Priority kennen die aktuelle Kapazität einer Source. Wer beides kombinieren möchte, braucht einen eigenen Algorithmus auf Basis des SourceSelectionInterface.
8Ab wie vielen Lagern lohnt sich Distance gegenüber Priority?
Sobald mehrere Lager geografisch klar getrennt sind und die Versanddauer für Kunden relevant ist, meist ab zwei bis drei Standorten in unterschiedlichen Regionen. Bei nur einem Haupt- und einem Backup-Lager reicht Priority meist aus.
9Wie wirkt sich ein abgelaufener Geocoding-API-Key aus?
Bereits geocodete Sources funktionieren weiterhin normal, aber neu angelegte Sources können nicht mehr geocodet werden und bleiben stillschweigend von der Distance-Auswahl ausgeschlossen, bis der Key erneuert wird.
10Lohnt sich Caching bei der Distanzberechnung?
Bei sehr großen Lagernetzen ja, da sich die Distanz zwischen einer Source und einem Postleitzahlgebiet praktisch nie ändert. Ein Cache pro Postleitzahlgebiet reduziert die Rechenlast bei stark frequentierten Checkouts spürbar.