Élaborer une liste des priorités d'achat avec les grilles quantiles - Optimisation

Classement par ordre de priorité des achats économiques










Accueil » Ressources » Ici

Les prévisions probabilistes offrent des indications sur le futur bien plus précises que celles obtenues par des approches de prévision traditionnelle et nous incitent à repenser entièrement le processus d'approvisionnement. Dans le présent document, nous détaillons comment une liste des priorités d'achat peut être générée avec l'aide de Lokad. Les deux bénéfices principaux de cette approche comparée aux points de commande sont : aucun taux de service à gérer et ajuster et une méthodologie d'achat plus flexible et mieux adaptée aux contraintes logistiques.

La liste des priorités d'achat est un exemple de commandes par ordre de priorité pour le stock. Cette large gamme de pratiques relatives au stock offre la possibilité d'atteindre des performances supérieures à celles obtenues à travers des pratiques plus traditionnelles. Autant que faire se peut, Lokad recommande d'effectuer des commandes par ordre de priorité.

Modèle de script destiné à établir la liste des priorités

Il est nécessaire d'utiliser un petit script Envision (voir ci-dessous) pour générer une liste de priorités. Ce script peut être créé dans votre compte Lokad grâce au bouton Create Envision script. Une fois le nouveau projet créé, l'éditeur de code source s'ouvre. Copiez-collez le code ci-dessous et cliquez sur Save.

read "/sample/Lokad_Items.tsv" with Supplier: text, Category: text, SubCategory: text
read "/sample/Lokad_Orders.tsv" as Orders
read "/sample/Lokad_PurchaseOrders.tsv" as PO

orderingLeadtime := 7 // 7 jours

where PO.DeliveryDate > PO.Date // exclusion des commandes non livrées
Leadtime = forecast.leadtime(
hierarchy: Category, SubCategory
present: (max(Orders.Date) by 1) + 1
leadtimeDate: PO.Date
leadtimeValue: PO.DeliveryDate - PO.Date + 1)

Demand = forecast.demand(
horizon: Leadtime +* dirac(orderingLeadtime)
hierarchy: Category, SubCategory
present: (max(Orders.Date) by 1) + 1
demandDate: Orders.Date
demandValue: Orders.Quantity)

show form "Purchase simulator" a1b3 tomato with Form.budget as "Max budget"

M = SellPrice - BuyPrice
S = - 0.25 * SellPrice // pénalité de rupture de stock
C = - 0.3 * BuyPrice * mean(Leadtime) / 365 // 0,3 % de coût de stockage annuel
MB = 0.5 * SellPrice // cas de commande en souffrance
SB = 0.5 * SellPrice // cas de commande en souffrance
AM = 0.3 // opportunité d'achat ultérieur
AC = 1 - 0.2 * mean(Leadtime) / 365 // 0,2 % de remise économique annuelle

RM = MB * uniform(1, Backorder) + (stockrwd.m(Demand, AM) * M) >> Backorder
RS = SB * uniform(1, Backorder) + zoz(stockrwd.s(Demand) * S) >> Backorder
RC = (stockrwd.c(Demand AC) * C) >> BackOrder
R = RM + RS + RC // recomposition

table G = extend.distrib(Demand >> BackOrder, StockOnHand + StockOnOrder, LotMultiplier)

where G.Max > StockOnHand + StockOnOrder
G.Q = G.Max - G.Min + 1
G.Reward = int(R, G.Min, G.Max) // intégral de la fonction de récompense associée au stock
G.Score = G.Reward / max(1, BuyPrice * G.Q)

G.Rank = rank(G.Score, Id, -G.Max) // meilleurs scores en premier, mais l'ordre des paires (Id, G.Max) est maintenu
G.Invest = cumsum(BuyPrice * G.Q, G.Rank)

where G.Invest < Form.budget + 0
where exists(G.Q)
show table "Purchase priority list with $\{Form.budget}" c1g3 tomato with
Id as "Id"
Supplier as "Supplier"
StockOnHand as "OnHand"
StockOnOrder as "OnOrder"
sum(G.Q) as "Qty"
mean(Leadtime) as "Leadtime"
sum(G.Reward) as "Reward" unit:"$"
sum(BuyPrice * G.Q) as "Cost" unit:"$"
group by Id
order by avg(G.Score) desc

Ce script produit un tableau de bord qui contient un tableau. Un planificateur logistique devra suivre l'ordre de la liste pour ses achats. Les quantités suggérées prennent en compte les « commandes en souffrance » ainsi que les « multiples de commande ».

Image

Voyons le contenu du script. Les premières lignes correspondent aux instructions de lecture des données contenues dans le répertoire /sample, où doivent se trouver les fichiers d'échantillon.

En ce qui concerne le fichier Lokad_Items.tsv qui doit contenir la liste des produits ou SKU, nous faisons l'hypothèse que deux colonnes spéciales sont disponibles :

  • SellPrice: prix de vente à l'unité (hors taxes).
  • BuyPrice: prix d'achat à l'unité (hors taxes).

Une fois que vous avez ajusté le script pour garantir qu'il extraie les données des bons fichiers d'entrée et, si les colonnes SellPrice et BuyPrice sont disponibles, vous pouvez cliquer sur le bouton Run. Le script est exécuté et produit un tableau de bord qui contient un seul grand tableau. Cliquez sur le tableau, en bas de l'écran, et vous pourrez le télécharger en tant que fichier Excel.

Au tout début du script se trouvent deux appels au moteur de prévisions probabilistes de Lokad. Ces appels visent à prévoir respectivement les délais d'approvisionnement et la demande.

Ensuite, nous introduisons les variables économiques utiles au calcul de la fonction de récompense associée au stock :
  • M : récompense (marge brute) par unité vendue depuis le stock.
  • S : pénalité par unité lorsque le demande ne peut être satisfaite à partir du stock.
  • C : coût de stock annuel par unité.
  • DAM : facteur de remise annuelle, facteur de remise sur le composant de marge.
  • AC : facteur de remise sur le composant des coûts de stockage.

Le cœur de la logique de priorisation se trouve dans le calcul de G.Reward et G.Score.
  • G.Reward : représente la récompense économique pour Gr.Q unité(s) supplémentaire(s) en stock (en général Gr.Q est égal à 1).
  • G.Score : représente les retours en euros pour chaque euro investi dans le stock.

Le filtre where qui suit ces calculs exclut les situations dans lesquelles le point de commande est en dessous des niveaux de stock actuels. Nous excluons ces situations car nous ne considérons ici que les scénarios d'achat, dans lesquels il s'agit d'acquérir plus de stock. Avec ce bloc de code, nous traitons une deuxième série de calculs qui amènent à la priorisation :

  • G.Rank: classe toutes les entrées de la grille en fonction de leur score. Le classement est spécial : pour chaque article, le nouveau classement conserve l'ordre des points de commande.
  • G.Invest: décrit un calcul cumulatif. Nous calculons l'investissement total (cumulé), en faisant l'hypothèse que chaque article est acheté en suivant l'ordre de la liste.

Enfin, le script se termine avec une instruction show table et toutes les lignes des grilles sont regroupées par Id pour obtenir une liste où chaque article n'apparaît qu'une fois.

Affiner les priorités

Le script détaillé ci-dessus fait des hypothèses quelque peu simplistes à propos des variables utilisées pour le calcul de la récompense associée au stock. Tous vos articles ne sont peut-être pas sujets au même coût de stock. Certains articles peuvent être périssables, d'autres très encombrants, etc. Vous pouvez consulter notre page sur les coûts de stock pour des hypothèses plus réalistes sur ce type de coût. Dans la pratique, nous observons que la plupart des commerçants sous-estiment systématiquement ces coûts. D'après notre expérience, un coût annuel de stock inférieur à 25 % est douteux.

Il peut paraître fastidieux d'étudier ce script mais, en pratique, il semble que celui-ci représente l'une des seules solutions assez souples pour mettre en œuvre des hypothèses conformes à votre activité. Le script Envision offre l'expressivité que l'on trouve généralement dans une feuille de calcul Excel.

Du côté des bénéfices, le script favorise une maximisation pure de la marge brute. Cela peut avoir un impact négatif sur votre entreprise si ce sont des articles sur lesquels votre marge est faible qui font tourner votre activité en générant de nombreuses ventes plus petites mais plus rentables (par exemple, un client achète un smartphone avec une marge brute de 2,5% puis deux accessoires sur lesquels la marge est de 50 %). Dans ce cas, vous pouvez introduire un facteur de "bonne volonté" représenté par des marges différées appliquées à ces articles phares.

D'après notre expérience, il y a presque autant d'options de priorisation que d'entreprises mais la priorisation reflète le mélange très spécifique qui définit votre entreprise. N'hésitez pas à si vous souhaitez un accompagnement plus poussé.