Archive

Archive for the ‘CRM’ Category

[Step by Step] Model-driven apps | In-app notifications

Using in-app notification feature (Preview) we can notify Users with in the Model-driven apps. In this article lets learn how to enable the feature and use the in-app notifications with different options step by step.

Enable In-app notifications feature:

  • Connect to Power Apps Maker Portal.
  • Open the ‘Model Driven App’ using ‘Edit in preview’ option.
  • In the App Editor, select ‘Settings -> Upcoming’ and enable the In-app notifications (Preview) as below.

Create a Test User:

  • To test the In-app notifications, create a new user account. This User acts as recipient of notification.
    • Note: If you already have more users in your environment, skip this step and use one of the existing Users as recipient.
  • I’ve created an User named ‘Test User 1’ to send the notifications to.
  • Open the Model driven app in another browser using the Test User account.
  • Next copy the ‘Test User 1’ GUID by opening the User from ‘Advanced Find’. We will use this GUID while creating notification.

As we completed pre-requisites, its time to create notifications.

Creating our first notification:

  • Notification features uses an OOB table called “appnotification”.
  • We create a record in ‘appnotification’ table which turns out to be a notification for targeted User.
  • Each notification row is meant for a single user, identified by the Owner column value.
  • If a notification needs to be sent to multiple users, a record needs to be added for each recipient.
  • The sender controls the recipient through the Owner column.

Following is code snippet is using ‘Client API’ to create a basic notification.

function showBasicNotification() {
    // GUID of User (i.e.,Test User 1 in my case) whom you want to send the Notification to.
    var systemuserid = "0758fd55-c2ca-ec11-a7b5-00224808dd66";
    var notificationRecord =
    {
        "title": "Welcome",
        "body": "Welcome to the world of app notifications!",
        "ownerid@odata.bind": "/systemusers(" + systemuserid + ")",
        "icontype": 100000000, // info
        "toasttype": 200000000 // timed
    }
    // Create notification record
    Xrm.WebApi.createRecord("appnotification", notificationRecord).
        then(
            function success(result) {
                console.log("notification created with ID: " + result.id);
            },
            function (error) {
                console.log(error.message);                
            }
        );
}
  • Register the showBasicNotification() function on one of the form jscript events (i.e., On Load/On Save/Field_OnChange).
  • For this blog post, I’ve registered script on ‘On Load’ event.
  • Use Browser ‘DevTools’ (F12) to check the successful execution of function.
  • Up on executing the script, end user (i.e., Test User 1) would get a notification as below.

Notification with Action(s):

  • Using “data” tag we can create notifications that include actions, custom body definitions, and custom icons.
  • Following code snippet contain 2 actions (i.e., 2 URLs to navigate to) in Notification.
    • ‘actions’ is an array.
function showNotificationWithMultipleActions() {
    // Notification with multiple actions as center dialog 
    var systemuserid = "0758fd55-c2ca-ec11-a7b5-00224808dd66";
    var notificationRecord =
    {
        "title": "Different Search Options",
        "body": "This is to inform you that you can use following search options",
        "ownerid@odata.bind": "/systemusers(" + systemuserid + ")",
        "icontype": 100000000, // info
        "data": JSON.stringify({
            "actions": [
                {
                    "title": "Bing",
                    "data": {
                        "url": "https://bing.com",
                        "navigationTarget": "dialog"
                    }
                },
                {
                    "title": "Google",
                    "data": {
                        "url": "https://google.com",
                        "navigationTarget": "dialog"
                    }
                }
            ]
        })
    }
    Xrm.WebApi.createRecord("appnotification", notificationRecord).
        then(
            function success(result) {
                console.log("notification created with multiple actions: " + result.id);
            },
            function (error) {
                console.log(error.message);
            }
        );
}
  • Up on execution, End User gets a notification with 2 navigation actions as below.

Notification with a custom Title and Body:

  • The data field supports overriding the Title and Body simple strings with a limited subset of markdown based.
  • Below is the supported markdown.
Text StyleMarkdown
Bold**Bold**
Italic_Italic_
Bullet list- Item 1\r- Item 2\r- Item 3
Numbered list1. Green\r2. Orange\r3. Blue
Hyperlinks[Title](url)
  • Newlines can be included with the body using \n\n\n\n.
  • Following is a code sample using ‘Markdown’ to customize Title and Body.
    • Under ‘actions’ tag, url is pointing to an existing record.
function notificationWithCustomTitleAndBody() {
    var systemuserid = "0758fd55-c2ca-ec11-a7b5-00224808dd66";
    var notificationRecord =
    {
        "title": "Example of Custom Title and Body",
        "body": "Maria Campbell mentioned you in a post.",
        "ownerid@odata.bind": "/systemusers(" + systemuserid + ")",
        "icontype": 100000004, // mention (Displays @ symbol)
        "data": JSON.stringify({
            "title": "[Potential Prospect](?pagetype=entityrecord&etn=raj_prospect&id=48f5d750-cbca-ec11-a7b5-00224808dd66)",
            "body": "Here is a [Potential Prospect](?pagetype=entityrecord&etn=raj_prospect&id=48f5d750-cbca-ec11-a7b5-00224808dd66)",
            "actions": [
                {
                    "title": "View record",
                    "data": {
                        "url": "?pagetype=entityrecord&etn=raj_prospect&id=48f5d750-cbca-ec11-a7b5-00224808dd66"
                    }
                }
            ]
        })
    }
    Xrm.WebApi.createRecord("appnotification", notificationRecord).
        then(
            function success(result) {
                console.log("notification created with custom title and body: " + result.id);
            },
            function (error) {
                console.log(error.message);
            }
        );
}
  • Up on execution End User receives notification as below.

Notification with a custom Icon:

  • Within the notification, set iconType to Custom and in the body, include iconUrl with a value pointing to a web resource.
    • “icontype”: 100000005, // custom
    • “data”: “{ ‘iconUrl’: ‘/WebResources/cr245_AlertOn’}”
  • The icon can be either an SVG or PNG file type.
  • Following is the ‘notificationRecord’ object.
var notificationRecord = 
{
  "title": "Welcome",
  "body": "Welcome to the world of app notifications!",
  "ownerid@odata.bind": "/systemusers(" + systemuserid + ")",
  "icontype": 100000005, // custom
  "data": "{ 'iconUrl': '/WebResources/cr245_AlertOn'}"
}
  • Notification with Custom icon looks as below.

Key points on Notification usage:

  • If you don’t specify “ownerid@odata.bind” in ‘notificationRecord’ object, notification will go to the User who created Notification.
  • Notification Polling:
    • In-app notifications uses polling to retrieve notifications periodically when the app is running.
    • New notification are retreived at start of the model-driven app and when a page navigation occurs as long as the last retreival is more than one minute ago.
    • If a user stays on a page for a long duration, new notifications will be retrieved.
  • Notifications appear in the notification center until the recipient dismisses them or they expire. By default, a notification expires after 14 days but your administrator can override this setting
  • You can change in-app notification behavior by setting Toast Type to one of the following values.
Toast TypeBehaviorValue
TimedThe notification appears for a brief duration (the default is four seconds) and then disappears.200000000
HiddenThe notification appears only in the notification center and not as a toast notification.200000001
  • You can change the in-app notification icon by setting Icon Type to one of the following values.
Icon TypeValueImage
Info100000000Info Icon
Success100000001Success Icon
Failure100000002Failure Icon
Warning100000003Warning Icon
Mention100000004Mention Icon
Custom100000005

🙂

Categories: CRM

Dynamics 365 and Microsoft Power Platform | Release planner

As the Dynamics Release Wave 1 2022 is being deployed this month, if you are planning for an upgrade of your existing system, Release planner tool (BETA) helps you to organize and plan for New and Upcoming features.

  • To get started, first create an account. Alternately you can connect using your Work Account.
  • Pick the feature you want to try add that to your plan by clicking ‘+ To my plan’.
    • Click ‘Learn more’ to understand about the feature.
  • Once you add the Features, go to ‘My Release Plans’ for collated list.
  • Refer this article by Microsoft FastTrack Team on how to plan and approach the products release wave upgrades.

🙂

Categories: CRM, Dynamics 365 Tags:

[Step by Step] Using JSLint extension in VSCode

In this article, lets see how to Install and use JSLint extension in VSCode.

What is JSLint:

  • JSLint is a JavaScript program that looks for problems in JavaScript programs. It is a code quality tool.
  • JSLint takes a JavaScript source and scans it. If it finds a problem, it returns a message describing the problem.

Install JSLint extension in VSCode:

  • From the VSCode ‘Extensions’, search for ‘JSLint’ and Install.
  • Next, we need to install ‘jslint’ Globally by running ‘npm install -g jslint’ command from Terminal.
  • All the required files gets installed and Terminal looks as below.

Run JSLint on a JavaScript File:

  • Open the JavaScript file, which you want to validate in VSCode.
  • Open the Terminal and run ‘jslint {file_name}’ command. In my case, its ‘jslint HelloWorld.js’.
  • Script violations will be listed in Terminal as below.

🙂

Categories: JScript Tags: ,

Dataverse | New Auditing Features

February 14, 2022 Leave a comment

Audit data is now stored separately from customer records so an organization’s audit log can grow to many terabytes in size without limiting available Database capacity.

Audit Retention Policy:

  • In the ‘Admin Center’, on the ‘Environment’ page now we have ‘Auditing -> Manage’ option to set the Audit Retention Policy.
  • Select one of the options from the dropdown to set the retention duration.
  • Audit records are automatically deleted after the retention period is over, relieving administrators from the burden of deleting audit data manually. 
  • It is also possible to keep the audit log indefinitely by not specifying a retention period.

Free up capacity:

  • With the new audit deletion options, Administrators can delete the logs of one or more audited tables, delete the user access logs, or delete logs up to a specific date in order to free up storage space.

Refer the docs link for more insights.

Dataverse | Plugins | ILMerge Alternative | Shared Project

Role of ILMerge in Plugin Development:

If you are familiar with writing Plugins in Dataverse, chances are that you would have used ILMerge to merge the Assemblies.

In a typical Dynamics Plug-in development, we will have following .Net Class Library Projects.

  • Plugins.csproj
  • Plugins.Helper.csproj

When you compile above projects, you get two .dlls (i.e., Plugins.dll and Plugins.Helper.dll). As we can only deploy one .dll to Dataverse, we use ILMerge to merge both Plugins.dll and Plugins.Helper.dll in to one.

Is it recommended to use ILMerge in Plugin development? Answer is No. As per this Microsoft article ILMerge is not supported in Plugins development.

Now whats the alternative? Answer is Shared Projects.

Steps to use Shared Projects in Plug-in Development:

To explain the Shared Projects, I am going to build a simple Plugin project ‘Plugins.csproj’ with ‘PreAccountCreate’ class, which refers a ‘Shared’ Helper project ‘Plugins.Helper’.

  • Create a new C# class library project and add ‘PreAccountCreate’ class as below.
    • You can copy the code I’ve used from here.
  • Now lets add a ‘Shared’ Helper project which our Plugin project would refer.
  • Right click your Solution and click ‘New Project’.
  • Select a Project template of type C# ‘Shared Project’.
  • Give a Name to your ‘Shared Project’.
    • I’ve named it as ‘Plugins.Helper’.
  • ‘Plugins.Helper’ Shared Project, looks as below in the Solution Explorer.
  • Now add a Class file ‘AccountHelper.cs’ to the ‘Shared Project’.
  • I’ve added a simple function ‘GetAccountName()’ which returns ‘Microsoft India’.
  • To use the ‘Shared Project’ in our Plug-in project, right click ‘Plugins’ project and add ‘Reference’.
  • From ‘Shared Projects’, choose your project (i.e., Plugins.Helper in my case).
  • Once you referred the ‘Shared Project’ in your Plugin project, it looks as below.
  • Now its time to call ‘GetAccountName()’ from our ‘PreAccountCreate’ class.
  • Sign the Assembly.
  • Build the Plug-in project and you would get the ‘Plugins.dll’ in bin/Debug folder.
  • Go ahead and deploy the ‘Plugins.dll’ to Dataverse and register step using Plugin Registration Tool.

🙂

Categories: Plug-Ins Tags: , ,

Dataverse | Modernize business units (Public Preview)

November 12, 2021 Leave a comment

With this preview feature,

  • Users are no longer restricted to accessing/managing data in their own business unit.
  • Users can now access and own records across business units.
  • Security roles from different business units can be assigned to the users regardless of the business unit the users belong to.
  • This feature enables the Owning Business Unit column of the record so that it can be set/updated by the users.
  • The Owning Business Unit column determines the business unit that owns the record.
  • Business units’ data access can now support “Matrix data access” structure.

Modernize Business Unit – Feature Goals:

Modernize Business Unit – Design Elements:

New Organization Settings while Changing the User’s Business Units:

Refer following videos to learn more about this preview feature:

🙂

Categories: CRM

Dynamics CRM | Microsoft Power Apps | Legacy OData v2.0 Service removal date

November 12, 2021 Leave a comment

OData v2.0 endpoint:

  • The Organization Data Service (Also known as the OData endpoint or the REST endpoint when it was released, the Organization Data Service offers limited capabilities to only create, retrieve, update, or delete table data) is an OData v2.0 endpoint introduced with Dynamics CRM 2011.
  • The Organization Data Service was deprecated with Dynamics 365 Customer Engagement v8.0 in favor of the Web API, an OData v4.0 service.
  • Organization Data Service is planned to remove on November 11, 2022. Any code that uses the Organization Data Service should be migrated to use the Web API before that time.
  • Its recommended to Use the Microsoft Dataverse Web API.

Action Required:

  1. Use the Solution Checker to detect any JavaScript web resource code. The rule web-avoid-crm2011-service-odata should detect use in client-side code.
  2. Check any other code, including PowerShell scripts, that send requests to this endpoint: /xrmservices/2011/organizationdata.svc.
  3. Check any Power BI reports or Excel Data sources that may be using this endpoint.

Refer this link for more details.

🙂

Categories: CRM Tags: ,

Dataverse | New Text Formats | json, richtext

September 16, 2021 Leave a comment

Text in Dataverse is a data type that can store a max of 4000 characters. Text has multiple formats that instruct the UI to treat it differently.

As an example, Email is a text format tells the client to treat the contents of the field as an email. It can display the data as a link that, when clicked, launches your default email client and inserts the address in the To: field.

There are 2 new formats, json and richtext have been introduced.

Json 

  • json format will store text strings in a json format.
  • This format will not perform any validations on the correctness of the json. It simply allows you to store, view, and retrieve the content with json markup.
  • This is currently limited for use on non-SQL tables (like Data Lake).

Richtext 

  • richtext format will allow the use of markup tags to format your text when viewed in a compatible control.
  • By setting this value you can enable richtext for any other text or multiline text column.
  • A control is coming soon in the Canvas and Model Driven space that will be used whenever a column indicates it is richtext.

Please refer this article for more details.

🙂

Categories: CRM

Azure DevOps (ADO) | Pipeline failure | Could not get the latest source version

September 15, 2021 1 comment

I’ve created a new ADO project and configured a Pipeline to export Power Apps solution. While running the Pipeline it failed in immediately with following exception.

The pipeline is not valid. Could not get the latest source version for repository…

Reason:

  • Under the ‘Get sources’ step of the Pipeline, ‘Default branch for manual and scheduled builds’ was auto selected as master.
  • However my existing Branch Name was main.
What is the difference between master and main branches:
  • In ADO, default ‘Branch Name’ used to be master until October 2020. Post that default ‘Branch Name’ changed to main.
  • This Branch name change was not taken affect in Pipelines. New Pipeline defaults the Branch Name to master which is invalid. It has to be main.
  • Refer this ADF product blog for more details.

Fix:

  • In the ‘Get sources’ step of the pipeline, change the Default Branch from master to main.
  • Save and Rerun the pipeline.

🙂

Categories: Azure, CRM Tags: , , ,

Power Platform Tools | Developer Toolkit for Visual Studio 2019

September 1, 2021 4 comments

Power Platform Tools for Visual Studio supports the rapid creation, debugging, and deployment of plug-ins.

You may note that Power Platform Tools for Visual Studio is similar in appearance and function to the Developer Toolkit for Microsoft Dynamics CRM 2013.

While Power Platform Tools for Visual Studio is similar in appearance and function to the Developer Toolkit for Microsoft Dynamics CRM 2013, Power Platform Tools is a new product and completely independent of the Developer Toolkit.

Power Platform Tools is not directly compatible with any templates or projects from the Developer Toolkit and vice versa.

Steps to enable ‘Power Platform Tools’ extension in VS 2019:

  • From the Visual Studio 2019, click on ‘Extensions -> Manage Extensions’.
  • Expand the left navigation panel node Online > Visual Studio Marketplace. Search for “Power Platform Tools”, then click on ‘Download’.
  • Post Download, close all the Visual Studio instances and wait for few seconds, you would get below installer screen.
  • Click ‘Modify’ and complete the installation.
  • Post installation, open the Visual Studio and initiate ‘Create New Project’.
  • You should find ‘New Visual Studio Solution Template for Dynamics 365’ solution template.
  • Provide Project Name and click ‘Create’ which will open up the familiar ‘Developer Toolkit’.
Note:
  • After installing Power Platform Tools, you will not find any Power Platform Tools related menu items or views in the Visual Studio user interface until you create or load a Visual Studio solution that contains at least one project created from a Power Platform Tools template.

Refer Microsoft docs for detailed steps to install Power Platform Tools on Visual Studio.

🙂