Dynamics 365





Wednesday, August 28, 2013

Prevent Users to Mark Complete or Close the Task if "Owner" of the Task is not the "Created by" of the Task using Plug-in in Dynamics CRM 2011

Requirement :  Prevent Users to Mark Complete or Close the Task if "Owner" of the Task is not the "Created by" of the Task using Plug-in in Dynamics CRM 2011.
On Click of Mark Complete on Ribbon button from anywhere in CRM Webpage (Form, Subgrid, HomeGrid), if the Task "Owner" is not Same as Task "Created By" then Owner should be prevented from Mark the Task Complete or Close with a User Friendly Message and and also a custom field on Task form called "Able to Mark complete" if the value of the Check box is true (Yes) then to override this requirement, i mean user can Mark Complete or Close.
Implementation:
First Create a Javascript to control the enabling and disabling of "Able to Mark complete" field on the Update form of Task. This field will be enabled for Creator of the Task on Create or Update form, but if the Owner of the Task is not the Creator of the Task then this field should be prevented to update on Update form of Task entity. Here is the JavaScript code to do so (I am avoiding the step to Add the JavaScript as web-resource and Attaching the code to Task form).
function DisableAbleToCompleteField()
{

var  formType = Xrm.Page.ui.getFormType();

   if (formType == 2)
   {
      var userid = Xrm.Page.context.getUserId();
      var creatorlookup = Xrm.Page.getAttribute("createdby");
      if (creatorlookup!= null)
      {
         var creatorlookupvalue = creatorlookup .getValue();
         if (creatorlookupvalue != null)
         {
              var creatorid = creatorlookupvalue[0].id;
          }
       }
                if (userid == creatorid) 
                  Xrm.Page.getControl("new_abletomarkcomplete").setDisabled(false);
           else       
                  Xrm.Page.getControl("new_abletomarkcomplete").setDisabled(true);
          
    }   else        
 Xrm.Page.getControl("new_abletomarkcomplete").setDisabled(false);
}

The Complete Code for the Plug-in to prevent an Owner to Mark Complete or Close the Task:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Diagnostics;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.CSharp;
using System.Data;
using System.Runtime.Serialization;
using Microsoft.Crm.Sdk.Messages;

namespace TaskClosurePermissionPlugin

{
    public class TaskClosure : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            if (context.PrimaryEntityName == "task")
            {

                if (context.InputParameters.Contains("EntityMoniker") && context.InputParameters["EntityMoniker"] is EntityReference && context.Depth < 2)

                {
                    if (context.PreEntityImages.Contains("PreImage"))
                    {

                        Entity taskentity = (Entity)context.PreEntityImages["PreImage"];

                        EntityReference owneridLookup = (EntityReference)taskentity.Attributes["ownerid"];
                        EntityReference createdbyLookup = (EntityReference)taskentity.Attributes["createdby"];
                       
                        if (owneridLookup.Id != createdbyLookup.Id)
                        {
                            if (taskentity.Contains("new_abletomarkcomplete") && !taskentity.GetAttributeValue<bool>("new_abletomarkcomplete"))
                            {
                                throw new InvalidPluginExecutionException("This Task is Created by : "+createdbyLookup.Name+" ,  User : "+owneridLookup.Name +" is not allowed to Mark Complete or Close the Task.");
                            }
                        }
                    }
                }
                else
                {
                    throw new InvalidPluginExecutionException("Activity should be Task.");
                }

            }


       }

    }
}

The Plugin has to use Pre-Image to compare the values of the fields before transaction happens in the Database.
Now the Registration Process of Plug-in:
Open the Plugin registration Tool, Select your Organization, Log as Admin user (Or if any user has granted permission). 
1. Register New Assembly by browsing your dll.
2. You have to Register steps for the plugin on SetState and SetStateDynamicEntity both steps.
3. Register Pre-Image for both Steps.
 
Once done, you are now Ok to test your business scenario,

Following are the screen shots, on Single Task and Multiple Tasks Closure Process from the CRM Landing Page (In My case Dashboard):

Single Task Selected:
Once done, you are now Ok to test your business scenario,

Following are the screen shots, on Single Task and Multiple Tasks Closure Process from the CRM Landing Page (In My case Dashboard):

Single Task Selected:
Once done, you are now Ok to test your business scenario,

Following are the screen shots, on Single Task and Multiple Tasks Closure Process from the CRM Landing Page (In My case Dashboard):

Single Task Selected:

Tuesday, August 6, 2013

Display label of option set based on value

 Dynamics 365 Optionset label display using Javascript

string GlobaloptionsetText = GetCRMOptionSetLabel(service, entity.LogicalName, "new_rating", irating);
   private string GetCRMOptionSetLabel(IOrganizationService service, string entityname, string optionsetname, int value)
        {
            Microsoft.Xrm.Sdk.Messages.RetrieveAttributeRequest reqOptionSet = new Microsoft.Xrm.Sdk.Messages.RetrieveAttributeRequest();
            reqOptionSet.EntityLogicalName = entityname;
            reqOptionSet.LogicalName = optionsetname;
            Microsoft.Xrm.Sdk.Messages.RetrieveAttributeResponse resp = (Microsoft.Xrm.Sdk.Messages.RetrieveAttributeResponse)service.Execute(reqOptionSet);
            Microsoft.Xrm.Sdk.Metadata.PicklistAttributeMetadata opdata = (Microsoft.Xrm.Sdk.Metadata.PicklistAttributeMetadata)resp.AttributeMetadata;
            var option = opdata.OptionSet.Options.FirstOrDefault(o => o.Value == value);
            return option.Label.LocalizedLabels.FirstOrDefault().Label;
        }