Friday, April 22, 2016

Call Workflow within Workflow in MS Dynamics CRM 2011/2013/2015/2016

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;
using Microsoft.Crm;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Workflow;
using Microsoft.Xrm.Sdk.Workflow.Activities;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Messages;

namespace cel_WorkflowActivities
{

    public sealed class runRelatedWorkflow : CodeActivity
    {
        [RequiredArgument]
        [Input("Workflow To Execute")]
        [ReferenceTarget("workflow")]
        public InArgument<EntityReference> workflowId { get; set; }

        [RequiredArgument]
        [Input("Related Entity Logical Name")]

        public InArgument<string> entityName { get; set; }

        [RequiredArgument]
        [Input("Attribute Logical Name")]
        public InArgument<string> attributeName { get; set; }


        protected override void Execute(CodeActivityContext executionContext)
        {
            StringBuilder sb = new StringBuilder("starting; ");

            try
            {

                Guid wFlowId = ((EntityReference)executionContext.GetValue(this.workflowId)).Id;
                string eName = executionContext.GetValue(this.entityName);
                string fName = executionContext.GetValue(this.attributeName);
                IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
                IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
                IOrganizationService service = serviceFactory.CreateOrganizationService(context.InitiatingUserId);

                QueryByAttribute q = new QueryByAttribute(eName);
                q.Attributes.AddRange(fName, "statecode");
                q.Values.AddRange(context.PrimaryEntityId.ToString(), "Active");
                EntityCollection retrieved = service.RetrieveMultiple(q);

                sb.Append(string.Format("Retrieved {0} records; ", retrieved.Entities.Count.ToString()));
                foreach (Entity c in retrieved.Entities)
                {
                    ExecuteWorkflowRequest exec = new ExecuteWorkflowRequest();
                    exec.EntityId = c.Id;
                    exec.WorkflowId = wFlowId;
                    sb.Append(string.Format("Executing workflow on record with id {0}; ", c.Id.ToString()));
                    service.Execute(exec);
                }

                sb.Append("done");
            }
            catch (Exception ex)
            {
                throw new InvalidPluginExecutionException("An error occurred running related workflows: " + ex.Message);
            }
        }
    }
}

Tuesday, April 19, 2016

Differences between Dynamics CRM Workflows and Dialogs and Plugins

Differences between Dynamics CRM Workflows and Dialogs
WorkflowsDialogs
Can be either started by a user or can be automated.Must be started by a user.
Asynchronous processes, and no user input. background process.Synchronous processes, require user input, a wizard-like interface will popup
Triggers are supported for workflowsTriggers are not supported for dialogs.


Differences between Workflows and Plug-ins
Plug-inWorkflow
Executes immediately before or after the core operation (synchronous).Can also be queued to execute after the core operation (asynchronous).Queued to execute after the core operation (always asynchronous).
Synchronous plug-ins can increase the platform’s response time because they are part of the main platform processing. Asynchronous plug-ins have less impact on server response time because the code is run in a different process.Less impact on server response time because the code is run in a different process.
To register a plug-in with the platform requires a System Admin or System Customizer security role and membership in the Deployment Administrator group.Users can interactively create workflows in the Web application. However, to register a custom workflow activity, the deploying user must have the same security roles as those required for registering plug-ins.
A plug-in registered for synchronous or asynchronous execution is restricted to complete its execution within a 2 minute time limit.Works well for either short or long processes.
Both online and offline are supported. Works when the Microsoft Dynamics CRM for Outlook client is offlineWorkflows do not execute when offline.
Plug-ins execute to completion. Plug-ins must be written to be stateless where no in-memory data is persisted.Workflows can be paused, postponed, canceled, and resumed through SDK calls or by the user through the Web application. The state of the workflow is automatically saved before it is paused or postponed.
Plug-ins can perform data operations on behalf of another system user.Workflows cannot use impersonation.


Differences between Background(Asynronous) VS Run-time Workflow
Real Time Workflow:
1. An RTW triggered on a particular event (e.g. Create, Update, Assign and Delete) can also be configured to run on demand. This will still run immediately once triggered rather than being queued to run at later point of time as an asynchronous workflow would.

2. Unlike an async workflow, when a real time workflow runs it can do so in the context of the workflow owner, or can be configured based on user who made changes to record.

3. RTW do not contain any delay or wait activities step.

4. CRM users must have organizational permission on the following two security levels to create and activate a real time workflow:

CRM provides an option to convert existing asynchronous workflows into real time workflows without the need to define any manual steps & vice-versa... 

Asynchronous Workflow:
Asynchronous workflows do remain an important option for carrying out high volumes of processes which aren't time critical, for example creating activities or sending emails. In these examples the operation will take place without halting the user process.

Monday, April 18, 2016

Create Dynamic Table Row in MS CRM 2011/2013/2015/2016



<html><head><meta charset="utf-8"></head><body>


    <link href="../StylesheetLibrary/payperioddashboardstyles.css" rel="Stylesheet" type="text/css">
    <script src="../../ClientGlobalContext.js.aspx" type="text/javascript"></script>
    <script src="../JavaScriptLibrary/jquery1.6.2.min.js" type="text/javascript"></script>
    <title>EEPRs</title>
    <script language="javascript" type="text/javascript">
        /************************************************
        getParameters - function to handle the extraction
        of the extraqs parameters
        ************************************************/
        function getParameters(values, unescapeValues) {
            //Taken from samples in the CRM SDK
            var parameters = new Array();
            var vals = ('?' == values.charAt(0) ? values.substr(1) : values).split("&");
            for (var i in vals) {
                vals[i] = vals[i].replace(/\+/g, " ").split("=");
                if (unescapeValues) {
                    parameters[unescape(vals[i][0])] = unescape(vals[i][1]);
                }
                else {
                    parameters[vals[i][0]] = vals[i][1];
                }
            }

            return parameters;
        }
        /***   end getParameters   ***/

        function openPayperiodFee(feeId) {
            Xrm.Utility.openEntityForm("cel_payperiodfee", feeId);
        }
        function loadData() {

            var requestUrl = serverUrl + "/xrmservices/2011/OrganizationData.svc/cel_payperiodfeeSet?$select=cel_payperiodfeeId,cel_FeeParty,cel_name,cel_Quantity,cel_Amount,cel_ExtendedAmount,cel_TotaltoSendtoICP&$filter=cel_PayPeriod/Id eq (guid'" + payperiodId + "')";
            //   prompt("the url", requestUrl);
            $.ajax({
                type: "GET",
                contentType: "application/json; charset=utf-8",
                datatype: "json",
                url: requestUrl,
                beforeSend: function (XMLHttpRequest) {
                    //Specifying this header ensures that the results will be returned as JSON.             
                    XMLHttpRequest.setRequestHeader("Accept", "application/json");
                },
                success: function (data, textStatus, XmlHttpRequest) {
                    var results = data.d["results"];

                    for (resultKey in results) {
                        var rowHTML = "<tr  onclick=\"openPayperiodFee('" + results[resultKey].cel_payperiodfeeId + "')\">";
                        rowHTML += "<td>" + getFeePartyName(getVal("cel_FeeParty", results[resultKey])) + "</td>";
                        rowHTML += "<td>" + getVal("cel_name", results[resultKey]);
                        rowHTML += "<td>" + getVal("cel_Quantity", results[resultKey]);
                        rowHTML += "<td>" + getAmountValue(getVal("cel_Amount", results[resultKey]));
                        rowHTML += "<td>" + getVal("cel_ExtendedAmount", results[resultKey]);
                        rowHTML += "<td>" + getVal("cel_TotaltoSendtoICP", results[resultKey]);
                        rowHTML += "</tr>";

                        $("#resultsTable > tbody:last").append(rowHTML);
                    }
                },
                error: function (XmlHttpRequest, textStatus, errorThrown) {
                    alert(XmlHttpRequest.status + "\n" + textStatus + "\n" + errorThrown);
                }

            });
        }
        function getAmountValue(objAmount) {
            return (objAmount != null) ? objAmount.Value : "";
        }

        function getFeePartyName(objFeeParty) {
            var feePartyName = '';

            if (objFeeParty != null) {
                if (objFeeParty.Value == '279140000')
                    feePartyName = "Celergo"
                else if (objFeeParty.Value == '279140001')
                    feePartyName = "One Price"
                else if (objFeeParty.Value == '279140002')
                    feePartyName = "ICP"
            }
            return feePartyName;
        }
        function getVal(field, fileData) {
            if (fileData && fileData.hasOwnProperty(field)) {
                var tmpData = "no data";
                if (fileData[field] != null) {
                    if (fileData[field].hasOwnProperty("__metadata")) {
                        switch (fileData[field].__metadata.type) {
                            case "Microsoft.Crm.Sdk.Data.Services.EntityReference":
                                tmpData = fileData[field].Name;
                                break;
                            default:
                                tmpData = fileData[field];
                                
                                break;
                        }

                    }

                    else {
                        tmpData = fileData[field];
                    }
                }
                else {
                    tmpData = "&nbsp;";
                }

                return tmpData;
            }
        }

    </script>
<table><tbody><tr><td>Click anywhere in the row to open the record</td></tr></tbody></table>
<table id="resultsTable" style="vertical-align: top;" border="1">
        <tbody>
            <tr>
                <td style="width: 100px; font-weight: bold;">
                    Fee Party
                </td>
                <td style="width: 100px; font-weight: bold;">
                    Invoice Description
                </td>
                <td style="width: 100px; font-weight: bold;">
                   Celergo Quantity
                </td>
                <td style="width: 100px; font-weight: bold;">
                    Amount
                </td>
                <td style="width: 100px; font-weight: bold;">
                    Total to Bill to Client
                </td>
                <td style="width: 100px; font-weight: bold;">
                    Total to Send to ICP
                </td>
            </tr>
        </tbody>
    </table>
    <script language="javascript" type="text/javascript">
        var context = GetGlobalContext();
        var serverUrl = context.getClientUrl();
        var userId = context.getUserId();

        var parameters = getParameters(location.search, true);
        var payperiodId = parameters["id"] || "noid";
        if (payperiodId != "noid") {
            loadData();
        }
        else {

        }

    </script>


</body></html>

Hope it will Help!!

Sunday, April 17, 2016

Scheduled Workflows in CRM

Workflows are a valuable tool within Microsoft Dynamics CRM. So what if you want to schedule workflows at a certain time, or execute a workflow every night, week, or month? This blog will show you how to create a recursive workflow to be executed for a certain time, and how to create scheduled workflows in CRM.
In this example, we will create workflows to be executed every night, which will check if the account’s primary contact is empty. If it is empty, the workflow will find its primary contact and populate the primary contact field.
  1. Create the 1st new workflow with Contact as the primary Entity.
    Set this workflow as “Child Process” and as “on-demand” as well:
    scheduled workflows in CRM
  2. Add a wait condition to start every day or every 24 hours.
  3. Add check conditions and actions. One of the actions is called a child workflow, the identical second workflow, right before stop itself.
    When complete, it will look like the sample below:
  4. Create the second workflow similarly.
  5. The workflow will need to be to be triggered manually the first time.
Once you have triggered one of the workflows, it will automatically execute and trigger the other workflow right before it stops. Therefore, only one of the workflows will be in  process and handle the same job recursively.
If you want the workflow to start at 3:00 a.m. and you don’t want to stay up in the middle of the night to manually trigger it, you can create a third workflow, which will have a similar timeout condition set as step 2. The third workflow will trigger the first workflow instead of having to be manually triggered by you.
Similarly, if you just want to create a scheduled workflow instead of a recursive workflow, you can simply create the first workflow with a timeout condition set as step 2; then, wait for certain time to trigger the second workflow.
In summary, you can set up two identical-child-type workflows to handle recursive jobs; add an additional timeout workflow to handle any scheduled jobs.
If this was helpful, 

Saturday, April 16, 2016

Add Two Decimal Digit

Add Two Decimal Digit

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;
using Microsoft.Crm;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Workflow;
using Microsoft.Xrm.Sdk.Workflow.Activities;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Messages;

namespace glt_WorkflowActivities
{

    public sealed class addTwoDecimals : CodeActivity
    {
        [RequiredArgument]
        [Input("First Decimal")]
        public InArgument<Decimal> FirstDecimal { get; set; }

        [RequiredArgument]
        [Input("Second Decimal")]
        public InArgument<Decimal> SecondDecimal { get; set; }

        [RequiredArgument]
        [Input("Third Decimal")]
        public InArgument<Decimal> ThirdDecimal { get; set; }

        [RequiredArgument]
        [Input("First Whole Number")]
        public InArgument<int> FirstWhole { get; set; }

        [RequiredArgument]
        [Input("Second Whole Number")]
        public InArgument<int> SecondWhole { get; set; }

        [RequiredArgument]
        [Input("Third Whole Number")]
        public InArgument<int> ThirdWhole { get; set; }

        [Output("Output Decimal")]
        public OutArgument<Decimal> outDecimal { get; set; }

        [Output("Output Whole Number")]
        public OutArgument<int> outWhole { get; set; }

        protected override void Execute(CodeActivityContext executionContext)
        {
            decimal tmpTotal = 0m;
            decimal? tmpHrs = this.FirstDecimal.Get(executionContext);
            tmpTotal += (tmpHrs ?? 0);

            tmpHrs = this.SecondDecimal.Get(executionContext);
            tmpTotal += (tmpHrs ?? 0);

            tmpHrs = this.ThirdDecimal.Get(executionContext);
            tmpTotal += (tmpHrs ?? 0);

            tmpHrs = this.FirstWhole.Get(executionContext);
            tmpTotal += (tmpHrs ?? 0);

            tmpHrs = this.SecondWhole.Get(executionContext);
            tmpTotal += (tmpHrs ?? 0);

            tmpHrs = this.ThirdWhole.Get(executionContext);
            tmpTotal += (tmpHrs ?? 0);

            this.outDecimal.Set(executionContext, tmpTotal);
            this.outWhole.Set(executionContext, Convert.ToInt16(tmpTotal));
        }
    }
}

Friday, April 8, 2016

Set Values of all Data Types using Web API in Dynamics CRM 2015/16

Create with all Data Type (Account) 

function AccountWithAllDT() {
    try {
        //declare variables
        var uri = null;
        var stringJSONAcc = null;
        var entityIdWithLink = null;
        var getEntityId = null;

        //create JSON object 
        var JSONAcc = {};

        //set fields using JSON object
        //Single line of text
        JSONAcc.name = "CompanyName Pvt. Ltd."; //Account Name
        
        //Option Set
        JSONAcc.accountcategorycode = "2" //Category : 1--> Preferred Customer, 2--> Standard

        //Two Options
        JSONAcc.donotsendmm = false;//Marketing Materials : 0-->False/Send, 1-->True/Do Not Send
        //Whole Number
        JSONAcc.numberofemployees = 151; //Number of Employees

        //Decimal Number
        JSONAcc.new_decimalnumber = 345.12; //Decimal Number (Custom Field) 

        //Lookup
        JSONAcc["transactioncurrencyid@odata.bind"] = "/transactioncurrencies(4e950855-9eb3-e511-80de-6c3be5a8ad10)"; //Currency

        JSONAcc["primarycontactid@odata.bind"] = "/contacts(DFE54660-37CD-E511-80DE-6C3BE5A831DC)" //Primary Contact

        //Currency
        JSONAcc.creditlimit = 15000; //Currency Limit

        //Date 
        JSONAcc.new_dateonly = new Date();//Date Only (Custom Field)

        //convert JSON object to string
        stringJSONAcc = JSON.stringify(JSONAcc);

        //url for ajax request to create account
        uri = Xrm.Page.context.getClientUrl() + "/api/data/v8.0/accounts";

        //ajax request to create account
        $.ajax({
            type: "POST",
            dataType: "json",
            contentType: "application/json; charset=utf-8",
            url: uri,
            data: stringJSONAcc,
            beforeSend: function (XMLHttpRequest) {
                XMLHttpRequest.setRequestHeader("Accept", "application/json");
                XMLHttpRequest.setRequestHeader("Content-Type", "application/json; charset=utf-8");
                XMLHttpRequest.setRequestHeader("Prefer", "odata.include-annotations=*");
            },
            //Success Callback Function
            success: function (data, textStatus, XMLHttpRequest) {
                //get Response from Created Record
                entityIdWithLink = XMLHttpRequest.getResponseHeader("OData-EntityId");

                //get EntityId from ResponseHeader of Created Record  
                getEntityId = entityIdWithLink.split(/[()]/);
                getEntityId = getEntityId[1];

                //Display Enttity ID of Created Record
                Xrm.Utility.alertDialog("Entity ID : " + getEntityId);
            },
            //Error Callback Function
            error: function () {
                Xrm.Utility.alertDialog("Something Wrong in Script POST...:(");
            }
        });
    } catch (e) {
        Xrm.Utility.alertDialog(e.message + "\n" + e.description);
    }
}
=================================================

create an Activity & set Activity Party
///------------ Create Phone Call Activity ----------

function PhoneCall() {
    try {
        //declare variables
        var phonecallId = null;
        var stringJSONPhone = null;
        var urlPhone = null;

        //create activity party collection
        var parties = [];

        //create JSON object 
        var JSONPhone = {};

        //set fields using JSON object
        //Single line of text
        JSONPhone["subject"] = "Test Phone Call"; //Subject

        //Single line of text & format of phone 
        JSONPhone["phonenumber"] = "9876543210"; //Phone Number

        //Multiple Line of Text
        JSONPhone["description"] = "Phone Call Activity for Testing Purpose only...!"; //Description

        //Date and Time
        JSONPhone["scheduledend"] = new Date(); //Due

        //Lookup
        JSONPhone["regardingobjectid_account@odata.bind"] = "/accounts(B386D403-F7AD-E511-80DC-A45D36FC4F90)"; //Regarding is an account

        //ActivityParty (From)
        var sender = {};
        sender["partyid_systemuser@odata.bind"] = "/systemusers(D949B11D-9240-4037-8379-F31C7A36680E)";
        sender["participationtypemask"] = 1; //From

        //ActivityParty (To)
        var receiver1 = {};
        receiver1["partyid_account@odata.bind"] = "/accounts(B386D403-F7AD-E511-80DC-A45D36FC4F90)";
        receiver1["participationtypemask"] = 2; //To
        //receiver["addressused"] = "roohi@dyn20161.onmicrosoft.com";

        var receiver2 = {};
        receiver2["partyid_contact@odata.bind"] = "/contacts(DFE54660-37CD-E511-80DE-6C3BE5A831DC)";
        receiver2["participationtypemask"] = 2; //To

        var receiver3 = {};
        receiver3["partyid_lead@odata.bind"] = "/leads(ED81F0D9-37CD-E511-80DE-6C3BE5A831DC)";
        receiver3["participationtypemask"] = 2; //To

        //add this to collection
        parties.push(sender);
        parties.push(receiver1);
        parties.push(receiver2);
        parties.push(receiver3);

        //pass parties[] to phonecall_activity_parties
        JSONPhone["phonecall_activity_parties"] = parties;

        //Whole Number
        JSONPhone["actualdurationminutes"] = 25; //Duration

        //Two Options
        JSONPhone["directioncode"] = true;//Direction : 0-->False/Incomming, 1-->True/Outgoing

        //convert JSON object to string
        stringJSONPhone = JSON.stringify(JSONPhone);

        //url for ajax request to create phonecall activity
        urlPhone = Xrm.Page.context.getClientUrl() + "/api/data/v8.0/phonecalls";

        //ajax request to create phonecall activity
        $.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            url: urlPhone,
            data: stringJSONPhone,
            beforeSend: function (CreatePhoneCallActivityRequest) {
                CreatePhoneCallActivityRequest.setRequestHeader("Accept", "application/json");
                CreatePhoneCallActivityRequest.setRequestHeader("Content-Type", "application/json; charset=utf-8");
                CreatePhoneCallActivityRequest.setRequestHeader("Prefer", "odata.include-annotations=*");
                CreatePhoneCallActivityRequest.setRequestHeader("OData-MaxVersion", "4.0");
                CreatePhoneCallActivityRequest.setRequestHeader("OData-Version", "4.0");
            },
            //Success Callback Function
            success: function (data, taxtStatus, getPhoneCallActivityResponse) {
                //get Response from Created Record
                phonecallId = getPhoneCallActivityResponse.getResponseHeader("OData-EntityId");

                //get EntityId from ResponseHeader of Created Record 
                phonecallId = phonecallId.split(/[()]/);
                phonecallId = phonecallId[1];

                //Display Enttity ID of Created Record
                Xrm.Utility.alertDialog("Entity ID : " + phonecallId);

            },
            //Error Callback Function
            error: function (CreatePhoneCallActivityRequest, textStatus, errorThrown) {
                Xrm.Utility.alertDialog("Something Wrong in Script...:(");
            }
        });
    } catch (e) {
        Xrm.Utility.alertDialog(e.message + "\n" + e.description);
    }
}

Wednesday, April 6, 2016

Create New Account Record using Web API in MS CRM 2015/16

Create new account record on click of custom button.


function CreateaccountRecord()
{
   var serverURL = Xrm.Page.context.getClientUrl();  
    var account= {};  
    account["name"] = "Rajeev Kumar";  
    account["address1_city"] = "Pune";  
  
    account["primarycontactid@odata.bind"]="/contacts(757B1E74-FBA3-E511-80DE-3863BB341BF0)";  //setting existing lookup  
  
    
  

  
    var req = new XMLHttpRequest();  
    req.open("POST", serverURL + "/api/data/v8.0/accounts", true);  
    req.setRequestHeader("Accept", "application/json");  
    req.setRequestHeader("Content-Type", "application/json; charset=utf-8");  
    req.setRequestHeader("OData-MaxVersion", "4.0");  
    req.setRequestHeader("OData-Version", "4.0");  
    req.onreadystatechange = function() {  
        if (this.readyState == 4 /* complete */ ) {  
            req.onreadystatechange = null;  
            if (this.status == 204) {  
                var accountUri = this.getResponseHeader("OData-EntityId");  
                var ID = accountUri.substr(accountUri.length - 38).substring(1, 37); //get only GUID  
                Xrm.Utility.openEntityForm("account", ID); //Open newly created account record  
            } else {  
                var error = JSON.parse(this.response).error;  
                alert(error.message);  
            }  
        }  
    };  
    req.send(JSON.stringify(account));  

}

Hope it Help!!

Get Workflow Guid in Javascript using OData query

I find that using workflow id might be problematic across deployment, so I wrote a function to retrieve workflow’s guid given the workflow’s name. However, please take some care in assigning workflow name to avoid pain.

function call()
{
     
alert("Tets");
var name="Create Phone Call Via Js";
alert(name);
var wf=getWorkflowId(name);
alert(wf);

 }

function getWorkflowId(workflowName) {
var aa=workflowName;
var entityId = Xrm.Page.data.entity.getId();
alert(entityId);
alert(workflowName);

var serverUrl = Xrm.Page.context.getClientUrl();
alert(serverUrl);

var odataSelect = serverUrl + "/xrmservices/2011/OrganizationData.svc/WorkflowSet?$select=WorkflowId&$filter=StateCode/Value eq 1 and ParentWorkflowId/Id eq null and Name eq 'Create Phone Call Via Js'";

alert(odataSelect);

    var xmlHttp = new XMLHttpRequest();
    xmlHttp.open("GET", odataSelect, false);
    xmlHttp.send();

    if (xmlHttp.status == 200) {
        var result = xmlHttp.responseText;

        var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async = false;
        xmlDoc.loadXML(result);
         
        return xmlDoc.getElementsByTagName("d:WorkflowId")[0].childNodes[0].nodeValue;
    }
}

Hope it Help!!

Monday, April 4, 2016

Role based Dashboards – CRM 2013/15/16

Dashboards/charts visibility
  • System charts are like System views, only Users with System Administrator or System Customizer can create and view-able by all users.
  • Personal charts are like Personal views, only visible to User who created them (i.e., Unless the created user shares the personal Dashboard/chart, nobody else can see it, not even a system administrator)
Restrict User to access Dashboards/Charts
  • To restrict users to access System dashboards/Charts
    • Open security role –> Customization tab, set ‘System Chart/System Form’ access level to ‘none’
System charts Access/Privilages
System charts Access/Privileges
  • To restrict users to access Personal dashboards/Charts
    • Open security role –> Core Records tab, set ‘User Chart/User Dashboard’ access level to ‘none’
Personal charts Privileges/Access
Personal charts Privileges/Access
By removing privileges to User, he can’t access any of the Dashboards or Charts in the system.
What if you want to restrict a particular System Dashboard or Chart to all ‘Sales Person’ security role Users but not others? You cannot configure OOB this in CRM 2011 (However you can do this by Plug-ins).
With CRM 2013,  we got a new feature Role based dashboards similar to Role based forms.

Role based Dashboards in CRM 2013/15/16

  • With CRM 2013/15/16, we can manage permissions for Dashboards and control which user can see each dashboards based on security roles.
  • To configure the dashboards based on security roles.
    • Open the Solution –> Dashboards, choose single dashboard and click ‘Enable Security Roles‘ button
Configure dashboards by roles
Configure dashboards by roles
  • Select the “Display only to these select security roles” and select the security roles which are allowed to view this dashboard.
  • Publish the customization’s.

Hope this will help!!.

Get files of last hour in Azure Data Factory

  Case I have a Data Factory pipeline that should run each hour and collect all new files added to the data lake since the last run. What is...