Wednesday, 5 March 2014

Convert TextBox to DropDown in CRM 2011

Convert TextBox to DropDown in CRM 2011 Form

Today, we got a requirement where we don’t know the options to be populated in the dropdown as they are supposed to get from external data source. So we thought of converting TextBox to DrowDown with the values from data source in JavaScript and worked on it.

Here is the code for it…
// Conver TextBox to DropDown in CRM 2011
function CreateDropDownList() {
    //synchronous AJAX function to get Xml content from a custom webservice
    $.ajax({
        type: "POST",
        async: false,
        contentType: "application/json; charset=utf-8",
        datatype: "json",
        url: url + "/**********.asmx/*************",
        data: "{'status':'true'}",
        beforeSend: function (XMLHttpRequest) {
            //Specifying this header ensures that the results will be returned as JSON.
            XMLHttpRequest.setRequestHeader("Accept", "application/json");
            //XMLHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        },
        success: function (XmlHttpRequest) {
            //alert(XmlHttpRequest);
            msg = XmlHttpRequest.d; //window.JSON.parse(XmlHttpRequest.responseText);
            //alert('Response ' + msg);
        },
        error: function (XmlHttpRequest) {
            var error = window.JSON.parse(XmlHttpRequest.responseText);
            //alert("Error : " + XmlHttpRequest.responseText);
        }
    });
    // Check for the browser
    try {
        if (window.ActiveXObject) {
            //Code for IE
            var Details = msg;
            var NDetails = Details.replace(/\\"/g, '\"')
            xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
            xmlDoc.async = false;
            xmlDoc.loadXML(NDetails);
        }
        else {
            // code for Mozilla, firefox, Opera, etc.
            var Details = msg;
            var NDetails = Details;
            xmlDoc = document.implementation.createDocument("", "", null);
            parser = new DOMParser();
            xmlDoc = parser.parseFromString(NDetails, "text/xml");
        }
    }
    catch (e) {
        alert(e.message);
    }
    var lsElements = xmlDoc.getElementsByTagName("Description");
    ////Erase the pick list
    var pick = document.getElementById("new_source");
    var ctName = pick.name;
    var ctId = pick.id + '_lst';
    var ctClass = "ms-crm-SelectBox";
    // Get the existing, we can use for populating it on the dropdown.
    var pVal = Xrm.Page.getAttribute("new_source").getValue();
    var parent = document.getElementById('new_source_d');
    pick.style.display = "none";
    var picklistControl = document.createElement("SELECT");
    ////Copy the Text field properties to the picklist 
    picklistControl.id = ctId;
    //// picklistControl.req = textControl.req;
    picklistControl.name = ctName;
    //// Set Required Style 
    picklistControl.className = ctClass;
    var usedNames = {};

    ////Create a new Option 
    var option = document.createElement("OPTION");
    option.value = 0;
    option.innerText = "";
    option.text = "";

    ////Add the option to the picklist   
    picklistControl.appendChild(option);
    for (vCount = 0; vCount < lsElements.length; vCount++) {
        var Source = lsElements.item(vCount).childNodes.item(0).nodeValue;
        //// Do not add duplicate options
        var isExist = false;
        if (usedNames[Source.toUpperCase()]) {
            continue;
        }
        else {
            usedNames[Source.toUpperCase()] = Source.toUpperCase();
        }
        ////Create a new Option 
        option = document.createElement("OPTION");
        option.value = vCount + 1;
        option.innerText = Source;
        option.text = Source;
        if (pVal != null && Source != null) {
            // Check if Source and Existing Value is same, just select option set selected property to True.
            option.selected = (trim(Source) == trim(pVal));
        }
        ////Add the option to the picklist   
        picklistControl.appendChild(option);
    }
    ////append the picklist to the document 
    parent.appendChild(picklistControl);
}

//

--
Happy CRM’ing,
Gopinath

CRM Outlook trying to connect

Things to be followed when Outlook is not able to connect CRM


First, try accessing Web CRM and if you are able to access it, follow the below steps to connect CRM in Outlook.

Microsoft Dynamics CRM processes and records may create and store files in a temporary cache. When updates occur, software may still be referencing some of these old files in cache, which can cause various issues. The same can be true for the Microsoft Dynamics Outlook client and the need to clear the cache periodically.

Note: Often a user’s Outlook could be open for days without ever closing (even if workstation is hibernating). Due to the long duration, sometimes the CRM client may stop syncing. The diagnostics tool can help resolve issues stemming from that.

Many simple issues can be resolved by clearing out the temporary cache for Dynamics CRM. Things like: 
    • CRM stops syncing
    • CRM ribbon buttons are disabled and not usable
    • Lists of records do not display properly
    • Outlook won’t load

         How to Clear the Temporary Files for Dynamics CRM
         To open the Diagnostics Utility, follow these steps:
    •  Open the Start Menu.
    •  Click All Programs.
    •  Click Microsoft Dynamics CRM 2011.
    •  Click on the Diagnostics utility.

  


To delete the temporary CRM files, follow these steps in the Diagnostics utility: 
    • Click on the Advanced Troubleshooting tab.
    • Under the heading “Delete Temporary Microsoft Dynamics CRM Client files”,click Delete.
    • Click Save.
    • Close and re-open your Outlook to check if the clearing of the cache resolved your problem.     
This is usually the first step recommended when troubleshooting Microsoft Dynamics CRM Outlook add-in problems. 

Tuesday, 4 March 2014

CRM On Premise User Enable(External Error - No such object on server)

Today, we got an issue while enabling the user in CRM 2011. 

An user was created in Active Directory.
Added the same user to CRM users list.
Disabled the user in CRM and deleted the active directory.

Now, added Active directory account with the same user details and try to a user in CRM.

You will get the following error message.




That is because, when we enable the user the CRM looks for corresponding active directory account. As we have deleted active directory and added it again, the guid saved in CRM database is different.

You can check that in the SystemUser table, columnname ActiveDirectoryGuid.

For resolving the issue, just get the active directory guid of the user and update it in the CRM's database and try enabling the user. After this, you won't get any error messsage.

Delete Event in CRM 2011 Plug-In

Today, I have written a plug-in which fires on record delete message. I have deployed it successfully and when I test it, the code is not firing and even I don't see any error message. I went further and debugged the code and found the cause of the issue.

Event

Type
Delete
context.InputParameters["Target"]
EntityReference
Create
context.InputParameters["Target"]
Entity
Update
context.InputParameters["Target"]
Entity

So your code should be as follows

Delete
if (context.InputParameters.Contains("Target") && context.InputParameters["Target"is EntityReference)
{
    if (context.MessageName == "Delete")
    {
         // Your code
    }
}

Create and Update
if (context.InputParameters.Contains("Target") && context.InputParameters["Target"is Entity)
{
    if (context.MessageName == "Create")
    {
         // Your code
    }
    if (context.MessageName == "Update")
    {
         // Your code
    }
}

--
Happy CRM'ing
Gopinath

Sunday, 31 March 2013

Clone CRM Record CRM 2011


Many times while working on CRM 2011, we come across a situation to clone the quote or invoice records. Immediately we will start writing the code for getting the record and creating the same record again and continue the same for child records i.e. quote products or invoice lines etc...

Even I have came across the same situation then my team lead and me wrote a generic method for cloning CRM records.

Here is that method...

        #region CloneRecord
                /// <summary>
                /// Method to Clone CRM Record.
                /// </summary>
                /// <param name="strEntityName">Parent entity name ex: invoice</param>
                /// <param name="strParentEntityPKAttrName">Parent primary attribute name ex:invoiceid</param>
                /// <param name="guidParent">Guid of the parent record</param>
                /// <param name="strAttributesToFetch">Selected attributes to copy from one record to another. If you wanna copy all records,
                /// just send the parameter as null then the considers all attributes.</param>
                /// <param name="strArrRemoveParentAttributes">Attributes to remove from parent entity.</param>
                /// <param name="strChildEntity">Child entity name ex: invoicedetail</param>
                /// <param name="strChildEntityFKAttrName">Child primary attriubute name ex: invoicedetailid</param>
                /// <param name="strArrRemoveChildCols">Attributes to remove from child entity</param>
               /// <returns>Guid of the parent record</returns>
                public Guid CloneCRMRecord(string strEntityName, string strParentEntityPKAttrName, Guid guidParent, string[] strAttributesToFetch, string[] strArrRemoveParentAttributes, string strChildEntity, string strChildEntityFKAttrName, string[] strArrRemoveChildCols)
                {
                    Microsoft.Xrm.Sdk.Entity parentEntity = new Microsoft.Xrm.Sdk.Entity(strEntityName);
                    if (strAttributesToFetch == null)
                    {
                        parentEntity = _crmService.Retrieve(parentEntity.LogicalName, guidParent, new ColumnSet(true));
                    }
                    else
                    {
                        parentEntity = _crmService.Retrieve(parentEntity.LogicalName, guidParent, new ColumnSet(strAttributesToFetch));
                    }
                    if (strArrRemoveParentAttributes == null) strArrRemoveParentAttributes = new string[] { "" };
                    RemoveEntityAttributes(ref parentEntity, strArrRemoveParentAttributes);
                    /*
                        Below line is must otherwise, "Create" will result in:
                        FaultException'1 was unhandled.
                        Cannot insert duplicate key.
                    */
                    parentEntity.Id = Guid.NewGuid();
                    Guid newEntityRecordId = _crmService.Create(parentEntity);
                    //
                    if (string.IsNullOrEmpty(strChildEntity) == false)
                    {
                        #region Retrieve all the Child Entity Record details from the original Parent Entity Record.
                                ConditionExpression expression = new ConditionExpression();
                                expression.AttributeName = strChildEntityFKAttrName;
                                expression.Operator = ConditionOperator.Equal;
                                expression.Values.Add(guidParent);
                                FilterExpression expression2 = new FilterExpression();
                                expression2.FilterOperator = LogicalOperator.And;
                                expression2.Conditions.Add(expression);
                                QueryExpression query = new QueryExpression();
                                query.EntityName = strChildEntity;
                                query.ColumnSet = new ColumnSet(true);
                                query.Criteria = expression2;

                        #endregion
                        EntityCollection allChildEntityRecords = _crmService.RetrieveMultiple
(query);
                        if (allChildEntityRecords != null)
                        {
                            //One by one create Child Entity records in the Parent Entity.sales order detail record and set its FK Id to the Cloned Parent Entity Id
                            //and PK Id to new GUID.
                            #region Create Child Entity Records under the Parent Entity.
                                    Microsoft.Xrm.Sdk.Entity clonedChildEntity = null;
                                    if (strArrRemoveChildCols == null) strArrRemoveChildCols = new string[] { "" };
                                    Guid newChildEntityRecordId = Guid.Empty;
                                    foreach (Microsoft.Xrm.Sdk.Entity childEntity in allChildEntityRecords.Entities)
                                    {
                                        clonedChildEntity = new Microsoft.Xrm.Sdk.Entity(strChildEntity);
                                        clonedChildEntity = _crmService.Retrieve(clonedChildEntity.LogicalName, childEntity.Id, new ColumnSet(true));
                                        EntityReference refParent = new EntityReference(parentEntity.LogicalName, parentEntity.Id);
                                        clonedChildEntity.Attributes[strChildEntityFKAttrName] = refParent;
                                        RemoveEntityAttributes(ref clonedChildEntity, strArrRemoveChildCols);
                                        /*
                                            Below line is must otherwise, "Create" will
result in: FaultException'1 was unhandled. Cannot insert duplicate key.
                                        */
                                        clonedChildEntity.Id = Guid.NewGuid();
                                        newChildEntityRecordId = _crmService.Create(clonedChildEntity);
                                    }
                            #endregion
                        }
                    }
                    return parentEntity.Id;
                }
          
                 //Method to remove attributes from entity.
                private void RemoveEntityAttributes(ref Microsoft.Xrm.Sdk.Entity inputEntity, string[] strArrRemoveCols)
                {
                    for (int intLoop = 0; intLoop < strArrRemoveCols.Length; intLoop++)
                    {
                        inputEntity.Attributes.Remove(strArrRemoveCols[intLoop]);
                    }
                }
        #endregion

 Happy Programming.... :)