Category Archives: Workflows

Call Workflow from Javascript

This is the code needed.


function triggerBulkWorkflowByName(wfName, svid) {
    var wId = getWorkflowId(wfName);
    triggerWorkflow(wId, svid);
}

function getWorkflowId(wfName) {

    var urlPos = Xrm.Page.context.getServerUrl() + "/XRMServices/2011/OrganizationData.svc/WorkflowSet?$filter=Name eq '" + wfName + "' and ParentWorkflowId/Id eq null";
    //var urlPos = Xrm.Page.context.getServerUrl() + "/XRMServices/2011/OrganizationData.svc/WorkflowSet";

    var id;

    $.ajax({
        type: "GET",
        contentType: "application/json; charset=utf-8",
        async: false,
        datatype: "json",
        url: urlPos,
        beforeSend: function (XMLHttpRequest) {
            //Specifying this header ensures that the results will be returned as JSON.
            XMLHttpRequest.setRequestHeader("Accept", "application/json");
        },
        success: function (data, textStatus, XmlHttpRequest) {
            if (data.d.results.length > 0) {
                id = data.d.results[0].WorkflowId;
            }
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            alert("Error");

        }
    });

    return id;
}

function triggerWorkflow(wfId, entityId) {

    try {
var soapBody = "<soap:Body>" + 
" <Execute xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>" +
 " <Request xsi:type=\'ExecuteWorkflowRequest\'>" +
 " <EntityId>" + entityId + "</EntityId>" +
 " <WorkflowId>" + wfId + "</WorkflowId>" +
 " </Request>" +
 " </Execute>" +
 "</soap:Body>";

/*Wrap the Soap Body in a soap:Envelope.*/
 var soapXml = "<soap:Envelope " +
 " xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' " +
 " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' " +
 " xmlns:xsd='http://www.w3.org/2001/XMLSchema'>" +
 GenerateAuthenticationHeader() +
 soapBody +
 "</soap:Envelope>";

        /* Create the XMLHTTP object for the execute method.*/
        var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
        xmlhttp.open("POST", "/MSCRMservices/2007/crmservice.asmx", false);
        xmlhttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        xmlhttp.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2007/WebServices/Execute");
        /* Send the XMLHTTP object. */
        xmlhttp.send(soapXml);
    }

    catch (e) {
        alert("An error has occured: " + e.description);
    }

}

How to generate Fetch XML from LINQ using LinqPad

Linqpad is a great tool to query any system using LINQ.

Fetch XML with LinqPad

Fetch XML with LinqPad

If we want to use this tool connected with CRM we need to install a plugin that you can get by going to the downloads tab in the following site.

Generating Fetch From Linq

Once we have LinqPad properly installed and we are able to query results in CRM it would be great to be able to convert those Linqueries into Fetch. To do so we can follow the instructions described by Keydet (Microsoft Employee) in this great post.

Basically we need to add into “My Extensions File” the following code in the MyExtensions class.

public static class MyExtensions
{
	public static string ToFetchXml(this IQueryable linqQuery, dynamic orgService)
	{
		var queryExpression = GetQueryExpression(linqQuery);
	
		var expressionToFetchXmlRequest = new Microsoft.Crm.Sdk.Messages.QueryExpressionToFetchXmlRequest
		{
		Query = queryExpression
		};
	
		var organizationResponse = (Microsoft.Crm.Sdk.Messages.QueryExpressionToFetchXmlResponse)orgService.Execute(expressionToFetchXmlRequest);
	
		return organizationResponse.FetchXml;
	}
 
	private static Microsoft.Xrm.Sdk.Query.QueryExpression GetQueryExpression(IQueryable linqQuery)
	{
		object projection = null;
		object source = null;
		object linkLookups = null;
		bool flag = false;
		bool flag2 = false;
	
		object[] arguments = new object[6];
		arguments[0] = (object)linqQuery.Expression;
		arguments[1] = (object)flag;
		arguments[2] = (object)flag2;
		arguments[3] = (object)projection;
		arguments[4] = (object)source;
		arguments[5] = (object)linkLookups;
	
		Microsoft.Xrm.Sdk.Query.QueryExpression query = (Microsoft.Xrm.Sdk.Query.QueryExpression)linqQuery.Provider.GetType().InvokeMember("GetQueryExpression", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, linqQuery.Provider, arguments);
		return query;
	}
	
}

Then pressing F4 we need to add 3 libraries (Microsoft.crm.sdk.proxy , microsoft.xrm.sdk and System.Runtime.Serialization (.NET 4.0)) and then we will be able to get the Fetch XML from the query by adding .ToFetchXML(this) to any LinQ statement between parentesis as shown in the image:


(from cm in lema_controlmeasureSet
join intersect in lema_controlmeasure_hazardouseventrevisionSet on cm.Id equals intersect.lema_controlmeasureid.Value
join he in lema_hazardouseventrevisionSet on intersect.lema_hazardouseventrevisionid.Value equals he.Id
where (he.lema_status.Value == 3 || he.lema_status.Value == 4)
select cm).ToFetchXml(this)

Getting QueryExpression from FetchXML

Now from any LinQ we can get easily our FetchXML. Then using the CRM2011 SDK we can easily generate QueryExpresions from Fetch as described here.

I think this was helpfull!!

Regards,

Miguel

Scheduling workflows on CRM

I found this amazing post about scheduling jobs on CRM that could make our lives a lot simpler!

It is about scheduling jobs on CRM using the Bulk Delete Schedule system already present on CRM.

Click Dimensions Blog

Thanks a lot to the click dimensions crowd for it!

And here:

http://blogs.msdn.com/b/mvpawardprogram/archive/2013/03/11/scheduling-recurring-workflows-in-microsoft-dynamics-crm-2011-online-and-on-premise.aspx

Query N to N relationship

Having and N to N relationship between points and parameters, from a point ID we want to retrieve all the related parameters.


 EntityCollection getEPParameters(IOrganizationService serv, Guid POINTid)
        {
            QueryExpression query = new QueryExpression()
            {   //Parameters entity
                EntityName = "mile_emissionpointparameters",
                ColumnSet = new ColumnSet(true),
                LinkEntities = 
                        {
                            new LinkEntity
                            {
                                LinkFromEntityName = "mile_emissionpointparameters", //Parameters table
                                LinkFromAttributeName = "mile_emissionpointparametersid", //Parameters table id
                                LinkToEntityName = "mike_mile_emissionpoint_mile_emissionpointpara", // N to N entity 
                                LinkToAttributeName = "mile_emissionpointparametersid", 
                                LinkCriteria = new FilterExpression
                                {
                                    FilterOperator = LogicalOperator.And,
                                    Conditions = 
                                    {
                                        new ConditionExpression
                                        {
                                            AttributeName = "mile_emissionpointid",
                                            Operator = ConditionOperator.Equal,
                                            Values = { POINTid }  // Point id
                                        }
                                    }
                                }
                            }
                        }
            };

            // Obtain results from the query expression.
            return serv.RetrieveMultiple(query);

        }

If what we need is to get a list of entities filtered by some values of the other entities in the N to N relationship we just need to use nested LinkEntities. Imagine we have an N 2 N between control measures and eventRevisions. We want to get all the measures related to any open – semiopen (L_status 3 or 4) revisions.


QueryExpression objQueryExpression = new QueryExpression("lema_controlmeasure");
objQueryExpression.ColumnSet = new ColumnSet(true);
objQueryExpression.Distinct = true;

// Add the filter using the N to N middle table 
LinkEntity linkEntity1 = new LinkEntity();
linkEntity1.JoinOperator = JoinOperator.Inner;
linkEntity1.LinkFromEntityName = "L_controlmeasure";
linkEntity1.LinkFromAttributeName = "L_controlmeasureid";
linkEntity1.LinkToEntityName = "L_controlmeasure_hazardouseventrevision";
linkEntity1.LinkToAttributeName = "L_controlmeasureid";

// To be able to do a double Link we use another LinkEntity within the the original linked Entity
LinkEntity InnerLinkEntity = new LinkEntity();
InnerLinkEntity.JoinOperator = JoinOperator.Inner;
InnerLinkEntity.LinkFromEntityName = "L_controlmeasure_hazardouseventrevision";
InnerLinkEntity.LinkFromAttributeName = "L_hazardouseventrevisionid";
InnerLinkEntity.LinkToEntityName = "L_hazardouseventrevision";
InnerLinkEntity.LinkToAttributeName = "L_hazardouseventrevisionid";

// Filter of the inner Join by a value of the second entity of the N 2 N
InnerLinkEntity.LinkCriteria.AddCondition("L_status", ConditionOperator.In, 3, 4);

//Add this link to the original link
linkEntity1.LinkEntities.Add(InnerLinkEntity);

objQueryExpression.LinkEntities.Add(linkEntity1);   

EntityCollection results = _service.RetrieveMultiple(objQueryExpression);

Following this idea of having a InnerLinkEntity, we could add more innerLinkEntities being able to query N relationships at once!

I hope it was helpfull!!!

Cheers,