quote → cash
FR/EN Contact

Product·Avancé·11 min·Mis à jour le 05/10/2026

Guide · Produit

Une offre vraiment complexe : paliers de setup, adders et vingt et une variantes matérielles

Ce qu’il faut pour modéliser une offre d’infogérance où le frais de setup change de palier selon un effectif, où les adders se calculent sur une quantité qui n’est pas le nombre de postes, et où un seul bundle porte vingt et une variantes de boîtier en trois rôles.

Salesforce docs documenté par SalesforceTerrain constaté sur une vraie orgRecommandé ce que nous recommandonsÀ vérifier non vérifié

L’offre

Un prestataire d’infogérance vend plusieurs offres qui paraissent simples sur une plaquette et ne le sont pas dans un catalogue. L’une a un frais de setup qui dépend d’un palier d’effectif, plus des adders à l’unité. Une autre repose sur du matériel : vingt et une variantes de boîtier, chacune vendable en trois rôles, à l’intérieur d’un seul bundle.

Rien d’exotique ici. C’est simplement plus réel que les exemples de la documentation, et chaque mécanisme qui casse le fait pour une raison qui mérite d’être connue.

La quantité qui pilote le prix n’est pas celle qu’on croit

Le frais de setup change de palier selon un effectif : un prix en dessous du seuil, un autre au-dessus. C’est une vraie condition, donc une vraie decision table. Très bien.

Le piège est dans ce qui pilote les autres éléments. Les composants récurrents de pilotage — délivrance de service, comités, supervision — ne se calculent pas sur le nombre de postes. Ils se calculent sur le nombre d’utilisateurs supportés, qui est un autre nombre porté par un autre champ.

Les deux sont assez proches pour que le mauvais paraisse juste sur tous les devis de test où ils coïncident, et faux sur tous les vrais où ils diffèrent.

La défense pratique, c’est de documenter au point d’usage : nommer explicitement la quantité pilote sur le produit, et écrire quelle quantité pilote quel élément de pricing. C’est très exactement le détail qu’il faudra redériver, péniblement, un an plus tard, par quelqu’un qui n’était pas là.

Paliers de setup, et où mettre les parties fixes

Le seuil va dans une decision table. Les adders non — ce sont des prix fixes, et un prix fixe vit sur le PricebookEntry, où il ne consomme aucune capacité de procédure.

Ça compte plus qu’il n’y paraît, parce qu’ une pricing procedure a un plafond et que les decision tables ajoutées par réflexe sont ce qui le remplit. Un catalogue de cette taille peut épuiser une procédure avec des tables qui ne répondent à aucune question.

Les franchises incluses, et pourquoi une seule fonctionnait

Plusieurs bundles incluent une franchise — tant d’heures de formation, tant de mois d’un service — le surplus étant facturé au tarif réel. La façon native d’exprimer ça est un barème d’ajustement de prix avec des paliers : la quantité incluse à zéro, le surplus au prix réel.

Cinq franchises avaient été configurées ainsi. Exactement une s’appliquait.

Les paliers étaient corrects. La cause était ailleurs : la pricing procedure par défaut applique les barèmes par des constantes en dur, pas dynamiquement. Une constante pointait sur un barème, donc un seul barème était jamais lu. Les quatre autres étaient configurés, valides, et jamais consultés.

Le correctif est un barème global unique portant toutes les franchises, avec la constante pointée dessus. Les barèmes par offre peuvent rester en place, inertes, ou être désactivés pour ne pas induire en erreur la personne suivante.

Un détail de plus, qui coûte un après-midi quand une offre arrive dans une nouvelle région : les paliers portent une devise. Des paliers écrits en euros ne matchent pas une transaction en dollars, et la franchise ne s’applique pas, en silence. Aucun avertissement — la ligne price simplement comme si aucune franchise n’existait.

Vingt et un boîtiers en trois rôles

L’offre matérielle est un bundle de vingt et un modèles de boîtier, chacun vendable en unité principale, unité secondaire ou élément de cluster. Modélisé naïvement, ça fait soixante-trois produits. Modélisé en bundle à trois groupes de composants, ça fait vingt et un produits et trois groupes.

Deux pièges mécaniques apparaissent immédiatement à cette taille :

  • Une séquence nulle sur un composant de bundle déclenche une erreur d’index au moment de la configuration. Avec trois composants c’est évident. Avec soixante-trois relations de composant, non, et l’erreur ne nomme rien d’utile. Vérifiez-les toutes avant de livrer.
  • Un PricebookEntry en double dont l’un est inactif bloque l’actif, avec le message « price book entry is inactive » — qui désigne le mauvais enregistrement. Supprimez le doublon plutôt que d’essayer de le réactiver.

Et un qui est définitif plutôt que simplement agaçant : ProductSellingModelId sur le PricebookEntry est obligatoire et non modifiable après insertion. S’il est faux, le seul retour possible est supprimer et recréer. Posez-le à l’insert.

Construit par API, cassé par API

Le bundle matériel a été créé en masse par API — vingt-quatre produits, le bundle, trois groupes, les prix et les selling models. Tout paraissait correct. À la configuration, échec sur une erreur de succès nul dans la réponse de configuration, qui ne dit rien de sa cause.

Ce que l’élimination a prouvé, dans l’ordre :

  1. Pas le pricing. Reculer les réglages de procedure plan n’a rien changé, ce qui a écarté tout le chemin de pricing d’un seul geste.
  2. Pas le champ évident. Corriger le flag de configuration à la vente sur les composants n’a eu aucun effet.
  3. Pas une séquence nulle — la cause connue des erreurs d’index sur les composants de bundle — puisqu’il n’y en avait aucune.

Ce qui restait : un bundle équivalent construit à la main dans l’interface fonctionnait. L’hypothèse de travail est que l’interface remplit des champs que l’appel API ne remplit pas, et le diagnostic qui suit est mécanique — construire un produit à la main, puis le comparer champ par champ à un produit créé par API.

C’est rapporté comme une investigation ouverte, pas comme un problème résolu, parce que c’est ce que c’est.

Les champs obligatoires propres à l’org

Dernière catégorie, facile à rater et propre à chaque org : les champs obligatoires locaux. Sur celle-ci, les produits portent deux champs custom obligatoires, le second étant une picklist dépendante dont les valeurs disponibles sont contrôlées par la famille de produits. Un chargement en masse qui pose la famille et la valeur dépendante indépendamment produit des combinaisons individuellement valides et conjointement impossibles.

Une chose dont on n’a pas besoin, et qu’on construit souvent quand même : un champ formule sur la ligne pour exposer un attribut produit au pricing. Le contexte sait traverser jusqu’au produit, donc l’attribut est atteignable sans le dupliquer sur la ligne.

Ce qu’on ferait différemment

Construire un produit à la main dans l’interface, de bout en bout, avant de charger quoi que ce soit — jusqu’à la configuration, le pricing et un devis repricé. Puis comparer un équivalent créé par API. Cette seule comparaison aurait attrapé l’échec du configurateur, l’immuabilité du selling model et la picklist dépendante en une passe, avant que vingt-quatre produits n’existent à corriger.

Composants Salesforce

Sélectionnez-en un pour ouvrir son détail.

Sur quoi ça repose

  • L’échec du bundle matériel est une investigation ouverte, pas un problème résolu. Il est publié parce que l’élimination est utile même si la cause n’est pas encore prouvée.
  • Tous les comportements décrits ont été constatés sur de vraies orgs en construisant ces catalogues.

Ressources Salesforce