CRM2011 – Search what is the database associated at Organization

Sometimes I need to search what is a database associated at an existing organization. It is simple: From CRM Server, we need to ope SQL Server tools and execuete this query:

By running this query within MSCRM_CONFIG database we should be able to easily identify each organization:

SELECT [DatabaseName]
      ,[FriendlyName]
      ,[SqlServerName]
      ,[SrsUrl]
      ,[State]
      ,[UniqueName]
      ,[UrlName]
      ,[IsDeleted]
FROM [MSCRM_CONFIG].[dbo].[Organization]

That’s all…

Annunci

CRM2011 – Retrieve Plugin

2007_microsoft_dynamics_crmToday I need to execute a method every time open a Contact record.

Usually this would be frowned upon because this code could easily present a performance issues, especially if the data you’re gathering is hosted on an external resource.

In the off-change you do need to do this, here is the solution:

First, create a new Plugin and sign the assembly with a key:

public void Execute(IServiceProvider serviceProvider)
{
    // Obtain the execution context from the service provider.
    Microsoft.Xrm.Sdk.IPluginExecutionContext context = (Microsoft.Xrm.Sdk.IPluginExecutionContext)
        serviceProvider.GetService(typeof(Microsoft.Xrm.Sdk.IPluginExecutionContext));

    if (context.Depth == 1)
    {
        IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
        IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

        // Obtain the target entity from the input parmameters.
        EntityReference entity = (EntityReference)context.InputParameters["Target"];

        ColumnSet cols = new ColumnSet(
                             new String[] { "lastname", "firstname", "address1_name" });

        var contact = service.Retrieve("contact", entity.Id, cols);

        if (contact != null)
        {
            if (contact.Attributes.Contains("address1_name") == false)
            {
                Random rndgen = new Random();
                contact.Attributes.Add("address1_name", "first time value: " + rndgen.Next().ToString());
            }
            else
            {
                contact["address1_name"] = "i already exist";
            }
            service.Update(contact);
        }
    }
}

Next, hop over to the Plugin Registration Tool (included with the CRM SDK) and register the plugin:
Unbenannt

What you’ll end up with in this example is:

On first open of the record:

clip_image002_thumb

 

 

 

On all future opens of the record:

clip_image0025_thumb

CRM 2011 – Pass Data Between Plugins using SharedVariables

2007_microsoft_dynamics_crmEvery day I have new things to learn … and yesterday I had a problem about tho share variables between plugins in my CRM2011 project. MSCRM2011 and the execution pipeline provides the ability to pass data from one plug-in to another through an IPluginExecutionContext property called SharedVariables. This property is a collection of key/value pairs which developers can use to share data between plug-ins which are registered on both the pre and post events.

Here is the way to pass some paramters and get in between the steps in MS CRM 2011, while writing plugin.

Pre-Create Account Plug-in

if (context.InputParameters.ContainsKey("Target") && context.InputParameters["Target"] is Entity)
{
Entity target = context.InputParameters["Target"] as Entity;
if (target != null)
{
// some wacky data validation
string city = target.GetAttributeValue<string>("address1_city") ?? string.Empty;
int numEmployees = target.GetAttributeValue<int>("numberofemployees");
int accountCategory = target.GetAttributeValue<int>("accountcategorycode");

// city is auckland, numEmployees > 100, account category is preferred customer
bool updateRelated = city.Equals("Auckland", StringComparison.InvariantCultureIgnoreCase) && numEmployees > 100 && accountCategory == 1;
context.SharedVariables.Add("updatedRelated", updateRelated);
}
}

Post-Create Account Plug-in

if (context.InputParameters.ContainsKey("Target") && context.InputParameters["Target"] is Entity)
{
Entity target = context.InputParameters["Target"] as Entity;
if (target != null)
{
if (context.SharedVariables.ContainsKey("updatedRelated"))
{
bool updateRelated = (bool)context.SharedVariables["updatedRelated"];
if (updateRelated)
{
// additional logic to update related records of the Account
}
}
}
}

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 });
     }
 }

CRM2011 – Retrieve all Entities, Update and Publish them

I needed to change an property on all entities in my organitation. The unique way was to open all entites, modify the attribute, save and publish.. but it is a long and boring work and I don’t like this kind of job. I created a small console application that make it. In this article I will show you how to access items in CRM 2011 via new built in WCF webservice. The main code is the following:

IServiceConfiguration<IOrganizationService> orgConfigInfo =
ServiceConfigurationFactory.CreateConfiguration<IOrganizationService>(new Uri("http://server/Organization/XRMServices/2011/Organization.svc"));

//Set the credentials
System.Net.NetworkCredential userDefined = new System.Net.NetworkCredential("Username", "Password", "domain");

var creds = new ClientCredentials();
creds.Windows.ClientCredential = userDefined;

using (_serviceProxy = new OrganizationServiceProxy(orgConfigInfo, creds))
{
   RetrieveAllEntitiesRequest request = new RetrieveAllEntitiesRequest()
   {
      EntityFilters = EntityFilters.Entity,
      RetrieveAsIfPublished = true
   };
   // Retrieve the MetaData.
   RetrieveAllEntitiesResponse response = (RetrieveAllEntitiesResponse)_serviceProxy.Execute(request);

   foreach (EntityMetadata currentEntity in response.EntityMetadata)
   {
      currentEntity.IsVisibleInMobile.Value = false;

      UpdateEntityRequest updateEntityRequest = new UpdateEntityRequest();
      updateEntityRequest.Entity = currentEntity;
      _serviceProxy.Execute(updateEntityRequest);
   }

   PublishAllXmlRequest publishRequest = new PublishAllXmlRequest();
   _serviceProxy.Execute(publishRequest);
}

I got all entities, I updated them and at the end I published all modified….. 🙂
The console application is on my Github repository (MsCrm.RetrieveUpdate.ConsoleApplication)