Monday, August 21, 2017

(Post of the Month) - Build offline apps with new PowerApps capabilities

One of the most common scenarios you face as a mobile app developer is enabling your users to be productive when there is limited connectivity or no connectivity at all. PowerApps has a set of features and behaviors that help you to develop offline-capable apps. You can:
  • Launch the PowerApps mobile app when offline.
  • Run apps you develop when offline.
  • Determine when an app is offline, online, or in a metered connection by using the Connection signal object.
  • Use collections and leverage functions such as LoadData and SaveData for basic data storage when offline.

How to build offline capable apps

The first thing to discuss is how PowerApps applications access data. The primary mechanism for PowerApps applications to consume data is through a set of connectors provided by the platform such as SharePoint, Office 365 and the Common Data Service. You can also build your own custom connectors that can allow you to build any custom logic and capabilities as well as run them anywhere (such as using Azure Functions). The connectors are accessed over the internet using HTTPS which means your users will need to be online for them to access this data or functions that they offer.

Handling offline data

One of the interesting aspect of PowerApps is that it offers a set of capabilities and formulas that allow you to filter, search, sort, aggregate, insert and manipulate data that is consistent regardless of the data source such as if you are using a SQL database, a SharePoint List, a Common Data Service entity, or even collections that are locally stored the device. This allows us not only to easily build applications that can be retargeted to use a different backend but also that can be modified to use local collections instead with almost no changes to the logic. When dealing with offline data, local collections will be the primary mechanism that PowerApps offers today.

What we’ll be building

To keep the focus on the offline aspects and showing some of these new capabilities we are going to keep the scenario very simple. In this case, we are going to build an application that allows you to read twitter posts while being offline as well as tweet while being offline and when the application comes online the tweets will be posted and the local data will be reloaded.

At a high level, the application that we will be creating will do the following:
  • On application startup (First screen OnVisible property)
    • If online, we will access directly the connector to fetch the data and use it to populate a local collection
    • If offline, we will load the data from a local cache using LoadData
  • We will allow the user to post tweets, if online we will post directly and refresh the cache
  • Every 5 minutes, if online
    • We will post any tweets that we have in the cache
    • We will refresh the local cache and save it using SaveData

Building an offline Twitter app

To keep the focus on the offline aspects of app development, we'll show you a simple scenario focused around Twitter. We'll build an app that enables you to read Twitter posts and submit tweets while being offline. When the app comes online, the app posts tweets and reloads the local data.
At a high level, the app does the following:
  1. On app startup (based on the first screen's OnVisible property):
    • If the device is online, we access the Twitter connector directly to fetch data, and populate a collection with that data.
    • If the device is offline, we load the data from a local cache file using LoadData.
    • We enable the user to submit tweets - if online we post directly to Twitter and refresh the local cache.
  2. Every 5 minutes, if online:
    • We post any tweets that we have in the local cache.
    • We refresh the local cache and save it using SaveData.

Step 1: Create a new phone app

  1. Open PowerApps Studio.
  2. Click or tap New > Blank app > Phone layout.

Step 2: Add a Twitter connection

  1. Click or tap Content > Data sources, then choose Add data source on the Data sources panel.
  2. Click or tap New Connection , select Twitter , and click or tap Create.
  3. Enter your credentials, and create the connection.

Step 3: Load tweets into a LocalTweets collection on app startup

Select the OnVisible property for Screen1 in the app, and copy in the following formula:

If(Connection.Connected,

    ClearCollect(LocalTweets, Twitter.SearchTweet("PowerApps", {maxResults: 100}));

    UpdateContext({statusText: "Online data"})
    ,
    LoadData(LocalTweets, "Tweets", true);
    UpdateContext({statusText: "Local data"})
);

LoadData(LocalTweetsToPost, "LocalTweets", true);
SaveData(LocalTweets, "Tweets")

This formula checks if the device is online:
  • If the device is online, it loads into a LocalTweets collection up to 100 tweets with the search term "PowerApps".
  • If the device is offline, it loads the local cache from a file called "Tweets," if it's available.

Step 4: Add a gallery and bind it to the LocalTweets collection

  1. Insert a new flexible height gallery: Insert > Gallery > Blank flexible height.
  2. Set the Items property to LocalTweets.
  3. Add four Label controls to display data from each tweet, and set the Text properties to:
    • ThisItem.TweetText
    • ThisItem.UserDetails.FullName & " @" & ThisItem.UserDetails.UserName
    • "RT: " & ThisItem.RetweetCount
    • Text(DateTimeValue(ThisItem.CreatedAtIso), DateTimeFormat.ShortDateTime)
  4. Add an Image control, and set the Image property to ThisItem.UserDetails.ProfileImageUrl.

Step 5: Add a connection status label

Insert a new Label control, and set its Text property to the following formula:
If (Connection.Connected, "Connected", "Offline")
This formula checks if the device is online. If it is, the text of the label is "Connected", otherwise it's "Offline".

Step 6: Add a text input to compose new tweets

  1. Insert a new Text input control named "NewTweetTextInput".
  2. Set the Reset property of the text input to resetNewTweet.

Step 7: Add a button to post the tweet

  1. Add a Button control, and set the Text property to "Tweet".
  2. Set the OnSelect property to the following formula:
    If (Connection.Connected,
    
        Twitter.Tweet("", {tweetText: NewTweetTextInput.Text}),
        Collect(LocalTweetsToPost, {tweetText: NewTweetTextInput.Text});
        SaveData(LocalTweetsToPost, "LocalTweetsToPost")
    );
    UpdateContext({resetNewTweet: true});
    UpdateContext({resetNewTweet: false})
    
This formula checks if the device is online:
  • If the device is online, it tweets the text immediately.
  • If the device is offline, it captures the tweet in a LocalTweetsToPost collection, and saves it to the app.
Then the formula resets the text in the text box.

Step 8: Add a timer to check for tweets every five minutes

Add a new Timer control:
  • Set the Duration property to 300000.
  • Set the AutoStart property to true.
  • Set the OnTimerEnd to the following formula:
    If(Connection.Connected,
        ForAll(LocalTweetsToPost, Twitter.Tweet("", {tweetText: tweetText}));
        Clear(LocalTweetsToPost);
        Collect(LocalTweetsToPost, {tweetText: NewTweetTextInput.Text});
        SaveData(LocalTweetsToPost, "LocalTweetsToPost");
        UpdateContext({statusText: "Online data"})
    )
    
This formula checks if the device is online. If it is, the app tweets all the items in the LocalTweetsToPost collection.
Then it clears the collection.
Now that the app is finished, let's check out how it looks before we move on to testing. On the left, the app is connected;
and on the right, it's offline, with one tweet ready to post when it's online again.

Drilling into a CRM record from a Power BI table.


Power Bi is powerful but SQL Reporting Services remains relevant One trick with SSRS  is the ability to drill into a CRM record from a CRM SSRS report with a custom expression in the drill action of a text box.

This can also be accomplished in Power BI in a very similar way.

It works for both Online and On-Premises.
Note: If your data is On-premises and you publish to the Power BI service, your deployment must be IFD (Internet Facing Deployment) in order to launch the record.

Create a query that includes the ‘Id’ field of the entity. In my example, I am reporting on Cases, so along with other fields I have selected ‘incidentid’


Navigate to an entity record and click the ‘pop-out’. This will relaunch your record and provide the complete url.


Copy and paste into notepad. What is important are the highlighted parts

1.     Your org information

2.     The Object or Entity type code of your entity (use could also use the LogicalName=incident”)

3.     The GUID of the record – dynamically supplied by the id field in the query


<img title="Drill into CRM records from Power BI" src="https://image-pobjects.netdna-ssl.com/wp-content/uploads/2017/06/062717_2021_Drillthroug3.png" alt="" />

Return to further edit your query. Select to create a ‘Custom Column’


Build out your concatenation partly by pasting from your url you pasted into notepad and partly using available columns. Use the ampersand as the connecting operator. Be sure to put double-quotes around text (“xxx”)
I named the column: URL


You should now see a field with your url

Click ‘Close and Apply’


Select your ‘URL’ column and change the Data Category to ‘Web URL’


Add the column in a table and it will be a clickable link that launches the actual record!


the long url is unattractive. We can fix that.

1.     Select the table

2.     Click on the editing paint roller

3.     Expand the values section

4.     Toggle the url icon selection to ‘On’

 

Error while setting a value of Account lookup on Contact in D365 Javascript Web API


You may get an error while setting a value of Account lookup on Contact in D365 Javascript Web API as below:
“An undeclared property ‘customerid’ 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.”

issue arises when lookup attribute of the entity can accept multiple types of entity references.  Examples
1. Customer on Incident
2. Customer on Contact
3. Customer type field on Custom Entity.

We can resolve the issue for setting Customer type field in Javascript D365 Web API by adding a suffix entity name to the schema name of the field.

We can achieve that by adding the suffix entity name to the schema name of the field.

This  code demonstrates how to set Account on Contact.

entity["parentcustomerid_account@odata.bind"] = "/accounts(" + Account_GUID + ")";

This code demonstrates how to set Contact on Contact.

entity["parentcustomerid_contact@odata.bind"] = "/contacts(" + Contact_GUID + ")";

Fetch xml -'under'

FetchXML language provide Dynamics 365 users with more and more functionality.

This language is behind the user-friendly querying tool of Advanced Find, which offers many powerful options to filter your data.




A condition that became available with the release of CRM 2015 is ‘Under’.

This condition returns all records under the referenced record in the hierarchy of its entity context.

For example, an Account record in CRM could have a ‘Parent Account’ or many ‘Sub-Accounts’ or child accounts. It is possible since CRM 2015 possible to display these relationships as a hierarchy visualization. See attachment of a former note.

Out-of-the-box hierarchy setup with Account – the parent-child relationship within Account supports the concept of Sub-Accounts.

We have Account Adventure Works with Adventure Works Chicago and Adventure Works New York as Sub-Accounts.

We also have another parent-child relationship from Accounts being the Contact entity, Contacts being related directly to one Account.

For our example three Contacts are linked to Adventure Works, two with Adventure Works Chicago, and one with Adventure Works New York.

What do we do to see all six Contacts of Adventure Works, regardless of whether those are linked to the actual Account or a Sub-Account?!

Use  the power of ‘Under’, even across parent-child relationships.
 
From the s Advanced Find query above, look for Contacts, where their related Account (“link-entity” via the Company Name attribute), is Under our parent Account Adventure Works. This gives a list of six Contacts that are all linked to Adventure Works.
The FetchXML behind the scenes, with link-entity and Under code in bold:
<fetch version=”1.0″ output-format=”xml-platform” mapping=”logical” distinct=”false”>
<entity name=”contact”>
<attribute name=”fullname” />
<attribute name=”contactid” />
<link-entity name=”account” from=”accountid” to=”parentcustomerid” >
<attribute name=”parentaccountid” />
<filter type=”and”>
<condition attribute=”accountid” operator=”under” uiname=”Adventure Works” uitype=”account” value=”{account
guid}” />
</filter>
</link-entity>
</entity>
</fetch>
This example of use og Under can be related to other related entities that have r parent-child relationships and hierarchy configuration set up correctly
 

Microsoft Social Engagement 2017 Update 1.7


Microsoft Social Engagement 2017 Update 1.7 is ready and will be released in August 2017.

New and updated features

Microsoft Social Engagement 2017 Update 1.7 introduces the following features:

Listening and engagement on YouTube


·         Get in touch with your audience on YouTube directly from within Social Engagement.

·          Users with at least a Responder interaction role can now rate and reply to videos and comments on YouTube.

·         Add a social profile for YouTube under Settings > Social Profiles, or get a YouTube profile shared with you before you can interact on this source.

·         Additionally, Social Engagement extended the listening capabilities and is now capable of acquiring video posts and comments on YouTube channels.

·         Any user with permission to create search rules can create YouTube rules under any search topic and add YouTube channels to gather posts and comments from.

·         Keyword-based searches on the video source continue to reside under the keywords rule and now also contain comments for actively discussed video posts.

Resolved issues

In addition to the new features, Update 1.7 addresses the following issues:

  • Fixed an issue in the Social Engagement content pack for Power BI that was causing the content pack installation to fail when the Social Engagement solution has no name set (found in Settings -> Global Settings -> Default Preferences). Please download the latest content pack from AppSource to avoid this issue
  • Fixed an issue in Social Profiles displaying the wrong icons regarding acquisition usage.
Fixed an issue for Surface Hub devices where the on-screen keyboard wasn’t shown when defining keyword filters

Power bi new matrix feature - Update August 2017

You can now natively put measures on rows in a matrix in both Power BI Desktop and PowerBI.com.
This is accomplished via a new formatting option for the matrix.
Here is  a table with years on columns and measures in values (and nothing on rows).
Add three measures: Sales Amount, Total Cost, Gross Margin.

 
Initially, the matrix puts the measures across the columns

 
Change that in the formatting options.

Find the Values section on the formatting pane and look for Show On rows.
Toggle that switch to On.
That  gives you the three values on rows.



Wednesday, June 28, 2017

Install the LinkedIn Sales Navigator to Microsoft CRM Dynamics 365 Online


Pre-Requisites:


  1. D365 CRM Online Environment
  2. MSDynamics 2016 and 365 Widget Rar File.

Procedure:


The following are the steps to Install the LinkedIn widget to Microsoft CRM D365

Step1: The user will have to download the zip folder from the following LinkedIn website link. Do not unzip the folder as we need to import the solution as it is to the D365 CRM Environment.

For downloading the zip folder use the following link and save the zip folder to a particular folder.
https://www.linkedin.com/help/sales-navigator/answer/78963

Click on the zip folder download link as shown in the above image.

Step 2: Now the user will have to go D365 CRM and on the ribbon, go to Settings> Solutions as shown below

On the solution page select ‘Import’ option

Browse for the solution file that we had previously downloaded and click on ‘Open’ then ‘Next’

In the next window the user will get the information of the solution.

The user can view the information by clicking on the ‘View solution package details’.

lick on Next to proceed ahead.

Note: User will have to check the ‘Enable any SDK message processing steps included in the solution’ if it is unchecked, click on the Import option

A dialog box will pop up showing progress of the import. Once the importing has finished click ‘Next’.

A summary window will display all the imported components, indicating the solution import.

Step 3: The last step of the installation process is to assign all users a ‘LinkedIn Configuration’ security role to give them access to the integration. In the All Areas drop down, navigate to Settings > Security and click on Users.

Select all the required users to whom you want to provide the LinkedIn widget access and click on ‘Manage Roles’ at the top.

A dialog box will pop up as shown below and check ‘LinkedIn Configuration’ and click OK.

The user has finished importing and configuring the LinkedIn for Microsoft Dynamics CRM online solution.

Dynamics CRM Word Document Templates that use FetchXML for Complex Data Retrieval


It is a little bit longer but informative post so please bare with me :)

Dynamics CRM now allows you to create and persist Document Templates using Microsoft Word. I discovered one shortcoming. The user interface in CRM forces you to select a single starting entity and only entities that have a direct relationship for the data. SO what if you want to pull in data from other entities that do not have a direct relationship in your data model? Or what if you want to retrieve data from another external system?

We have already created reports in SSRS that use FetchXML as the data source so what else can we do to leverage FetchXML as the data source for the new Word Document Templates?. This approach is possible and not at all difficult leveraging the Open XML SDK for Microsoft Office.

1. Retrieve your Data

Determine what data it to be be retrieves to display in the Word Template.

The easiest way to create your FetchXML query is to do an advanced find from within CRM and then export the FetchXML from there.

So, for our example, let’s just run a default Fetch for Accounts.

Click the Download Fetch XML button and Save the resulting Fetch statement. You should have a simple FetchXML query that looks like the following:

Now that we know what data and how to get it, let’s move onto creating a Word Template.

2. Create Word Template in CRM

From the Settings menu select Templates and then Document Templates. 

From this page see the Available OOTB Templates that come with CRM and either Create a New Template or Upload one you already have.

For our approach, we will select New.

On the next screen, l select Word Template and for our example use the Account entity. Keep in mind that the entity you select is irrelevant with this approach since we will be retrieving and binding the data on our own.

After clicking Select Entity you are presented with the Select Entity screen  - pick any other Entities that have a direct Relationship to the Account. This is limiting since there might be other entities that we would like to pull in (or you might have data from other systems as well you would like to retrieve and display in the report).

At this point select Download Template and do some design in Word.

3. Populate Word Template with Content Controls

At this point we have a not-so-exciting blank document Open in Word. The first thing we need to do is Show the Developer tab in the Word Ribbon.


 Now we can insert Plain Text Content Controls to display the data we would like in the document.

 click the 2nd Aa button in the Controls section of the Developer tab.

See the Content Control appear in your document at the position of your cursor that reads "Click or tap here to enter text".

The Content Control is basically just a placeholder that you can use to control the layout of your document.

We still have not specified what data this field should display. - select the Content Control and click Properties from the Controls section of the Developer tab.

Now here is a bit of the magic, you must be familiar with what data you will be retrieving which we already determined in Section 1 when defining our Fetch.

You will need the following function to execute your Fetch and to return the results as a DataTable:

The call for that will look like the following:

This gives you a resulting XML in accountDataAsXML:

Let’s say for this first control we want to display the Account Name. The XPath for that in XML will be: /ReportData/Account/name.

XPath is straight forward you just follow down the hierarchy of the XML.
With that information, populate the tag on our Content Control so it looks like the following:


To keep this extremely simple since save the template and upload it into CRM. Just like before, from the Settings menu select Templates and then Document Templates. From this page, you can select UPLOAD TEMPLATE and browse out to the Word Template on your local system.



4. Retrieve Word Template Contents

 When you get ready to run the report (how you choose to do this is entirely up to you and can be custom workflow activity, plugin, etc.) you will need to retrieve the Word Template Contents. Here is a function to get the Document Template ID which is a basic retrieve of the DocumentTemplate entity with a name filter.

Once you have that, you can get the Document Template contents as a byte array like this:

5. Merge the data into the Word Document Template



So now at this point we have our CRM data in an XML string and our Word Document contents in a byte array and we need to get the two to merge. Here is an example of how to do that:

that’s a large amount of code, what does it all do? While most of this understandable to a CRM developer, the main part to pay attention to is the using statement with the WordprocessingDocument. To understand that code, take a quick detour into the land of OpenXML.

All Microsoft Office documents are just a bunch of files zipped together? Take that Word Document Template we have been working with on your machine for this example and change the .docx extension to a .zip. Now extract that file.? You might see something like this:

We won’t examine all of these files, look at the document.xml in the word folder. If you open that file then you will see an XML representation of what is in your Document starting with a ton of namespaces for the different Office libraries. After that you get into the body of the document which will look something like this:

Notice anything familiar? - that XPath that we entered on the Content Control is there in the tag  - right where we put it.

The Open XML SDK for Microsoft Office is what allows you to manipulate this underlying XML. So let’s do a quick breakdown of that code above.

To save the generated document as a Note on an entity, you could do something like the following (which again is fairly common CRM coding):

that was a whirlwind tour of how to leverage FetchXML for data retrieval and use that data within a Word Document Template.  To recap the steps are:

1.     Retrieve your data

2.     Create Word Template in CRM

3.     Populate Word Template with content control placeholders

4.     Retrieve the Word Template contents

5.     Merge the data into the template using the Open XML sdk.

 Keep in mind, that FetchXML is obviously only one choice for data retrieval and we chose that since we were porting over existing SSRS reports. You could also leverage other means of gathering data such as web services to external systems. The only real requirement is that the data you retrieve eventually ends up in an XML string so you can leverage XPath to bind it to the Content Controls.

More Than One Form Was Opened at Once for the Lookup Control

In Dynamics 365 for Finance and Operations, when subscribing to a lookup event to modify an existing lookup on a form control, you must...