Labels

Tuesday, August 7, 2018

Plugins In Dynamics CRM


Plugins:
A plugin is a custom business logic (code) that you can integrate with Dynamic CRM to modify or argument the standard behavior of the platform.

Plugin Event execution pipeline:
The Dynamics CRM 365 event processing subsystem executes plug-ins based on a message pipeline execution model.
A user action in the Microsoft Dynamics 365 Web application or an SDK method call by a plug-in or other application results in a message being sent to the organization Web service.
This message contains business entity information and core operation information. The message is passed through the event execution pipeline where it can be read or modified by the platform core operation and any registered plug-ins

Pipeline Stages
The event pipeline is divided into multiple stages, of which 4 are available to register custom developed or 3rd party plug-ins.
Multiple plug-ins that are registered in each stage can be further be ordered (ranked) within that stage during plug-in registration.

Event
Stage name
Stage number
Description
Pre-Event
Pre-validation
10
Stage in the pipeline for plug-ins that are to execute before the main system operation. Plug-ins registered in this stage may execute outside the database transaction.
Pre-Event
Pre-operation
20
Stage in the pipeline for plug-ins that are to execute before the main system operation. Plug-ins registered in this stage are executed within the database transaction.
Platform Core Operation
Main Operation
30
In-transaction main operation of the system, such as create, update, delete, and so on. No custom plug-ins can be registered in this stage. For internal use only.
Post-Event
Post-operation
40
Stage in the pipeline for plug-ins which are to execute after the main operation. Plug-ins registered in this stage are executed within the database transaction.

Developing a Sample Plugin:


Add a class library project into the C# solution and name your class "MyFirstPlugin". 



Add references to the 2 DLLs. 

  • Microsoft.Crm.Sdk.Proxy.dll
  • Microsoft.Xrm.Sdk.dll

You will find both of the DLLs in the SDK/bin folder of your latest SDK. 

Inherit the IPlugin interface. 




Implement the IPlugin Interface and you will get an Execute method with the IserviceProvider interface object as a parameter.

Execute method: 
This method runs as an entry point for any plugin in Microsoft Dynamic CRM.

IserviceProvider interface: 
This interface provides access to various services of dynamic, this interface has a method called GetService() that uses the reflection feature of .NET and allows us to get any type of service we want. 









Once you’ve implemented the ITracingService within your code, you can then write to Trace Log at any time in your code using the following snippet:
tracingService.Trace("Insert your text here...");


Since we need to trigger our plug-in when an event is executed, we need to get the service of IPluginExecutionContext using the IServiceProvider object.


And the GetService method returns an object of the specified type. We need to type caste that object. 

IOrganizationServiceFactory:
Return an IOrganizationService instance for the organization that the specified user is a member of.




Plugin execution is an object with a property called InputParameter. 
  • Using this Inputparamter we can get the entity and other types of dynamic CRM. 

  • Target is one of the main parameters of this IPluginExecutionContext object.

  • All the plug-in events are first stored in this variable called “Target”.

  • When any events occur we need to check if this variable is there in our current context execution.

  • And if so then we need to check if it's an entity.


Step 3
Now when you know, we have a value in the target and it's an Entity.

Then typecast it into an Entity and using its logicalname property we can determine if the current executing event is for an entity or not.

Below is the Sample Plugin Code for Auto Increment Number.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;

namespace Appeal_Update
{
   public class TicketNumber : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
             ITracingService tracingService =
               (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            // Obtain the execution context from the service provider.
            IPluginExecutionContext context = (IPluginExecutionContext)
                serviceProvider.GetService(typeof(IPluginExecutionContext));
            // Obtain the organization service reference.
            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);



            // The InputParameters collection contains all the data passed in the message request.
            if (context.InputParameters.Contains("Target") &&
                context.InputParameters["Target"] is Entity)
            {
                // Obtain the target entity from the input parameters.
                Entity entity = (Entity)context.InputParameters["Target"];

                // Verify that the target entity represents an account.
                // If not, this plug-in was not registered correctly.
                if (entity.LogicalName != "new_ticket")
                    return;
                try
                {

                    int i = 0;

                    QueryExpression query = new QueryExpression("new_ticket");

                    query.ColumnSet.AddColumns("new_ticketnumber");

                    EntityCollection listentities = service.RetrieveMultiple(query);

                    if (listentities.Entities.Count > 0)
                    {

                        foreach (var item in listentities.Entities)
                        {

                            i = (int)item.Attributes["new_ticketnumber"];

                        }

                        entity.Attributes["new_ticketnumber"] = i + 1;

                    }

                    else
                    {

                        entity.Attributes.Add("new_ticketnumber", 1);

                    }

                }
                catch (Exception ex)
                {
                    tracingService.Trace("TicketeNumber: {0}", ex.ToString());
                    throw;
                }
            }
        }
    }
}

Build your Project. 

Once you build your project, you need to generate a key that will act as certificate for your plug-in. Without this key you cannot deploy a plug-in onto a server. 

To create a key, go to project property (ALT+ Enter) and go to the signing tab and check sign the assembly. 

Select new in the drop down and add a key name and your dynamic CRM Password. And select save (CTRL+ S).

If you have done this then it will add a pfx encrypted key for your current project. 

Rebuild your project 
 


Procedure to deploy this assembly using SDk\Tools\PluginRegistration\PluginRegistration.exe.

Step 1 
  • Run it and Click Create New connection,
  • Enter your Login Credentials for Connection with Dynamic CRM.
  • The first time you login, you need to pass all the details of your CRM Account.

Step 2

After logging in successfully, click Register > Register New Assembly.

Browse to the DLL you just created and click OK. 
 


Step 3
  • Now we need to add steps of this DLL execution.
  • So select the assembly and again click Register > Register new Steps.
  • Or just right-click the assembly you just added and select Register new Steps.




This Window includes an option for how and when you want to execute or fire your assembly or plug-in. 

Message: It defines on which event you want to run the plug-in.

Example: Create.

Primary Entity: It define on which Entity execution you want to run the plug-in.

Example: Ticket.


Event pipeline stage of Execution: It defines when you want to run the DLL, before the core operations or after the core operations.

Execution Mode:
 Execution can be synchronous by default or can be asynchronous (that will be handled further by the Dynamic CRM Queue manager).

Deployment: Server where every plug-in is deployed.


Click Register New Step and it's done.

Your assembly or plug-in is deployed on the server.
Now go to Dynamic CRM and create an Ticket and save it .Then an incremented number will be updated in the field.

Saturday, January 6, 2018

JavaScript - Lock all fields on the form

As we all frequently use to get requirements to lock the whole form to stop the end user from editing the record.
There are some out of the box options available to achieve this but these out of box options will not fulfill the actual requirement completely:
  1. Create a business rule : you can easily create a business and use lock field feature however you will have to select all the field on the form one by one   for .e.g. if you have 50 fields on the form, you will have to add action for all of them.                                                                                             Moreover another limitation is if a field is removed from the form – your business rule will stop working.
  2. We all know if record status is set to inactive – form become un-editable but in our scenarios we want to keep the record active but un-editable.
Therefore, we come down to our final easy solution to tackle all problems above, the JavaScript.


function onload()
{
var Topic= Xrm.Page.getAttribute("subject").getValue();
if(Topic!=null)
{
DisableAllFields();
}
}

function DisableAllFields()

{

       Xrm.Page.ui.controls.forEach(function (control, index) {

           var controlType = control.getControlType();

           if (controlType != "iframe" && controlType != "webresource" && controlType != "subgrid")

           {

               control.setDisabled(true);

           }

       });

}


Above code takes the control of the form directly rather than of each field & locks all of them. 

Just call the function on Onload, I have used this on my form and it looks like below:












Sunday, December 3, 2017

Dynamics 365 – Alternate keys can stop duplicates

Alternative keys give a method to stop users adding duplicates records, speed up Dynamics 365 searching and are useful for integrating Dynamics 365 with external services/systems.

Alternate keys can stop duplicates
  • Alternate keys can increase record lookup speed
  • Alternative keys allow you to lookup records without a GUID but with information which makes an alternate key.  E.g. lookup a person using surname and email.
  • Work well with upsert, allowing you to find a record and either update or create
  • Can sometimes cause problems when trying to remove them solutions
  • Added in Dynamics CRM 2016 and available in Dynamics 365 online and on premise

An alternate key can be added to an entity and can be made up of one or more fields on the entity.  Alternate keys use database indexes, this has the benefit of making records unique by stopping duplicates and increasing performance when retrieving records with an alternate key.




Alternate key facts
  • Each entity can have 5 alternate keys
  • You can only use strings, decimals and integers (whole number) to create an alternate key
  • There is a maximum key size to be aware of
  • After creating an alternate key, an async job will create the index and the status will be pending, In Progress, Active and failed.  If you have a lot of records this could take a long time.
  • You can retrieve an alternate key using RetrieveEntityKeyRequest, you delete an alternate key using DeleteEntityKeyRequest.

Stopping Duplicates
Alternate keys is they give a way to stop users adding duplicate records.  When you add an alternate key and a user tries to add a duplicate, Dynamics 365 will stop the user from adding the record and show the warning below.



 This is better than out of the box duplicate stopping functionality which only warns the user but lets them add a duplicate.
  

Wednesday, November 22, 2017

CRM Advance Find to get the list of Pending & Failed Emails

The list of Customer and their email address that have been sent email to them, but they still not received any Email yet.
And here is the Advanced Find Query to List all Customer + Email address that in the list of attempted sending Email, but still Failed or Pending.
We have the relationship, so-called Activities Parties that we can use to do query.






You also can use this Advanced Find method to query about Phone Call (Call with whom), Appointment, and another Type, just change the ‘Activity (Email)’ to any Activity Type as required.