locked
oData: how do I retrieve the GUID of a record returned by a query? RRS feed

  • Question

  • Hi there,

    I need to fetch the GUID of a parent account for a contact through the use of JScript.

    Through oData, I managed to fetch the correct record as follows:

    	if(Xrm.Page.getAttribute("customerid").getValue()!=null) {
    		if(Xrm.Page.getAttribute("customerid").getValue()[0].typename=="contact") {
    		alert ("this op is bound to a contact");
    		
    		var idCustomer = Xrm.Page.getAttribute("customerid").getValue()[0].id;
    		
    		var retrieveRecordsReq = new XMLHttpRequest();
    		var ODataPath = Xrm.Page.context.getServerUrl() + "/XRMServices/2011/OrganizationData.svc";
    		var filter = "/ContactSet?$filter=parentcustomerid/Id eq guid'" + idCustomer + "'";

    However I am mot sure how I could proceed from here to fetch the GUID of the parent account and store it in a variable. Could someone please advise?

    Regards,
    P.


    MCC, MCT, MCP, MCTS
    If you find this post helpful then please "Vote as Helpful". If I helped you with an answer to a question then please "Mark As Answer".

    Monday, April 30, 2012 2:01 PM

Answers

  • Sorry my friend, I did not understand your requirement correctly

    As you need to get parentcustomerid based on contact id we don't need to use filter at all.

    you need to use code like below

    function setOpAccountPerContact() {

    var CRM_FORM_TYPE = Xrm.Page.ui.getFormType();
    if (CRM_FORM_TYPE != 2) { return; }
     
    if(Xrm.Page.getAttribute("customerid").getValue()!=null) {
    if(Xrm.Page.getAttribute("customerid").getValue()[0].typename=="contact") {
    alert
    ("this op is bound to a contact");

    var idCustomer = Xrm.Page.getAttribute("customerid").getValue()[0].id;
     
    var retrieveRecordsReq = new XMLHttpRequest();
      var ODataPath = Xrm.Page.context.getServerUrl() + "/XRMServices/2011/OrganizationData.svc";
        
      // Not sure how to proceed from here. How can I get the GUID for the parent account?
      retrieveRecordsReq.open('GET', ODataPath+"/ContactSet(guid'" + idCustomer + "')",false);
      retrieveRecordsReq.setRequestHeader("Accept", "application/json");
      retrieveRecordsReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
      retrieveRecordsReq.send();

      var records = this.parent.JSON.parse(retrieveRecordsReq.responseText).d;
       alert(records.ParentCustomerId.Id);

    }}}


    Mahain : Check My Blog
    Follow me on Twitter
    Make sure to "Vote as Helpful" and "Mark As Answer",if you get answer of your question.

    • Marked as answer by pmdci Monday, April 30, 2012 5:02 PM
    Monday, April 30, 2012 4:35 PM
    Moderator
  • Hi Mahnder!

    Once again you saved my day :) Here is my final code, which is working beautifully. I also have a workflow that does the same in case the user closes the record without saving the changes.

    The reason for this is because in this implementation I am working on, Opportunities can only be bound to Accounts. I managed to add a JScript to the customerid field to disable users choosing Contacts. However opportunities bound to Contacts could still be created if, for example, a user creates an opportunity from an activity.

    function setOpAccountPerContact() {
    
    	var CRM_FORM_TYPE = Xrm.Page.ui.getFormType();
    	if (CRM_FORM_TYPE != 2) { return; }
      
    	if(Xrm.Page.getAttribute("customerid").getValue()!=null) {
    		if(Xrm.Page.getAttribute("customerid").getValue()[0].typename=="contact") {
    		alert ("This opportunity is bound to a contact. The relationship will automatically change for the contact's parent account.");
    
    		var idCustomer = Xrm.Page.getAttribute("customerid").getValue()[0].id;
    		var retrieveRecordsReq = new XMLHttpRequest();
    		var ODataPath = Xrm.Page.context.getServerUrl() + "/XRMServices/2011/OrganizationData.svc";
        
    		retrieveRecordsReq.open('GET', ODataPath+"/ContactSet(guid'" + idCustomer + "')",false);
    		retrieveRecordsReq.setRequestHeader("Accept", "application/json");
    		retrieveRecordsReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
    		retrieveRecordsReq.send();
    
    		var records = this.parent.JSON.parse(retrieveRecordsReq.responseText).d;
    
    		var lookupValue = new Array(); 
    		lookupValue[0] = new Object();
    		lookupValue[0].id = records.ParentCustomerId.Id;
    		lookupValue[0].name = records.ParentCustomerId.Name; 
    		lookupValue[0].entityType = "account"; 
    		Xrm.Page.getAttribute("customerid").setValue(lookupValue); 
    		
    		}
    	}
    }

    Thanks again for your help!

    Cheers,
    P.

    • Edited by pmdci Monday, April 30, 2012 9:37 PM
    • Marked as answer by pmdci Monday, April 30, 2012 9:38 PM
    Monday, April 30, 2012 5:05 PM
  • Hi Tudor,

    I actually wrote a post in my blog about this. You can check it out here.

    Cheers,
    P.

    • Marked as answer by pmdci Friday, April 12, 2013 9:37 AM
    Thursday, April 11, 2013 10:52 PM

All replies

  • you basically need to plug in the oData call into a request

    this forum has a good piece of code you can burry

    http://social.microsoft.com/Forums/en/crmdevelopment/thread/8d57d177-f990-45b7-9a87-5d5e38dd0b9b

    this code, you can modify a bit to pass in your customerID and change the query to use your filter data

    function updateAccountRecord(Id) {
     var updateAccountReq = new XMLHttpRequest();
    var changes = new Object();
    changes.Name = "Updated Sample";
    changes.Telephone1 = "555-0123";
    changes.AccountNumber = "ABCDEFGHIJ";
    changes.EMailAddress1 = "someone1@example.com";

    updateAccountReq.open("POST", ODataPath + "/AccountSet(guid'" + Id + "')", true);
    updateAccountReq.setRequestHeader("Accept", "application/json");
    updateAccountReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
    updateAccountReq.setRequestHeader("X-HTTP-Method", "MERGE");
    updateAccountReq.onreadystatechange = function () {
      updateAccountReqCallBack(this, Id);
    };
    updateAccountReq.send(JSON.stringify(changes));
    showMessage("updateAccountRecord function END.");
    }

    and this has an ajax version

    http://www.toplinestrategies.com/dotneters/ms-crm/microsoft-crm-2011-update-odata-example/?lang=en

    or this one

    http://technet.microsoft.com/en-us/library/gg309549.aspx


    Ben Hosking
    Check out my CRM Blog
    Linked-In Profile
    Follow Me on Twitter!

    Monday, April 30, 2012 2:32 PM
  • My friend once you executed your request and got result you can fetch parentcustomerid like below

    you need to change your filter like below

    var filter = "/ContactSet?$filter=ParentCustomerId/Id eq guid'" + idCustomer + "'"; // you need to specify schema name not field name

    now let's say your result is stored in RetrievedContact so you need to check like below

    if(RetrievedContact.ParentCustomerId!=null)

    var _Parentcustomer=RetrievedContact.ParentCustomerId;

    let us know if you need anything else


    Mahain : Check My Blog
    Follow me on Twitter
    Make sure to "Vote as Helpful" and "Mark As Answer",if you get answer of your question.

    Monday, April 30, 2012 2:38 PM
    Moderator
  • Hi Mahender,

    I am having problems storing the retrieved contact. I think I am not using the correct functions. Here is my script so far. I am trying to use an alert to show the ParentcustomerId...

    function setOpAccountPerContact() {
    
    	var CRM_FORM_TYPE = Xrm.Page.ui.getFormType();
    	if (CRM_FORM_TYPE != 2) { return; }
      
    	if(Xrm.Page.getAttribute("customerid").getValue()!=null) {
    		if(Xrm.Page.getAttribute("customerid").getValue()[0].typename=="contact") {
    		alert ("this op is bound to a contact");
    		
    		var idCustomer = Xrm.Page.getAttribute("customerid").getValue()[0].id;
    		
    		var retrieveRecordsReq = new XMLHttpRequest();
    		var ODataPath = Xrm.Page.context.getServerUrl() + "/XRMServices/2011/OrganizationData.svc";
    		var filter = "/ContactSet?$filter=ParentCustomerId/Id eq guid'" + idCustomer + "'";
    		
    		// Not sure how to proceed from here. How can I get the GUID for the parent account?
    		retrieveRecordsReq.open('GET', ODataPath+filter, false);
    		retrieveRecordsReq.setRequestHeader("Accept", "application/json");
    		retrieveRecordsReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
    		retrieveRecordsReq.send(null);
    		var records = this.parent.JSON.parse(retrieveRecordsReq.responseText).d;
    		
    		alert(records.ParentCustomerId);
    		
    		}
    	
    	}
    }

    Any ideas?

    Cheers,
    P.


    MCC, MCT, MCP, MCTS
    If you find this post helpful then please "Vote as Helpful". If I helped you with an answer to a question then please "Mark As Answer".

    Monday, April 30, 2012 3:45 PM
  • Hi there, 

    Have you looked through the sample code in the sdk for the example of the retrieve? http://msdn.microsoft.com/en-us/library/gg334427.aspx

    Your XmlHttpRequest object is making a service call asynchronously so you need to create a callback method to get the result back out. Also you do not need to pass anything into the send method:

    function setOpAccountPerContact() {
    
    	var CRM_FORM_TYPE = Xrm.Page.ui.getFormType();
    	if (CRM_FORM_TYPE != 2) { return; }
      
    	if(Xrm.Page.getAttribute("customerid").getValue()!=null) {
    		if(Xrm.Page.getAttribute("customerid").getValue()[0].typename=="contact") {
    		alert ("this op is bound to a contact");
    		
    		var idCustomer = Xrm.Page.getAttribute("customerid").getValue()[0].id;
    		
    		var retrieveRecordsReq = new XMLHttpRequest();
    		var ODataPath = Xrm.Page.context.getServerUrl() + "/XRMServices/2011/OrganizationData.svc";
    		var filter = "/ContactSet?$filter=ParentCustomerId/Id eq guid'" + idCustomer + "'";
    		
    		// Not sure how to proceed from here. How can I get the GUID for the parent account?
    		retrieveRecordsReq.open('GET', ODataPath+filter, false);
    		retrieveRecordsReq.setRequestHeader("Accept", "application/json");
    		retrieveRecordsReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
                    retrieveRecordsReq.onreadystatechange=function () {
            if (this.readyState == 4 /* complete */) {
                 if (this.status == 200) {
                      var returned = JSON.parse(this.responseText).d;
                     successCallback(returned.results);
    }
    }
    };
    		retrieveRecordsReq.send();
    		
    		
    		}
    	
    	}
    }
    
    function successCallback(results){
    //code here
    }

    Also, I'm not quite following your logic. You have a contact id, you are then searching for all contacts who have this contact as its parent? The returned contacts won't have a parent account, they will only have a parent contact. Do you instead want to find the parent account of the specified contact? In which case your REST filter would be:

    \ContactSet(guid'youridhere')?$select=ParentCustomerId

    Hope that helps

    Kirsten

    Monday, April 30, 2012 4:04 PM
  • Hi,

    Thanks for the help with the code.

    About the oData query. As I mentioned, I want to get the GUID of the parent Account for the current contact.

    I am trying make an alert show the GUID of the account for the contact as per your code, but I can't seem to do it. :(

    Here is my code:

    function setOpAccountPerContact() {
    
    	var CRM_FORM_TYPE = Xrm.Page.ui.getFormType();
    	if (CRM_FORM_TYPE != 2) { return; }
      
    	if(Xrm.Page.getAttribute("customerid").getValue()!=null) {
    		if(Xrm.Page.getAttribute("customerid").getValue()[0].typename=="contact") {
    		alert ("this op is bound to a contact");
    		
    		var idCustomer = Xrm.Page.getAttribute("customerid").getValue()[0].id;
    		
    		var retrieveRecordsReq = new XMLHttpRequest();
    		var ODataPath = Xrm.Page.context.getServerUrl() + "/XRMServices/2011/OrganizationData.svc";
    		var filter = "/ContactSet?$filter=ParentCustomerId/Id eq guid'" + idCustomer + "'";
    		
    		// Not sure how to proceed from here. How can I get the GUID for the parent account?
    		retrieveRecordsReq.open('GET', ODataPath+filter, false);
    		retrieveRecordsReq.setRequestHeader("Accept", "application/json");
    		retrieveRecordsReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
    		retrieveRecordsReq.send(null);
    
    		retrieveRecordsReq.onreadystatechange=function () {
    			if (this.readyState == 4 /* complete */) {
    				if (this.status == 200) {
    					var returned = JSON.parse(this.responseText).d;
    					successCallback(returned.results);
    				}
    			}
    		};
    		
    		retrieveRecordsReq.send();
    		
    		
    		}
    	
    	}
    }
    
    function successCallback(results){
    alert(retrieveRecordsReq.ParentCustomerId); // NOT SURE IN WHICH VARIABLE IS THE ParentCustomerId !
    }

    I'm still stuck with this :(

    Thanks for the help,

    P.



    MCC, MCT, MCP, MCTS
    If you find this post helpful then please "Vote as Helpful". If I helped you with an answer to a question then please "Mark As Answer".

    Monday, April 30, 2012 4:29 PM
  • Sorry my friend, I did not understand your requirement correctly

    As you need to get parentcustomerid based on contact id we don't need to use filter at all.

    you need to use code like below

    function setOpAccountPerContact() {

    var CRM_FORM_TYPE = Xrm.Page.ui.getFormType();
    if (CRM_FORM_TYPE != 2) { return; }
     
    if(Xrm.Page.getAttribute("customerid").getValue()!=null) {
    if(Xrm.Page.getAttribute("customerid").getValue()[0].typename=="contact") {
    alert
    ("this op is bound to a contact");

    var idCustomer = Xrm.Page.getAttribute("customerid").getValue()[0].id;
     
    var retrieveRecordsReq = new XMLHttpRequest();
      var ODataPath = Xrm.Page.context.getServerUrl() + "/XRMServices/2011/OrganizationData.svc";
        
      // Not sure how to proceed from here. How can I get the GUID for the parent account?
      retrieveRecordsReq.open('GET', ODataPath+"/ContactSet(guid'" + idCustomer + "')",false);
      retrieveRecordsReq.setRequestHeader("Accept", "application/json");
      retrieveRecordsReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
      retrieveRecordsReq.send();

      var records = this.parent.JSON.parse(retrieveRecordsReq.responseText).d;
       alert(records.ParentCustomerId.Id);

    }}}


    Mahain : Check My Blog
    Follow me on Twitter
    Make sure to "Vote as Helpful" and "Mark As Answer",if you get answer of your question.

    • Marked as answer by pmdci Monday, April 30, 2012 5:02 PM
    Monday, April 30, 2012 4:35 PM
    Moderator
  • Hi Mahnder!

    Once again you saved my day :) Here is my final code, which is working beautifully. I also have a workflow that does the same in case the user closes the record without saving the changes.

    The reason for this is because in this implementation I am working on, Opportunities can only be bound to Accounts. I managed to add a JScript to the customerid field to disable users choosing Contacts. However opportunities bound to Contacts could still be created if, for example, a user creates an opportunity from an activity.

    function setOpAccountPerContact() {
    
    	var CRM_FORM_TYPE = Xrm.Page.ui.getFormType();
    	if (CRM_FORM_TYPE != 2) { return; }
      
    	if(Xrm.Page.getAttribute("customerid").getValue()!=null) {
    		if(Xrm.Page.getAttribute("customerid").getValue()[0].typename=="contact") {
    		alert ("This opportunity is bound to a contact. The relationship will automatically change for the contact's parent account.");
    
    		var idCustomer = Xrm.Page.getAttribute("customerid").getValue()[0].id;
    		var retrieveRecordsReq = new XMLHttpRequest();
    		var ODataPath = Xrm.Page.context.getServerUrl() + "/XRMServices/2011/OrganizationData.svc";
        
    		retrieveRecordsReq.open('GET', ODataPath+"/ContactSet(guid'" + idCustomer + "')",false);
    		retrieveRecordsReq.setRequestHeader("Accept", "application/json");
    		retrieveRecordsReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
    		retrieveRecordsReq.send();
    
    		var records = this.parent.JSON.parse(retrieveRecordsReq.responseText).d;
    
    		var lookupValue = new Array(); 
    		lookupValue[0] = new Object();
    		lookupValue[0].id = records.ParentCustomerId.Id;
    		lookupValue[0].name = records.ParentCustomerId.Name; 
    		lookupValue[0].entityType = "account"; 
    		Xrm.Page.getAttribute("customerid").setValue(lookupValue); 
    		
    		}
    	}
    }

    Thanks again for your help!

    Cheers,
    P.

    • Edited by pmdci Monday, April 30, 2012 9:37 PM
    • Marked as answer by pmdci Monday, April 30, 2012 9:38 PM
    Monday, April 30, 2012 5:05 PM
  • Hi

    I'm pretty new to JScript on CRM and am wondering how the above code is actually used. What I am looking to do is have two fields on the opportunity form one for Customer Contact and one for Customer Account. Basically a user would select the Customer Contact from the lookup Customer Contact and the Customer Account should be automatically populated with the contacts Parent Account...would I need to do something similar to your code to accomplish this?

    Thanks

    Tudor

    Thursday, April 11, 2013 10:42 PM
  • Hi Tudor,

    I actually wrote a post in my blog about this. You can check it out here.

    Cheers,
    P.

    • Marked as answer by pmdci Friday, April 12, 2013 9:37 AM
    Thursday, April 11, 2013 10:52 PM
  • Use the following code, Call the JS functioin RetrieveRecord as shown below and capture the parentcustomerid inside successCallBack function. this is a working a JS and if you can't follwo then let me know.

    OWB.Service.RetrieveRecord(Xrm.Page.data.entity.getId(), Xrm.Page.data.entity.getEntityName, '$select=ParentCustomerId', false, successCallBack, errorCallback);

    if (typeof (OWB) == "undefined")
    { OWB = { __namespace: true }; }

    OWB.Service = {

    RetrieveRecord: function(id, type, systemQueryOptions, async, successCallBack, errorCallback) {
            try {
                var request = new XMLHttpRequest();
                request.open("GET", Xrm.Page.context.getServerUrl() + '/xrmservices/2011/OrganizationData.svc/' + type + "Set" + "(guid'" + id + "')" + systemQueryOptions, async);
                request.setRequestHeader("Accept", "application/json");
                request.setRequestHeader("Content-Type", "application/json; charset=utf-8");

                request.onreadystatechange = function() {
                    if (this.readyState == 4 /* complete */) {
                        if (this.status == 200) {
                            successCallBack(request);
                        } else {
                            errorCallback(OWB.Service._errorHandler(this));
                        }
                    }
                }
                request.send();
            }
            catch (e) {
                errorCallback(_errorHandler(this));
            }
        },

     _errorHandler: function(req) {       
            if (req.status == 12029)
            { return new Error("The attempt to connect to the server failed."); }
            if (req.status == 12007)
            { return new Error("The server name could not be resolved."); }
            var errorText;
            try
            { errorText = JSON.parse(req.responseText).error.message.value; }
            catch (e)
            { errorText = req.responseText }

            return new Error("Error : " +
            req.status + ": " +
            req.statusText + ": " + errorText);
        },
    _namespace: true
    };


    Make sure to "Vote as Helpful" and "Mark As Answer",if you get answer of your question.


    • Proposed as answer by Litonn Thursday, April 11, 2013 11:17 PM
    • Edited by Litonn Thursday, April 11, 2013 11:18 PM
    Thursday, April 11, 2013 11:16 PM
  • hi,

    Use code like this....

    var context;
    var ODataPath;
    function getSvrUrl() {
        var serverUrl = context.getServerUrl();

        if (serverUrl.match(/\/$/))
            serverUrl = serverUrl.substring(0, serverUrl.length - 1);

        return serverUrl;
    }


    function UpdateAmount() {

    context = Xrm.Page.context || GetGlobalContext();
        ODataPath = getSvrUrl() + "/XRMServices/2011/OrganizationData.svc";
        var projectId = Xrm.Page.data.entity.getId();

        var retrieveReq = new XMLHttpRequest();

        retrieveReq.open("GET", ODataPath + "/ymsli_projectSet?$select=ymsli_ymsli_project_ymsli_projectitem_Project/ymsli_Amount" +
      ",ymsli_ymsli_project_ymsli_projectitem_Project/ymsli_EstimatedAmount&$expand" +
      "=ymsli_ymsli_project_ymsli_projectitem_Project&$filter=ymsli_projectId eq guid'" + projectId + "'", true);
        retrieveReq.setRequestHeader("Accept", "application/json");
        retrieveReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        retrieveReq.onreadystatechange = function () {
            retrieveUpdateAmountBack(this);
        };
        retrieveReq.send();
    }


    function retrieveUpdateAmountBack(retrieveReq) {

        if (retrieveReq.readyState == 4 /* complete */) {
            if (retrieveReq.status == 200) //Success
            {
                var Amount = 0.0; var EstAmount = 0.0;
                var responseData = JSON.parse(retrieveReq.responseText).d;
                if (responseData != null && responseData.results != null && responseData.results.length > 0) {
                    for (i = 0; i < responseData.results[0].ymsli_ymsli_project_ymsli_projectitem_Project.results.length; i++) {
                        if (responseData.results[0].ymsli_ymsli_project_ymsli_projectitem_Project.results[i].ymsli_Amount.Value != null)
                            Amount += parseFloat(responseData.results[0].ymsli_ymsli_project_ymsli_projectitem_Project.results[i].ymsli_Amount.Value);
                        if (responseData.results[0].ymsli_ymsli_project_ymsli_projectitem_Project.results[i].ymsli_EstimatedAmount.Value != null)
                            EstAmount += parseFloat(responseData.results[0].ymsli_ymsli_project_ymsli_projectitem_Project.results[i].ymsli_EstimatedAmount.Value);
                    }
                }
                if (Amount > 0)
                    Xrm.Page.data.entity.attributes.get("ymsli_actualcost").setValue(Amount);
                if (EstAmount > 0)
                    Xrm.Page.data.entity.attributes.get("ymsli_estimatedcost").setValue(EstAmount);
            }
        }
        Xrm.Page.getAttribute("ymsli_actualcost").setSubmitMode("always");
        Xrm.Page.getAttribute("ymsli_estimatedcost").setSubmitMode("always");
    }

    Friday, April 12, 2013 4:50 AM