Trade Promotion Management Transformation Engine Workflows

The workflow comprises APEX callable class to apply the transformations from the input JSON into the output structure.

Business object API workflow rules use the concept of Entities to identify records in both the data input (input payloads) and output (generated objects or records). The supported entities on the engine can be found on the business object API entities object. The ones provided by the managed package are:

Entity NameLocationDescription
PromotionInputRepresents the input Promotion. The attributes for the object are defined in the Workflow Rules that use this Entity.
TacticInputRepresents an input Tactic. The attributes for the object are defined in the Workflow Rules that use this Entity.
ManualInputsInputRepresents a Manual Inputs Array. The attributes for the object are defined in the Workflow Rules that use this Entity.
ProductFilterInputRepresents a Product Filter Structure. The attributes for the object are defined in the Workflow Rules that use this Entity.
TPM_PromotionOutputRepresents the TPM_Promotion Instance with all the promotion data.
TPM_Promotion.PromotionOutputRepresents a TPM_Promotion.Record instance with all the Promotion SObject Data. SObject fields can be used with dot notation.
TPM_Promotion.TacticOutputRepresents a TPM_Promotion.TacticRecord instance with all the Tactic SObject Data. SObject fields can be used with dot notation.
TPM_Promotion.AttachmentOutputRepresents a TPM_Promotion.Record instance with all the Promotion Attachment SObject Data. SObject fields can be used with dot notation.
TPM_Promotion.AttachmentLinkOutputRepresents a TPM_Promotion.Record instance with all the Promotion Attachment Link SObject Data. SObject fields can be used with dot notation.
TPM_Promotion.ProductFilterOutputRepresents a TPM_ProductFilter instance with all the Promotion Product filter information.
TPM_Promotion.ProductShareOutputRepresents a TPM_Promotion.Record instance with all the Promotion Product Share SObject Data. SObject fields can be used with dot notation.
TPM_Promotion.TacticConditionCreationDefinitionOutputRepresents a TPM_Promotion.Record instance with all the Tactic Condition Creation Definition SObject Data. SObject fields can be used with dot notation.
TPM_Promotion.TacticFundOutputRepresents a TPM_Promotion.Record instance with all the Tactic Fund SObject Data. SObject fields can be used with dot notation.
TPM_Promotion.TacticProductFilterOutputRepresents a TPM_ProductFilter instance with all the Tactic Product filter information.
CustomStateOutputRepresents a generic Object that is passed to the Promotion Saving Process while saving.

Workflow Step SObject

Workflow steps are defined in the Workflow StepSObject. Each step requires the following series of attributes:

ObjectDescriptionRequired/Optional
NameName of the business rule.Required
EntityEntity of the Input the rule must be applied to.Optional
MethodAction method that is passed to the callable class.Optional
ClassnameName of the APEX Callable class implementing the transformation.Required
DescriptionHigh-level overview of what the rule doesOptional

Input Structure records

Every rule must have a list of input structure records that reflect the expected inputs for the rule. Each record requires the following information:

ObjectDescription
PathPath of the input JSON, in which the rule reads a value.
Possible values are:
  • .TacticTemplate
  • .Categories
RequiredBoolean to indicate if the property is mandatory or optional.
RecordTypeThe type of the input expected for the property.
Possible values are:
  • Object
  • Array
  • String
  • Number
  • Boolean
  • Maximum and Minimum (Numbers)
  • Pattern (String)

The input structure records are used to generate the JSON schema. If an input attribute received isn’t as per the rules, the step reports an error.

Note

Applied Transformation Rules

Applied Transformation Rules are configured in the Transformation Configuration Record. The following table provides information about the record fields that must be updated:

ObjectDescription
Transformation RuleTransformation rule to be applied.
EnabledIndicates whether the rule is applied or not.
SortRules are executed in ascending order (allows the creation of dependencies).

Transformation Rules APEX classes receive a context object with the following attributes:

1// Common to all steps.
2String txId: TransactionId of the process
3String salesOrg: Sales organization passed to the execution.
4Object input: Whole Input Object
5Object output: Whole Output Object
6 
7// Step specific
8SObject workflowStepRecord: Workflow Step Record.
9 
10// Entity specific
11String inputPath: Path of the current input in the main input object.
12String inputEntityPath: A list of the names of the parent input entities ordered based on the deepness level. (i.e. Promotion/Tactic/TacticBrand).
13Object currentInput: Current block of the input object being processed.
14List<Object> parentInputs: A list of the parent Input Entities for this step. Each entry on the list will be the input Entity. Has the same number of elements as the inputEntityPath. (i.e. [ 0 ] → Promotion, [ 1 ] → Tactic, [ 2 ] → TacticBrand)
15 
16String outputPath: Path of the current output in the main output object.
17String outputEntityPath: A list of the names of the parent output entities ordered based on the deepness level. (i.e. BOPromotion/LOTactic).
18Object currentOutput:  Output object where the rule is expected to set the attributes. Rules are expected to set this object into the proper place of the parent.
19List<Object> parentOutputs: A list of the parent Output Entities for this step. Each entry on the list will be the output Object for the Entity. Has the same number of elements as the outputEntityPath. (i.e. [ 0 ] → BOPromotion, [ 1 ] → LOTactic)

Example 

Create a complete new workflow that to update the Tactic Comment field with a new specified value.

  1. Navigate to Business Object APIs Tab and navigate to the Promotion entry for Sales Org 0001. If it does not exist, create a record with those attributes.

  2. Configure the BO API Output entities. The Output entities for a BO API define which kind of objects the API works with. In the Output Entities related list, ensure the following entities are displayed. If not present in the related list, add them:

    1. TPM_Promotion (Main promotion object wrapper)
    2. TPM_Promotion.Tactic (Tactic Records)
    3. TPM_Promotion.Promotion (Promotion Record)
  3. In the workflows tab, create a workflow with the following attributes:

    1. Name: updateTacticComments
    2. Description: Updates Tactic Comments with the input parameters
  4. Navigate to your new workflow record.

  5. Configure how the input records are going to be mapped to the output records. To do so, add entries to the “Input Entities and Mapping” related list. Create the following records in the related list.

    Record 1

    1. Business Object API Entity: Promotion
    2. Output Entity: TPM_Promotion.Promotion
    3. Input Mapping Field: Id
    4. Output Mapping Field: Id, cgcloud__ExternalId__c

    Record 2

    1. Business Object API Entity: Tactic
    2. Output Entity: TPM_Promotion.Tactic
    3. Input Mapping Field: Id
    4. Output Mapping Field: Id, cgcloud__ExternalId__c
  6. Add Steps into the workflow. To load all the required promotion data, we can reuse Managed Package provided workflow steps. In the Workflow Steps related list, create the following records:

    Record 1

    1. Business Object API Workflow Step: loadPromotionDefaults(update)2
    2. Enabled: checked
    3. Sort: 10

    Record 2

    1. Business Object API Workflow Step: loadTacticDefaults(update)2
    2. Enabled: checked
    3. Sort: 20
  7. Check the input payloads structure for this API by clicking the “View Schema” button on the Workflow header. The schema should look like:

    1{
    2  "required" : [ "Id" ], // Promotion requires an Id because of the Promotion workflow step
    3  "properties" : {
    4    "Tactics" : {
    5      "items" : {
    6        "required" : [ "Id" ], // Tactic requires an Id because of the Tactic workflow step
    7        "properties" : {
    8          "TacticTemplate" : {
    9            "pattern" : null,
    10            "minLength" : null,
    11            "maxLength" : 40,
    12            "type" : "string"
    13          },
    14          "Id" : {
    15            "pattern" : null,
    16            "minLength" : null,
    17            "maxLength" : 40,
    18            "type" : "string"
    19          }
    20        },
    21        "additionalProperties" : false,
    22        "type" : "object"
    23      },
    24      "type" : "array"
    25    },
    26    "PromotionTemplate" : {
    27      "pattern" : null,
    28      "minLength" : null,
    29      "maxLength" : 40,
    30      "type" : "string"
    31    },
    32    "Id" : {
    33      "pattern" : null,
    34      "minLength" : null,
    35      "maxLength" : 40,
    36      "type" : "string"
    37    }
    38  },
    39  "additionalProperties" : false,
    40  "type" : "object"
    41}
  8. Add custom behavior. To add additional workflow steps create an APEX class that copies an input attribute from the input into the SObject Field Comment__c. Create the following APEX class in your org:

    1global with sharing class SetCommentValue implements System.Callable {
    2    public class SetCommentValueException extends Exception {}
    3    /**
    4    * This Sample Business Rule copies the value from the MyComment input attribute,
    5    * into the Output Comment__c field
    6    */
    7    public static Object call(String method, Map<String, Object> context) {
    8        // We use the context to extract variables
    9        // The type of the output object is defined by it's output entity in the mapping.
    10        cgcloud.TPM_Promotion.TacticRecord tactic = (cgcloud.TPM_Promotion.TacticRecord)
    11            context.get('currentOutput');
    12        // For input entities, it's type is always Map<String, Object>
    13        Map<String, Object> input = (Map<String, Object>) context.get('currentInput');
    14        
    15        // Set the value to the record
    16        cgcloud__Tactic__c myRecord = (cgcloud__Tactic__c) tactic.getRecord();
    17        
    18        myRecord.Comment__c = input.get('MyComment') != null 
    19            ? String.valueOf(input.get('MyComment'))
    20            : '';
    21            
    22        // After setting the value, we can return. The promotion and its
    23        // related records will be saved
    24        
    25        // If any exception is thrown, no data is committed
    26        return null;
    27    }
    28}
  9. Create the BO API Workflow Step record. Navigate to the “Business Object API Workflow Steps” Tab and create a new Record:

    1. Business Object API Workflow Step Name: SetCommentValue
    2. Classname: SetCommentValue (Name of the APEX class)
    3. Description: Sets the Comment Value for Tactic from the input attributes.
    4. Method: test (Method is passed to the callable class. This way, with different methods, the same class can implement multiple behaviors)
    5. Entity: Tactic (Since we want to apply this step on each Input Tactic)
    6. Sales Org: 0001
  10. Define which input structures the step needs. Create records in the Step Input Structures related list of the Workflow Step. The attributes for the Step input structures are used to determine the schema that the input should have (View Schema button). If the input does not match the schema, an error is displayed.

    1. RecordType String
    2. Description: New Comment Attribute value
    3. Path: .MyComment
    4. Required: unchecked
    5. Maximum Length: 80
  11. Add a Workflow step into the Workflow record.

    1. Business Object API Workflow Step: SetCommentValue
    2. Enabled: checked
    3. Sort: 30
  12. Click View Schema and the schema should have the following structure. The schema accpets the new MyComment attribute.

    1{
    2  "required" : [ "Id" ],
    3  "properties" : {
    4    "Tactics" : {
    5      "items" : {
    6        "required" : [ "Id" ],
    7        "properties" : {
    8          "MyComment" : {
    9            "pattern" : null,
    10            "minLength" : null,
    11            "maxLength" : 80,
    12            "type" : "string"
    13          },
    14          "TacticTemplate" : {
    15            "pattern" : null,
    16            "minLength" : null,
    17            "maxLength" : 40,
    18            "type" : "string"
    19          },
    20          "Id" : {
    21            "pattern" : null,
    22            "minLength" : null,
    23            "maxLength" : 40,
    24            "type" : "string"
    25          }
    26        },
    27        "additionalProperties" : false,
    28        "type" : "object"
    29      },
    30      "type" : "array"
    31    },
    32    "PromotionTemplate" : {
    33      "pattern" : null,
    34      "minLength" : null,
    35      "maxLength" : 40,
    36      "type" : "string"
    37    },
    38    "Id" : {
    39      "pattern" : null,
    40      "minLength" : null,
    41      "maxLength" : 40,
    42      "type" : "string"
    43    }
    44  },
    45  "additionalProperties" : false,
    46  "type" : "object"
    47}
  13. Test the API by making a REST call to the Promotion BO API endpoint and passing the required parameters.

    1POST /services/apexrest/cgcloud/promotions/ingest
    2
    3{
    4  "workflow": "updateTacticComments", // Name of your workflow
    5  "salesOrg": "0001",
    6  "promotions": [
    7    {
    8      "Id": "a2VTC0000001lJR2AY",  // A promotion in the system
    9      "Tactics": [
    10        {
    11          "Id": "a36TC0000000XYfYAM", // It's tactics
    12          "MyComment": "Comment 1 - updated"
    13        },
    14        {
    15          "Id": "a36TC0000000XYgYAM",
    16          "MyComment": "Comment 2 - updated"
    17        }
    18      ]
    19    }
    20  ]
    21}
  14. Track the execution status from the “Business Object API Transaction Logs” Tab by referencing the request by the returned importId.

Coding Guidelines 

  • Avoid expensive operations (such as significant JSON serializations or deserializations) in the Business Rules code.
  • Cache the SObject records from the database, as other rules might be impacted. (check SimplePromotionCoreBusinessRules.readSObjectById)
  • Ensure that the Business Rules focus on a single job, to enable a modular and configurable approach.