Vous êtes ici :
Créer un champ personnalisé et définir des déclencheurs Apex
Créez les champs personnalisés nécessaires et définissez des déclencheurs Apex dans les objets Élément de ligne de devis et Produit de commande (OrderItem).
Éditions requises
| Disponible avec : Lightning Experience |
| Disponible avec : les éditions Enterprise, Unlimited et Developer de Gestion du revenu (anciennement Revenue Cloud) avec la licence Revenue Cloud Growth ou Revenue Cloud Advanced |
Création du champ personnalisé ConstraintEngineNodeStatus
Créez un champ personnalisé dans les objets Élément de ligne de devis, Produit de commande et Source d'action de l'actif pour stocker les données que le Moteur de règles de contrainte utilise pour le traitement interne.
Accédez aux paramètres de gestion des objets suivants, puis créez un champ personnalisé avec les valeurs suivantes :
- Sélectionnez le type de données Zone de texte (long).
- Saisissez Statut du nœud moteur de contrainte en tant qu'étiquette de champ.
- Saisissez 131072 comme longueur.
- Saisissez ConstraintEngineNodeStatus comme nom de champ.
- Sélectionnez Accès visible, puis désélectionnez Accès en lecture seule pour les profils des utilisateurs qui utiliseront le Moteur de règles de contrainte, et des utilisateurs de Customer Community et Partner Community.
- Désélectionnez les présentations de page.
Consultez Création d'un champ personnalisé.
Définition de déclencheurs Apex pour des éléments de ligne de devis et de commande
Définissez des déclencheurs pour les objets Élément de ligne de devis et Produit de commande (OrderItem) en utilisant un code Apex.
Utilisez ce code Apex pour l'objet Élément de ligne de devis.
trigger QuoteItemTrigger on QuoteLineItem (before insert) {
//collect QuoteActionIds
Set<Id> quoteActionIds = new Set<Id>();
for (QuoteLineItem qi : Trigger.new) {
if (qi.QuoteActionId != null && qi.ConstraintEngineNodeStatus__c == null) {
quoteActionIds.add(qi.QuoteActionId);
}
}
if (!quoteActionIds.isEmpty()) {
// Step 1: Get QuoteAction → SourceAsset
Map<Id, Id> quoteActionToAssetId = new Map<Id, Id>();
for (QuoteAction qAction : [
SELECT Id, SourceAssetId
FROM QuoteAction
WHERE SourceAssetId != null
AND Id IN :quoteActionIds
]) {
quoteActionToAssetId.put(qAction.Id, qAction.SourceAssetId);
}
// Step 2: Get AssetActions
List<AssetAction> assetActions = [
SELECT Id, AssetId, ActionDate
FROM AssetAction
WHERE AssetId IN :quoteActionToAssetId.values()
];
// Step 3: Get latest AssetAction per Asset
Map<Id, AssetAction> assetIdToLatestAction = new Map<Id, AssetAction>();
for (AssetAction aAction : assetActions) {
AssetAction existing = assetIdToLatestAction.get(aAction.AssetId);
if (existing == null || aAction.ActionDate > existing.ActionDate) {
assetIdToLatestAction.put(aAction.AssetId, aAction);
}
}
// Step 4: Get related AssetActionSource records
Map<Id, Id> assetIdToActionId = new Map<Id, Id>();
for (Id assetId : assetIdToLatestAction.keySet()) {
assetIdToActionId.put(assetId, assetIdToLatestAction.get(assetId).Id);
}
List<AssetActionSource> assetActionSources = [
SELECT ConstraintEngineNodeStatus__c, AssetAction.AssetId
FROM AssetActionSource
WHERE AssetActionId IN :assetIdToActionId.values() ORDER BY CreatedDate DESC
];
// Step 5: Map AssetId → Status
Map<Id, String> assetIdToStatus = new Map<Id, String>();
for (AssetActionSource actionSource : assetActionSources) {
if (!assetIdToStatus.containsKey(actionSource.AssetAction.AssetId) &&
actionSource.ConstraintEngineNodeStatus__c != null) {
assetIdToStatus.put(
actionSource.AssetAction.AssetId,
actionSource.ConstraintEngineNodeStatus__c
);
}
}
List<QuoteLineItem> toUpdate = new List<QuoteLineItem>();
// Step 6: Set ConstraintEngineNodeStatus__c directly on Trigger.new records
for (QuoteLineItem qi : Trigger.new) {
if (qi.QuoteActionId != null && qi.ConstraintEngineNodeStatus__c == null) {
Id assetId = quoteActionToAssetId != null ? quoteActionToAssetId.get(qi.QuoteActionId) : null;
if (assetId != null && assetIdToStatus != null) {
String status = assetIdToStatus.get(assetId);
if (status != null) {
qi.ConstraintEngineNodeStatus__c = status;
}
}
}
}
}
}Utilisez ce code Apex pour l'objet Produit de commande (OrderItem).
trigger OrderItemTrigger on OrderItem (before insert) {
//collect orderActionIds
Set<Id> orderActionIds = new Set<Id>();
for (OrderItem oi : Trigger.new) {
if (oi.OrderActionId != null && oi.ConstraintEngineNodeStatus__c == null) {
orderActionIds.add(oi.OrderActionId);
}
}
if (!orderActionIds.isEmpty()) {
// Step 1: Get OrderAction → SourceAsset
Map<Id, Id> orderActionToAssetId = new Map<Id, Id>();
for (OrderAction oAction : [
SELECT Id, SourceAssetId
FROM OrderAction
WHERE SourceAssetId != null
AND Id IN :orderActionIds
]) {
orderActionToAssetId.put(oAction.Id, oAction.SourceAssetId);
}
// Step 2: Get AssetActions
List<AssetAction> assetActions = [
SELECT Id, AssetId, ActionDate
FROM AssetAction
WHERE AssetId IN :orderActionToAssetId.values()
];
// Step 3: Get latest AssetAction per Asset
Map<Id, AssetAction> assetIdToLatestAction = new Map<Id, AssetAction>();
for (AssetAction aAction : assetActions) {
AssetAction existing = assetIdToLatestAction.get(aAction.AssetId);
if (existing == null || aAction.ActionDate > existing.ActionDate) {
assetIdToLatestAction.put(aAction.AssetId, aAction);
}
}
// Step 4: Get related AssetActionSource records
Map<Id, Id> assetIdToActionId = new Map<Id, Id>();
for (Id assetId : assetIdToLatestAction.keySet()) {
assetIdToActionId.put(assetId, assetIdToLatestAction.get(assetId).Id);
}
List<AssetActionSource> assetActionSources = [
SELECT ConstraintEngineNodeStatus__c, AssetAction.AssetId
FROM AssetActionSource
WHERE AssetActionId IN :assetIdToActionId.values() ORDER BY CreatedDate DESC
];
// Step 5: Map AssetId → Status
Map<Id, String> assetIdToStatus = new Map<Id, String>();
for (AssetActionSource actionSource : assetActionSources) {
if (!assetIdToStatus.containsKey(actionSource.AssetAction.AssetId) &&
actionSource.ConstraintEngineNodeStatus__c != null) {
assetIdToStatus.put(
actionSource.AssetAction.AssetId,
actionSource.ConstraintEngineNodeStatus__c
);
}
}
List<OrderItem> toUpdate = new List<OrderItem>();
// Step 6: Set ConstraintEngineNodeStatus__c directly on Trigger.new records
for (OrderItem oi : Trigger.new) {
if (oi.OrderActionId != null && oi.ConstraintEngineNodeStatus__c == null) {
Id assetId = orderActionToAssetId != null ? orderActionToAssetId.get(oi.OrderActionId) : null;
if (assetId != null && assetIdToStatus != null) {
String status = assetIdToStatus.get(assetId);
if (status != null) {
oi.ConstraintEngineNodeStatus__c = status;
}
}
}
}
}
}
Voir Définition des déclencheurs Apex.
Après avoir défini les déclencheurs Apex, configurez le moteur.
