Tuesday, May 21, 2013

CRM 2011 Installation files for Windows server 2012

Installation of Crm 2011 on windows server 2012 is now fully supported after the release of rollup 13. The only thing you need is the updated installation files and patch for Windows Server 2012.
The updated installation file can be downloaded from http://www.microsoft.com/en-us/download/details.aspx?id=27822 this was published on 1/20/2012.
Next you will need the patch for Windows Server 2012,This will be downloaded automatically if you select Get Updates during the installation, however in case your server does not have internet access then you will have to manually download the files. These can be hard to find as I discovered but looking hard enough you can figure it out.
Just to save people time  here is the link to the updated installation files. Go to the Microsoft Update catalogue site http://catalog.update.microsoft.com/v7/site/home.aspx
Do a search for CRM.

After downloading the update patch files, you will need to copy them to a location on your server.  Note you only need to copy the file relevant to you language in English's case this is 1033. After than you will need to start the installer using command line and specify the location of the patch files in the xml element.
<Patch update="true">\\vmware-host\Shared Folders\Downloads\crm patch\Server_KB2434455_amd64_1033.msp</Patch>

Now when you run the installation from the command line using the XML config file, you will be easily able to install CRM on Windows server 2012 and SQL Server 2012.
Hope this saves some time.

In the next post I will shed some light on using CRM 2011 on windows server 2012

Happy CRMing!

Tuesday, April 17, 2012

Changing the reply email address to the queue's email address when replying from a queue in crm 2011

The problem was that we have multiple queues with email addresses in crm 2011. When an email arrives it goes to a particular queue depending on the address that was used. Now what happens when you try to reply to that email? Well nothing much only that the "FROM address" lookup defaults to the currently logged on user instead of defaulting to the queue's email address.
There are various ways you can solve this issue by writing plugin or workflow custom activity etc, but the crux of the matter is that the crm user replying from a queue needs to the see what the from email address is.
This can be best achieved by using Java script.
Please note that the code below is an unsupported customization, but it works.
function CheckEnquiryReplyAddress() {
 // Only complete this validate on Create Form
 var formType = Xrm.Page.ui.getFormType();
 var emailStatus = GetAttributeValue("statecode");
                    var emailDirection = GetAttributeValue("directioncode");



 if (formType == 1 || (formType == 2 && emailStatus == "Open")) {  
                                             
                                       
  if (emailDirection == "1"){
                                                              var previousEmailId=getExtraqsParam("_InReplyToId", window.parent.location.search);

   //getting context from the parent window
   var context = Xrm.Page.context;

   try {
    var serverUrl = context.getServerUrl();
    //The XRM OData end-point
    var ODATA_ENDPOINT = "/XRMServices/2011/OrganizationData.svc";
                                                                                     var query="/EmailSet?$select=ActivityId,ActivityTypeCode,DirectionCode,";
                                                                                     query=query+"ToRecipients,Email_QueueItem/QueueId&$expand=Email_QueueItem&$filter=ActivityId eq guid'" + previousEmailId +"'";
    query =serverUrl+ODATA_ENDPOINT+ query;

    var request= new XMLHttpRequest();
    request.open("GET", query, false);
    request.setRequestHeader("Accept", "application/json");
    request.setRequestHeader("Content-Type", "application/json; charset=utf-8"); 
    request.onreadystatechange=function(){ CompleteEnquiryReplyCheck(request,serverUrl);}
    request.send(null);
   }
   catch(e) {
    alert(e.Description);
   }
  }
 }

          
}
function CompleteEnquiryReplyCheck(request,url)
{
 if (request.readyState==4) {
  if(request.status==200) {
   var queue=JSON.parse(request.responseText).d.results[0];
   
   if (queue != null) {
    var queueId = queue.Email_QueueItem.results[0].QueueId.Id;
    var lookup = new Array();
      var lookupItem = new Object();
  
    lookupItem.id = queueId;
    lookupItem.name = queue.Email_QueueItem.results[0].QueueId.Name;
    lookupItem.typename = "queue";
     
    lookup[0] = lookupItem;
  
    Xrm.Page.getAttribute("from").setValue(lookup);
   }
  }
    }
}
The key here is the _InReplyToId query string parameter from here we are able to query the oData service and get the "To" email address of the original email and then it is simply a matter of putting the "To" address in the "From" lookup. Also note that I am checking that this is an outgoing email. Find the code for getExtraqsParam here. Happy Crming!.

Monday, April 16, 2012

Executing CRM 2011 workflow via Javascript

To execute a workflow we have to use the soap web service. We cannot use oData service. So we have to create a soap envelope and post it to the organization web service. The following function will execute the workflow.
function ExecuteWorkFlow(entityId,workflowId,url)
{

    var OrgServicePath = "/XRMServices/2011/Organization.svc/web";
    url = url + OrgServicePath;
    var request;
    request = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
  "<s:Body>" +
    "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">"+
      "<request i:type=\"b:ExecuteWorkflowRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\" xmlns:b=\"http://schemas.microsoft.com/crm/2011/Contracts\">"+
        "<a:Parameters xmlns:c=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">"+
          "<a:KeyValuePairOfstringanyType>"+
            "<c:key>EntityId</c:key>"+
            "<c:value i:type=\"d:guid\" xmlns:d=\"http://schemas.microsoft.com/2003/10/Serialization/\">"+ entityId+"</c:value>"+
          "</a:KeyValuePairOfstringanyType>"+
          "<a:KeyValuePairOfstringanyType>"+
            "<c:key>WorkflowId</c:key>"+
            "<c:value i:type=\"d:guid\" xmlns:d=\"http://schemas.microsoft.com/2003/10/Serialization/\">"+ workflowId +"</c:value>"+
          "</a:KeyValuePairOfstringanyType>"+
        "</a:Parameters>"+
        "<a:RequestId i:nil=\"true\" />"+
        "<a:RequestName>ExecuteWorkflow</a:RequestName>"+
      "</request>"+
    "</Execute>"+
  "</s:Body>"+
"</s:Envelope>";

  var req = new XMLHttpRequest();
  req.open("POST", url, true)
  // Responses will return XML. It isn't possible to return JSON.
  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/Execute");
  req.onreadystatechange = function () { assignResponse(req); };
  req.send(request);
  

}

function assignResponse(req) {
if (req.readyState == 4) {
    if (req.status == 200) {
        alert('successfully executed the workflow');
   }
   }
}

Happying Coding!

Accessing HTML web resource funcitons from entity Form in CRM 2011

I found this piece of code really handy. If you have a web resource that you place inside a form and if you want to manipulate the html within that html web resource you can do it.
Xrm.Page.getControl("WebResource_YourWebResource").getObject().contentWindow.window.WebResourceFunction
The function WebResourceFunction sits inside the HTML web resource and can do anything.
An example of how I used it was to call the HTML web resource function on the onchange event of a lookup and display something different for different values in the lookup box. Oh and yes you can pass parameters to the function as well.
To be fair, I found this technique on some other blog, but I can reference it since I lost the address and can't find it any more.
Happy Coding!

Tuesday, April 3, 2012

Parsing query string values in the extraqs parameter

If you want to get values of query string parameters that are inside the extraqs query string field in your crm form then you can call the getExtraqsParam function. It takes two values: they key is the param whose value you want to get to and the query is the actual query string which you can find through window.location.search property. Note that that window.locaiton.search only returns the query string part of the url.
 function getExtraqsParam(key,query)
        {   //Get the any query string parameters and load them
            //into the vals array

            var vals = new Array();
           
                vals = query.substr(1).split("&");
                for (var i in vals)
                {
                    vals[i] = vals[i].replace(/\+/g, " ").split("=");
                }
                //look for the parameter named 'extraqs'
                var found = false;
                var returnVal=null;
                for (var i in vals)
                {

                    if (vals[i][0].toLowerCase() == "extraqs")
                    {
                       
                         
                         returnVal= vals[i][1];

                          break;
                    }
                }

                return parseExtraqs(key,returnVal);                     

        }

function parseExtraqs(key,val)
{

    var returnVal;
    var vals;
    vals=decodeURIComponent(val).split("&");
    for (var i in vals)
     {
         vals[i] = vals[i].replace(/\+/g, " ").split("=");
         if (vals[i][0]==key)
        returnVal=decodeURIComponent(vals[i][1]);
     }
return returnVal;

}
Happy Crming!

Saturday, December 24, 2011

Loading JSON in your CRM ribbon

Add an enable rule in your customizations.xml and put the following
  <EnableRules>
            <EnableRule Id="Atif.new_customentity.WebClient.EnableRule">
              <CrmClientTypeRule Type="Web" />
              <CustomRule Library="$webresource:agd_/scripts/json2.js" FunctionName="isNAN" Default="true"></CustomRule>
            </EnableRule>
          </EnableRules></EnableRules>

Next in your Command Definition you need to put the display rule defined above.
  <CommandDefinition Id="Atif.new_customentity.SubGrid.AddSecondAssessment.Command">
            <EnableRules>
              <EnableRule Id="Atif.new_customentity.WebClient.EnableRule" />
            </EnableRules>
            <DisplayRules>
              <DisplayRule Id="Atif.new_customentity.WebClient.DisplayRule" />
            </DisplayRules>
            <Actions>
              <JavaScriptFunction Library="$webresource:agd_/scripts/Ribbonfunctions.js" FunctionName="AddSecondAssessment">
                <CrmParameter Value="FirstPrimaryItemId" />
                <CrmParameter Value="OrgName" />
              </JavaScriptFunction>
            </Actions>
          </CommandDefinition>
        </CommandDefinitions>
Now when your ribbon loads JSON will be loaded as well and you can use it in any of your custom ribbon javascript functions.

Happy CRMing!

Friday, December 23, 2011

How to stop CRM form from saving

I had to write some validation code on the OnSave event of the form and if the validation code was not successful I needed to cancel the save. To accomplish this you have to use JavaScript and you need to pass context to your javascript function.
If your business logic fails you need to call this function.
ExecutionObj.getEventArgs().preventDefault();
Where ExecutionObj is the first parameter of the function (i.e. context object).

Cheers