Thursday, 22 October 2020

How to Filter SubGrid Lookup view in Dynamics 365 CRM

How to Filter SubGrid Lookup view in Dynamics 365 CRM. 

Please check the comments in the below code and do follow the steps accordingly and call the filterSubGrid() funtion on onload.

var LastQuery = "";

function filterSubGrid() {
    debugger;
    setSubgridLookupFiltering();
}

function AddLookupFilter(entity_type, customFilter) {
    var subgridLookup = Xrm.Page.getControl("lookup_Contacts_Participants");
    subgridLookup.addCustomFilter(customFilter, entity_type);
}

function setSubgridLookupFiltering() {
    var subgridAddButtonId = "Contacts_Participants_addImageButton";
 
    //Try to get the element from both the current and the parent document.
    var subgridAddButton = document.getElementById(subgridAddButtonId) || window.parent.document.getElementById(subgridAddButtonId);
 
    //This script may run before the subgrid has been fully loaded on the form. If this is the case,
    //delay and retry until the subgrid has been loaded.
    if (subgridAddButton == null) {
        setTimeout(setSubgridLookupFiltering, 2000);
        return;
    }
 
    //Local function to retrieve the lookup control and apply the filter. We will queue this function in the click event handler of the
    //Add button's click event.
    var getSubgridLookupAndAddFilter = function() {
        var subgridLookup = Xrm.Page.getControl("lookup_Contacts_Participants");
 
        //Delay and retry until we can locate the lookup.
        if (subgridLookup == null) {
            setTimeout(getSubgridLookupAndAddFilter, 200);
            return;
        }
 
        //This is a custom property we are tagging on to the lookup control to ensure that we will
        //apply the custom filter only once when the Add button is first clicked.
        if (subgridLookup.customFilterAdded) {
            subgridLookup.removePreSearch(function () {
                subgridLookup.addCustomFilter(LastQuery, "contact");
                //AddLookupFilter("contact", LastQuery);
            });
        }

        var LookUp = Xrm.Page.getAttribute("jar_cliente").getValue();

        console.log(LastQuery);
 
        subgridLookup.addPreSearch(function() {
            //Standard logic to build up the filter query string
            var filterQuery = "<filter type='and'><condition attribute='parentcustomerid' operator='eq' value='" + LookUp[0].id + "' /></filter>";
            
//Set Global Variable to remove PreSearch
LastQuery = filterQuery; //Standard call to add filter to the lookup control subgridLookup.addCustomFilter(filterQuery, "contact"); }); //Mark the fact that we have already added the filter so that we won't do it again the next time the user clicks the Add button. subgridLookup.customFilterAdded = true; }; //Attach the function to retrieve the lookup and apply the filter to the Add button's click event. Remember that we //can only get the lookup after the user has clicked the Add button. subgridAddButton.addEventListener("click", function() { setTimeout(getSubgridLookupAndAddFilter, 200); }); }

Only a one problem, when the user change the principal lookup field, not work the filter, the function is called removePreSearch.

if (subgridLookup.customFilterAdded) {
            subgridLookup.removePreSearch(function () {
                subgridLookup.addCustomFilter(LastQuery, "contact");
                //AddLookupFilter("contact", LastQuery);
            });
        }
link: https://community.dynamics.com/crm/f/microsoft-dynamics-crm-forum/261801/filter-new-record-subgrid-with-field

Monday, 11 May 2020

How To Retrieve All Files from SharePoint Library Folder & Send an Email Attachment using Microsoft Flows


msflowsmallicon In this blog I will explain how to retrieve all files from a specified SharePoint folder and send email as an attachment.

Every flow needs a trigger to start with so here I am using a manual trigger.

Next step I am using flow step SharePoint List Folder which returns files contained in a SharePoint folder.

The return response is array of BlobMetadata which contains the below details.

NamePathTypeDescription
ItemIdItemIdintegerThe value that can be used to Get or Update file properties in libraries.
IdIdstringThe unique id of the file or folder.
NameNamestringThe name of the file or folder.
DisplayNameDisplayNamestringThe display name of the file or folder.
PathPathstringThe path of the file or folder.
LastModifiedLastModifieddate-timeThe date and time the file or folder was last modified.
SizeSizeintegerThe size of the file or folder.
MediaTypeMediaTypestringThe media type of the file or folder.
IsFolderIsFolderbooleanA boolean value (true, false) to indicate whether or not the blob is a folder.
ETagETagstringThe etag of the file or folder.
FileLocatorFileLocatorstringThe filelocator of the file or folder.

Next, we need to collect the file name and contents. For this we need to declare a variable type array called FilesArray.

Next step we need to construct a loop for reading all the SharePoint list folder contents. List folder contents will have files and folders. So within the loop I am checking whether the content is a folder or not. See below image.

Next, we need to construct rest of the logic under the yes condition for getting all the file names & contents to array variable which we declared earlier. To get the file content use flow step Get file content using path. Path property is available from the above step using Blobmetadata content. Append to array will have two properties ContentBytes and Name. See format below.

The expression for file ContentBytes is as follows:

body(‘Get_file_content_using_path’).$content

Note: There is a property called FileContent available from the Dynamic content, but this will result in error for flow step send email. So it’s important to use the above expression for the contentbytes.

Finally, outside the apply each loop use the send email flow action for sending all the files as one attachment.


Below is the final preview of the flow solution which we discussed above.

Thank you for reading.

Ref: https://mydevexperience.wordpress.com/2019/10/12/microsoft-flow-retrieve-all-files-from-sharepoint-library-folder-send-email-attachment/

Saturday, 11 April 2020

How to fix “Undeclared Property Error” when setting the Lookups with Dynamics 365 Web API

A very quick note to remind you about something really important when working with the Dynamics Web API, it is one of those things that you always forget to check until you spent 3 hours trying to figure out why it isn’t working.
I was updating my code to create some related records after creating  a contact record and in one of the related entities I got this error:

“An error occurred while validating input parameters: Microsoft.OData.ODataException: An undeclared property ‘YOUR FIELD’ which only has property annotations in the payload but no property value was found in the payload. In OData, only declared navigation properties and declared named streams can be represented as properties without values.”
This is caused because in my request I had the wrong field name, please remember always use the schema name for the lookups!

It is quite common for different people to create the fields in an entity and as I am sure you know Dynamics 365 tends to keep the characters in Capitals when it maps the schema name:

Some people would correct this and leave the schema name to be: mif_myfield
Others will just leave it like that.
Personally I tend to correct it and leave everything lower case but whatever works for you.
So my issue with my request was that I was using the Name of the field rather than the Schema Name:
This is wrong:
This is correct:

Wednesday, 5 February 2020

Plugin is not triggering while importing data in Dynamics 365 CRM



This problem is due to checking for depth in plugin, the async job that inserts imported data into CRM sets plugin depth to ‘2’, so the solution is to disable check for depth while data import.

Thursday, 9 January 2020

What happens when a user is Assigned Multiple Security Roles in Microsoft Dynamics 365 CRM

What happens when a user is assigned multiple security roles in Microsoft Dynamics CRM?

In smaller organizations, you may find situations when a Manager would like to have access to both a Sales Profile and a Service Profile in Microsoft Dynamics CRM.
You may wonder what exactly happens when a user is assigned multiple security roles.
Assume that a user is assigned the profiles shown below in the screenshot. You see that there are different access levels set for each profile. 

You will that when the user gets assigned to both ‘Baseline for all users’ and ‘Sales Person’ profiles, the access levels get combined, and the user then has permissions as shown in the ‘Effective Permissions’ section.

So you see that when a user is assigned multiple roles, the user gains the permissions associated with each role.

Thursday, 2 January 2020

How to Filter Sub-Grid in Dynamics 365

In this example, I've added an "Accounts" sub-grid to my Account, configured to show "All Record Types" rather than "Only Related Records". The using this JavaScript we're filtering the sub-grid to display all the Accounts that the Primary Contact is a Primary Contact of (which will obviously include the current account). This function can be added to the form OnLoad and Primary Contact field OnChange to ensure the sub-grid is updated when the Primary Contact changes as well.
NOTE: I've found it best to create a custom view to be used as the default sub-grid view, and to customize this view to display no results by default (using a filter such as: Name equals "X" and Name does not equal "X" – which will always return no results), this way you won't see incorrect data initially on load before the JavaScript kicks in.
// Generic function to perform the filtering - this function shouldn't need to change
function filterSubGrid(subgridName, fetchXml, attempts) {
    // Try 10 times, then stop
    if (attempts < 0) { return; }

    var crmWindow = Xrm.Internal.isTurboForm() ? parent.window : window;

    // Get the subgrid element to filter
    var subgrid = crmWindow.document.getElementById(subgridName);
    if (subgrid == null || subgrid.control == null) {
        // If the subgrid hasn't loaded yet, keep trying
        setTimeout(function () { filterSubGrid(subgridName, fetchXml, (attempts || 10) - 1); }, 500);
        return;
    }

    // Update the fetchXml on the subgrid and refresh the grid
    subgrid.control.SetParameter("fetchXml", fetchXml);
    subgrid.control.refresh();
}

// Filters an accounts subgrid by the primary contact ID - this function is unique for your requirements
function filterAccountGrid() {
    // Get the dynamic contactId to filter on
    var contactValue = Xrm.Page.getAttribute("primarycontactid").getValue();

    // If the contact is null display nothing 
    var contactId = "00000000-0000-0000-0000-000000000000";
    if (contactValue != null) {
        contactId = contactValue[0].id;
    }

    // Fetch xml code which will retrieve all the accounts related to the contact 
    var fetchXml = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>" +
    "  <entity name='account'>" +
    "    <attribute name='name' />" +
    "    <attribute name='address1_city' />" +
    "    <attribute name='primarycontactid' />" +
    "    <attribute name='telephone1' />" +
    "    <attribute name='accountid' />" +
    "    <order attribute='name' descending='false' />" +
    "    <filter type='and'>" +
    "      <condition attribute='primarycontactid' operator='eq' uitype='contact' value='" + contactId + "' />" +
    "    </filter>" +
    "    <link-entity name='contact' from='contactid' to='primarycontactid' visible='false' link-type='outer' alias='accountprimarycontactidcontactcontactid'>" +
    "      <attribute name='emailaddress1' />" +
    "    </link-entity>" +
    "  </entity>" +
    "</fetch>";

    filterSubGrid("Accounts", fetchXml);
}
Note: This code is unsupported, and is likely to break in any major releases (as it has in the past). The idea of sourcing this project on GitHub is that if/when it does break again, it can be updated here rather than having to release new blog posts and hoping people who have previously used it see it. Also if it breaks in an update and I don't get a chance to fix it, someone else can fix it :)

How to use Form Component Control to Edit Related Entity Information in Dynamics 365 CRM

In the recent release of the Dynamics 365 CRM, new features have been added. One of the most important and useful features among these is th...