CRM 2011 – How to get the current user from within a dialog

2007_microsoft_dynamics_crmI needed to get the current user in a dialog but CRM 2011 Dialogs do not provide any easy way to access the currently logged in user’s information. To get this information I found two ways (I don’t know if they are the unique ways.. but run!!):

1. USE ENTITY

The first way was to create a new instance if an entity: I created a new entity, the owner field will contain the currently logged in user.
The steps I followed:

  • Log into CRM and create a new entity, call it new_CurrentDialogUser. You do not have to add any new fields.
  • Open your existing dialog for editing.
  • From the Dialog editor, the first thing to do is create an instance of new_CurrentDialogUser.
    • Create a new stage, positioned at the very beginning of the dialog.
    • Click ‘Add Step’ and select ‘Create Record’.
    • Choose the type to be new_CurrentDialogUser.
    • Click on properties. Notice the owner field is presented. Do not populate this field. Instead, when the ‘Create Record’ step executes, it will default the owner to the currently logged in user.
  • Once the ‘Create Record’ steps executes in your dialog, you have the ability to reference this step from throughout the rest of your dialog, just as if you were referencing the current record that is related to your dialog.
  • In my case, I use an ‘Assign Value’ step to store the owner of the newly created new_ CurrentDialogUser to a local variable, called CurrentUser.
    • Click ‘Add Step’ and choose ‘assign value details.’
    • In the ‘Look For’, select from the local values, the choice ‘Create (Current Dialog User)’.
  • Finally, once my am done using the current user, I perform an ‘UpdateStatus’ step, as a means to
    deactivate the dynamically created new_CurrentDialogUser instance.
    • Add step, select ‘Change Status’
    • Select the ‘Create (Current Dialog user)’.
    • Change the status to ‘Inactive’.

2. USE ACTIVITY WORKFLOW

I created a new workflow activity with Output parameters. This output parameters are all parameters that I needed in my dialog. For example I have the Current User, etc. In following the piece of code:

// <copyright file="ParametersActivity.cs" company="">
// Copyright (c) 2014 All Rights Reserved
// </copyright>
// <author>Alessandro Graps</author>
// <date>6/25/2014 8:34:52 AM</date>
// <summary>Implements the ParametersActivity Workflow Activity.</summary>

using ActivityRecording.Entities;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Query;

namespace Winvs.Next.ActivityRecording.Workflow
{
    using System;
    using System.Activities;
    using System.ServiceModel;
    using Microsoft.Xrm.Sdk;
    using Microsoft.Xrm.Sdk.Workflow;

    public sealed class ParametersActivity : CodeActivity
    {
        [Output("Current User")]
        [ReferenceTarget("systemuser")]
        public OutArgument<EntityReference> CurrentUser { get; set; }

        [Output("Current Time Mapping")]
        [ReferenceTarget(winvs_unitconfiguration.EntityLogicalName)]
        public OutArgument<EntityReference> CurrentTimeMapping { get; set; }

        protected override void Execute(CodeActivityContext context)
        {
            IWorkflowContext workflowContext = context.GetExtension<IWorkflowContext>();

            if (workflowContext == null)
            {
                throw new InvalidPluginExecutionException("Failed to retrieve workflow context.");
            }

            if (workflowContext.Depth > 1)
                return;
            
            CurrentUser.Set(context, new EntityReference("systemuser", workflowContext.InitiatingUserId));


            IOrganizationServiceFactory serviceFactory = context.GetExtension<IOrganizationServiceFactory>();
            IOrganizationService service = serviceFactory.CreateOrganizationService(workflowContext.UserId);

            winvs_unitconfiguration winvsUnitconfiguration = GetConfigurationEntityUnitGroup(service);

            CurrentTimeMapping.Set(context, new EntityReference("winvs_unitconfiguration", winvsUnitconfiguration.Id));

        }

        public winvs_unitconfiguration GetConfigurationEntityUnitGroup(IOrganizationService service)
        {
            string entityName = "winvs_unitconfiguration";

            // Get the metadata for the currently list's entity
            // This metadata is used to create a "Property Descriptor Collection"

            QueryExpression qe = new QueryExpression();
            qe.ColumnSet = new ColumnSet(true);
            qe.EntityName = entityName;

            RetrieveMultipleRequest request = new RetrieveMultipleRequest();
            request.Query = qe;
            RetrieveMultipleResponse response = (RetrieveMultipleResponse)service.Execute(request);


            if (response.EntityCollection.Entities.Count == 0)
                throw new Exception(string.Format("The configuration entity is empty."));

            foreach (Entity unitConfigurationEntity in response.EntityCollection.Entities)
            {
                winvs_unitconfiguration winvsUnitconfiguration = unitConfigurationEntity.ToEntity<winvs_unitconfiguration>();
                return winvsUnitconfiguration;
                break;
            }

            throw new Exception(string.Format("The configuration entity is empty."));
        }

    }
}

This is a fast way to get all information that I don’t have in dialogs.

CRM2011 – Disable / enable fields, sections, tabs and the whole form

Today the problem is about enable and disable fields on form in CRM. When working with CRM, you often want to enable (set to read/write) or disable (set to read / only) selected fields, sections, tabs and the whole form depending on your business logic.

1) Enable / Disable a field

Xrm.Page.getControl("fieldname").setDisabled(false); 

2) Enable / Disable a Section

	function sectiondisable (sectionname, disablestatus)
	{
	    var ctrlName = Xrm.Page.ui.controls.get();
	    for(var i in ctrlName) {
	         var ctrl = ctrlName[i];
	         var ctrlSection = ctrl.getParent().getName();
	         if (ctrlSection == sectionname) {
	               ctrl.setDisabled(disablestatus);
	        }
	    }
	}  // sectiondisable

3) Enable / Disable a Tab

	function tabdisable (tabname, disablestatus)
	{
	 var tab = Xrm.Page.ui.tabs.get(tabname);
	 if (tab == null) alert("Error: The tab: " + tabname + " is not on the form");
	 else {
	     var tabsections =  tab.sections.get();
	     for (var i in tabsections) {
	         var secname = tabsections[i].getName();
	         sectiondisable(secname, disablestatus);
	     }
	  }
	}   // tabdisable

4) Enable / Disable a Form

	function formdisable(disablestatus)
	{
	    var allAttributes = Xrm.Page.data.entity.attributes.get();
	    for (var i in allAttributes) {
	           var myattribute = Xrm.Page.data.entity.attributes.get(allAttributes[i].getName());
	           var myname = myattribute.getName();          
	           Xrm.Page.getControl(myname).setDisabled(disablestatus); 
	    }
	} // formdisable

5) Disabling all Fields on a Form
Add this code to your web resource:

function doesControlHaveAttribute(control) {
    var controlType = control.getControlType();
    return controlType != "iframe" &amp;&amp; controlType != "webresource" &amp;&amp; controlType != "subgrid";
}


function disableFormFields(onOff) {
    Xrm.Page.ui.controls.forEach(function (control, index) {
        if (doesControlHaveAttribute(control)) {
            control.setDisabled(onOff);
        }
    });
}

Call the function:
Generally, you will have another function that is triggered on-load that will determine if the form should be disabled. It may check a picklist value or it may check the current user’s role.

function setupForm(){
    if (Xrm.Page.ui.getFormType() == 2 &amp;&amp;
        Xrm.Page.getAttribute("incidentstagecode").getValue() != null &amp;&amp;
        Xrm.Page.getAttribute("incidentstagecode").getValue() == "200001") 
    {
           disableFormFields(true);
    }
}

- See more at: http://blog.avtex.com/2011/04/01/disabling-all-fields-on-a-form-in-crm-2011/#sthash.nfN8z64a.dpuf

CRM2011 – Associate and Disassociate Many to Many relationship records

In my Solution I needed to associate programmaticaly an N:N relationship in my entity.

If we have any N:N(Many to Many) relationship in Microsoft Dynamics CRM 2011, need to manually assign relationship between two entities using SDK.

In the next example we discuss about the example to associate and disassociate N:N(Many to Many) relationship records in CRM 2011 thru SDK.

In the example I have N:N relationship between Case (Incident) and Activity (task). Relationship name is ls_incident_activity_task.

// Creates the custom many-to-many relationship between the case and task.
public void AssociateRelationship(IOrganizationService service, EntityReference caseRef, EntityReference taskRef)
{
//If one of the ID's is null, do nothing
if (caseRef == null) return;
if (taskRef == null) return;
if (caseRef.LogicalName != "incident") return;
if (taskRef.LogicalName != "task") return;

var caseId = caseRef.Id;
var taskId = taskRef.Id;

//The relationship schema to create
string relationshipName = "ls_incident_activity_task";

//Create a query that will check to see if the relationship already exists between this account and contact
QueryExpression query = new QueryExpression(relationshipName)
{
NoLock = true,
ColumnSet = new ColumnSet(false),//only get the row ID, since we don't need any actual values
Criteria =
{
Filters =
{
new FilterExpression
{
FilterOperator = LogicalOperator.And,
Conditions =
{
//Get the row for the relationship where the account and contact are the account and contact passed in
new ConditionExpression("incidentId", ConditionOperator.Equal, caseId.ToString()),
new ConditionExpression("activityId", ConditionOperator.Equal, taskId.ToString()),
},
},
}
}
};
var result = service.RetrieveMultiple(query);
//Check if the relationship was not found
if (result == null || result.Entities == null || result.Entities.Count < 1)
{
//The relationship was not found, so create it
service.Associate(caseRef.LogicalName, caseRef.Id, new Relationship(relationshipName), new EntityReferenceCollection() { caseRef });
}
}


public void DisassociateRelationship(IOrganizationService service, EntityReference caseRef, EntityReference taskRef)
 {
     //If one of the ID's is null, do nothing
     if (caseRef == null) return;
     if (taskRef == null) return;
     if (caseRef.LogicalName != "incident") return;
     if (taskRef.LogicalName != "task") return;
 
     var caseId = caseRef.Id;
     var taskId = taskRef.Id;
 
     //The relationship schema to create
     string relationshipName = "ls_incident_activity_task";
 
     //Create a query that will check to see if the relationship already exists between this account and contact
     QueryExpression query = new QueryExpression(relationshipName)
     {
         NoLock = true,
         ColumnSet = new ColumnSet(false),//only get the row ID, since we don't need any actual values
         Criteria =
         {
             Filters =
             {
                 new FilterExpression
                 {
                     FilterOperator = LogicalOperator.And,
                     Conditions =
                     {
                         //Get the row for the relationship where the account and contact are the account
                         new ConditionExpression("incidentId", ConditionOperator.Equal, caseId.ToString()),
                         new ConditionExpression("activityId", ConditionOperator.Equal, taskId.ToString()),
                     },
                 },
             }
         }
     };
     var result = service.RetrieveMultiple(query);
     //check if record exists
     if (result != null && result.Entities != null && result.Entities.Count > 0)
     {
         //Delete the N:N relation
         service.Disassociate(caseRef.LogicalName, caseRef.Id, new Relationship(relationshipName), new EntityReferenceCollection() { taskId });
     }
 }

MobileDev: panoramica sullo sviluppo Mobile e sulle possibili alternative .Net

FocusDayCiao a tutti,

volevo pubblicizzare il Focus Day di Overnet che si terrà a settembre. In particolare l’evento “MobileDev: panoramica sullo sviluppo Mobile e sulle possibili alternative .Net“. In questo evento di circa 4 ore discuteremo sul mondo Mobile (I mercati, i device ed inoltre vedremo una valida alternativa per riutilizzare codice .Net: XAMARIN). Naturalmente il relatore saro’ io.. Spero possa interessare e spero di vedervi numerosi. Di seguito il link dell’evento: http://overneteducation.it/DettaglioCorso.aspx?corso=EV030&v=1

 

L’evento si terrà a Milano. L’indirizzo è il seguente:

OverNet Education
Strada 4 Palazzo Q7, 1°piano
Centro Direzionale Milanofiori
20089 – Rozzano MI