Thursday, April 26, 2012

Dynamics CRM 2011 : Add Record to Queue via Workflow, JScript & C# Code


In Dynamics CRM 2011 we can manually assign the entity records to Queue from the Entity Form or List View (Grid) ribbon Add to Queue button but to assign the items automatically to queue, we can create a process Workflow, use JScript or can perform via C# or Vb.Net code.
The following example below can be use to add an entity record to the Queue via a process Workflow, Jscript and C# code.
[Workflow Process Example]

The following steps below describe the solution for adding a High Priority cases to the High Priority Cases Queue.

1.    Cretae new workflow process, go to Settings Process Center Processes, click on new button and enter process details:

·       Enter Processname i.e.  Assign Cases to Queue,
·       In Entity field choose Case
·       In Category field choose Workflow and click ok button

2.    In workflow Options for Automatic Process choose the following:

·       In Scope choose Organization
(If require to run this workflow for all Case records regardless of Business Units or User specific records)

·      In Starts When check Record is Created option

3.    Add Check Condition step, click on the condition and In Specify Condition Web Dialog, choose Case  (entity) in first list box, choose Priority (case entity field) from second list box, choose Equals (condition operator) in list box  and choose High (case priority field value) in the final list box. The condition will look like:

Case                Priority                        Equals             High

4.    Add Create Records Step in Crete field choose Queue Item, click on Set properties button and set the following properties:

·       In Queue field, choose queue record i.e. High Priority Queue
·       Click on Queue Item field and in Form Assistant Dynamics Values  In Look For choose Case in both list items, clickon the Add button and then OK
·       In Worked By field choose User or Team to be assigned or leave this field empty for manual queue assignment

5.    Click on Activate button to Activate the process

[C# Code Example]


   private void Main(IOrganizationService wod_CrmService)
    {

        // Assigning CRM Queue GUID value, the entity record will be added to this queue
        Guid wod_QueueId = new Guid("51B0325E-1D8F-E111-A6A1-B8AC6F3EDD32");

        // Assigning entity name & id, this entity record will be added to the queue
        EntityReference wod_CaseLookup = new EntityReference()
        {
            LogicalName = "incident",
            Id = new Guid("1B3B27C2-1C8F-E111-A6A1-B8AC6F3EDD32")
        };

        // Assigning the user Id to whom the queue item will be assigned
        EntityReference wod_UserLookup = new EntityReference()
        {
            LogicalName = "systemuser",
            Id = new Guid("1AF3D79C-C599-E011-868E-000C29C2F593")
        };

        // You may also assigned the record to the team by changing the
        // logical name to team and changing Id value to Team record GUID value

        // Calling AddToQueue function to create new queue item in the queue
        // Function will take CRM Web service object, CRM Queue GUID,
        // Record Entity Lookup and queue item owner user/team lookup
        // If you will pass Null value into last parameter then  queue
        // item will only add to Queue for manual assignment
           
        AddToQueue(wod_CrmService, wod_QueueId, wod_CaseLookup, wod_UserLookup);
    }

    private void AddToQueue(IOrganizationService prmCrmService, Guid prmQueueId,
                 EntityReference prmEntityLookup, EntityReference prmWorkerLookup)
    {
        // Creating Queue Item Type entity Object
        Entity wod_QueueItem = new Entity("queueitem");

        // Assinging CRM Queue record lookup reference
        // this entity record will be added to this queue
        wod_QueueItem["queueid"] = new EntityReference("queue", prmQueueId);

        // Assigning entity record lookup reference
        // the entity recoed will be added to this queue
        wod_QueueItem["objectid"] = prmEntityLookup;

        if (prmWorkerLookup != null)
        {
            // Assigning the worker id to whom the queue item will be assigned
            wod_QueueItem["workerid"] = prmWorkerLookup;
        }

        prmCrmService.Create(wod_QueueItem);


[JScript Code Example]


if (typeof (wod_SDK) == "undefined")
{ wod_SDK = { __namespace: true }; }
//This will establish a more unique namespace for functions in this library. This will reduce the
// potential for functions to be overwritten due to a duplicate name when the library is loaded.
wod_SDK.QueuesLib = {
    _getServerUrl: function () {
        ///<summary>
        /// Returns the URL for the SOAP endpoint using the context information available in the form
        /// or HTML Web resource.
        ///</summary>
        var ServicePath = "/XRMServices/2011/Organization.svc/web";
        var serverUrl = "";
        if (typeof GetGlobalContext == "function") {
            var context = GetGlobalContext();
            serverUrl = context.getServerUrl();
        }
        else {
            if (typeof Xrm.Page.context == "object") {
                serverUrl = Xrm.Page.context.getServerUrl();
            }
            else
            { throw new Error("Unable to access the server URL"); }
        }
        if (serverUrl.match(/\/$/)) {
            serverUrl = serverUrl.substring(0, serverUrl.length - 1);
        }

        return serverUrl + ServicePath;
    },
    AddToQueue: function (prmQueueId, prmEntityName, prmEntityId, prmQueueWorkerEntityName, prmQueueWorkerEntityId) {
        var wod_Request = ""
        wod_Request += "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">";
        wod_Request += "  <s:Body>";
        wod_Request += "    <Create xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
        wod_Request += "      <entity xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
        wod_Request += "        <a:Attributes xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
        wod_Request += "          <a:KeyValuePairOfstringanyType>";
        wod_Request += "            <b:key>objectid</b:key>";
        wod_Request += "            <b:value i:type=\"a:EntityReference\">";
        wod_Request += "              <a:Id>" + prmEntityId + "</a:Id>";
        wod_Request += "              <a:LogicalName>" + prmEntityName + "</a:LogicalName>";
        wod_Request += "              <a:Name i:nil=\"true\" />";
        wod_Request += "            </b:value>";
        wod_Request += "          </a:KeyValuePairOfstringanyType>";
        wod_Request += "          <a:KeyValuePairOfstringanyType>";
        wod_Request += "            <b:key>queueid</b:key>";
        wod_Request += "            <b:value i:type=\"a:EntityReference\">";
        wod_Request += "              <a:Id>" + prmQueueId + "</a:Id>";
        wod_Request += "              <a:LogicalName>queue</a:LogicalName>";
        wod_Request += "              <a:Name i:nil=\"true\" />";
        wod_Request += "            </b:value>";
        wod_Request += "          </a:KeyValuePairOfstringanyType>";

        if (prmQueueWorkerEntityName != null && prmQueueWorkerEntityId != null) {
            wod_Request += "          <a:KeyValuePairOfstringanyType>";
            wod_Request += "            <b:key>workerid</b:key>";
            wod_Request += "            <b:value i:type=\"a:EntityReference\">";
            wod_Request += "              <a:Id>" + prmQueueWorkerEntityId + "</a:Id>";
            wod_Request += "              <a:LogicalName>" + prmQueueWorkerEntityName + "</a:LogicalName>";
            wod_Request += "              <a:Name i:nil=\"true\" />";
            wod_Request += "            </b:value>";
            wod_Request += "          </a:KeyValuePairOfstringanyType>";
        }

        wod_Request += "        </a:Attributes>";
        wod_Request += "        <a:EntityState i:nil=\"true\" />";
        wod_Request += "        <a:FormattedValues xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\" />";
        wod_Request += "        <a:Id>00000000-0000-0000-0000-000000000000</a:Id>";
        wod_Request += "        <a:LogicalName>queueitem</a:LogicalName>";
        wod_Request += "        <a:RelatedEntities xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\" />";
        wod_Request += "      </entity>";
        wod_Request += "    </Create>";
        wod_Request += "  </s:Body>";
        wod_Request += "</s:Envelope>";

        var req = new XMLHttpRequest();
        req.open("POST", wod_SDK.QueuesLib._getServerUrl(), false)
        req.setRequestHeader("Accept", "application/xml, text/xml, */*");
        req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        req.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Create");
        req.send(wod_Request);

        //Checking if error occurs
        var errorMessage = wod_SDK.QueuesLib._getError(req.responseXML);

        if (errorMessage != "") {
            alert(errorMessage);
        }
    },
    _getError: function (faultXml) {
        ///<summary>
        /// Parses the WCF fault returned in the event of an error.
        ///</summary>
        ///<param name="faultXml" Type="XML">
        /// The responseXML property of the XMLHttpRequest response.
        ///</param>
        var errorMessage = "";
        if (typeof faultXml == "object") {
            try {
                var bodyNode = faultXml.firstChild.firstChild;
                //Retrieve the fault node
                for (var i = 0; i < bodyNode.childNodes.length; i++) {
                    var node = bodyNode.childNodes[i];

                    if ("s:Fault" == node.nodeName) {
                        for (var j = 0; j < node.childNodes.length; j++) {
                            var faultStringNode = node.childNodes[j];
                            if ("faultstring" == faultStringNode.nodeName) {
                                errorMessage = faultStringNode.text;
                                break;
                            }
                        }
                        break;
                    }
                }
            }
            catch (e) { };
        }
        return errorMessage;
    },

    __namespace: true
};



[JScript Code Function Call Example]


// Function Call : creating queue item for incident record & assigning to user/team
wod_SDK.QueuesLib.AddToQueue(QueueGUID, "incident", IncidentGUID, "systemuser", UserGUID);