During development in CRM, I have seen that many times the requirements can get too complicated to be achieved using Odata queries. Sometimes it just feels good to execute a fetch XML that we have formed using the advanced find and use the resultant data to perform further business logic.
XrmServiceToolkit (find it here!) is an invaluable tool that every Dynamics CRM developer should have in his kitty to make development easy. In the example I will show how I achieved a complicated requirement by using XrmServiceToolkit's fetch method in my Javascript web resource:
The requirement was to find out whether there was any active campaign associated with a custom entity (contoso_contosoentity) associated with opportunity product through a field called Signing entity on the form of opportunity product associated with the current opportunity. The custom entity (contoso_contosoentity) and campaign were related by a N:N relation. The objective was to show a notification to the user on the opportunity (deal) form when the conditions met.
var presentDealRecordId = Xrm.Page.data.entity.getId();
var fetchXml =
"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>" +
"<entity name='campaign'>" +
"<attribute name='name' />" +
"<order attribute='name' descending='false' />" +
"<filter type='and'>" +
"<condition attribute='statecode' operator='eq' value='0' />" +
"</filter>" +
"<link-entity name='contoso_campaign_contoso_contosoentity' from='campaignid' to='campaignid' visible='false' intersect='true'>" +
"<link-entity name='contoso_contosoentity' from='contoso_contosoentityid' to='contoso_contosoentityid' alias='ag'>" +
"<link-entity name='opportunityproduct' from='contoso_signingentityid' to='contoso_contosoentityid' alias='ah'>" +
"<link-entity name='opportunity' from='opportunityid' to='opportunityid' alias='ai'>" +
"<filter type='and'>" +
"<condition attribute='opportunityid' operator='eq' uitype='opportunity' value='" + presentDealRecordId + "' />" +
"</filter>" +
"</link-entity>" +
"</link-entity>" +
"</link-entity>" +
"</link-entity>" +
"</entity>" +
"</fetch>";
var associatedActiveCampaigns = XrmServiceToolkit.Soap.Fetch(fetchXml);
if (associatedActiveCampaigns && associatedActiveCampaigns.length > 0) {
shouldDisplayNotification = true;
campaignName = associatedActiveCampaigns[0].attributes["name"].value;
}
}
var dealAlertNotificationId = "dealAlertCampaign";
if (shouldDisplayNotification && campaignName != null) {
var message = "Please consider associating this deal or a deal product to the following campaign: " + campaignName;
Xrm.Page.ui.setFormNotification(message, "INFO", dealAlertNotificationId);
} else {
Xrm.Page.ui.clearFormNotification(dealAlertNotificationId);
}
I have highlighted the line where we make the call to the Fetch method (which internally uses the SOAP endpoint). I have also highlighted the line where I use the returned result set to perform some action (in this case to populate the campaign name to show to the user)
Note:
1. I took the fetch XML from the advanced find window and then removed the attributes that were not required to reduce the load of the service call.
2. This service call is performed in a synchronous manner, which may not give a very good experience to the end user. We can make it asynchronous by passing a callback function as the third parameter here:
var fetch = function (fetchCore, fetchAll, callback) {
///<summary>
/// Sends synchronous/asynchronous request to do a fetch request.
///</summary>
///<param name="fetchCore" type="String">
/// A JavaScript String containing serialized XML using the FetchXML schema.
/// For efficiency, start with the "entity" node.
/// </param>
///<param name="callback" type="Function">
/// A Function used for asynchronous request. If not defined, it sends a synchronous request.
/// </param>
Hope this helps you implement some complicated requirements in CRM!
XrmServiceToolkit (find it here!) is an invaluable tool that every Dynamics CRM developer should have in his kitty to make development easy. In the example I will show how I achieved a complicated requirement by using XrmServiceToolkit's fetch method in my Javascript web resource:
The requirement was to find out whether there was any active campaign associated with a custom entity (contoso_contosoentity) associated with opportunity product through a field called Signing entity on the form of opportunity product associated with the current opportunity. The custom entity (contoso_contosoentity) and campaign were related by a N:N relation. The objective was to show a notification to the user on the opportunity (deal) form when the conditions met.
var presentDealRecordId = Xrm.Page.data.entity.getId();
var fetchXml =
"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>" +
"<entity name='campaign'>" +
"<attribute name='name' />" +
"<order attribute='name' descending='false' />" +
"<filter type='and'>" +
"<condition attribute='statecode' operator='eq' value='0' />" +
"</filter>" +
"<link-entity name='contoso_campaign_contoso_contosoentity' from='campaignid' to='campaignid' visible='false' intersect='true'>" +
"<link-entity name='contoso_contosoentity' from='contoso_contosoentityid' to='contoso_contosoentityid' alias='ag'>" +
"<link-entity name='opportunityproduct' from='contoso_signingentityid' to='contoso_contosoentityid' alias='ah'>" +
"<link-entity name='opportunity' from='opportunityid' to='opportunityid' alias='ai'>" +
"<filter type='and'>" +
"<condition attribute='opportunityid' operator='eq' uitype='opportunity' value='" + presentDealRecordId + "' />" +
"</filter>" +
"</link-entity>" +
"</link-entity>" +
"</link-entity>" +
"</link-entity>" +
"</entity>" +
"</fetch>";
var associatedActiveCampaigns = XrmServiceToolkit.Soap.Fetch(fetchXml);
if (associatedActiveCampaigns && associatedActiveCampaigns.length > 0) {
shouldDisplayNotification = true;
campaignName = associatedActiveCampaigns[0].attributes["name"].value;
}
}
var dealAlertNotificationId = "dealAlertCampaign";
if (shouldDisplayNotification && campaignName != null) {
var message = "Please consider associating this deal or a deal product to the following campaign: " + campaignName;
Xrm.Page.ui.setFormNotification(message, "INFO", dealAlertNotificationId);
} else {
Xrm.Page.ui.clearFormNotification(dealAlertNotificationId);
}
I have highlighted the line where we make the call to the Fetch method (which internally uses the SOAP endpoint). I have also highlighted the line where I use the returned result set to perform some action (in this case to populate the campaign name to show to the user)
Note:
1. I took the fetch XML from the advanced find window and then removed the attributes that were not required to reduce the load of the service call.
2. This service call is performed in a synchronous manner, which may not give a very good experience to the end user. We can make it asynchronous by passing a callback function as the third parameter here:
var fetch = function (fetchCore, fetchAll, callback) {
///<summary>
/// Sends synchronous/asynchronous request to do a fetch request.
///</summary>
///<param name="fetchCore" type="String">
/// A JavaScript String containing serialized XML using the FetchXML schema.
/// For efficiency, start with the "entity" node.
/// </param>
///<param name="callback" type="Function">
/// A Function used for asynchronous request. If not defined, it sends a synchronous request.
/// </param>
Hope this helps you implement some complicated requirements in CRM!
No comments:
Post a Comment