Friday, July 19, 2019

The email must have at least one recipient before it can be sent.



This is the most common exception in Dynamic CRM when sending an email using a workflow. There could be multiple reason for this exception to occur. 

In this blog post I will be discussing how to troubleshoot and identify possible cause for such an exception.

It is only about Recipient (To, CC or BCC)

We have nothing to do with From section of an email, otherwise you will get different error when sending an email. We only need to focus on recipient of an email.

'To' is mandatory among all Recipient.



In workflow designer you might skip To and set only CC or BCC alone or set both CC and BCC, but in run-time you will get an exception.


Recipient entity without an email address


It is always better to check if email field is populated or not in a workflow before we  try to sent an email to either Contact, Account, Lead etc. 

If your business requires sending an email to such entities why not make email as mandatory field.


In above workflow we are verifying if respective entity (Contact in this context) has Email field populated, otherwise we are notifying CRM Admin or Business Owner about missing email address.

Contact Preference set to - Do Not Allow.


Even if Contact, Lead or Account have a valid email address populated in its email field, CRM workflow engine will not consider this as valid recipient if its contact preference is set to Do Not Allow

So it is a good practise that we should always verify such conditions in our workflow steps before we send out an email.



Hope it Helps
Vipin Jaiswal

Thursday, July 18, 2019

Resource not found for the segment - Error while Invoking Action in MS CRM


Verify the following


  • Confirm if action are in in Activated State, under Settings -> Process.
  • Name of the actions are case-sensitive, including the prefix name.
  • Must present and in default customization.
  • Calling of a Global and Entity Specific action is different, refer the code below for a reference.

Calling of Global Action

function CallGlobalCustomAction(){

//get the current organization name
var serverURL = Xrm.Page.context.getClientUrl();

//query to send the request to the global Action
var actionName = "new_MyCustomAction"; // Global Action Unique Name - Also Case Sensitive

//set the current loggedin userid in to _inputParameter of the
var InputParameterValue = Xrm.Page.context.getUserId();

//Pass the input parameters of action
var data = {
    "MyInputParameter": InputParameterValue
};

//Create the HttpRequestObject to send WEB API Request
var req = new XMLHttpRequest();

//Post the WEB API Request 
req.open("POST", serverURL + "/api/data/v8.0/" + actionName, true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");

req.onreadystatechange = function () {
    if (this.readyState == 4 /* complete */) {
        req.onreadystatechange = null;
        if (this.status == 200 || this.status == 204) {
            alert("Action Executed Successfully...");
            //You can get the output parameter of the action with name as given below
            result = JSON.parse(this.response);
            alert(result.MyOutputParameter);
        }
        else {
            var error = JSON.parse(this.response).error;
            alert("Error in Action: " + error.message);
        }
    }
};
//Execute request passing the input parameter of the action 
req.send(window.JSON.stringify(data));
}

Calling of Entity Specific Action

function ExecuteEntitySpecificAction(entityName, entityId, actionName) {
debugger;
var serverURL = Xrm.Page.context.getClientUrl();
var query = entityName + "(" + entityId + ")/Microsoft.Dynamics.CRM." + actionName;
var req = new XMLHttpRequest();
req.open("POST", serverURL + "/api/data/v8.2/" + query, false);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.onreadystatechange = function () {
    if (this.readyState == 4 /* complete */) {
        req.onreadystatechange = null;
        if (this.status == 200) {
            var data = JSON.parse(this.response);
            if (data != null)
                if (data.Result == "True") {
                    alert("Duplicate Quote created...");
                    var windowOptions = {
                        openInNewWindow: true
                    };
                    Xrm.Utility.openEntityForm("quote", data.DuplicateQuoteId, null, windowOptions);
                }
                else
                    alert("Something went wrong while copying Quote. Error: " + data.Result);
        } else {
            var error = JSON.parse(this.response).error;
            alert(error.message);
        }
    }
};
req.send();
}


The calling mechanism can be further simplified for calling custom actions by using Process.js and can be found here. This library simplifies calling custom actions from JavaScript.  Calling custom actions involves creating rather lengthy XML Http Requests and this library simplifies that down to a function call with a couple of parameters.  It also provides callbacks for success and errors.





Tuesday, July 9, 2019

How to get and set value for different datatypes in Dynamic 365 CRM


Let’s first see how many different data types we have in dynamic 365 CRM v9.0


Make sure that when we are defining a method, we should pass execution context as a first parameter.


Below is a complete method in JavaScript code.


function GettingAndSettingValues(context) {

var formContext = context.getFormContext();
// formContext will be used to access form attributes.

debugger;

// Retrieving Form Attribute is same for all Types using getAttribute()
// So here is a list of attribute name which we are trying to get and save value into.

var new_singlelineoftext = formContext.getAttribute("new_singlelineoftext");
var new_optionset = formContext.getAttribute("new_optionset");
var new_multiselectoptionset = formContext.getAttribute("new_multiselectoptionset");
var new_twooptions = formContext.getAttribute("new_twooptions");
var new_wholenumber = formContext.getAttribute("new_wholenumber");
var new_floatingpointnumber = formContext.getAttribute("new_floatingpointnumber");
var new_decimal = formContext.getAttribute("new_decimal");
var new_currency = formContext.getAttribute("new_currency");
var new_multiplelineoftext = formContext.getAttribute("new_multiplelineoftext");
var new_dateandtime = formContext.getAttribute("new_dateandtime");
var new_countryLookup = formContext.getAttribute("new_lookup");


*************************************************************

// Single Line Of Text
if (new_singlelineoftext != null) {
    var tempValue = new_singlelineoftext.getValue();
    if (tempValue != null)
        new_singlelineoftext.setValue(tempValue + " : Appending Text");
    else
        new_singlelineoftext.setValue("New Text");
}

// OptionSet or Drop Down List   
if (new_optionset != null) {
    var internalValue = new_optionset.getValue();

    if (internalValue != null) {
        var optionSelectedValue = new_optionset.getSelectedOption().value;
        var optionSelectedText = new_optionset.getSelectedOption().text;
    }
    else {
        alert("Nothing Selected - So Setting value to Item 2");
        new_optionset.setValue(100000001);
    }
}

// Multi-Select OptionSet
if (new_multiselectoptionset != null) {
    var selectedValue = new_multiselectoptionset.getValue();

    if (selectedValue != null) {
        var allSelectedOptions = new_multiselectoptionset.getSelectedOption();
        for (var i = 0; i < allSelectedOptions.length; i++) {
            var text = allSelectedOptions[i].text;
            var value = allSelectedOptions[i].value;
        }
    }
    else {
        // Setting some default Value for nothing selected
        new_multiselectoptionset.setValue([100000001, 100000002]);
    }
           
}

// Two OptionSet - Boolean
if (new_twooptions != null) {
    var selectedValue = new_optionset.getValue();

    if (selectedValue != null) {
        if (selectedValue == true)
            alert("TRUE");
        else
            alert("Its False");
    }
    new_twooptions.setValue(true);
}

// Whole-Number
if (new_wholenumber != null) {
    var inputNumber = new_wholenumber.getValue();
    if (inputNumber != null)
        new_wholenumber.setValue(inputNumber + 10);
}

// Floating Point Number
if (new_floatingpointnumber != null) {
    var inputNumber = new_floatingpointnumber.getValue();
    if (inputNumber != null)
        new_floatingpointnumber.setValue(inputNumber + 10);

}
// Decimal Number
if (new_decimal != null) {
    var inputNumber = new_decimal.getValue();
    if (inputNumber != null)
        new_decimal.setValue(inputNumber + 10);
}

// Currency Type
if (new_currency != null) {
    var currencyValue = new_currency.getValue();
    if (currencyValue != null)
        new_currency.setValue(currencyValue + 10);
}

// Multiple-Line-Of-Text
if (new_multiplelineoftext != null) {
    var tempValue1 = new_multiplelineoftext.getValue();
    if (tempValue1 != null)
        new_multiplelineoftext.setValue(tempValue1 + " : Appending Text");
    else
        new_multiplelineoftext.setValue("New Text");
}

// Date and Time
if (new_dateandtime != null) {
    var tempdate = new_dateandtime.getValue();
    if (tempdate != null) // if Not set to 1 day after current set day
        new_dateandtime.setValue(tempdate.setDate(tempdate.getDate() + 1));
    else
        new_dateandtime.setValue(new Date());
}

// Lookup
if (new_countryLookup != null) {
    countryLookupValue = new_countryLookup.getValue();
    if (countryLookupValue != null) {
        var entityTypeCode = countryLookupValue[0].type;
        var entityTypeName = countryLookupValue[0].entityType;
        var entityId = countryLookupValue[0].id.replace("{", "").replace("}", "");
        var entityText = countryLookupValue[0].name;
    }
}

        Xrm.Page.getAttribute("uomid").setValue([{ id: "69DAC10E-96BC-4F84-8BE9-29F84FF4401C", name: "Default Unit", entityType: "uomschedule" }]); // Unit Group

Xrm.Page.getAttribute("ownerid").setValue([{ id: createdUser[0].id, name: createdUser[0].name, entityType: "systemuser" }]);

// Its a good habit to explicity tell Dynamic CRM to save value, which are change via Javascript Code

new_singlelineoftext.setSubmitMode('always');
new_optionset.setSubmitMode('always');
new_multiselectoptionset.setSubmitMode('always');
new_twooptions.setSubmitMode('always');
new_wholenumber.setSubmitMode('always');
new_floatingpointnumber.setSubmitMode('always');
new_decimal.setSubmitMode('always');
new_currency.setSubmitMode('always');
new_multiplelineoftext.setSubmitMode('always');
new_dateandtime.setSubmitMode('always');
new_countryLookup.setSubmitMode('always');
}