Aller au contenu principal
Aller au contenu principal
Guide

Comment Pivio calcule — guide

Transparence totale sur les formules, seuils et hypothèses derrière chaque alerte et chaque dollar de ROI.

Notre philosophie

Pivio ne cherche pas à gonfler les chiffres. Chaque valeur affichée est défendable devant un comptable ou un CFO. Quand on ne peut pas calculer avec certitude, on affiche une hypothèse explicite (plafond, plancher) plutôt qu'un chiffre arbitraire. L'objectif : qu'un gérant puisse expliquer son ROI en 30 secondes à son banquier.

Comment une alerte devient critique, modérée ou mineure

Chaque détecteur décide de la sévérité selon ses propres seuils (ex. jours de couverture pour une rupture, écart en % pour un shrinkage). La sévérité globale utilise un code couleur uniforme :

Critique (rouge)
Action requise maintenant. Exemples : rupture totale, écart d'inventaire ≥ 5 %, prix divergent de ≥ 35 %. Le détecteur a déclenché son seuil le plus haut.
Modéré (ambre)
À surveiller cette semaine ou à inclure dans la prochaine commande. Exemples : couverture stock < 5 j, rotation lente avec surstock, shrinkage 2-5 %.
Mineur (sable)
Signal d'hygiène catalogue — dérive de marge ou SKU sans entrée. Pas d'action immédiate mais à corriger lors du prochain dépôt catalogue.

Une alerte peut changer de sévérité d'un run à l'autre si les conditions s'améliorent ou se détériorent. Le bandeau « Récurrente » (voir ci-dessous) apparaît quand une alerte résolue re-fire.

Section Hebdomadaire : pourquoi c'est un snapshot du lundi

La section Hebdomadaire du tableau de bord affiche 5 alertes prioritaires à traiter cette semaine. Elle n'est pas recalculée à chaque visite — elle est figée pour la durée de la semaine pour que tu ne sois pas distrait par un ré-ordonnancement constant.

  • Chaque lundi, Pivio prend un instantané (snapshot) des 5 alertes actives les plus coûteuses (triées par impact estimé).
  • Ces 5 alertes restent affichées toute la semaine, même si tu en résouds certaines — elles apparaîtront alors comme résolues dans la liste, te donnant un sentiment de progression.
  • Lundi matin suivant, un nouveau snapshot est pris à partir des alertes actives de ce moment-là. Les alertes précédentes résolues disparaissent ; de nouvelles remontent.
Selon ton rythme de dépôt
  • Si tu déposes un fichier chaque semaine : le snapshot du lundi capture les nouvelles alertes générées par ce dépôt.
  • Si tu déposes un fichier une fois par mois : le snapshot du lundi reflète l'état actuel des alertes actives (aucun nouveau dépôt mi-cycle) — les alertes critiques remontent naturellement chaque semaine au fur et à mesure que tu résouds les plus urgentes.

Alertes récurrentes

Une alerte récurrente est une alerte qui était déjà résolue mais qui re-fire dans les données. Deux scénarios :

Scénario 1 — Résolution prématurée
Tu cliques « Résolu » sur une rupture, mais au prochain run le stock est toujours à 0. La condition sous-jacente n'a pas été réparée. Pivio la surface avec le badge Récurrente et un message ⚠️ te rappelant que le problème persiste.
Scénario 2 — Problème auto-résolu puis revenu
Le tracker a vu l'alerte cesser de fire (ex : une commande fournisseur a réglé la rupture). Quelques semaines plus tard, la condition re-fire. Pivio l'étiquette Récurrente pour te donner le contexte : « ça revient ».

Les alertes récurrentes comptent comme actives dans toutes les KPI (alertes actives, marge à risque, Hebdomadaire top 5). Le gérant a deux options : soit investiguer la cause racine et agir, soit marquer « Pas applicable » si l'alerte est un faux positif pour ce SKU/magasin.

Marquer « Pas applicable » silence l'alerte pendant 180 jours. Après ce délai, si la condition est toujours active, elle re-surface comme « Nouveau » pour re-évaluation (ex. nouveau fournisseur, saison différente).

Comment Pivio calcule le ROI

Quand tu résouds une alerte, Pivio lui attribue une valeur en $. Cette valeur représente la perte que tu aurais subie si Pivio ne t'avait pas alerté. Deux réalités à respecter en même temps :

  • Les alertes fraîches méritent un plancher — résoudre immédiatement ce qui vient d'être détecté a de la valeur, même si l'historique de pertes cumulées est à zéro.
  • Les alertes chroniques méritent leur plein poids — un problème qui traîne depuis 4 mois sans que personne le voie représente 4 mois de pertes réelles que Pivio a débloqué.
La formule
Alertes de flux (rupture, anomalie, promo, prix) :
effective_days = min(plafond, max(plancher, jours_de_persistance)) valeur = effective_days × perte_journalière
Alertes de stock immobilisé (rotation lente, stock mort, shrinkage) :
valeur = stock_immobilisé × taux_de_récupération
Exemples concrets
Alerte rupture fraîche (0 j d'historique) résolue immédiatement
14 × baseline × marge
Plancher appliqué
Alerte rupture avec 30 j de persistance
30 × baseline × marge
Crédit = historique réel
Alerte rupture avec 4 mois (120 j) de persistance
120 × baseline × marge
Plein crédit — le client ne l'aurait pas vue
Alerte zombie (2 ans, 730 j) résolue
min(365, 730) × baseline × marge
Plafond 365 j (crédibilité financière)
Pourquoi ce modèle ?
  • Laisse la donnée parler — le temps pendant lequel un problème a existé sans être résolu est une mesure directe du délai de détection naturel du gérant.
  • Borné en haut et en bas — pas d'inflation artificielle sur des données anciennes, pas de zéro artificiel sur des alertes récentes.
  • Tunable par client — les constantes (plancher 14 j, plafond 365 j, taux de récupération) vivent dans la configuration et peuvent être adaptées selon ta réalité.

Types d'alertes et seuils

Chaque détecteur a sa propre logique. Voici en clair ce que chacun cherche, comment il déclenche, et comment sa valeur de résolution est calculée.

F1Risque de rupture
Ce que l'alerte détecte
Détecte les SKUs dont la couverture (stock / ventes journalières) est trop faible pour tenir jusqu'à la prochaine livraison.
Seuils de déclenchement
Seuil rouge : ≤ 3 jours de couverture. Jaune : ≤ 5 jours. Ajusté au délai fournisseur quand le catalogue l'inclut (lead_time_days).
Champ de persistance utilisé
historical_stockout_days — nombre total de jours où le stock est tombé à 0 dans l'historique.
Formule de valeur ROI
min(cap, max(14j, historical_stockout_days)) × baseline_quotidien × marge_unitaire
F2Rotation lente (slow mover)
Ce que l'alerte détecte
SKU avec beaucoup de stock immobilisé qui se vend peu par rapport à son historique ou au réseau.
Seuils de déclenchement
Rouge : ≥ 75 j de couverture. Jaune : ≥ 45 j. Exclut les SKUs sans ventes récentes (ceux-ci tombent en F3).
Champ de persistance utilisé
inventory_days — jours de couverture actuels (proxy pour l'âge du stock stagnant).
Formule de valeur ROI
stock_immobilisé × taux_récupération (0.30 si < 60 j, 0.45 si 60–180 j, 0.65 si > 180 j)
F3Stock mort (dead inventory)
Ce que l'alerte détecte
SKU avec stock mais aucune vente depuis ≥ 60 jours. Stock gelé sans opportunité de vente naturelle.
Seuils de déclenchement
Jours depuis la dernière vente ≥ 60 ET stock > 3 unités ET valeur stock ≥ 50 $.
Champ de persistance utilisé
days_since_last_sale — jours écoulés depuis la dernière transaction.
Formule de valeur ROI
stock_immobilisé × taux_récupération (barème identique à F2)
F4Ventes anormales (anomalie)
Ce que l'alerte détecte
Écart significatif (chute ou pic) entre les ventes réelles et le baseline attendu sur les 7 derniers jours.
Seuils de déclenchement
Chute : ventes réelles ≤ 70 % du baseline. Pic : ≥ 140 % du baseline. Ignoré pendant les promos.
Champ de persistance utilisé
Fixe à 7 j — l'anomalie est par définition un écart récent.
Formule de valeur ROI
7 × écart_quotidien × marge_unitaire
F5Promo non rentable
Ce que l'alerte détecte
Promotion dont la hausse de ventes n'a pas compensé la remise appliquée — marge totale inférieure au scénario sans promo.
Seuils de déclenchement
Marge réalisée pendant la promo < marge estimée sans promo. Seuil configurable par client.
Champ de persistance utilisé
promo_duration_days — durée de la promotion.
Formule de valeur ROI
durée_promo × écart_marge_quotidien
F6Shrinkage (manquant inventaire)
Ce que l'alerte détecte
Écart entre le stock théorique (calculé à partir des réceptions et ventes) et le stock physique déclaré.
Seuils de déclenchement
Rouge : ≥ 5 % d'écart. Jaune : ≥ 2 %. Minimum 5 unités et 50 $ de valeur stock. Fenêtre par défaut : 30 jours.
Champ de persistance utilisé
window_days — fenêtre d'analyse (30 j par défaut).
Formule de valeur ROI
unités_manquantes × coût_unitaire
F7Transfert inter-magasin
Ce que l'alerte détecte
Un magasin est en excédent sur un SKU pendant qu'un autre est en rupture imminente — opportunité de transfert évitant une commande fournisseur.
Seuils de déclenchement
Magasin donneur : ≥ 60 j de couverture. Magasin receveur : ≤ 5 j de couverture. Même catégorie.
Champ de persistance utilisé
Plancher 14 j (alerte transactionnelle par nature).
Formule de valeur ROI
14 × baseline_receveur × marge_unitaire (perte évitée)
F8Rupture récurrente
Ce que l'alerte détecte
SKU qui rupture ≥ 3 fois en 180 jours. Indique un problème structurel (cycle fournisseur, sous-estimation saisonnière, etc.) plutôt qu'un incident ponctuel.
Seuils de déclenchement
≥ 3 épisodes distincts de rupture critique sur la fenêtre lookback (180 j par défaut).
Champ de persistance utilisé
lookback_days — fenêtre historique d'analyse (180 j par défaut).
Formule de valeur ROI
lookback_days × baseline_quotidien × marge_unitaire (plafonné)
F9Prix hors-réseau (outlier)
Ce que l'alerte détecte
SKU dont le prix de vente d'un magasin diverge significativement de la médiane du réseau — risque de perdre des ventes ou de laisser de la marge sur la table.
Seuils de déclenchement
Écart ≥ 15 % vs médiane réseau sur ≥ 30 jours d'historique. Minimum d'unités vendues pour filtrer le bruit.
Champ de persistance utilisé
Approximé à 30 j (fenêtre de détection) — à raffiner avec la durée réelle de divergence dans une version future.
Formule de valeur ROI
|prix_magasin − médiane_réseau| × unités × 0.5 (facteur d'érosion approximé)
F10Dérive de marge (info-only)
Ce que l'alerte détecte
Le coût d'achat réel observé sur les ventes diverge significativement du prix d'achat inscrit dans le catalogue fournisseur. Signal d'hygiène données — souvent une hausse fournisseur non répercutée ou un catalogue obsolète. N'EST PAS chiffré en dollars dans les KPIs : la magnitude est un écart de données, pas une perte réelle.
Seuils de déclenchement
|drift| ≥ 20 % entre coût réel moyen (sur 30 j) et catalogue.unit_cost. Rouge ≥ 30 %, jaune entre 20 % et 30 %. Min 5 unités vendues. Ne fire que si le catalogue contient un unit_cost > 0 pour le SKU.
Champ de persistance utilisé
Pas de persistance — c'est un instantané sur la fenêtre. La sévérité reflète l'amplitude actuelle.
Formule de valeur ROI
drift_pct = (coût_réel_moyen − catalog_unit_cost) / catalog_unit_cost — informationnel, jamais sommé en $
F11SKU sans entrée catalogue (info-only)
Ce que l'alerte détecte
Un SKU vendu sur la fenêtre n'a aucune entrée dans le catalogue fournisseur déposé. Conséquence : impossible de générer un bon de commande PDF pour ce produit (pas de fournisseur, pas de prix d'achat, pas de MOQ connus). Signal d'hygiène pour compléter le catalogue.
Seuils de déclenchement
SKU vendu ≥ 5 unités ET ≥ 25 $ de revenu sur 30 jours, qui n'apparaît pas dans le catalogue. Une seule alerte par SKU (pas par magasin). Sévérité jaune systématique. Désactivée tant qu'aucun catalogue n'est déposé.
Champ de persistance utilisé
Pas de persistance — l'absence est binaire (présent ou pas dans le catalogue).
Formule de valeur ROI
set(skus_vendus_30j) − set(skus_catalogue) — informationnel, jamais sommé en $

Constantes tunables

Ces valeurs par défaut peuvent être ajustées dans la configuration client. Parle à ton équipe Pivio pour les tuner à ta réalité.

detection_delay_floor_daysdéfaut: 14 j
Plancher : minimum de jours crédités pour une résolution. Basé sur le cycle médian de revue fournisseur d'une PME quincaillerie québécoise.
persistence_cap_daysdéfaut: 365 j
Plafond : maximum de jours crédités. Évite qu'un SKU abandonné depuis 3 ans génère un chiffre de ROI irréaliste.
capital_recovery_rate_shortdéfaut: 0.30
Pour inventaire bloqué < 60 j : 30 % récupérable via clearance naturelle.
capital_recovery_rate_middéfaut: 0.45
Pour inventaire bloqué 60–180 j : 45 % récupérable avec liquidation modérée.
capital_recovery_rate_longdéfaut: 0.65
Pour inventaire bloqué > 180 j : 65 % récupérable avec liquidation agressive (au risque de perdre plus en attendant).

Sources & benchmarks industrie

  • NHPA CODB 2024 — marge brute médiane 39,8 %, profit net 2,9 % (benchmark pour les quincailleries indépendantes).
  • AQMAT 2025 — contexte marché québécois et taux de rotation médians.
  • Cycle médian de revue fournisseur : 14 j (Epicor Eagle case studies, secteur retail quincaillerie).