locked
CRM 2011 populate primary contact when creating new phone call RRS feed

  • Question

  • Hello,

    I am trying to figure out a way to get the primary contact to populate the Receipent field when selecting new call from the accounts form.

    Any input would be appreciated.

    Thanks,

    Chris

    Monday, July 8, 2013 9:52 PM

Answers

  • Nick's code is a good starting point, a full implementation can be this one (call the function inside the OnLoad event for Phone Call entity)

    function ChangePhoneCallRecipientFromAccountToPrimaryContact() {
        // check if is a new phone call
        if (Xrm.Page.ui.getFormType() == 1) {
            // get the Phone Call To Recipient
            var to = Xrm.Page.getAttribute("to").getValue();
            // if the Recipient is an account we continue
            if (to != null && to[0].entityType == "account") {
                // get the account Id
                var accountId = to[0].id;    
                // get the right url for the OData Query
                var serverUrl;
                if (Xrm.Page.context.getClientUrl !== undefined) {
                    serverUrl = Xrm.Page.context.getClientUrl();
                } else {
                    serverUrl = Xrm.Page.context.getServerUrl();
                }
                // build the request
                var ODataPath = serverUrl + "/XRMServices/2011/OrganizationData.svc"; 
                var accountRequest = new XMLHttpRequest();
                accountRequest.open("GET", ODataPath + "/AccountSet(guid'" + accountId + "')", false); 
                accountRequest.setRequestHeader("Accept", "application/json"); 
                accountRequest.setRequestHeader("Content-Type", "application/json; charset=utf-8");
                // execute the request
                accountRequest.send();
                if (accountRequest.status === 200) {
                    var retrievedAccount = JSON.parse(accountRequest.responseText).d;
                    // retrieve the primary contact of the account
                    var primaryContact = retrievedAccount.PrimaryContactId;
                    // if there is a primary contact we set as new To Recipient
                    if (primaryContact.Id != null) {
                        var newTo = new Array();
                        newTo[0] = new Object();
                        newTo[0].id = primaryContact.Id;
                        newTo[0].name = primaryContact.Name;
                        newTo[0].entityType = primaryContact.LogicalName;
                        Xrm.Page.getAttribute("to").setValue(newTo);
                    }
                }
                else {
                    alert("error");
                }
            }
        }
    }


    My blog: www.crmanswers.net


    Tuesday, July 9, 2013 2:49 PM
  • I think this does what  you want.  It sets the regarding on the created phone call to the parent customer associated with the contact record that was originally set as the regarding.

    // This function should execute on load of the phone call form
    function PhoneCallPopulateContact() {
    
        // Check form type
        if (Xrm.Page.ui.getFormType() !== 1) {
            // Not create form type
            return;
        }
        
        // Get the regarding 
        var regarding = Xrm.Page.getAttribute("regardingobjectid").getValue();    
        if (!regarding || !regarding[0] || (regarding[0].typename !== "contact")) {
            // Regarding is not an contact
            return;
        }
        
        // Build REST service URL
        var restUrl = "/XRMServices/2011/OrganizationData.svc/ContactSet(guid'" + regarding[0].id.replace(/\{|\}/g, "") + "')?$select=ParentCustomerId";
        restUrl = Xrm.Page.context.prependOrgName(restUrl);
        
        // Execute REST service call
        var request = new XMLHttpRequest();
        request.open("GET", restUrl, false);
        request.setRequestHeader("Accept", "application/json");
        request.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        request.send();
        
        // An error occurred in the REST request
        if (request.status !== 200) {
            alert("error");
        }
        
        // Parse the REST response
        var response = JSON.parse(request.responseText);
        var parentCustomer = response && response.d && response.d.ParentCustomerId;
    
        // Set the recipient field
        if (!parentCustomer || !parentCustomer.Id) { 
            // Parent Customer is not set on contact  
            return;
        }
        
        // Set the party list field, i.e. recipient
        Xrm.Page.getAttribute("regardingobjectid").setValue([{
            id: parentCustomer.Id,
            name: parentCustomer.Name,
            typename: parentCustomer.LogicalName
        }]);
        
    }
    PhoneCallPopulateContact();


    Nick

    • Marked as answer by chrisc543-1 Tuesday, July 9, 2013 5:02 PM
    Tuesday, July 9, 2013 4:54 PM

All replies

  • The easiest way to accomplish this is to write a script on the load of the phone call form that would retrieve the value of the primary contact from the referenced regarding record if the form is a create form and the regarding record is an account. 

    You could also do this by passing a custom query string parameter to the phone call form, but that would require a lot more customizations including ribbon customizations to override the buttons that create phone call activities.  Unfortunately, because the recipient field is a party list lookup it cannot be set directly with a query string parameter and you would also need custom logic on the form to process the custom query string parameter.


    Nick

    Tuesday, July 9, 2013 12:03 PM
  • Nick, Thanks for the reply. So this is what I came up with does this look right?

    function PhoneCallPopulate()
    {
                        
     try
     
     {
      if (Xrm.Page.getAttribute("primarycontactid").getValue() != null) {
       var contactvar = Xrm.Page.getAttribute("primarycontactid").getValue()[0].name;
       Xrm.Page.getAttribute("to").setValue("contactvar");
     } 

     }
     catch(e) {}
    }

    Thanks,

    Chris

    Tuesday, July 9, 2013 1:39 PM
  • Well that does nothing. I am thinking I am missing how to lookup into the other record. I am not sure how to call for the account record to get the primarycontactid and then push to the phone call form. Any help is appreciated.
    Tuesday, July 9, 2013 1:50 PM
  • Hi,
    Setting a PartyList is not in the way you have used. The party lists are multi entity type lookups. The "To" fields are also party lists. To set a party list using a JavaScript function use the function below:
    function PartyListSet() {
       var Party = new Array();
       Party[0] = new Object();
       Party[0].id = id;
       Party[0].name = name;
       Party[0].entityType = entitytypename; //the schema name of the entity which you want to set
       Xrm.Page.getAttribut("to").setValue(Party);
    }


    My Weblog | My Website

    Tuesday, July 9, 2013 2:14 PM
    Moderator
  • You will need to retrieve the data using one of the CRM services.  The easiest way is to use the rest service.  There is more information on using the REST service endpoint in the SDK here.  Your script should look something like the following.


    // This function should execute on load of the phone call form
    function PhoneCallPopulate() {
    
        // Check form type
        if (Xrm.Page.getFormType !== 1) {
            // Not create form type
            return;
        }
        
        var regarding = Xrm.Page.getAttribute("regardingobjectid").getValue();
        
        if (!regarding || !regarding[0] || (regarding[0].typename !== "account")) {
            // Regarding is not an account
            return;
        }
        
        // Build REST service URL
        var restUrl = "/XRMServices/2011/OrganizationData.svc/AccountSet(guid'" + regarding[0].id.replace(/\{|\}/g, "") + "')?$select=PrimaryContactId";
        
        // Execute REST service call
        // Use XMLHTTPRequest and JSON to retrieve and deserialize primary contact from account record
        // Set primaryContact variable as PrimaryContactId field
        
    
        // Set the recipient field
        if (!primaryContact || !primaryContact.Id) { 
            // Primary Contact is not set on account       
        }
        
        // Set the party list field, i.e. recipient
        Xrm.Page.getAttribute("recipient").setValue([{
            id: primaryContact.Id,
            name: primaryContact.Name,
            entityType: primaryContact.LogicalName
        }]);
        
    }



    Nick


    Tuesday, July 9, 2013 2:19 PM
  • Nick's code is a good starting point, a full implementation can be this one (call the function inside the OnLoad event for Phone Call entity)

    function ChangePhoneCallRecipientFromAccountToPrimaryContact() {
        // check if is a new phone call
        if (Xrm.Page.ui.getFormType() == 1) {
            // get the Phone Call To Recipient
            var to = Xrm.Page.getAttribute("to").getValue();
            // if the Recipient is an account we continue
            if (to != null && to[0].entityType == "account") {
                // get the account Id
                var accountId = to[0].id;    
                // get the right url for the OData Query
                var serverUrl;
                if (Xrm.Page.context.getClientUrl !== undefined) {
                    serverUrl = Xrm.Page.context.getClientUrl();
                } else {
                    serverUrl = Xrm.Page.context.getServerUrl();
                }
                // build the request
                var ODataPath = serverUrl + "/XRMServices/2011/OrganizationData.svc"; 
                var accountRequest = new XMLHttpRequest();
                accountRequest.open("GET", ODataPath + "/AccountSet(guid'" + accountId + "')", false); 
                accountRequest.setRequestHeader("Accept", "application/json"); 
                accountRequest.setRequestHeader("Content-Type", "application/json; charset=utf-8");
                // execute the request
                accountRequest.send();
                if (accountRequest.status === 200) {
                    var retrievedAccount = JSON.parse(accountRequest.responseText).d;
                    // retrieve the primary contact of the account
                    var primaryContact = retrievedAccount.PrimaryContactId;
                    // if there is a primary contact we set as new To Recipient
                    if (primaryContact.Id != null) {
                        var newTo = new Array();
                        newTo[0] = new Object();
                        newTo[0].id = primaryContact.Id;
                        newTo[0].name = primaryContact.Name;
                        newTo[0].entityType = primaryContact.LogicalName;
                        Xrm.Page.getAttribute("to").setValue(newTo);
                    }
                }
                else {
                    alert("error");
                }
            }
        }
    }


    My blog: www.crmanswers.net


    Tuesday, July 9, 2013 2:49 PM
  • Thanks Nick. I just implemented and have not change. It does not change the recipient. Not sure how to debug as it didn't through a javascript error.
    Tuesday, July 9, 2013 4:10 PM
  • Did you implement the REST service call?  I didn't put that piece in there... thought I would leave you something to chew on.  Here is a more complete example with the REST service call in place.

    // This function should execute on load of the phone call form
    function PhoneCallPopulate() {
    
        // Check form type
        if (Xrm.Page.getFormType !== 1) {
            // Not create form type
            return;
        }
        
        // Get the regarding 
        var regarding = Xrm.Page.getAttribute("regardingobjectid").getValue();    
        if (!regarding || !regarding[0] || (regarding[0].typename !== "account")) {
            // Regarding is not an account
            return;
        }
        
        // Build REST service URL
        var restUrl = "/XRMServices/2011/OrganizationData.svc/AccountSet(guid'" + regarding[0].id.replace(/\{|\}/g, "") + "')?$select=PrimaryContactId";
        restUrl = Xrm.Page.context.prependOrgName(restUrl);
        
        // Execute REST service call
        var request = new XMLHttpRequest();
        request.open("GET", restUrl, false);
        request.setRequestHeader("Accept", "application/json");
        request.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        request.send();
        
        // An error occurred in the REST request
        if (request.status !== 200) {
            alert("error");
        }
        
        // Parse the REST response
        var response = JSON.parse(request.responseText);
        var primaryContact = response && response.d && response.d.PrimaryContactId;
    
        // Set the recipient field
        if (!primaryContact || !primaryContact.Id) { 
            // Primary Contact is not set on account  
            return;
        }
        
        // Set the party list field, i.e. recipient
        Xrm.Page.getAttribute("recipient").setValue([{
            id: primaryContact.Id,
            name: primaryContact.Name,
            typename: primaryContact.LogicalName
        }]);
        
    }
    


    Nick

    Tuesday, July 9, 2013 4:20 PM
  • Thanks it worked. but not they requested that it also does from contact to set regarding the account. Otherwise it doesn't show up in the activities of the account. I'm not good at coding and not even able to follow what exactly is happening here. But basically doing this same thing from contacts and have the regarding read the account name.
    Tuesday, July 9, 2013 4:26 PM
  • Sorry, I had a bug in there.  Here is an update.

    // This function should execute on load of the phone call form
    function PhoneCallPopulate() {
    
        // Check form type
        if (Xrm.Page.ui.getFormType() !== 1) {
            // Not create form type
            return;
        }
        
        // Get the regarding 
        var regarding = Xrm.Page.getAttribute("regardingobjectid").getValue();    
        if (!regarding || !regarding[0] || (regarding[0].typename !== "account")) {
            // Regarding is not an account
            return;
        }
        
        // Build REST service URL
        var restUrl = "/XRMServices/2011/OrganizationData.svc/AccountSet(guid'" + regarding[0].id.replace(/\{|\}/g, "") + "')?$select=PrimaryContactId";
        restUrl = Xrm.Page.context.prependOrgName(restUrl);
        
        // Execute REST service call
        var request = new XMLHttpRequest();
        request.open("GET", restUrl, false);
        request.setRequestHeader("Accept", "application/json");
        request.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        request.send();
        
        // An error occurred in the REST request
        if (request.status !== 200) {
            alert("error");
        }
        
        // Parse the REST response
        var response = JSON.parse(request.responseText);
        var primaryContact = response && response.d && response.d.PrimaryContactId;
    
        // Set the recipient field
        if (!primaryContact || !primaryContact.Id) { 
            // Primary Contact is not set on account  
            return;
        }
        
        // Set the party list field, i.e. recipient
        Xrm.Page.getAttribute("to").setValue([{
            id: primaryContact.Id,
            name: primaryContact.Name,
            typename: primaryContact.LogicalName
        }]);
        
    }
    


    Nick

    Tuesday, July 9, 2013 4:27 PM
  • Thanks Nick for giving me something to chew on. I am so below this though. I am a network engineer that is interested in programming. I started a C++ book and getting some concepts down but the javascript is what I need to know as ourselves and other customers using CRM. with help from guys like you I have been able to get somewhere but the first one I did was much similar than this. It only had the get and set for the two fields. This has some logic in it and confusing me. I am trying to edit what you gave to do the same on the contact phone call so if phone call made from contact it will set regarding the account. This is what I cam up with but not sure if or how it will work. I am not sure where you get the party list fields from.

    // This function should execute on load of the phone call form
    function PhoneCallPopulateContact() {

        // Check form type
        if (Xrm.Page.ui.getFormType() !== 1) {
            // Not create form type
            return;
        }
       
        // Get the regarding
        var regarding = Xrm.Page.getAttribute("regardingobjectid").getValue();   
        if (!regarding || !regarding[0] || (regarding[0].typename !== "PrimaryContactId")) {
            // Regarding is not an contact
            return;
        }
       
        // Build REST service URL
        var restUrl = "/XRMServices/2011/OrganizationData.svc/AccountSet(guid'" + regarding[0].id.replace(/\{|\}/g, "") + "')?$select=account";
        restUrl = Xrm.Page.context.prependOrgName(restUrl);
       
        // Execute REST service call
        var request = new XMLHttpRequest();
        request.open("GET", restUrl, false);
        request.setRequestHeader("Accept", "application/json");
        request.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        request.send();
       
        // An error occurred in the REST request
        if (request.status !== 200) {
            alert("error");
        }
       
        // Parse the REST response
        var response = JSON.parse(request.responseText);
        var primaryAccount = response && response.d && response.d.account;

        // Set the recipient field
        if (!primaryAccount || !primaryContact.Id) {
            // Primary Contact is not set on account 
            return;
        }
       
        // Set the party list field, i.e. recipient
        Xrm.Page.getAttribute("to").setValue([{
            id: primaryContact.Id,
            name: primaryContact.Name,
            typename: primaryContact.LogicalName
        }]);
       
    }

    Tuesday, July 9, 2013 4:47 PM
  • I think this does what  you want.  It sets the regarding on the created phone call to the parent customer associated with the contact record that was originally set as the regarding.

    // This function should execute on load of the phone call form
    function PhoneCallPopulateContact() {
    
        // Check form type
        if (Xrm.Page.ui.getFormType() !== 1) {
            // Not create form type
            return;
        }
        
        // Get the regarding 
        var regarding = Xrm.Page.getAttribute("regardingobjectid").getValue();    
        if (!regarding || !regarding[0] || (regarding[0].typename !== "contact")) {
            // Regarding is not an contact
            return;
        }
        
        // Build REST service URL
        var restUrl = "/XRMServices/2011/OrganizationData.svc/ContactSet(guid'" + regarding[0].id.replace(/\{|\}/g, "") + "')?$select=ParentCustomerId";
        restUrl = Xrm.Page.context.prependOrgName(restUrl);
        
        // Execute REST service call
        var request = new XMLHttpRequest();
        request.open("GET", restUrl, false);
        request.setRequestHeader("Accept", "application/json");
        request.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        request.send();
        
        // An error occurred in the REST request
        if (request.status !== 200) {
            alert("error");
        }
        
        // Parse the REST response
        var response = JSON.parse(request.responseText);
        var parentCustomer = response && response.d && response.d.ParentCustomerId;
    
        // Set the recipient field
        if (!parentCustomer || !parentCustomer.Id) { 
            // Parent Customer is not set on contact  
            return;
        }
        
        // Set the party list field, i.e. recipient
        Xrm.Page.getAttribute("regardingobjectid").setValue([{
            id: parentCustomer.Id,
            name: parentCustomer.Name,
            typename: parentCustomer.LogicalName
        }]);
        
    }
    PhoneCallPopulateContact();


    Nick

    • Marked as answer by chrisc543-1 Tuesday, July 9, 2013 5:02 PM
    Tuesday, July 9, 2013 4:54 PM
  • Nick,

    It sure does. My edit was not very accurate at all. Thanks for all the help. Hopefully someday I will get a better grasp on the REST requests.

    How do you guys test them and make sure they will work?

    • Edited by chrisc543-1 Tuesday, July 9, 2013 5:06 PM question
    Tuesday, July 9, 2013 5:03 PM
  • You can use the debugger tools that come with IE or other browsers.  F12 will bring up a debugger window in IE and you can start debugging by going to the script tag.  Then you can set a breakpoint where needed or put in a debugger statement that will cause the debugger to break at that point.

    Nick

    Tuesday, July 9, 2013 5:26 PM