Rabatte von Lieferanten in Envision

Rabatte von Lieferanten












Startseite » Ressourcen » Hier

Preisnachlässe oder Mengenrabatte stellen Fälle dar, in denen der Grenzpreis der Ware pro Stück sich nach der geplanten Bestellmenge richtet. Gewöhnlich sinken Stückpreise, wenn die Bestellmenge steigt, um Kunden einen Anreiz zu geben, mehr zu kaufen. Wenn Lieferanten Rabatte bieten, besteht ein wirtschaftlicher Anreiz zur Anpassung der Bestellmenge, um diese Rabatte auszunutzen. Envision bietet eine breitgefächerte Unterstützung für Rabatte von Lieferanten. In diesem Abschnitt erklären wir, wie Rabatte aus der Perspektive der Einkaufsoptimierung modelliert werden können.


Darstellung der Rabatte als Tabelle

Die häufigste Art, Rabatte für eine Produktliste darzustellen, besteht aus einer Tabelle mir 3 Spalten:

  • Id der Bezeichner des Produkts
  • MinQ die Mindestmenge, die zu Anwendung des Stückpreises nötig ist
  • P der Kaufpreis des Produkts pro Einheit

Zur besseren Lesbarkeit der Tabelle beim Nachschlagen eines bestimmten Produkts, werden die Zeilen gewöhnlich in aufsteigender Reihenfolge nach Menge sortiert. Diese Sortierreihenfolge hilft, das Ausmaß der Rabatte besser zu verstehen.

Diese Darstellung neigt zu negativen Grenzpreisen pro Stück, bei denen der Kauf einer zusätzlichen Einheit zu einem niedrigeren Gesamtpreis führen kann.

Gehen wir vom Produkt A aus, das für 1,00 € pro Einheit verkauft wird. Für Produkt A wird ein Rabatt bei 50 Einheiten geboten, durch das der Stückpreis auf 0,90 € fällt. Der Kauf von 46 Einheiten würde somit 46,00 € kosten, während der Kauf von 50 Einheiten nur 45,00 € kostet. Daher besteht kein wirtschaftlicher Anreiz, Mengen zwischen 46-49 Einheiten zu kaufen, da es günstiger ist, stattdessen 50 Einheiten zu kaufen. Der Grenzpreis pro Einheit der 50. Einheit ist -4€.

Diese negativen Grenzpreise sind die Folge des zugrundeliegenden Datenmodells der Rabatte. Es gibt auch anspruchsvollere Rabattmodelle, die diese negativen Grenzpreise beseitigen, doch diese gehen über das Ziel dieses Abschnitts hinaus.

Im Folgenden gehen wir davon aus, dass die Daten zu Rabatten über eine Tabelle wie der obigen zur Verfügung gestellt werden können.

pricebrk() Funktion

Die pricebrk() Funktion in Envision hat zum Ziel, tabellarische Rabatt-Daten in eine Verteilung umzuwandeln, den Grenzpreis pro Stück darstellt. Die Syntax lautet, wie folgt:
// 'Prcs' ist die Rabatt-Tabelle
expect Prcs[Id, *]
B = pricebrk(D, P, Prcs.MinQ, Prcs.P, Stk, StkP)
Die Funktion gibt die Verteilung der Grenzpreise für den Kauf eines Stücks zurück, also, den Preis, der für den Kauf von der kten Einheit bezahlt werden muss. Diese Funktion ist etwas komplex. Im Folgenden begründen und erklären wir die Komplexität.

Die Argumente sind:
  • D (für „Bedarf“) ist eine Verteilung, die zur Auswahl eines Trägers, im mathematischen Sinne, benutzt wird, um die Verteilung zurückzugeben. Die Werte dieser Verteilung werden nicht benutzt, doch die zurückgegebene Verteilung wird angepasst, um mindestens genau so präzise wie D zu sein.
  • P ist eine Zahl, die als standardmäßiger Stückpreis für das Produkt interpretiert wird. Dieser Wert wird benutzt, wenn kein Rabatt für eine Mindestmenge von 1 vorhanden ist; entweder weil der Rabatt bei einem Wert größer null beginnt, oder weil für das Produkt keine Rabatte verfügbar sind.
  • Prcs.MinQ ist die Mindestmenge, auf die die Zeile des Rabatts zutrifft. Es muss eine ganze Zahl größer gleich 1 sein. Duplikate sind nicht zulässig.
  • Prcs.P ist der Stückpreis für diese Rabatt-Zeile. Er trifft für alle gekauften Einheiten zu, nicht nur für diejenigen, die über Prcs.MinQ liegen. Es muss eine fallende Funktion von Prcs.MinQ sein.
  • Stk ist der vorhandene Bestand des Produkts. Werte ungleich null bedeuten, dass weniger Einheiten nötig sind, um eine bestimmte Bestandshöhe zu erreichen, was gleichzeitig heißt, dass Rabatte schwieriger zu erreichen sind. Es muss sich um eine nicht negative ganze Zahl handeln. Dieses Argument ist optional. Wenn das Argument ausgelassen wird, sollte StkP auch ausgelassen werden. Wenn dieses Argument ausgelassen wird, ist der Wert standardmäßig null.
  • StkP ist der Stückpreis für Einheiten, die bereits Teil des Bestands sind. Dieses Argument ist optional. Wird es ausgelassen, ist der Standardwert null.

Das P-Argument ist lediglich syntaktischer Zucker, der für Fälle gedacht ist, bei denen die Rabatt-Tabelle nur Produkte deckt, die auch tatsächlich von einem Rabatt profitieren. Über dieses Argument vermeiden wir die Notwendigkeit, die Prcs-Tabelle zu erweitern, um mindestens eine Zeile pro Produkt zu haben.

Auflösung von Verteilungen

Als erstes Argument von pricebrk() ist eine Verteilung nötig, weil diese in Envision nicht beliebig genau sind. In der Tat bestehen praktische Grenzen zur Auflösung von Verteilungen in Envision. Doch die Rabatte, die von einem bestimmten Lieferanten erhalten werden, können vom Kauf 1 Stücks bis hin zum (theoretischen) Kauf von 10 Millionen Stücken reichen. Die Demand-Verteilung wird in der pricebrk()-Funktion zur Anpassung der Auflösung der zurückgegebenen Verteilung auf den gewünschten Bereich benutzt.

So vermeidet Envision eine Logik zur Bestandsoptimierung, die den Kauf von 999 Stück vorschlägt, wenn der Grenzpreis, ab dem der Rabatt eingesetzt wird, bei 1000 Stück liegt. Solche Fälle könnten auftreten, wenn die von Envision erzeugte Verteilung intern nicht die Werte bei 999 und bei 1000 Stück unterscheidet. Durch die Übergabe einer Verteilung an die pricebrk()-Funktion stellt Envision sicher, dass dieses spezifische Szenario vermieden wird, indem die Auflösung der zurückgegebenen Verteilung angepasst wird.

Bestellbereich vs. Bestandsbereich

Die Tabelle der Rabatte ist nach der Perspektive der Bestellung sortiert, wobei jeder Bestellmenge ein Stückpreis zugeordnet wird. Doch die Bestandsoptimierung richtet sich nach der Bestandsperspektive: Wenn man 1 Bestandseinheit hinzufügen möchte, wird der bereits vorhandene Bestand berücksichtigt, also der Bestandsbereich. Die pricebrk() Funktion übersetzt die Darstellung der Rabatte aus dem ursprünglichen Bestellbereich in den Bestandsbereich.

Wegen dieser Übersetzung weist pricebrk() zwei Argumente auf, die dem Bestand zugeordnet werden: die Bestandshöhe und der Stückpreis des Bestands. Diese beiden Argumente werden zur Verschiebung der Verteilung des Grenzpreises um Bestandseinheiten nach rechts benutzt. Die Verschiebung könnte mit dem gewöhnlichen Shift-Operator >> auf Verteilungen vorgenommen werden, doch dies könnte zu Situationen führen, bei denen kleinere Schätzungen mit der Schwelle, ab der der Rabatt gilt, in Konflikt treten. Die pricebrk() Funktion internalisiert die Verschiebung, um diese Schätzungen zu entfernen.

Grenzpreis pro Stück

Die von pricebrk() zurückgegebene Verteilung stellt den Grenzpreis pro Stück dar. Die Segmente [1;Stk] sind dem aktuellen Bestand und dem StkP zugeordnet. Dann ist, wenn B eine von pricebrk() zurückgegebene Verteilung ist, das Integral int(B, Stk + 1, Stk + N) die Gesamtkosten beim Einkauf von N Stück, über den Einheiten, die sich bereits im Bestand befinden.

Wie oben beschrieben, hängen Rabatt-Tabellen oft mit negativen Grenzkosten zusammen, gerade in Fällen, in denen der Kauf eines zusätzlichen Stücks negative Kosten erzeugt. Die von pricebrk() zurückgegebene Verteilung spiegelt solche Fälle über lokale negative Werte wieder. Diese negativen Werte werden als direkte Folge des Rabatt-Datenmodells betrachtet.

Kombination von Rabatten und Bestandsbelohnungen

Die Bestandsbelohnungsfunktion berechnet die Verteilung der Grenzrendite für jede zusätzliche Bestandseinheit, die im Bestand gehalten wird. In einem früheren Abschnitt konnten wir beobachten, wie dieser Funktion Wirtschaftsvariablen zugeordnet werden können, die die Bruttogewinnspanne, die Bestrafung für Fehlbestände und die Lagerhaltungskosten darstellen. In dieser Diskussion waren diese Wirtschaftsvariablen einfache Zahlen. Doch wenn Rabatte im Spiel sind, ändern sich diese Wirtschaftsvariablen zusammen mit den Bestellmengen. Diese Variationen werden einfach über Verteilungen Modelliert.
B = pricebrk(D, BuyP, Prcs.MinQ, Prcs.P, Stk, StkP)

// 'M', 'S' und 'C' sind Verteilungen
M = SellPrice - B
S = -0.5 * (SellPrice - B)
C = -0.3 * B * mean(Leadtime) / 365

AM = 0.3
AC = 1 - 0.2 * mean(Leadtime) / 365

// punktweise Multiplikation für 'RM', 'RS' und 'RC'
RM = stockrwd.m(D, AM) * M
RS = stockrwd.s(D) * S
RC = stockrwd.c(D, AC) * C
R = RM + RS + RC 
Der Hauptunterschied zwischen diesem Code-Block und dem ursprünglichen, wenn man die Bestandsbelohnungsfunktion einführt ist BuyP. Die BuyP Spalte wird in Zeile 1 über die Funktion pricebrk() in eine Verteilung der Rabatte B umgewandelt. Dann geht das restliche Skript auf die direkte Anwendung der Algebra der Verteilungen zurück, die uns die schwere Arbeit abnimmt.

In Zeilen 4-6 werden die Wirtschaftsvariablen in Verteilungen umgewandelt. So ergibt sich durch die Summe einer Konstante und einer Verteilung eine Verteilung. Dasselbe gilt auch für Subtraktionen. Oben ist M die Grenzbelohnung pro Stück (also die marginale Gewinnspanne). Da die Rabatte gewöhnlich geringere Stückpreise bei steigender Menge bieten, wird erwartet, dass die Verteilung M steigend ist.

In Zeilen 12-14 werden den Komponenten der Bestandsbelohnungsfunktion die wirtschaftlichen Verteilungen (vielmehr als Zahlen) zugeordnet, doch die Syntax bleibt gleich. Eigentlich werden unter den Verteilungen punktweise Multiplikationen ausgeführt. Zuletzt wird in Zeile 15 die endgültige Bestandsbelohnung, wie früher, erstellt.