Download File : Power Automate and JavaScript

What is Issue?

When working on D365 CRM, Some time user wants to download file from SharePoint, OneDrive or CRM Notes itself. So how you will do it in shortest way?

The Reason-

Downloading file from SharePoint or any other cloud location it will be time consuming process if you choose Web service or any WCF service.

Solution-

Now Power Automate provides less code and quick solutions. Power Automate has all the connectors and Actions which help you to connect these cloud locations and process on the files.

Let’s see a scenario, I want to download a file on button click on my CRM Account form. The file is located in my account record Timeline Notes.

Let’s go step by step.

First of all, as this is action on click of button on form, we can choose “When Http Request Received” trigger in Power Automate. And in HTTP request we need record id i.e. accountid to retrieve specific Note attachment i.e. “CustomerInfoDoc”-

Now from above step we will get the Document – File name and Document body (base64) content.

So we need a variable to store files in array and another variable for document content-

Setting the variables from the Notes list which we got from “List rows” action-

We need to append array with below json-

{
“Name”: @{items(‘Apply_to_each’)?[‘filename’]},
“ContentBytes”: @{items(‘Apply_to_each’)?[‘documentbody’]}
}

We will use Name and ContentBytes in JavaScript Code which will be in the response of HttpRequest.

Now once file we got file content we need to send them in response-

We need the only file from Notes, In List Row action we can add row count =1, but still in response we can set formula in body first(variable(‘ContentArray’). As this is document in response add headers “Content-type”:”multipart/form-data”

Now our complete flow is ready and it looks like –

So now remaining part is calling the flow from button to download the file-

Add the below javascript and call “callPowerAutomateFlow” function on button click. Below is complete code for download –

function callPowerAutomateFlow(formContext) { 
    id = formContext.data.entity.getId().replace("{", "").replace("}", ""); 
    var account = '{ "accountid": "' + id + '"'+ '}'; 
    var flowUrl = "https://prod-04.centralindia.logic.azure.com:443/workflows/xxxxxxxxxxxxxxxxxxxxxxxxxx/triggers/manual/paths/invoke?api-version=2016-06-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=xxxxxxxxxxxx"; 
 
    var req = new XMLHttpRequest(); 
    req.open("POST", flowUrl, true); 
    req.setRequestHeader("Accept", "application/json"); 
    req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); 
    req.onreadystatechange = function () { 
        if (this.readyState === 4) { 
            req.onreadystatechange = null; 
            if (this.status === 200) { 
                    var result = JSON.parse(this.response); 
                    var fileName = result.Name; 
                    var fileCont = result.ContentBytes; 
                    var filebyte = base64ToBufferArray(fileCont); 
                    downloadFile(fileName, [filebyte]); 
            } else { 
                Xrm.Utility.alertDialog(this.responseText); 
            } 
        } 
    }; 
    req.send(account); 
} 
 
function base64ToBufferArray(base64content) { 
    var binaryString = window.atob(base64content); 
    var binaryLen = binaryString.length; 
    var bytes = new Uint8Array(binaryLen); 
    for (var i = 0; i < binaryLen; i++) { 
        var ascii = binaryString.charCodeAt(i); 
        bytes[i] = ascii; 
    } 
    return bytes; 
} 
 
function downloadFile(name,data) { 
        var blob = new Blob(data, { type: "octet/stream" }), 
            url = window.URL.createObjectURL(blob); 
        if (window.navigator && window.navigator.msSaveOrOpenBlob) { 
            window.navigator.msSaveOrOpenBlob(blob, name); 
        } else { 
            const url = window.URL.createObjectURL(blob); 
            const a = document.createElement('a'); 
            document.body.appendChild(a); 
            a.href = url; 
            a.download = name; 
            a.click(); 
            window.URL.revokeObjectURL(url); 
            document.body.removeChild(a); 
        } 
}

That’s it!! when I am clicking on Download button in CRM Account record, it is downloading my Attachment file from Notes which is with title “CustomerInfoDoc”.

Hope this will help…
Enjoy Ms CRM!!!

Follow on Facebook- FB: MSCRM16Tech

Get SharePoint Document details for particular record in MS CRM using FetchXML

What is Issue?

There are many cases while implementing MS CRM where clients ask to perform some operation in MS CRM based on the document uploaded in SharePoint. But how to get SharePoint document details in MS CRM other than “Documents” associated view? If you try to fetch records using advanced find or querying sharepointdocument entity directly, it will show you error. So how we can query and get the document details using code either from client side or server side?

The Reason-

MS CRM Supports only the associated view for Document i.e. sharepointdocument entity. MS CRM do not support direct querying on all sharepointdocument.

Solution-

There is a way to fetch SharePoint document details for particular record in MS CRM.

If you try to query on Document entity in MS CRM using Advanced find you will get the error-” SharePoint document entity does not support any view other than associated view”.

Now this seems trouble to get sharepoint document details. Don’t worry, as error itself says, the sharepoint document does not support any view other than associated view, We can keep building query in advance find itself.

Suppose I want to get documents details for one of my Opportunity in MS CRM , So I am building the query in the following way-
1. Look for : Document
2.Use Saved View :All Sharepoint Documents
3.If you want, you can edit the columns
4. Select Regarding(Opportunity) contains data
5. Select sub query for opportunity record(for which you want to get details)

If you click on results, it will still show you same error. Don’t worry, download the fetchXML for the query we built.

<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
  <entity name="sharepointdocument">
    <attribute name="documentid" />
    <attribute name="fullname" />
    <attribute name="relativelocation" />
    <attribute name="sharepointcreatedon" />
    <attribute name="filetype" />
    <attribute name="absoluteurl" />
    <attribute name="modified" />
    <attribute name="sharepointmodifiedby" />
    <attribute name="title" />
    <attribute name="readurl" />
    <attribute name="editurl" />
    <attribute name="author" />
    <attribute name="sharepointdocumentid" />
    <attribute name="ischeckedout" />
    <attribute name="locationid" />
    <attribute name="iconclassname" />
    <order attribute="relativelocation" descending="false" />
    <link-entity name="opportunity" from="opportunityid" to="regardingobjectid" link-type="inner" alias="ad">
      <filter type="and">
        <condition attribute="opportunityid" operator="eq" value="{83779C3E-xxxx-xxxx-xxxx-0CD3BEAFE160}" />
      </filter>
    </link-entity>
  </entity>
</fetch>

When I tried to use the fetchXML in Javascript query, I got the Sharepoint Document details in json as below-

As sharepoint document entity supports only associated view, it requires regarding object to query. So if you try to remove and link-entity tag from fetchXML, it will not return any record in response.

Now we have fetchXML which we can utilize in Javascript or C# based on requirement.

Hope this will help…
Enjoy Ms CRM!!!

Follow on Facebook- FB: MSCRM16Tech

Color Picker Custom Control for MS Dynamics CRM

What is Issue?

One of my previous projects had requirement of color picker in MS CRM to provide users flexibility to select any color to can display notifications(using HTML) on their records. But we had no other option than going with html and JavaScript web resources for this.

The Reason-

MS CRM don’t provide any color picker field out-of-box.

Solution-

As I already had a blog written for color picker using web resources and spectrum libraries-Color Picker in MS CRM ?

But it is web resource which needs much efforts to match to field styles in crm.

I have created the custom pcf control (PowerApps Custom Control). This control can be used for the single line text fields.

Depends on browser it appears in supported way-

On Browsers other than IE-

This slideshow requires JavaScript.

In IE it will appear as –

This slideshow requires JavaScript.

If you want to use it you form you can download ready custom control from here-ColorPickerSolution.zip

How to use it-
1. Import downloaded solution in CRM-
ColorPicker5

2. Create single line of Text field in any entity you want and add it on form.
3. when adding to form select field, click on change field property and in controls tab add custom control “ColorPicker”-

This slideshow requires JavaScript.

4.Save and publish the form.
Now the control is available and ready on form to use.

 

You can also download the source code from here-ColorPickerSource.zip

To work with source code you need some of the basic setup in your computer-
1. Nodejs installed
2. VS or Visual Studio Code installed
3.Understanding of below commands-


pac pcf init --namespace yourNamespace --name yourControlName --template field
npm install
npm run build
npm start
pac solution init --publisher-name yourPubliserName --publisher-prefix yourPrefix
pac solution add-reference --path "pcfproj folder path"
msbuild /t:restore
msbuild

Hope this will help…
Enjoy Ms CRM!!!

Follow on Facebook- FB: MSCRM16Tech

Add floating Chat Bot (Microsoft Virtual Agent) on Power Portal (PowerApps)

What is Issue?

Microsoft is providing the Virtual Agents(chat bots) to provide the customers better communication ability on many channels like websites, Skype, Teams. Microsoft is also introduced the Power Portals. But how to integrate this Virtual Agent(chat bot) with Power Portal?

The Reason-

Power Portal provides the way adding the extra code snippet in portals. But when we try to embed the Virtual Agents in Power Portal using this code snippet it shows the chatbot window at the bottom of the portal. Code provided by Microsoft Virtual Agent after publishing is just an IFrame. So user is not able to see floating chat bot.

Solution-

To make your Virtual agent float you need some customized embed code with some JavaScript and CSS.
1. Create a CSS Style-sheet File with below CSS-

/* Button used to open the chat form - fixed at the bottom of the page */
.open-button {
background-color: #555;
color: white;
padding: 16px 20px;
border: none;
cursor: pointer;
opacity: 0.8;
position: fixed;
bottom: 23px;
right: 28px;
width: 280px;
}
.closePopUp{
display: block;
position: fixed;
bottom: 312px;
right: 50px;
border: 3px solid #f1f1f1;
z-index: 99;
width:30px;
height:30px;
background-color: transparent;
color:#f1f1f1;
}
/* The popup chat - hidden by default */
.chat-popup {
display: none;
position: fixed;
bottom: 0;
right: 15px;
border: 3px solid #f1f1f1;
z-index: 9;
height:350px;
}

This CSS will help to float chat bot at bottom left corner.

2.Add the saved CSS file to power portal –
Navigate -> make.powerapps.com ->Apps -> Select Portal-> Click on Edit

VAPowerPortal1

3.When Editor Opens -> Click on Themes and upload the CSS
VAPowerPortal2

Save the Code Editor and close the Portal editor.

4. Open the Portal Management Model-Driven App
VAPowerPortal3

5. Navigate to Content Snippet under Content and search for “Chat Widget Code”-
VAPowerPortal4
If you want you can create other Content Snippet of HTML type and add it on “Home” Web Template.

6. Open the Content Snippet-Chat Widget Code or newly created content snippet by you-

VAPowerPortal5

7. Add the Below code in Value as HTML and save the content snippet-


<script>
  function openForm() {
    document.getElementById("myForm").style.display = "block";
  }
  function closeForm() {
    document.getElementById("myForm").style.display = "none";
  }
</script><button onclick="openForm()" class="open-button">Chat</button><button onclick="openForm()" class="open-button">Chat</button>
  <div id="myForm" class="chat-popup">
[your iframe code as belows from Microsoft Virtual Agent after Publishing]  
   <button onclick="closeForm()" class="closePopUp">X</button>
</div>
<p></p>

8. replace [your iframe code as belows from Microsoft Virtual Agent after Publishing] in above code with something like below-

VAPowerPortal8

9. Load the portal again you will find Chat option at the right-bottom corner. When you click on chat button it will open your chat bot.

This slideshow requires JavaScript.

Hope this will help…
Enjoy Ms CRM!!!

Follow on Facebook- FB: MSCRM16Tech

Make CRM user friendly using Dynamics 365 CRM new features

What is Issue?

This time it is not an issue but improvement in product to make CRM user friendly. Below are the common requirements from users-

1.There is always requirement from user that they don’t want to click multiple times to go to particular window. Many times happens when user accidentally clicks on look up field which opens up the record and to get back to previous record user have to navigate many areas on sitemap. Even user clicks on back button on browser it might take much time to load window again.
2.User not able to find the opportunity pipeline stage or its status.
3. Activities in CRM hard to manage with external calendar.

The Reason-

These are the basic requirements from the users. Previously Dynamics 365 didn’t had any option to figure out these multiple click issue and single view to manage opportunities and Activities with calendar.

Solution-

With Dynamics 365 -2020 Release Wave 1 Microsoft provided some features that will help us with our above requirements –

1. Multiple clicks-
How we avoid multiple clicks-
Microsoft provided new event for lookup fields-  addOnLookupTagClick
Using this event we can perform action when click on lookup field record.
To avoid multiple clicks we can open record in popup window with all buttons and functionality available for that record without closing parent record window.
How to use addOnLookupTagClick event-

//call function onload of form with execution context passed.
function LookupDialog(executionContext) {
    var formContext = executionContext.getFormContext();
    formContext.data.entity.attributes.forEach(function (attribute, index) {
        var attributeType = attribute.getAttributeType();
        if (attributeType == "lookup") {
            var attrName = attribute.getName();
            OpenDialogForLookup(formContext, attrName);
        }
    });
}

function OpenDialogForLookup(formContext, lookupField) {
    formContext.getControl(lookupField).addOnLookupTagClick(context => {
        context.getEventArgs().preventDefault();
        const lookupTagValue = context.getEventArgs().getTagValue();
        Xrm.Navigation.navigateTo(
            {
                pageType: "entityrecord",
                entityName: lookupTagValue.entityType,
                formType: 2,
                entityId: lookupTagValue.id
            },
            {
                target: 2,
                position: 1,
                width: {
                    value: 70,
                    unit: "%"
                }
            });
    });
}

Add the LookupDialog function on load event of form so that it will add this addOnLookupTagClick  event to all lookup fields on form. So that you don’t have to add this manually for every lookup field. If you have large number of lookup field then you can call this function asynchronously on form onload event.

After clicking on lookup field you will see window like below-
NewFeatures0

You can change the position like quick create window in UCI – change position: 2
and you can change the popup window screen coverage by changing –width: {
value: 50,
unit: "%"
}
in above code.
Below is screenshot for the same-
NewFeatures2

2.Opportunity Stages and Status in single view-
Microsoft introduced the new Kanban Control

that can be used to show opportunities based on their stages or status in single view with capability to move records from one stage to another.
NewFeatures3
How to activate this feature – Click here
This will give user a better view of opportunities in his bucket.

3.Calender Control-
Microsoft also provided new calendar control to manage activities as well as some entities which sticks to the time.
NewFeatures4

This can be also activated like Kanban control above.
This will help user to easily organize activities/records with calendar.

 

Hope this will help…
Enjoy Ms CRM!!!

Follow on Facebook- FB: MSCRM16Tech