Friday, May 31, 2019

How to pass and retrieve custom data to a WebResource in Dynamic 365 CRM


Below blog uses deprecated method so I created another one to launch a webresource and pass parameter to it refer here... it uses navigateTo method

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

We all know the concept of querystring parameters in Url. The easiest and visible way to pass the small chunks of data to a webpage.

Here is sample querystring:
https://vjcity.crm4.dynamics.com//WebResources/cm_/html/Dymolabelprinter/vjLabDymo.html?accountId=EEA310A9-8483-E911-A85F-000D3AB0DC71&entitytypename=account


window.open(url) : Not working !!!
Reason: 
  • When we create any new webresource, CRM generates the Url automatically for us without any parameters and CRM know only that registered webresource.
  • When we try to browse the Url using window.open with querystring parameter, it searches the whole string against the registered webresource and throws an 500 error as say webresource not found.

Therefore Dynamic CRM has come up with - Xrm.Utility.openWebResource

Here is an example to understand how to pass custom parameters

function passParameters(accountId)
{
    var webResource = "cm_/html/Dymolabelprinter/NeoLabDymo.html"; // webresource schema name
    var customParameters = encodeURIComponent("entityId=" + accountId + "&entitytypename=account");
    Xrm.Utility.openWebResource(webResource, customParameters);
}


How to retrieve them within webpage


var entityId = getUrlVars()["entityId"];
var entityName = getUrlVars()["entitytypename"];



// Read a page's GET URL variables and return them as an associative array.
function getUrlVars()
{
    var vars = [], hash;
    var hashes = unescape(window.location.search.replace('?', ''));
    hashes = hashes.replace('Data=', '').replace('data=', '').split(',');
    for (var i = 0; i < hashes.length; i++)
    {
        hash = hashes[i].split('=');
        vars.push(hash[0]);
        vars[hash[0]] = hash[1];
    }
    return vars;
}

As CRM append querystring data to the Url, it also appends data by default, we might want to get rid of that and just interested in the parameters that we have passed.


Another Limitation
Xrm.Utility.openWebResource always opens in new window in (IE11)
Xrm.Utility.openWebResource() performs different in Chrome as compared to IE11.

openInNewWindow = true/false in parameter window Options is not available for openWebResource()


An unsupported approach described by Andrii here - a33ik.blogspot.co.uk/.../step-by-step-creating-dialog-windows.html


Hope this helps.

Thanks
Vipin Jaiswal
vipinjaiswal12@gmail.com



Wednesday, May 22, 2019

Generic way to get OptionSet value or Text in Dynamic 365 CRM


Here are C# methods

public static string GetOptionSetTextFromValue(string entityName, string attributeName, int value)
{
    string optionsetText = string.Empty;
    var attributeRequest = new RetrieveAttributeRequest
    {
        EntityLogicalName = entityName,
        LogicalName = attributeName,
        RetrieveAsIfPublished = true
    };
    // Execute the request.
    var attributeResponse = (RetrieveAttributeResponse)service.Execute(attributeRequest);
    // Access the retrieved attribute.
    var attributeMetadata = (EnumAttributeMetadata)attributeResponse.AttributeMetadata;
    // Get the current options list for the retrieved attribute.
    var optionList = (from o in attributeMetadata.OptionSet.Options
                        select new { Value = o.Value, Text = o.Label.UserLocalizedLabel.Label }).ToList();

    optionsetText = optionList.Where(o => o.Value == value)
                                .Select(o => o.Text)
                                .FirstOrDefault();
    return optionsetText;
}


public static int GetOptionSetValueFromLabel(string entityName, string attributeName, string optionsetText)

{
    int optionSetValue = 0;
    var attributeRequest = new RetrieveAttributeRequest()
    {
        EntityLogicalName = entityName,
        LogicalName = attributeName,
        RetrieveAsIfPublished = true
    };
    // Execute the request.
    var attributeResponse = (RetrieveAttributeResponse)service.Execute(attributeRequest);
    // Access the retrieved attribute.
    var picklistAttributeMetadata = (PicklistAttributeMetadata)attributeResponse.AttributeMetadata;
    // Get the current options list for the retrieved attribute.
    OptionSetMetadata optionsetMetadata = picklistAttributeMetadata.OptionSet;
    var optionList = (from o in optionsetMetadata.Options
                        select new { Value = o.Value, Text = o.Label.UserLocalizedLabel.Label }).ToList();

    optionSetValue = (int)optionList.Where(o => o.Text.ToLower() == optionsetText.ToLower())
                                .Select(o => o.Value)
                                .FirstOrDefault();
    return optionSetValue;

}


Here is REST API Way

We need to include Formatted Values to get OptionSet Labels

var req = new XMLHttpRequest();
var fetchStatement = "/api/data/v9.1/contacts(EF5D6F09-399A-E811-A966-000D3AB0C08C)?$select=cm_language";
req.open("GET", Xrm.Page.context.getClientUrl() + fetchStatement, false);
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("Prefer", "odata.include-annotations=\"*\"");
req.onreadystatechange = function () {
    if (this.readyState === 4) {
        req.onreadystatechange = null;
        if (this.status === 200) {
            var result = JSON.parse(this.response);
            //OptionSet Value
            var cm_language = result["cm_language"];
            //OptionSet Label (Text)
            var cm_language_formatted = result["cm_language@OData.Community.Display.V1.FormattedValue"];
        } else {
            Xrm.Utility.alertDialog(this.statusText);
        }
    }
};

req.send();


Here is a Form Script



Xrm.Page.getAttribute("cm_customerservicelanguage").getSelectedOption().value 
Xrm.Page.getAttribute("cm_customerservicelanguage").getSelectedOption().text



Wednesday, May 8, 2019

Dynamic CRM SSRS Report Syntax Help


Enabling CRM Auto Filters


<fetch version="1.0" mapping="logical" distinct="false">
  <entity name="cm_invoice" enableprefiltering="1" prefilterparametername="CRM_FilteredInvoice">


Date Formatting

FORMAT(Cdate(Parameters!StartDate.Value), "dd/MM/yyyy")
Format(CDate(Fields!createdon.Value), "MM/dd/yyyy")


Switch Case Statement

   =Switch(First(Fields!cm_paymentmethod.Value, "ds_main") = "1","Bill",
           First(Fields!cm_paymentmethod.Value, "ds_main") = "2","Bill (part payment)",
           First(Fields!cm_paymentmethod.Value, "ds_main") = "3","Card (Debit)",
           First(Fields!cm_paymentmethod.Value, "ds_main") = "4","Card (Credit)",
           First(Fields!cm_paymentmethod.Value, "ds_main") = "5","Cash",
           First(Fields!cm_paymentmethod.Value, "ds_main") = "6","Voucher",
           First(Fields!cm_paymentmethod.Value, "ds_main") = "7","Cheque")


The IF Statement
=IIf(Fields!cm_vatnumber.Value is nothing,true,false)


Line Break or Enter Key

Vbcrlf

 CStr("Päiväys") + Cstr(Fields!cm_issuedate.Value) + vbcrlf +
 Cstr("Asiakasnumero") + CStr(Fields!cm_customernumber.Value)


Number Formatted with Commas (,)
Format(1212.89,"$#,#")            $1,213
Format(1212.89452,"F2")             $1212.89


Beginning of Current Month
DateSerial(Year(Date.Now), Month(Date.Now), 1)


Beginning of Last Month
DateAdd(DateInterval.Month, -1, DateSerial(Year(Date.Now), Month(Date.Now), 1))


End of Last Month
DateAdd(DateInterval.Minute, -1, DateSerial(Year(Date.Now), Month(Date.Now), 1))


Page Number  5th page of Total 15 pages

Tuesday, May 7, 2019

Dynamic CRM SSRS Report best configuration


Hey! Can we shift the logo to the top most?

Can we put a page number in the bottom and make it center align 

Can we shift an overall footer to the very bottom of the page?

If you involve yourself with SSRS report development, then you often hear such comments from your customer. 

When trying to export report in PDF or in MS-Word there will be more surprises and when it comes to printing your might be like - Awwwwww Jesus.

After making a lot of adjustments and doing trial and error one can have a perfect report. Some reports like Quotation or Invoice, which are mailed to customers requires an out most precision.


Please continue reading here for a perfect configuration

Wednesday, May 1, 2019

Deactivated business rule Running in MS CRM


Problem Statement

I have designed a plugin which is supposed to do some calculation and update some fields accordingly. But I realize that fields were not getting updated with correct values. I started debugging my plugin and I observe that plugin is doing the correct calculations, but fields are getting updated with some other values.

There were
  • No other Plugins registered who would affect
  • No other Workflows which might cause this odd behavior
  • Business rules does exist but were in De-Activated state.

I observed that though Business Rules were in deactivated state, but the formulas defined within them are giving an exact result which my fields are showing.

Now the question is Business Rule under Default customization are in Deactivated state but they still running in background affecting my plugin calculation and overwriting values in the field.

How can I check which business rule are still running?




Solution
The most powerful and favorite tool for any Dynamic CRM lover – Advanced Find. I have put a simple query to find all processes


I can see that there where multiple business rule with same name but may be different version (due to solution installation) and few among them were Activate state, which appears to be deactivated under default customization.



We need to deactivate or delete the respective business rule which might be causing a problem in dynamic CRM operations.

I hope this could save a lot of time.

Regards,
Vipin Jaiswal