How EasyPlugins works
EasyPlugins allows Dynamics CRM administrators to set Plugins and Scheduled tasks in a graphical editor.
It is accessible on EasyPlugins Solution => Configuration Page
When a plugin trigger is set, a matching plugin step is automatically created.
EasyPlugins accepts expressions based on
JavaScript language.
Moment.js library is included in JavaScript engine
Example (from Sample 5)
(#p1 ? #p1 : "") + " " + moment(new Date()).format("DD/MM/YYYY HH:mm") + " Created by : " + #p2.Name.toUpperCase()
Main Interface
This interface shows all created plugins and scheduled events.
Trigger Interface
Entity
This combo box defines the entity that will trigger this Plugin.
Event definition
This section defines the events and the mode of the trigger.- PreCreate : The Plugin will fire before creation
- PostCreate : The Plugin will fire after creation
- PreUpdate : The Plugin will fire before update
- PostUpdate : The Plugin will fire after update
- PreDelete : The Plugin will fire before deletion
- PostDelete : The Plugin will fire after deletion
- Synchronous : The Plugin will fire synchronously
- Asynchronous : The Plugin will fire asynchronously
Parameters Section (left)
This section defines the parameters that will be used during calculation.
EasyPlugins defines 4 types of parameters :
- Attribute : Attribute value of the current entity defined
- Request : FetchXml request
- Calculated : Parameter based on an expression (JavaScript)
- Javascript functions : Parameter based on an JavaScript functions
Actions section (right)
This section defines the actions that will be performed during the execution.
EasyPlugins defines 8 types of actions :
-
Override : The Plugin will override the current record attribute
(available for PreCreate and PreUpdate events only) - Create : The Plugin will create a record
- Update : The Plugin will update a record
- Delete : The Plugin will delete a record
- Associate : The Plugin will associate 2 records
- Disassociate : The Plugin will disassociate 2 records
- SetState : The Plugin will change the state of a record
- Abort Message : The Plugin will abort the current action by generating an error
- CRM Action : The Plugin will execute a CRM Action
Scheduled Trigger Interface
Top section
This section defines the schedule event and the Start Date.- Is Periodic : The trigger will fire periodically.
- Period : The trigger period (Minimum 2 hours)
- Perio Unit : The trigger period unit
- Start Date : The date and time from which the trigger will fire
Parameters section (left)
This section defines the parameters that will be used during calculation.
EasyPlugins defines 2 types of parameters :
- Request : FetchXml request
- Calculated : Parameter based on an expression (JavaScript)
Actions section (right)
This section defines the actions that will be performed during the execution
EasyPlugins defines 6 types of actions :
- Create : The Plugin will create a record
- Update : The Plugin will update a record
- Delete : The Plugin will delete a record
- Associate : The Plugin will associate 2 records
- Disassociate : The Plugin will disassociate 2 records
- SetState : The Plugin will change the state of a record
- CRM Action : The Plugin will execute a CRM Action
Parameters
This section defines the parameters that will be used during calculation.EasyPlugins defines 4 types of parameters :
- Attribute : Attribute value of the current entity defined
- Request : FetchXml request
- Calculated : Parameter based on an expression (JavaScript)
- JavaScript functions : Parameter based on an JavaScript functions
Attribute Parameter
Use this parameter to retrieve an attribute value of current record that fired the Plugin.
- Display Logical Names defines the way the attributes are displayed : Logical Names / Display Names
- Attribute State defines if the attribute value used as parameter is before or after the user action
Request Parameter
Fetch Xml
Paste you FetchXml request here, then select an aggregate function.
EasyPlugins defines 7 types of aggregations :
- Count : The result will return the count of records found
- First : The result will return an array of the first record found
- Last : The result will return an array of the last record found
- ForEach : The result will return an array of arrays. It will loop actions for each record found
- Sum : The result will return the sum of the retrieved numeric value (aggregation available only with unique attribute in the FetchXml)
- Average : The result will return the average of the retrieved numeric value (aggregation available only with unique attribute in the FetchXml)
- Concat : The result will return the concatenation of the string value (aggregation available only with unique attribute in the FetchXml)
Available parameters
This tab defines the available parameters to use in the current request.Calculated Parameter
Expression
Create your expression (JavaScript) using available parameters then click on "Test Expression" to validate it.
The result of the expression must match the type of return expected to be able to save
JavaScript functions
JavaScript
Create your own functions (JavaScript) using available parameters (or functions).
These functions can be used in other expressions (parameters or actions expressions)
Available parameters
This tab defines the available parameters to use in the current request.Read only parameters
A parameter is read only when it's used on at least 1 action or 1 other parameter Click on to see the dependencies list of the current parameter
Actions
This section defines the actions that will be performed during the executionEasyPlugins defines 8 types of actions :
- Override : The Plugin will override the current record attribute (available for PreCreate and PreUpdate events only)
- Create : The Plugin will create a record
- Update : The Plugin will update a record
- Delete : The Plugin will delete a record
- Associate : The Plugin will associate 2 records
- Disassociate : The Plugin will disassociate 2 records
- SetState : The Plugin will change the state of a record
- Abort Message : The Plugin will abort the current action by generating an error
- CRM Action : The Plugin will execute CRM Action
Override Action
This action is only available for PreCreate and PreUpdate events.
- Entity : Current Entity
- Condition : Condition Expression of firing plugin (boolean)
- Attributes : Expression of each overriden attribute
Create Action
- Entity : Selected entity that will be created when the Plugin is fired
- Condition : Condition Expression of firing plugin (boolean)
- Attributes : Expression of each attribute of selected entity
- Max Depth : Maximum depth this action will be fired
- As Admin : If checked, the record will be created by System, otherwise the record will be created by the current user
Since version 2.0.0.2
Create Action automatically adds a return parameter (type : Guid)
If the creation concerns multiple lines, the corresponding parameter will have "Foreach" as aggregation function (like a request)
Update Action
- Entity : Selected entity that will be updated when the Plugin is fired
- Condition : Condition Expression of firing plugin (boolean)
- Attributes : Expression of each attribute of selected entity
- Max Depth : Maximum depth this action will be fired
- As Admin : If checked, the record will be updated by System, otherwise the record will be updated by the current user
Delete Action
- Entity : Selected entity that will be deleted when the Plugin is fired
- Condition : Condition Expression of firing plugin (boolean)
- Where Id : Expression of Id of entity to delete
- Max Depth : Maximum depth this action will be fired
- As Admin : If checked, the record will be deleted by System, otherwise the record will be deleted by the current user
Associate Action
- Entity : Selected entity that will be associated when the Plugin is fired
- Relationship : Available N:N relationships on selected entity
- Condition : Condition Expression of firing plugin (boolean)
- Selected Entity Id : Expression of Id of entity to associate
- Entity Id : Expression of Id of entity to associate
- Max Depth : Maximum depth this action will be fired
- As Admin : If checked, the record will be associated by System, otherwise the record will be associated by the current user
Disassociate Action
- Entity : Selected entity that will be disassociated when the Plugin is fired
- Relationship : Available N:N relationships on selected entity
- Condition : Condition Expression of firing plugin (boolean)
- Selected Entity Id : Expression of Id of entity to disassociate
- Entity Id : Expression of Id of entity to disassociate
- Max Depth : Maximum depth this action will be fired
- As Admin : If checked, the record will be disassociated by System, otherwise the record will be disassociated by the current user
SetState Action
- Entity : Selected entity that will be updated when the Plugin is fired
- Condition : Condition Expression of firing plugin (boolean)
- Where Id : Expression of Id of entity to update
- State : Expression of State value of entity
- Status : Expression of Status value of entity
- Max Depth : Maximum depth this action will be fired
- As Admin : If checked, the record will be updated by System, otherwise the record will be updated by the current user
Abort Message Action
- Condition : Condition Expression of firing plugin (boolean)
- Message : Expression to show as an error message when the Plugin is fired
CRM Action
Since version 2.0.0.2
CRM Action executes CRM Actions and adds a return parameter (if output defined) (type : Array) depending on defined output parameters
- Entity : Entity associated action, "none" if global
- Action : CRM Action to execute
- Attributes with Expression editor enabled: Action input parameters
- Attributes without Expression editor: Action output parameters
Expression Editor
Expression editor is always available when clicking on
- Return type is the type of the expression result
- Target type :is the expected type result. Result type must match to target type
- Available parameters are all the parameters that can be used on the expression
Main Page tools
Export
Export Button allows to export all EasyPlugins Configurations into to Json. Just use the filter to export only the triggers needed. The Json is automatically updated.
Import
Import Button allows to import EasyPlugins Configurations from Json. Just use the filter to take only the triggers needed.
Samples
Sample 1 : Create an associated Contact on Account creation
Step 1
Create a new trigger and set entity to account on post create event Synchronous
Step 2
Create a new "attribute parameter" and choose "name" attribute (after action)
Step 3
Add a "create action" on contact and set
- Lastname Equals #p1
- Firstname Equals " Contact Associated"
- Parentcustomerid Equals #Id
Step 4
Save the plugin
Import this configuration
[
{
"ake_synchronous":true,
"ake_order":1,
"ake_entity":"account",
"ake_postcreate":true,
"ake_active":true,
"ake_actions":"[{\"asadmin\":false,\"resume\":\"Create of contact (Single record)\",\"resumeDefault\":\"Create of contact (Single record)\",\"entity\":\"contact\",\"attributes\":[{\"id\":\"a67701f5-ebd0-4412-8b70-c61a99595647\",\"logicalname\":\"firstname\",\"attributetype\":\"String\",\"name\":\"Prénom\",\"validforcreate\":true,\"validforupdate\":true,\"type\":1,\"expression\":\"\\\"contact associated\\\"\",\"$$hashKey\":\"3QN\"},{\"id\":\"2f8fdd79-0372-490d-9053-b743becfca0d\",\"logicalname\":\"lastname\",\"attributetype\":\"String\",\"name\":\"Nom de famille\",\"validforcreate\":true,\"validforupdate\":true,\"type\":1,\"expression\":\"#p1\",\"$$hashKey\":\"3QX\"},{\"id\":\"c7a58b13-df19-491c-a918-1bc26eaf6eb3\",\"logicalname\":\"parentcustomerid\",\"attributetype\":\"Customer\",\"targets\":\"account;contact\",\"name\":\"Nom de la société\",\"validforcreate\":true,\"validforupdate\":true,\"type\":5,\"expression\":\"#Id\",\"$$hashKey\":\"3RA\"}],\"relations\":[],\"type\":0,\"depth\":1,\"condition\":\"true\",\"foreachparam\":0,\"order\":1,\"returnparam\":2}]",
"ake_precreate":false,
"ake_rules":"[{\"asadmin\":false,\"entity\":\"account\",\"attributestate\":1,\"type\":1,\"returntype\":1,\"locked\":true,\"logicalname\":\"name\",\"resumeDefault\":\"Attribute (name - After)\",\"resume\":\"Attribute (name - After)\",\"paramnumber\":1,\"code\":\"#p1\"},{\"asadmin\":false,\"resume\":\"Id(s) of Create of contact (Single record)\",\"paramnumber\":2,\"code\":\"#p2\",\"type\":6,\"returntype\":4,\"locked\":true,\"linefunction\":0}]",
"ake_preupdate":false,
"ake_predelete":false,
"ake_postdelete":false,
"ake_isperiodic":false,
"ake_triggertype":0,
"ake_name":"Sample 1",
"ake_postupdate":false,
"ake_periodunit":null,
"ake_processid":null,
"ake_period":null,
"ake_startdate":null,
"selected":true
}
]
Sample 2 : Deactivate all associated Contacts on Account deactivation
Step 1
Create a new trigger and set entity to account on PostUpdate event Synchronous
Step 2
Create a new "request parameter" and set fetchXml to
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="contact">
<attribute name="contactid" />
<attribute name="fullname" />
<filter type="and">
<condition attribute="parentcustomerid" operator="eq" uitype="account" value="{#Id}" />
</filter>
</entity>
</fetch>
This FetchXml retrieves contacts that parent account is the current account deleted then choose "ForEach" as aggregate function
Step 3
Create a new attribute parameter and choose "statecode" attribute (after action)
Step 4
Add a "setstate action" on contact and set
- Entity Equals "Contact"
-
Condition Equals
#p2.Value == 1
- Where ID Equals #p1[0] - contactid
- State Equals Inactive
- Status Equals Inactive
Step 5
Save the plugin
Import this configuration
[
{
"ake_synchronous":true,
"ake_order":4,
"ake_entity":"account",
"ake_postcreate":false,
"ake_active":true,
"ake_actions":"[{\"asadmin\":false,\"resume\":\"SetState of contact (Multiple records)\",\"resumeDefault\":\"SetState of contact (Multiple records)\",\"entity\":\"contact\",\"attributes\":[{\"logicalname\":\"statecode\",\"expression\":\"1\",\"type\":3,\"attributetype\":\"State\"},{\"logicalname\":\"statuscode\",\"expression\":\"2\",\"type\":3,\"attributetype\":\"Status\"}],\"type\":6,\"depth\":1,\"condition\":\"#p2.Value == 1\",\"foreachparam\":1,\"idexpression\":\"#p1[0]\",\"state\":\"1\",\"status\":\"2\",\"order\":1}]",
"ake_precreate":false,
"ake_rules":"[{\"asadmin\":false,\"type\":0,\"linefunction\":7,\"resumeDefault\":\"Request (contact)\",\"returntype\":8,\"locked\":true,\"fetchxml\":\"<fetch version=\\\"1.0\\\" output-format=\\\"xml-platform\\\" mapping=\\\"logical\\\" distinct=\\\"false\\\">\\n <entity name=\\\"contact\\\">\\n <attribute name=\\\"contactid\\\" />\\n <attribute name=\\\"fullname\\\" />\\n <filter type=\\\"and\\\">\\n <condition attribute=\\\"parentcustomerid\\\" operator=\\\"eq\\\" uitype=\\\"account\\\" value=\\\"{#Id}\\\" />\\n </filter>\\n </entity>\\n</fetch>\",\"attributereturntypes\":[4,1],\"attributereturnnames\":[\"contactid\",\"fullname\"],\"resume\":\"Request (contact)\",\"paramnumber\":1,\"code\":\"#p1\"},{\"asadmin\":false,\"entity\":\"account\",\"attributestate\":1,\"type\":1,\"returntype\":3,\"locked\":true,\"logicalname\":\"statecode\",\"resumeDefault\":\"Attribute (statecode - After)\",\"resume\":\"Attribute (statecode - After)\",\"paramnumber\":2,\"code\":\"#p2\"}]",
"ake_preupdate":false,
"ake_predelete":false,
"ake_postdelete":false,
"ake_isperiodic":false,
"ake_triggertype":0,
"ake_name":"Sample 2",
"ake_postupdate":true,
"ake_periodunit":null,
"ake_processid":null,
"ake_period":null,
"ake_startdate":null,
"selected":true
}
]
Sample 3 : Prevent update of particular Account
Step 1
Create a new trigger and set entity to account on PreUpdate event Synchronous
Step 2
Create a new "attribute parameter" and choose "name" attribute (before action)
Step 3
Add a "abort message action" and set
-
Condition
#p1 == "Microsoft"
-
Message
"You can not update or delete "+ #p1 +" account\nPlease contact your administrator\n"
Step 4
Save the plugin
Import this configuration
[
{
"ake_synchronous":true,
"ake_period":null,
"ake_order":5,
"ake_postcreate":false,
"ake_active":true,
"ake_actions":"[{\"asadmin\":false,\"resume\":\"Abort\",\"resumeDefault\":\"Abort\",\"entity\":\"\",\"attributes\":[],\"relations\":[],\"type\":5,\"depth\":1,\"condition\":\"#p1 == \\\"Microsoft\\\"\",\"message\":\"\\\"You can not update or delete \\\"+ #p1 +\\\" account\\\\nPlease contact your administrator\\\\n\\\"\",\"foreachparam\":0,\"order\":1}]",
"ake_startdate":null,
"ake_precreate":false,
"ake_rules":"[{\"asadmin\":false,\"entity\":\"account\",\"attributestate\":0,\"type\":1,\"returntype\":1,\"locked\":true,\"logicalname\":\"name\",\"resumeDefault\":\"Attribute (name - Before)\",\"resume\":\"Attribute (name - Before)\",\"paramnumber\":1,\"code\":\"#p1\"}]",
"ake_preupdate":true,
"ake_predelete":false,
"ake_postdelete":false,
"ake_isperiodic":false,
"ake_name":"Sample 3",
"ake_postupdate":false,
"ake_triggertype":0,
"ake_periodunit":null,
"ake_processid":null,
"ake_entity":"account",
"selected":true
}
]
Sample 4 : Periodic deletion of old lost opportunities
Step 1
Create a new scheduled trigger and set Period to 1 month starting from tomorrow
Step 2
Create a new "request parameter" and set fetchXml to
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="opportunity">
<attribute name="opportunityid" />
<attribute name="name" />
<filter type="and">
<condition attribute="statecode" operator="eq" value="2" />
<condition attribute="modifiedon" operator="olderthan-x-months" value="12" />
</filter>
</entity>
</fetch>
This FetchXml retrieves all lost opportunities older than 12 months
Choose "ForEach" as aggregate function
Step 3
Add a "delete action" on opportunities and set
- Entity Equals "Opportunity"
- Condition Equals true
- Where ID Equals #p1[0] - opportunityid
Step 4
Save the plugin
Import this configuration
[
{
"ake_synchronous":false,
"ake_period":1,
"ake_order":6,
"ake_postcreate":false,
"ake_active":true,
"ake_actions":"[{\"asadmin\":false,\"resume\":\"Delete opportunity (Multiple records)\",\"resumeDefault\":\"Delete opportunity (Multiple records)\",\"entity\":\"opportunity\",\"attributes\":[],\"relations\":[],\"type\":2,\"depth\":1,\"condition\":\"true\",\"foreachparam\":1,\"idexpression\":\"#p1[0]\",\"order\":1}]",
"ake_startdate":"2018-04-10T22:00:00.000Z",
"ake_precreate":false,
"ake_rules":"[{\"asadmin\":false,\"type\":0,\"linefunction\":7,\"resumeDefault\":\"Request (opportunity)\",\"returntype\":8,\"locked\":true,\"attributereturntypes\":[4,1],\"attributereturnnames\":[\"opportunityid\",\"name\"],\"fetchxml\":\"<fetch version=\\\"1.0\\\" output-format=\\\"xml-platform\\\" mapping=\\\"logical\\\" distinct=\\\"false\\\">\\n <entity name=\\\"opportunity\\\">\\n <attribute name=\\\"opportunityid\\\" />\\n <attribute name=\\\"name\\\" />\\n <filter type=\\\"and\\\">\\n <condition attribute=\\\"statecode\\\" operator=\\\"eq\\\" value=\\\"2\\\" />\\n <condition attribute=\\\"modifiedon\\\" operator=\\\"olderthan-x-months\\\" value=\\\"12\\\" />\\n </filter>\\n </entity>\\n</fetch>\",\"resume\":\"Request (opportunity)\",\"paramnumber\":1,\"code\":\"#p1\"}]",
"ake_preupdate":false,
"ake_predelete":false,
"ake_postdelete":false,
"ake_isperiodic":true,
"ake_name":"Sample 4",
"ake_postupdate":false,
"ake_triggertype":1,
"ake_periodunit":3,
"ake_processid":null,
"ake_entity":null,
"selected":true
}
]
Sample 5 : Add Date and Creator's name on note title
Step 1
Create a new trigger and set entity to account on PreCreate event Synchronous
Step 2
Create a new "attribute parameter" and choose "subject" attribute (after action)
Step 3
Create a new "attribute parameter" and choose "createdby" attribute (after action)
Step 4
Add an "override action" and set
- Condition Equals true
- Where ID Equals #Id
-
Subject Attribute Equals
(#p1 ? #p1 : "") + " " + moment(new Date()).format("DD/MM/YYYY HH:mm") + " Created by : " + #p2.Name
Step 5
Save the plugin
Import this configuration
[
{
"ake_synchronous":true,
"ake_order":5,
"ake_entity":"annotation",
"ake_postcreate":false,
"ake_active":true,
"ake_actions":"[{\"asadmin\":false,\"resume\":\"Override annotation (Single record)\",\"resumeDefault\":\"Override annotation (Single record)\",\"entity\":\"annotation\",\"attributes\":[{\"id\":\"06e8004c-87d8-4cdc-b306-73af76d7c6bd\",\"logicalname\":\"subject\",\"attributetype\":\"String\",\"name\":\"Titre\",\"validforcreate\":true,\"validforupdate\":true,\"type\":1,\"expression\":\"(#p1 ? #p1 : \\\"\\\") + \\\" \\\" + moment(new Date()).format('DD/MM/YYYY HH:mm') + \\\" Created by : \\\" + #p2.Name\",\"$$hashKey\":\"2TH\"}],\"relations\":[],\"type\":7,\"condition\":\"true\",\"depth\":1,\"foreachparam\":0,\"order\":1}]",
"ake_precreate":true,
"ake_rules":"[{\"asadmin\":false,\"entity\":\"annotation\",\"attributestate\":1,\"type\":1,\"returntype\":1,\"locked\":true,\"logicalname\":\"subject\",\"resumeDefault\":\"Attribute (subject - After)\",\"resume\":\"Attribute (subject - After)\",\"paramnumber\":1,\"code\":\"#p1\"},{\"asadmin\":false,\"entity\":\"annotation\",\"attributestate\":1,\"type\":1,\"returntype\":5,\"locked\":true,\"logicalname\":\"createdby\",\"resumeDefault\":\"Attribute (createdby - After)\",\"resume\":\"Attribute (createdby - After)\",\"paramnumber\":2,\"code\":\"#p2\"}]",
"ake_preupdate":false,
"ake_predelete":false,
"ake_postdelete":false,
"ake_isperiodic":false,
"ake_triggertype":0,
"ake_name":"Sample 5 (Imported)",
"ake_postupdate":false,
"ake_periodunit":null,
"ake_processid":null,
"ake_period":null,
"ake_startdate":null,
"selected":true
}
]
Sample 6 : Turn account's name into capital letters on creation
Step 1
Create a new trigger and set entity to account on PreCreate event Synchronous
Step 2
Create a new "attribute parameter" and choose "name" attribute (after action)
Step 3
Create a new "Javascript parameter" and paste this code
function ToUpper(str){
if(str) return str.toUpperCase();
return "";
}
Step 4
Add an "override action" and set
- Condition Equals true
- Where ID Equals #Id
-
Name Attribute Equals
ToUpper(#p1)
Step 5
Save the plugin
Import this configuration
[
{
"ake_name":"Sample 6",
"ake_active":true,
"ake_synchronous":true,
"ake_entity":"account",
"ake_precreate":true,
"ake_postcreate":false,
"ake_preupdate":false,
"ake_postupdate":false,
"ake_predelete":false,
"ake_postdelete":false,
"ake_actions":"[{\"asadmin\":false,\"resume\":\"Override account (Single record)\",\"resumeDefault\":\"Override account (Single record)\",\"entity\":\"account\",\"attributes\":[{\"id\":\"a1965545-44bc-4b7b-b1ae-93074d0e3f2a\",\"logicalname\":\"name\",\"attributetype\":\"String\",\"name\":\"Nom du compte\",\"validforcreate\":true,\"validforupdate\":true,\"type\":1,\"expression\":\"ToUpper(#p1)\",\"$$hashKey\":\"29J\"}],\"relations\":[],\"type\":7,\"condition\":\"true\",\"depth\":1,\"foreachparam\":0,\"order\":1}]",
"ake_rules":"[{\"asadmin\":false,\"entity\":\"account\",\"attributestate\":1,\"type\":1,\"returntype\":1,\"locked\":true,\"logicalname\":\"name\",\"resumeDefault\":\"Attribute (name - After)\",\"resume\":\"Attribute (name - After)\",\"paramnumber\":1,\"code\":\"#p1\"},{\"asadmin\":false,\"type\":5,\"resumeDefault\":\"Javascript function\",\"expression\":\"function ToUpper(str){\\n\\tif(str) return str.toUpperCase();\\n \\treturn \\\"\\\";\\n}\",\"returntype\":0,\"locked\":true,\"param\":{},\"resume\":\"Javascript function\",\"paramnumber\":2,\"code\":\"#p2\",\"functionslist\":[\"ToUpper\"]}]",
"ake_isperiodic":false,
"ake_triggertype":0,
"ake_periodunit":null,
"ake_processid":null,
"ake_period":null,
"ake_startdate":null,
"selected":true
}
]
Solution Downloads
Dynamics CRM 2016 & 365
EasyPlugins Solution 2.0.0.2 for Dynamics CRM versions : 8.0, 8.1, 8.2, 9.0