LINQ: GroupBy, Sum and EntityCollection in CRM

Just sharing a sample code that could be used for group by and sum operation on EntityCollection.

Suppose below is the output that we want

We can use the below code for that.


// select categoryid, final forecast, final awards from SubCategory Entity
// category id is lookup in SubCategory Entity

EntityCollection result = orgProxy.RetrieveMultiple(new FetchExpression(fetch));

var details = from r in result.Entities.AsEnumerable()
group r by new
{
groupByCategoryID = ((EntityReference)r.Attributes["categoryId"]).Id.ToString()
}
into g
select new
{
sumFinalForecast = g.Sum(x => Convert.ToInt32(x.Attributes["finalforecast"])),
sumFinalAwards = g.Sum(x => Convert.ToInt32(x.Attributes["finalawards"])),
categoryId = g.Key.groupByCategoryID
};

// update the parent record
foreach(var detail in details)
{
Entity entityUpdate = new Entity("category");
entityUpdate.Id = new Guid(detail.categoryId);
entityUpdate.Attributes["totalfinalforecast"] = detail.sumFinalForecast;
entityUpdate.Attributes["totalfinalawards"] = detail.sumFinalAwards;
orgProxy.Update(entityUpdate);
}

Hope it helps..

Sample code to call Action using Web API in CRM

Just sharing a sample code to call an Action through Web API.

Suppose below is our Action with one input parameter.

JavaScript code :-


function CallAction() {

// get the id of the record and remove the curly bracket part
// id will be used in Web API url
var Id = Xrm.Page.data.entity.getId().replace('{', '').replace('}', '');

var serverURL = Xrm.Page.context.getClientUrl();

// pass the id as inpurt parameter
var data = {

"recordid": Id
};

var req = new XMLHttpRequest();

// specify name of the entity, record id and name of the action in the Wen API Url
req.open("POST", serverURL + "/api/data/v8.2/sab_costmanagements(" + Id + ")/Microsoft.Dynamics.CRM.sab_Recalculate", 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) {
var data = JSON.parse(this.response);
alert(data);
} else {
var error = JSON.parse(this.response).error;
alert(error.message);
}
}
};

// send the request with the data for the input parameter
req.send(window.JSON.stringify(data));
}

Basically we need to pass name of the Entity Set with id of the record followed by name of the action appended with Microsoft.Dynamics.CRM.

In case of global action, we just need the Microsoft.Dynamics.CRM.<<ActionName>>.

More details here

https://www.inogic.com/blog/2016/10/execute-the-global-action-using-web-api-in-dynamics-crm/

Hope it helps..

Missing Action (message) in Plugin Registration Tool

Recently we created a new created Action and it twas not showing up in Plugin Registration Tool.

Closing and restarting the Plugin Registration tool fixed it.

Hope it helps..

Filter SubGrid in Dynamics 365 (with New Form Rendering or Turbo Form)

Recently we had a requirement wherein we wanted to see all the child records of a record in a SubGrid .

We had self-referential (hierarchical relationship) enabled for that entity.

Configuring the Sub Grid on the form.

We have also enabled the Editable grid for the Sub Grid.

The JavaScript code


function filterSubGrid()
{
// get the current record's guid
var entityId = Xrm.Page.data.entity.getId();

// refer the subgrid
var testGrid = window.parent.document.getElementById("Test");

if (testGrid == null)
{
setTimeout(function () {filterSubGrid(); }, 2000);
return;
}

// fetch xml code using User operator
var fetchXml = "<fetch distinct='false' no-lock='false' mapping='logical'>" +
"<entity name='new_test' >" +
"<attribute name='new_name' />" +
" <attribute name='new_testname' />" +
"<order attribute='new_name' descending='true' />" +
"<filter type='and'>" +
"<condition attribute='new_testid' operator='under' value='"+entityId+"'"+"/>" +
"</filter>" +
"</entity>" +
"</fetch>";

if (testGrid.control != null)
{
testGrid.control.SetParameter("fetchXml", fetchXml);
testGrid.control.refresh();
}
else
{
setTimeout(filterSubGrid, 500);
}
}

The filtered Sub Grid (editable)

Note :- The JavaScript code is unsupported as we are making use of getElementById instead of Xrm library to access subgrid.

Hope it helps..

Using ILMerge for Plugin in CRM

If we make use of external assembly in our Plugin (sandboxed) we will get the exception of FileNotFound.

So here we can make use of ILMerge which basically merges the assembly referenced and the plugin into a single assembly.

Install the following NuGet Package.

This adds the following files in our Plugin project.

We need to set Copy Local as true for all our referenced assembly that we want to merge with our plugin.

We need to set Copy Local as false for all other assemblies that we do not want to be merged with plugin.

Just build the project and we are done.

The assembly inside Reflector: –

Hope it helps.

Change Order Name and Payment Name Prefix in The Portal Connector (TPC)

To update the prefix, go to Administration – Settings

Then to Advanced

Then to Ecommerce settings

Scroll down to the bottom

Hope it helps..