Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 43 Next »

Salesforce Validation Rules

Pulsar directly supports evaluating Salesforce validation rules both online and offline.

  • Supports most Salesforce formulas (see more information about formula fields)
  • Follow the pre-processing steps on the Pulsar Settings Manager tab (NOTE: this is currently a limitation of the Salesforce platform, as we cannot directly sync validation rule metadata, but first have to pre-process it).
  • Set pulsar.validation.enableSFDCValidationRules Pulsar Setting to TRUE to enable this functionality in the Pulsar mobile app
  • NOTE: If a PSL BeforeSave setting exists on an object, it will be run BEFORE saving the object and BEFORE processing any Salesforce ValidationRules for that record.



PSL Validation Rules and Triggers

Pulsar originally did not support running Salesforce validation rules, and instead offered similar functionality through logic implemented in Pulsar Settings Language (PSL).  Because PSL leverages the power of raw SQL, you can create complex validation logic that exceeds what Salesforce formula validation rules can perform.  Despite (or frankly because of) the power of PSL validation rules and triggers, we recommend that you use Salesforce validation rules if possible before bringing PSL to bear on a thorny problem.

Admins can use Pulsar Settings to implement validation rules and triggers for the following execution points:

1. BeforeEdit

2. BeforeSave 

3. BeforeDelete

4. OnCreate

5. OnSave

6. OnDelete

7. onBarcodeScan

Validation Rules and Trigger execution points are composed of three "post-action" execution points, OnCreate, OnSave, and OnDelete, where the create, save, or delete action has occurred or is certain to occur, and three "pre-action" execution points, BeforeEdit, BeforeSave, and BeforeDelete, where conditions can be validated before the actions occur. The differences between Validation Rules and Triggers actually have to do with the actions taken within the setting. Validation Rules will contain Alert actions that inform the user of a failed condition. Triggers will often update the current record or other records with no user interaction. Validation Rules and Triggers can be combined in Pulsar, and all of the logic for a particular object type and execution point can be contained in a single setting. 

Usage

The Validation Rules and Triggers are defined using Pulsar Settings Language (PSL). The general format for such a setting is as follows:

Name:  Object Name – execution point
Key:     pulsar.<executionPoint>.<ObjectAPIName>
Value:  Pulsar Settings Language

One exception to this format is the OnCreate setting. See OnCreate Trigger section below for more information.


OnCreate Triggers

The OnCreate trigger executes whenever the related list plus button is tapped which is before other save triggers have a chance to run. When this setting is specified, the standard behavior to show the object in create mode is overridden with custom PSL code. This means that the PSL must ultimately handle how to respond to the plus button tap. For example, if the standard behavior is needed, the 'CreateAndMapFields' PSL action should be called as the last action in the custom PSL. 

There are two variants of OnCreate that can be used (Standard and PreInit), but only one should be specified per Parent/Child object association. If both happen to be specified, the PreInit variant will be executed and the Standard variant will be ignored. The difference between them is the context available to your PSL code. With the Standard variant, the context is the newly initialized object itself (in memory only). With the PreInit variant, the context is the parent of the object to create. You might decide to use PreInit if there are some actions or checks that must occur before the new child object can be initialized, perhaps to ensure certain values are passed to the create action.

Standard setting format:

Name:  Object Name – execution point
Key:     pulsar.onCreate.<Parent Object API Name>.<Child Object API Name>
Value:  Pulsar Settings Language

PreInit setting format:

Name:  Object Name – execution point

Key:     pulsar.onCreate.<Parent Object API Name>.<Child Object API Name>.PreInit
Value:  Pulsar Settings Language

Example Validation Rule

Name:   Order - Before Edit
Key:      pulsar.beforeEdit.Order__c
Value:   See the code below. This setting executes when the user tries to edit a record, and uses a query to determine if the user attempted to update a record that is already in status "Finalized" or "Cleared". If so, it alerts the user with the appropriate message.

DEFAULT{ 
Action=SetVar; 
VarName=Order_Id; 
VarValue=Id; 
| 
Action=SqlQuery; 
QueryString=SELECT Id FROM Order__c WHERE Id = '%%Order_Id%%' AND Status__c IN ('Cleared','Finalized'); 
QueryReturnFields=@@QueryCount; 
QueryTest=%%QueryCount%%=0; 
QueryTestTrue=SUCCESS; 
| 
Action=Alert; 
Message=Update is not allowed on Orders with status finalized, or cleared.; 
} 
SUCCESS 
{ 
}

Example Trigger

Name: On Save – Order Line Item

Key: pulsar.onSave.Order_Line_Item__c
Value:   See the code below. The following example  runs the code to update the total amount (Sub_Total__c) on the Order object when a line item is updated. This update is committed to the database when this setting executes, and this change will be pushed to the server upon the next sync. Note that this Trigger setting does not include any failure states (Alert actions).

DEFAULT{
Action=SetVar;
VarName=Order_Id;
VarValue=Order__c;
|
Action=SqlQuery;
QueryString=Select SUM ( CAST( Amount__c AS REAL ) ) AS SUM_ORDER_AMOUNT FROM Order_Line_Item__c WHERE Order__c = ‘%%Order_Id%%’;
QueryReturnFields=SUM_ORDER_AMOUNT;
|
Action=SqlQuery;
QueryString=Update Order__c SET Sub_Total__c = ‘%%SUM_ORDER_AMOUNT%%’ WHERE Id = ‘%%Order_Id%%’;
}

Special File Meta Object Usage for beforeSave and onSave

There is a special "FILE" meta object concept available as of Pulsar 9.0. It encapsulates and makes available data on all 3 content objects (ContentDocument, ContentVersion, and ContentDocumentLink),  within a single PSL beforeSave Validation Rule or PSL onSave Trigger, when saving files or attachments on other objects. For example, you could define a pulsar.beforeSave.File validation rule to restrict file types being added to Account Related Files.

The Full list of data available in pulsar.beforeSave.File or pulsar.onSave.File PSL follows:

ContentDocumentContentVersionContentDocumentLink

ContentDocument_Id

ContentVersion_IdContentDocumentLink_ContentDocumentIdorContentDocumentId
ContentDocument_FileExtensionContentVersion_ContentDocumentIdContentDocumentLink_LinkedEntityIdorLinkedEntityId
ContentDocument_FileMimeTypeContentVersion_FileExtensionContentDocumentLink_SystemModstamporSystemModstamp
ContentDocument_ContentSizeContentVersion_FileMimeTypeContentDocumentLink_ShareTypeorShareType
ContentDocument_ContentSizeMBContentVersion_ContentSizeContentDocumentLink_VisibilityorVisibility
ContentDocument_Base64ContentSizeContentVersion_ContentSizeMB


ContentDocument_Base64ContentSizeMBContentVersion_Base64ContentSize


ContentDocument_TitleContentVersion_Base64ContentSizeMB


ContentDocument_DescriptionContentVersion_Title



ContentVersion_Description



ContentVersion_Origin



ContentVersion_PathOnClient


Example of data available in PSL:

DatumExample ValueNotes
ContentDocument_Id0695e000007oQsJAAUwill be empty in beforeSave
ContentDocument_FileExtensionmp4
ContentDocument_FileMimeTypevideo/mp4
ContentDocument_ContentSize12207543
ContentDocument_ContentSizeMB11.64
ContentDocument_Base64ContentSize16236032
ContentDocument_Base64ContentSizeMB15.48
ContentDocument_Titleexample.mp4
ContentDocument_DescriptionExample MP4 Video
ContentVersion_Id0685e000007xDBQAA2will be empty in beforeSave
ContentVersion_ContentDocumentId0695e000007oQsJAAUwill be empty in beforeSave
ContentVersion_FileExtensionmp4
ContentVersion_FileMimeTypevideo/mp4
ContentVersion_ContentSize12207543
ContentVersion_ContentSizeMB11.64
ContentVersion_Base64ContentSize16236032
ContentVersion_Base64ContentSizeMB15.48
ContentVersion_Titleexample.mp4
ContentVersion_DescriptionExample MP4 Video
ContentVersion_OriginC
ContentVersion_PathOnClientexample.mp4
ContentDocumentLink_ContentDocumentId0695e000007oQsJAAUwill be empty in beforeSave
ContentDocumentLink_LinkedEntityId0016A00000oCv1dQAC
ContentDocumentLink_SystemModstamp2022-05-18T16:27:20.149+0000
ContentDocumentLink_ShareTypeV
ContentDocumentLink_VisibilityAllUsers

Example pulsar.beforeSave.File

The pulsar.beforeSave.File validation rule can be used with custom logic to prevent an end user from saving files. The example below restricts by file extension as well as size of the file.

DEFAULT {
Action=SetVar;
VarName=MaxFileSizeBytes;
VarValue=1000000;
|
Action=SetVar;
VarName=FileSizeBase64;
VarValue=ContentVersion_Base64ContentSize;
|
Action=SetVar;
VarName=Extension;
VarValue=ContentVersion_FileExtension;
|
Action=Log;
Message=FileSizeBase64 [%%FileSizeBase64%%] Extension [%%Extension%%];
|
Action=__CHECKFEXT;
|
Action=__CHECKSIZE;
}
CHECKSIZE {
Action=SqlQuery;
QueryString=SELECT %%FileSizeBase64%% AS TheValue;
QueryReturnFields=TheValue;
QueryTest=%%TheValue%% > %%MaxFileSizeBytes%%;
QueryTestTrue=CANTUPLOAD;
}
CHECKFEXT {
Action=SqlQuery;
QueryString=Select (CASE WHEN UPPER('%%Extension%%') IN ('ZIP','TXT','EXE','PY','PHP','ASP','ASPX','JAR','BAT','BIN','MSI','REG','VB','VBS','WS','SCR','PL','JSP') THEN 1 ELSE 0 END) as ValidateFileTypeCheck;
QueryReturnFields=ValidateFileTypeCheck;
QueryTest=%%ValidateFileTypeCheck%%=1;
QueryTestTrue=BAD_FILE_EXTENSION;
}
BAD_FILE_EXTENSION{
Action=SetResult;
Result=Invalid File Type;
ResultValid=false;
}
CANTUPLOAD{
Action=SetResult;
Result=Max file size is 1 mb.;
ResultValid=false;
}

Example pulsar.onSave.File

The pulsar.onSave.File trigger can be used to perform custom logic after a file has been saved. The below example outputs some basic information to the log upon saving an Attachment or File on an object such as an Account or Contact object.

DEFAULT{
Action=SetVar;
VarName=ParentObjectId;
VarValue=LinkedEntityId;
|
Action=SetVar;
VarName=Extension;
VarValue=ContentVersion_FileExtension;
|
Action=SetVar;
VarName=ContentSizeMB;
VarValue=ContentVersion_ContentSizeMB;
|
Action=SetVar;
VarName=Base64ContentSizeMB;
VarValue=ContentVersion_Base64ContentSizeMB;
|
Action=SetVar;
VarName=ContentTitle;
VarValue=ContentVersion_Title;
|
Action=SetVar;
VarName=ContentDescription;
VarValue=ContentVersion_Description;
|
Action=Log;
Message="EXAMPLE: ParentObjectId: %%ParentObjectId%%, FileExt (%%Extension%%), SizeMB (%%ContentSizeMB%% , %%Base64ContentSizeMB%%), Title (%%ContentTitle%%), Description (%%ContentDescription%%)";
|
Action=GetObjectType;
ObjectId=%%ParentObjectId%%;
VarName=ParentObjectType;
|
Action=Log;
Message="EXAMPLE: ParentObjectType: %%ParentObjectType%%";
}

Field Triggers

Currently we only support the 'After Update' trigger type for reference fields only.  The trigger code can be any valid PSL and is executed only after a specified reference field has been updated.

After Update Field Trigger Setting (without record type)

Name:  Field AfterUpdate Trigger (<object name> : <field name>)
Key:     pulsar.<Object API Name>.<Field API Name>.afterUpdate
Value:  Pulsar Settings Language

After Update Field Trigger Setting (with record type)

Name:  Field AfterUpdate Trigger (<object name> : <record type> : <field name>)
Key:     pulsar.<Object API Name>.<Record Type Developer Name>.<Field API Name>.afterUpdate
Value:  Pulsar Settings Language

Example After Update Field Trigger

Name: Field AfterUpdate Trigger (Opportunity : AccountId)
Key: pulsar.Opportunity.AccountId.afterUpdate
Value:   See the code below. The following example runs the code to update the NextStep field to 'Create Quote' every time the Account lookup field on the Opportunity object is updated.

DEFAULT{
Action=SetFieldInMemory;
FieldType=General;
FieldName=NextStep;
FieldValue=Create Quote;
}

Sync Triggers

Pulsar currently supports running custom Pulsar Settings Language upon completion of a successful sync. This can be useful for recording the sync time, counting records, or alerting the user to new information. NOTE:  This trigger is tied to sync, and any data changes during this setting execution will be pushed to the Salesforce server, even if the user is forced offline permanently via settings.

Starting in Pulsar 6.0, this trigger will NOT process the following PSL Actions:

  • Create
  • CreateAndMapFields
  • Delete
  • Update queries in SqlQuery Actions

Instead, use the following PSL actions, both new in 6.0:

NOTE: These PSL actions push changes direct to Salesforce and will NOT update the local Pulsar database. Any creates and updates using these actions will need to be synced to Pulsar at a later time.


Here is a trivial example that displays the sync date/time upon a successful sync:

Name:  After Sync Trigger 
Key:     pulsar.sync.AfterSyncTrigger
ValuePulsar Settings Language

DEFAULT{
Action=SetVar;
VarName=LastSync;
VarValue=@@LastSyncTime;
|
Action=Alert;
Message=Last successful sync time: %%LastSync%%;
}

Here is a bit more complicated example that displays the sync date/time upon a successful sync:

DEFAULT{
Action=SetVar;
VarName=LastSync;
VarValue=@@LastSyncTime;
|
Action=SetVar;
VarName=CurrentUserId;
VarValue=@@CurrentUserId;
|
Action=SetVar;
VarName=AppVersion;
VarValue=@@AppVersion;
|
Action=SetVar;
VarName=LastSyncSuccess;
VarValue=@@LastSyncSuccess;
|
Action=SqlQuery;
QueryString=SELECT CASE WHEN '%%LastSyncSuccess%%' = 'TRUE' THEN 1 ELSE 0 END AS SyncSuccess;
QueryReturnFields=SyncSuccess;
QueryTest=%%SyncSuccess%%=1;
QueryTestTrue=UpdateUser;
QueryTestFalse=NoAction;
}

UpdateUser{
Action=SFUpdate;
ObjectType=User;
Id=%%CurrentUserId%%;
LastSuccessfulPulsarSync__c=%%LastSync%%;
}

NoAction{
}
  • No labels