Scenario 1

The teacher of a class wishes to capture some key information for any student registering in the management system. The school management has several school buses in its roaster. Each roaster pertains to a region. Based on the post code and city of the student's home, they are classified into various regions. The school maintains that list of master data in Dynamics CRM. They wish that the system automatically updates the region of the student when the post code and city details are entered in the student's record.

The first step would be maintaining a master data for region, post code, and city.
Given the concepts of data normalization and ease of data entry, we will consider the following entities in the Dynamics CRM system. The list of attributes against the entity are also described in the table:

  1. Region:

Attribute

Data Type

Region Name

Single line of text

  1. Bus region roaster:

Attribute

Data Type

Region

Lookup to Region

Post Code

Single line of text

City

Single line of text

 

Here is a screenshot of region:

Here is a screenshot of the list of regions:

Here is a screenshot of the bus region roaster:

Here is a screenshot of the bus regions:

On the student main form, as mentioned in the following screenshot, there are fields of home city and post code. Along with that, we also have a read-only field of Region:

The next step would be to design the logic of the custom plugin that should fill the region field in the student form:

  1. The first step for the same is firstly identifying the entity and messages on which the plugin would trigger:
    • As the entity for which we are going to enter information is Contact, we can safely assume that the primary entity for the plugin would be contact.
    • There could be two possible scenarios in which we will need to populate the Region field. The first would be on the Create field of student. When the student record is being created in Dynamics CRM, the plugin logic should read the values of city and post code and populate the Region lookup. Another scenario for the same would be when users are updating the student record. However, we will only need to recalculate the region lookup when the user is updating the Post Code or City field. In all other cases, there won't be any need to trigger the repopulation logic.
  2. Now, since we have identified the message and the primary entity on which we need to write the plugin, the next step would be to write the plugin.
    As a starting step, we can create the plugin project in the same way as we described earlier. After the plugin project is created, we will add a new class to the project, and as described previously, we will implement the IPlugin interface. The following are the steps that we will need to follow for creating the plugin class:
    1. Firstly, we will just add a new class item, PreCreateUpdateStudent, in the same visual studio project that we created earlier. As a reference, we will use the late binding code terminology as C# as the base development language. The following is the complete code of the plugin class:
      using System; 
      using System.Collections.Generic; 
      using System.Linq; 
      using System.Text; 
      using Microsoft.Xrm.Sdk; 
      using Microsoft.Crm.Sdk.Messages; 
      using Microsoft.Xrm.Sdk.Query; 
 
      namespace SamplePluginProject 
      { 
        public class PreCreateUpdateStudent : IPlugin 
        { 
          public void Execute(IServiceProvider serviceProvider) 
          { 
            // Plugin Context object 
            Microsoft.Xrm.Sdk.IPluginExecutionContext context = 
(Microsoft.Xrm.Sdk.IPluginExecutionContext) serviceProvider.GetService(typeof(
Microsoft.Xrm.Sdk.IPluginExecutionContext)); // Retrieving Organisation service context object IOrganizationServiceFactory serviceFactory =
(IOrganizationServiceFactory)serviceProvider.GetService(
typeof(IOrganizationServiceFactory)); IOrganizationService service =
serviceFactory.CreateOrganizationService(context.UserId); // Exception handling to make sure that
// plugin target object is an entity if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity) { Entity entity =
(Entity)context.InputParameters["Target"]; // Checking if the logical name of target
// entity is contact if (entity.LogicalName == "contact") { // Name of plugin trigger message as create or update if (context.MessageName.ToLower() == "create" ||
context.MessageName.ToLower() == "update") { string city; string postCode; // Exception handling to make sure code
// is only triggered if city and post
// code are present. if (entity.Contains("address1_city") &&
entity.Contains("address1_postofficebox")) { // Reading city and post office code value city =
entity.Attributes["address1_city"].ToString(); postCode =
entity.Attributes[
"address1_postofficebox"].ToString(); EntityReference region =
this.RetrieveRegionID(city, postCode, service); // Adding region attribute to the entity if (region != null) { if (entity.Contains("new_regionid")) { entity["new_regionid"] = region; } else { entity.Attributes.Add("new_regionid", region); } } } } } } } // As the function is only accessed from inside
// the plugin class so the access modifier is Private private EntityReference RetrieveRegionID(
string city, string postOfficeBox,
IOrganizationService service) { // Query expression to retrieve Region based
// upon city and post code EntityReference region = new EntityReference(); ColumnSet columns = new ColumnSet("new_regionid"); QueryExpression regionQuery = new QueryExpression(); regionQuery.EntityName = "new_busregionroaster"; FilterExpression filterExpression = new FilterExpression(); filterExpression.FilterOperator = LogicalOperator.And; ConditionExpression cityCondition =
new ConditionExpression(); cityCondition.AttributeName = "new_city"; cityCondition.EntityName = "new_busregionroaster"; cityCondition.Operator = ConditionOperator.Equal; cityCondition.Values.Add(city); filterExpression.Conditions.Add(cityCondition); ConditionExpression postOfficeCondition =
new ConditionExpression(); postOfficeCondition.AttributeName = "new_name"; postOfficeCondition.EntityName = "new_busregionroaster"; postOfficeCondition.Operator = ConditionOperator.Equal; postOfficeCondition.Values.Add(postOfficeBox); filterExpression.Conditions.Add(postOfficeCondition); regionQuery.Criteria = filterExpression; regionQuery.ColumnSet = columns; EntityCollection regions =
service.RetrieveMultiple(regionQuery); if (regions != null) { if (regions.Entities.Count > 0) { if (regions.Entities[0].Contains("new_regionid")) { region = (EntityReference)regions.Entities[0]
["new_regionid"]; } } } return region; } } }
  1. The next step would be to build the project and make sure that it compiles without any compile-time errors:

Finally, we will need to register the assembly just as described in the earlier sections. We will need to register the plugin class with two steps: create the contact and update the contact with filtering attributes, Post Code and City.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset