FetchXML or condition on the attributes of two related entities - dynamics-crm

The requirements for this FetchXML statement are:
Return all 'ebs_opportunityinternshipunit' where
'createdon' is 'last-week'
and
'owner' of 'account' is 'eq-userid'
'account' is referenced by 'parentaccountid' of 'opportunity'
or
'owner' of 'account2' is 'eq-userid'
'account2' is referenced by 'mitacs_partner2' of 'opportunity'
I've tried configuring the filter with out-of-the-box tools, XRMToolbox FetchXML Builder, visiting the official CRM Community forum, and reading FetchXML documentation. Still, the best that I've been able to come up with is below:
<fetch version="1.0" mapping="logical">
<entity name="ebs_opportunityinternshipunit">
<attribute name="ebs_name" />
<attribute name="createdon" />
<attribute name="ebs_opportunityinternshipunitid" />
<order attribute="ebs_name" descending="false" />
<filter type="and">
<condition attribute="createdon" operator="last-week" />
<filter type="or">
<condition entityname="ab" attribute="ownerid" operator="eq-userid" />
<condition entityname="ac" attribute="ownerid" operator="eq-userid" />
</filter>
</filter>
<link-entity name="opportunity" from="opportunityid" to="ebs_opportunity" link-type="inner" alias="aa">
<link-entity name="account" from="accountid" to="parentaccountid" link-type="inner" alias="ab" />
<link-entity name="account" from="accountid" to="mitacs_partner2" link-type="inner" alias="ac" />
</link-entity>
</entity>
</fetch>

Related

How to pass null or empty to FetchXML filters?

Scenario: I've a text field in Dynamics CRM on Order Type. This field is integrated with some other systems and it'll be accepting only already stated list of values; like, ABC, IJK, XYZ etc. Now I can query this field using Advanced find if it contain data or not.
Now in report, I've a parameter that is having all those possible value and one additional as "Does not contain data" and its value is empty string. I've also enabled this report parameter for multi-select. But I am unable to get the orders if any of the value is selected from report parameters.
Below is my FetchXML query, Please let me know what I am missing in below.
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="invoicedetail">
<attribute name="productid" />
<attribute name="invoicedetailid" />
<attribute name="tv_ordertype" />
<order attribute="productid" descending="false" />
<filter type="and">
<condition attribute="tv_ordertype" operator="in" value="#Order_Types" />
</filter>
</entity>
</fetch>
Unfortunately you cannot combine the values ("ABC", "IJK", "XYZ") with an empty string option. Think about how SSRS will parse the empty string into FetchXml:
<condition attribute="tv_ordertype" operator="in" value="" />
Because the in operator has an empty string, there will be no matching results.
One approach that might work is to change your FetchXml to use an or filter, like this
<filter type="or">
<condition attribute="tv_ordertype" operator="null" />
<condition attribute="tv_ordertype" operator="in" value="#Order_Types" />
</filter>
This will now return all values from CRM that match your criteria OR have a null tv_ordertype
Then you can apply additional filtering at the tablix / report level
Try something like below
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="invoicedetail">
<attribute name="productid" />
<attribute name="invoicedetailid" />
<attribute name="tv_ordertype" />
<order attribute="productid" descending="false" />
<filter type='and'>
<condition attribute="tv_ordertype" operator="in" value="#Order_Types" />
</filter>
</entity>
</fetch>
Your fetch XML should look like this:
<?xml version="1.0" encoding="UTF-8"?>
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="invoicedetail">
<attribute name="productid" />
<attribute name="invoicedetailid" />
<attribute name="tv_ordertype" />
<order attribute="productid" descending="false" />
<filter type="and">
<condition attribute="tv_ordertype" operator="in"/>
<value>#Order_Types[0]</value>
<value>#Order_Types[1]</value>
<!-- etc -->
</condition>
</filter>
</entity>
</fetch>

How to filter using fetch to get accurate results?

I need to get all accounts that have phonecalls in state not open, so I created a query on fetch and got some results.
After checking my results I found that I got all accounts that have minimum 1 phonecall that was not open, but I need to get the accounts that all of their connected phonecalls are not open (can't have even 1 in open state) is it possible to do by fetch ?
** by NOT OPEN I mean state of Canceled or Completed.
Here is my fetch query:
#"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>
<entity name='account'>
<attribute name='name' />
<order attribute='accountamount' descending='true' />
<link-entity name='phonecall' from='regardingobjectid' to='accountid' alias='ab'>
<filter type='and'>
<condition attribute='statecode' operator='ne' value='0' />
</filter>
</link-entity>
</entity>
</fetch>";
What you are looking for is Unmatch query. This can be achieved in 2 queries using fetchxml.
First Query: You have to pull all the Accounts with open phonecalls.
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true" >
<entity name="account" >
<attribute name="accountid" />
<order attribute="accountamount" descending="true" />
<link-entity name="phonecall" from="regardingobjectid" to="accountid" alias="ab" >
<filter type="and" >
<condition attribute="statecode" operator="eq" value="0" />
</filter>
</link-entity>
</entity>
</fetch>
Second Query: Iterate & pass the first query Account resultset as <value> like below, to filter out them.
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true" >
<entity name="account" >
<attribute name="name" />
<attribute name="primarycontactid" />
<attribute name="telephone1" />
<attribute name="accountid" />
<order attribute="name" descending="false" />
<filter type="and" >
<condition attribute="accountid" operator="not-in" >
<value><GUID of ACCOUNT1 with OPEN PHONECALL></value>
<value><GUID of ACCOUNT2 with OPEN PHONECALL></value>
<value><GUID of ACCOUNT3 with OPEN PHONECALL></value>
</condition>
</filter>
</entity>
</fetch>
Read for idea

Dynamics - How to get all appointments that for a specific user attends by Web Api

In Dynamics CRM, I'm trying to get all the appointments where a specific user is an attendee, using Web API. I know that I have to deal with Appointment entity and ActivityParty with activitypartytypemask equals 9 but really cannot figure out how to make it. How can identify the attendee ?
You can use FetchXml for your purpose. Check following Fetch:
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true">
<entity name="appointment">
<attribute name="subject" />
<attribute name="statecode" />
<attribute name="scheduledstart" />
<attribute name="scheduledend" />
<attribute name="regardingobjectid" />
<attribute name="activityid" />
<link-entity name="activityparty" from="activityid" to="activityid" alias="aa">
<filter type="and">
<condition attribute="participationtypemask" operator="in">
<value>6</value>
<value>5</value>
</condition>
<condition attribute="partyid" operator="eq" value="{9CE2BF21-408B-E611-80F3-C4346BAC7ABC}" />
</filter>
</link-entity>
</entity>
</fetch>
Using provided FetchXml and WebApi you should get the result you wanted. Url should look like following:
[Server Base Url]/api/data/v8.2/appointments?fetchXml=%3Cfetch%20version%3D%221.0%22%20output-format%3D%22xml-platform%22%20mapping%3D%22logical%22%20distinct%3D%22true%22%3E%3Centity%20name%3D%22appointment%22%3E%3Cattribute%20name%3D%22subject%22%20%2F%3E%3Cattribute%20name%3D%22statecode%22%20%2F%3E%3Cattribute%20name%3D%22scheduledstart%22%20%2F%3E%3Cattribute%20name%3D%22scheduledend%22%20%2F%3E%3Cattribute%20name%3D%22regardingobjectid%22%20%2F%3E%3Cattribute%20name%3D%22activityid%22%20%2F%3E%3Clink-entity%20name%3D%22activityparty%22%20from%3D%22activityid%22%20to%3D%22activityid%22%20alias%3D%22aa%22%3E%3Cfilter%20type%3D%22and%22%3E%3Ccondition%20attribute%3D%22participationtypemask%22%20operator%3D%22in%22%3E%3Cvalue%3E6%3C%2Fvalue%3E%3Cvalue%3E5%3C%2Fvalue%3E%3C%2Fcondition%3E%3Ccondition%20attribute%3D%22partyid%22%20operator%3D%22eq%22%20value%3D%22%7B9CE2BF21-408B-E611-80F3-C4346BAC7ABC%7D%22%20%2F%3E%3C%2Ffilter%3E%3C%2Flink-entity%3E%3C%2Fentity%3E%3C%2Ffetch%3E
This article contains additional details.

Request URL Too Long for fetchXml query types

I'm using CRM 2016 web api with fetchxml query parameter, but my query is too long it's simulate the IN operator were the number of parameters passed in the IN list are 300 elements and some times will be more than that.
So my problem is the query are too big for a GET HTTP Request. I have tried to send the query in the http message body but that didn't work so what is the solution for this problem?
Here's a code snippet of the fetchxml query that I used:
<fetch mapping="logical" distinct="true">
<entity name="entity">
<attribute name="new_classopportunityid" />
<attribute name="new_trainingproduct" />
<attribute name="new_gtgstatus" />
<attribute name="new_scheduledstartdate" />
<attribute name="new_scheduledenddate" />
<attribute name="new_remainingnumberofseats" />
<attribute name="new_liveclassroom" />
<attribute name="new_maxlive" />
<attribute name="new_xavieruniversity" />
<attribute name="new_partnerlive" />
<attribute name="new_blended" />
<filter>
<condition attribute="new_classopportunityid" operator="in">
<value>001943ea-e263-e611-8158-00155d002810</value>
<value>0071e4ea-bd9b-e611-8163-00155d002810</value>
<value>00c32774-1c8f-e611-8161-00155d002810</value>
<value>00d513fa-f0bb-e611-8169-00155d002810</value>
<value>....</value>
<value>....</value>
<value>....</value>
</condition>
</filter>
</entity>
</fetch>
The CRM web api endpoint that I request is :
GET http://<org>/api/data/v8.0/<entity>?fetchXml=<fetch mapping="logical" distinct="true">
<entity name="entity">
<attribute name="new_classopportunityid" />
<attribute name="new_trainingproduct" />
<attribute name="new_gtgstatus" />
<attribute name="new_scheduledstartdate" />
<attribute name="new_scheduledenddate" />
<attribute name="new_remainingnumberofseats" />
<attribute name="new_liveclassroom" />
<attribute name="new_maxlive" />
<attribute name="new_xavieruniversity" />
<attribute name="new_partnerlive" />
<attribute name="new_blended" />
<filter>
<condition attribute="new_classopportunityid" operator="in">
<value>001943ea-e263-e611-8158-00155d002810</value>
<value>0071e4ea-bd9b-e611-8163-00155d002810</value>
<value>00c32774-1c8f-e611-8161-00155d002810</value>
<value>00d513fa-f0bb-e611-8169-00155d002810</value>
<value>....</value>
<value>....</value>
<value>....</value>
</condition>
</filter>
</entity>
</fetch>
This is the response I got from the api.
Error code: 414: HTTP/1.1 414 Request-URI Too Long Response : "<!DOCTYPE HTML PUBLIC \"-\/\/W3C\/\/DTD HTML 4.01\/\/EN\"\"http:\/\/www.w3.org\/TR\/html4\/strict.dtd\">\r\n<HTML><HEAD><TITLE>Request URL Too Long<\/TITLE>\r\n<META HTTP-EQUIV=\"Content-Type\" Content=\"text\/html; charset=us-ascii\"><\/HEAD>\r\n<BODY><h2>Request URL Too Long<\/h2>\r\n<hr><p>HTTP Error 414. The request URL is too long.<\/p>\r\n<\/BODY><\/HTML>\r\n" [] []
You'll need to use a Post, not a Get:
https://dreamingincrm.com/2017/01/15/executing-large-fetchxml-with-webapi/
Using the "in" operator with a big list of ids is probably not the best way to query, as you've seen. It would be better if you could filter on an attribute of the new_classopportunity entity by using a link-entity, like this:
<fetch mapping="logical" distinct="true" >
<entity name="entity" >
<!-- ... all your attributes ... -->
<link-entity name="new_classopportunity" from="new_classopportunityid" to="new_classopportunityid" >
<attribute name="new_name" />
<filter>
<condition attribute="statecode" operator="eq" value="0" />
</filter>
</link-entity>
</entity>
</fetch>
Notice you can pull in attributes from the link-entity as well. In this case I'm pulling in name and using a filter to only get new_classopportunity records that are active.
If you don't have a field on new_classopportunity that you can filter on to get the same list, add one! :)

CRM Reports, Why,Some Address fields not populating?

I known this a broad question, I just cant get my head around it. I have created a report that pulls client details for a specific sales person. I get back clients with addresses and some without addresses , even though the address composite field has been filled out on CRM. There is no equation/expression that I have used to pull the address date. Just get the field and display. Can you help me , by giving me a few pointers on what to check/look out for in CRM .
UPDATE 1:
<fetch distinct="false" no-lock="false" mapping="logical">
<entity name="activitypointer" enableprefiltering="1" prefilterparametername="CRM_FilteredActivityPointer">
<attribute name="scheduledstart" alias="scheduledstart" />
<attribute name="subject" alias="subject" />
<attribute name="regardingobjectid" alias="regardingobjectid" />
<attribute name="description" alias="description" />
<attribute name="activityid" />
<attribute name="ownerid" alias="ownerid" />
<attribute name="activitytypecode" />
<attribute name="actualstart" alias="actualstart" />
<attribute name="actualdurationminutes" alias="actualdurationminutes" />
<attribute name="actualend" alias="actualend" />
<link-entity name="opportunity" to="regardingobjectid" from="opportunityid" link-type="outer" alias="LE_3c8631e7bcbe64b3de96e66789a47536">
<attribute name="customerid" alias="LE_3c8631e7bcbe64b3de96e66789a47536_customerid" />
<attribute name="schedulefollowup_qualify" alias="LE_ad91c354eb5a26b004de4d41b2c3d454_schedulefollowup_qualify" />
<attribute name="new_accounttype" alias="LE_54d761d89ac278139a6836de7c3607db_new_accounttype" />
<attribute name="new_neworexisiting" alias="LE_5db2d6da9e43bd44c8949cb912432cba_new_neworexisiting" />
<attribute name="new_accaddresscomposite" alias="LE_c6b3b5d2a9364c90878a5d147b97b866_new_accaddresscomposite" />
<attribute name="parentaccountid" alias="LE_b7d5c9432034544323d9170db9688778_parentaccountid" />
<attribute name="actualclosedate" alias="LE_3d1bcadc4e9010d6d4689ded2531d68a_actualclosedate" />
</link-entity>
<link-entity name="account" to="regardingobjectid" from="accountid" link-type="outer" alias="LE_d08b5ac0b1b1a422353a6d092b699986">
<attribute name="name" alias="LE_d08b5ac0b1b1a422353a6d092b699986_name" />
</link-entity>
<link-entity name="account" to="regardingobjectid" from="accountid" link-type="outer" alias="LE_b6831392115770835cce64e99a59be4a">
<attribute name="address1_composite" alias="LE_b6831392115770835cce64e99a59be4a_address1_composite" />
</link-entity>
<link-entity name="new_visit" to="regardingobjectid" from="new_visitid" link-type="outer" alias="LE_041a4de02adecc6816a3be5b9389d9ac">
<attribute name="new_tmpdurationmins" alias="LE_041a4de02adecc6816a3be5b9389d9ac_new_tmpdurationmins" />
</link-entity>
<link-entity name="new_visit" to="regardingobjectid" from="new_visitid" link-type="outer" alias="LE_0238625bc02c72e091b42d4c6ece34e5">
<attribute name="new_arriveddatetime" alias="LE_0238625bc02c72e091b42d4c6ece34e5_new_arriveddatetime" />
</link-entity>
</entity>
As a first tweak I'd suggest you merge those separate link-entity joins on account into one:
current joins on account:
<link-entity name="account" to="regardingobjectid" from="accountid" link-type="outer" alias="LE_d08b5ac0b1b1a422353a6d092b699986">
<attribute name="name" alias="LE_d08b5ac0b1b1a422353a6d092b699986_name" />
</link-entity>
<link-entity name="account" to="regardingobjectid" from="accountid" link-type="outer" alias="LE_b6831392115770835cce64e99a59be4a">
<attribute name="address1_composite" alias="LE_b6831392115770835cce64e99a59be4a_address1_composite" />
</link-entity>
proposed change:
<link-entity name="account" to="regardingobjectid" from="accountid" link-type="outer" alias="LE_d08b5ac0b1b1a422353a6d092b699986">
<attribute name="name" alias="LE_d08b5ac0b1b1a422353a6d092b699986_name" />
<!-- move the address1_composite field here -->
<attribute name="address1_composite" alias="LE_d08b5ac0b1b1a422353a6d092b699986_composite" />
</link-entity>
This should at least yield a consistent behavior for all account fields but it still leaves open if using activitypointer as the root entity for your report is the right way. It depends on your reports business logic/user story.
You could verify this by formulating the report in plain language: "For all Activities, show me ..." vs. "For all Opportunities, show me ..." vs. "For all Accounts, show me ..."
A great way to test your reports FetchXml query is using FetchXmlTester contained in Xrm Toolbox.

Resources