1. Defaulting the Opportunity Price List

The first step for recording any kind of sale in MSCRM is to specify which Price List the sale will fall into – by default; this is a manual step for the Salesperson to determine which Price List he or she will be using to sell the Products involved.

Often however, this is a simple option of picking the single current Price List and so does not involve any real selection and so becomes a system-enforced step which reduces the usability of the MSCRM deployment which can result in more difficult user-adoption.

To remove this step, the following script can be added to the Opportunity onLoad function to automatically select the current Price List for the new Sales Opportunity.

//------------------------------FUNCTIONS-------------------------

function htmlEncode(source, display, tabs) {
    function special(source) {
        var result = '';
        for (var i = 0; i < source.length; i++) {
            var c = source.charAt(i);
            if (c < ' ' || c > '~') {
                c = '&#' + c.charCodeAt() + ';';
            }
            result += c;
        }
        return result;
    }

    function format(source) {
        // Use only integer part of tabs, and default to 4
        tabs = (tabs >= 0) ? Math.floor(tabs) : 4;
        // split along line breaks
        var lines = source.split(/\r\n|\r|\n/);

        // expand tabs
        for (var i = 0; i < lines.length; i++) {
            var line = lines[i];
            var newLine = '';
            for (var p = 0; p < line.length; p++) {
                var c = line.charAt(p);
                if (c === '\t') {
                    var spaces = tabs - (newLine.length % tabs);
                    for (var s = 0; s < spaces; s++) {
                        newLine += ' ';
                    }
                }
                else {
                    newLine += c;
                }
            }
            // Leading or ending spaces will be removed from a HTML Request, unless flagged as a nbsp type character
            newLine = newLine.replace(/(^ )|( $)/g, '&nbsp;');
            lines[i] = newLine;
        }
        // re-join lines
        var result = lines.join('<br />');
        // break up contiguous blocks of spaces with non-breaking spaces
        result = result.replace(/  /g, ' &nbsp;');

        return result;
    }
    var result = source;

    // ampersands (&)
    result = result.replace(/\&/g, '&amp;');
    // less-thans (<)
    result = result.replace(/\</g, '&lt;');
    // greater-thans (>)
    result = result.replace(/\>/g, '&gt;');

    if (display) {
        // format for display
        result = format(result);
    }
    else {
        // Replace quotes if it isn't for display,
        // since it's probably going in an html attribute.
        result = result.replace(new RegExp('"', 'g'), '&quot;');
    }

    result = special(result);
    return result;
}

FetchXmlResponse = function(fetchXml) {
    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\">" +
            GenerateAuthenticationHeader() +
            "<soap:Body>" +
                "<Fetch xmlns=\"http://schemas.microsoft.com/crm/2007/WebServices\">" +
                    "<fetchXml>" + htmlEncode(fetchXml) + "</fetchXml>" +
                "</Fetch>" +
            "</soap:Body>" +
        "</soap:Envelope>";


    var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
    xmlHttpRequest.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
    xmlHttpRequest.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2007/WebServices/Fetch");
    xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
    xmlHttpRequest.setRequestHeader("Content-Length", xml.length);

    xmlHttpRequest.send(xml);

    return xmlHttpRequest.responseXML;
}

FetchPriceList = function() {
    var productId;
    var assume = true;
    
    var fetchXml =
            "<fetch mapping=\"logical\">" +
                "<entity name=\"pricelevel\">" +
                    "<attribute name=\"name\" />" +
                    "<attribute name=\"pricelevelid\" />" +
                    "<filter>" +
                        "<condition attribute=\"statecode\" operator=\"eq\" value=\"" + "0" + "\" />" +
                    "</filter>" +
                "</entity>" +
            "</fetch>";

    if (assume == true) {
        var resultXml = FetchXmlResponse(fetchXml);

        var oXmlDoc = new ActiveXObject("Microsoft.XMLDOM");
        oXmlDoc.async = false;
        oXmlDoc.loadXML(resultXml.text);

        var pricelevel_name = oXmlDoc.getElementsByTagName('name');
        var pricelevel_pricelevelid = oXmlDoc.getElementsByTagName('pricelevelid');

        if (pricelevel_pricelevelid != null) {
            var lookupData = new Array();
            var lookupItem = new Object();

            // Set the id, typename, and name properties to the object.
            lookupItem.id = pricelevel_pricelevelid[0].text;
            lookupItem.typename = 'pricelevel';
            lookupItem.name = pricelevel_name[0].text;
            lookupData[0] = lookupItem;
            crmForm.all.pricelevelid.DataValue = lookupData;
        }
    }
}

//-------------------------------------MAIN-------------------------------

if (( crmForm.FormType == 1 ) && (crmForm.all.pricelevelid.DataValue == null))
{
  FetchPriceList();
}

2 Responses to 1. Defaulting the Opportunity Price List

  1. Laura says:

    Hi there, my customer has a price list for each currency. Would you still use fetch for this or would you need to look at retrieve or retrieve multiple?

    • You could keep this as a simple Retrieve with a condition for the Currency Code added:

      “” +
      “” +
      “” +
      “” +

      You probably would only need to perform a Retrieve Multiple if you had more than 1 Price List within each Currency – say for starting Price Lists with a Start Date and End Date for example.

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 )

Google+ photo

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

Connecting to %s