Setting the default unit for opportunity, quote and salesorder-product in CRM 2011 using JavaScript

June 27, 2011

For any product in the product catalog you have to define the default unit in which the product is usually sold. In more than 90% of all cases I guess the default unit is used for opportunities, quotes or salesorder. So quite often there is the requirement, that the unit should be populated with the products default unit after the product is chosen.
Now the approach is quite straight forward: attach to the productid fields onChange event, get the default unit from the product and populate the uomid field.
While in CRM 4.0 you could set the field directly in the onChange event, this approach does no longer work for CRM2011. It seems, Microsoft changed the behaviour here, so that first your custom code is executed and afterwards the uom field (and the amount) is cleared.
What you have to do is adding a slight delay to the event, so that your code is executed after the built-in onChange handler of the product. We found 100ms to be good value, since it’s enough for the built-in logic to execute, but small enough that the user won’t notice a delay.

function ProductOnChange_SetUOM() {
// This is the fields onChange handler. Here we add a delay of 100ms before the actual logic is executed.
window.setTimeout(“SetUomId()”, 100);
}

function SetUomId() {
// Actual logic goes here.
}

Advertisement

2 Responses to “Setting the default unit for opportunity, quote and salesorder-product in CRM 2011 using JavaScript”

  1. Yvan L. said

    Hi,

    I’m not too familiar with Javascript and I always get the following message for the ProductOnChange_SetUOM function.

    Javascript Error : Is Null or Not an Object Scripting

    On the Existing Product field onChange event, do I have to call the SetUOM function as well or the timeout funtion will do it itself?

    Should I put the SetUOM function in a different web resource?

    Here is my script :

    function ProductOnChange()
    {
    // This is the fields onChange handler. Here we add a delay of 100ms before the actual logic is executed.
    window.setTimeout(“setdefaultunit2()”, 100);
    }

    function setdefaultunit2()
    {
    //Create an array to set as the DataValue for the lookup control.
    var lookupData2 = new Array();
    //Create an Object add to the array.
    var lookupItem2= new Object();
    //Set the id, typename, and name properties to the object.
    lookupItem2.id = ‘{CE9C52A7-D978-4500-B562-6D7C6E85F09F}’;
    lookupItem2.typename = ‘uom’;
    lookupItem2.name = ‘Primary Unit’;
    // Add the object to the array.
    lookupData2[0] = lookupItem2;
    // Set the value of the lookup field to the value of the array.
    crmForm.all.uomid.DataValue = lookupData2
    }

    Thanks for the help!

    Yvan

    • Frank Bursitzke said

      Here is the complete code, in the OnChange Event you would just call the ProductOnChange_SetUOM function, the rest is done by the Timeout:


      function ProductOnChange_SetUOM() {
      var c = new ProductUomInfo();
      if (crmForm.all.productid.DataValue != null && crmForm.all.productid.DataValue.length > 0) {
      window.setTimeout("SetUomId()", 100);
      }
      }

      function SetUomId() {
      var guid = crmForm.all.productid.DataValue[0].id;
      c = RetrieveProductUomInfo(guid);
      var uomlookup = new Array();
      uomlookup[0] = new LookupControlItem(c.defaultuomid, c.defaultuomidtype, c.defaultuomidname);
      Xrm.Page.getAttribute('uomid').setValue(uomlookup);
      }

      ProductUomInfo = function () {
      this.defaultuomid = null;
      this.defaultuomidname = null;
      this.defaultuomidtype = 1055;
      this.name = "";
      }

      function RetrieveProductUomInfo(guid) {
      // generate Authentication header
      var authenticationHeader = GenerateAuthenticationHeader();

      // define xml command
      var xml = "<?xml version='1.0' encoding='utf-8'?>" +
      "<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'>" +
      authenticationHeader +
      "<soap:Body>" +
      "<Retrieve xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>" +
      "<entityName>product</entityName>" +
      "<id>" + guid + "</id>" +
      "<columnSet xmlns:q1='http://schemas.microsoft.com/crm/2006/Query' xsi:type='q1:ColumnSet'>" +
      "<q1:Attributes>" +
      "<q1:Attribute>defaultuomid</q1:Attribute>" +
      "<q1:Attribute>name</q1:Attribute>" +
      "</q1:Attributes>" +
      "</columnSet>" +
      "</Retrieve>" +
      "</soap:Body>" +
      "</soap:Envelope>";
      // Prepare the xmlHttpObject and send the request.
      var xHReq = new ActiveXObject("Msxml2.XMLHTTP");
      xHReq.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
      xHReq.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2007/WebServices/Retrieve");
      xHReq.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
      xHReq.setRequestHeader("Content-Length", xml.length);
      xHReq.send(xml);

      var resultXml = xHReq.responseXML;
      var c = new ProductUomInfo();

      if (resultXml.selectSingleNode('//q1:defaultuomid') != null) {
      c.defaultuomid = resultXml.selectSingleNode('//q1:defaultuomid').nodeTypedValue;
      c.defaultuomidname = resultXml.selectSingleNode('//q1:defaultuomid').getAttribute('name');
      //c.defaultuomidtype = resultXml.selectSingleNode('//q1:defaultuomid').getAttribute('type');
      }

      if (resultXml.selectSingleNode('//q1:name') != null)
      { c.name = resultXml.selectSingleNode('//q1:name').nodeTypedValue; }

      return c;
      }

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.