miércoles, 16 de enero de 2013

Mostrar usuario actual (logueado) en un Lookup

Hola, a veces en los formularios de Dynamics CRM necesitamos recoger el usuario actual o logueado para rellenar algún lookup con ese valor.
Hoy voy a plantear un ejemplo completo de esto y de como se puede resolver.
Lo primero que hay que hacer es la creación de un campo de tipo Lookup con usuario en la entidad de Cuenta:
image
Luego lo añadimos al formulario de Cuenta:
image
Finalmente debemos añadir el siguiente javascript que se ejecute en el Load para actualizar el valor del campo:
   1: function setUsuarioActual()
   2: {
   3:    var user = Xrm.Page.context.getUserId(); 
   4:    var userId = user.substring(1,37);
   5:    var serverUrl = Xrm.Page.context.getServerUrl()
   6:     var ODATA_ENDPOINT = "/XRMServices/2011/OrganizationData.svc";
   7:     var ODATA_EntityCollection = "/SystemUserSet";
   8:     // Specify the ODATA Query
   9:     var ODATA_Query = "(guid\'" + userId + "')";
  10:     // Combine into the final URL
  11:     var ODATA_Final_url = serverUrl + ODATA_ENDPOINT + ODATA_EntityCollection + ODATA_Query;
  12:  
  13:     //Calls the REST endpoint to retrieve data
  14:     $.ajax({
  15:         type: "GET",
  16:         contentType: "application/json; charset=utf-8",
  17:         datatype: "json",
  18:         url: ODATA_Final_url,
  19:         beforeSend: function (XMLHttpRequest) {
  20:             XMLHttpRequest.setRequestHeader("Accept", "application/json");
  21:         },
  22:         success: function (data, textStatus, XmlHttpRequest) {
  23:            var userName = data.d.FullName;
  24:            Xrm.Page.getAttribute("new_usuarioactualid").setValue( [{id: userId , name: userName , entityType: "systemuser"}]);
  25:  
  26:            },
  27:         error: function (XmlHttpRequest, textStatus, errorThrown) {
  28:             alert('Error: '+ ODATA_Final_url);
  29:  
  30:             }
  31:     });
  32:  
  33:  
  34: }
 

Añadirlo en un web resource y llamar a ese método en el load:

image

Por cierto, para que este código funcione, hay que añadir también la librería de jQuery.
Finalmente al abrir el formulario de las Cuentas, el campo “Usuario Actual” se rellena como se ve:


image


Un abrazo!

martes, 15 de enero de 2013

Guía para el examen de certificación MB2-866 (Customization & Configuration)

5801EN_Microsoft%20Dynamics%20CRM%202011Customization%20and%20Configuration%20(MB2-866)%20Certification%20Guide_cov
Neil Benson (Twitter: @customery), un arquitecto de de Dynamics CRM y conocido MVP ha publicado un libro que sirve como guía para el examen de certificación de Dynamics CRM 2011 “MB2-866”.
Este libro es mas bien una guía que recorre todos los temas requeridos en el comentado examen de certificación. Recorre cada uno los elementos de configuración y personalización que dispone Dynamics CRM 2011 de forma fácil y sencilla, explicando paso a paso como trabajar con los mismos.
Si bien este libro está enfocado mas bien a personas que estén queriendo certificarse en este examen, también sirve para personas que ya lo tengan, o usuarios finales avanzados que quieran comprender todas las posibilidades y funcionalidades que Dynamics CRM 2011 ofrece.
Por último, contiene una gran cantidad de preguntas guía para preparase el examen (similares a las del examen real), que sirven para acostumbrarse a la forma de preguntar y como responder.
La forma de leer el libro es muy cómoda y rápida, sin grandes descripciones, pero enfocado en los aspectos técnicos de cada tema.
El libro está disponible en "Amazon": http://www.amazon.com/dp/1849685800/?tag=packtpubli-20
y en "Packt Publishing": http://www.packtpub.com/microsoft-dynamics-crm-2011-customization-configuration-mb2-866-certification-guide/book

miércoles, 9 de enero de 2013

Nueva versión de la SDK (5.0.13)

Con la nueva actualización de Dynamics CRM 2011 (UR12 o “Polaris”) se incluyen nuevas funcionalidades. Es por esto que era necesaria la publicación de una nueva SDK, y esto ha ocurrido esta semana.
Se ha publicado la nueva versión de la SDK ya disponible para la descarga: http://www.microsoft.com/en-us/download/details.aspx?id=24004
El listado de modificaciones está recogido en este enlace: http://msdn.microsoft.com/en-us/library/jj863620.aspx
Uno de los temas que creo que son de los mas interesantes es lo de la nueva funcionalidad de acciones con datos de forma “masiva” como se explica aquí: http://msdn.microsoft.com/en-us/library/jj863631.aspx
Un ejemplo de utilización de esta nueva funcionalidad:
   1: // Get a reference to the organization service.

   2: using (_serviceProxy = ServerConnection.GetOrganizationProxy(serverConfig))
   3: {
   4:     // Enable early-bound type support.
   5:     _serviceProxy.EnableProxyTypes();
   6:  
   7:     #region Execute Multiple with Results
   8:     // Create an ExecuteMultipleRequest object.
   9:     ExecuteMultipleRequest requestWithResults = new ExecuteMultipleRequest()
  10:     {
  11:         // Assign settings that define execution behavior: continue on error, 
  12:         // return responses. 
  13:         Settings = new ExecuteMultipleSettings()
  14:         {
  15:             ContinueOnError = false,
  16:             ReturnResponses = true
  17:         },
  18:         // Create an empty organization request collection.
  19:         Requests = new OrganizationRequestCollection()
  20:     };
  21:  
  22:     // Create several (local, in memory) entities in a collection. 
  23:     EntityCollection input = GetCollectionOfEntitiesToCreate();
  24:  
  25:     // Add a CreateRequest for each entity to the request collection.
  26:     foreach (var entity in input.Entities)
  27:     {
  28:         CreateRequest createRequest = new CreateRequest { Target = entity };
  29:         requestWithResults.Requests.Add(createRequest);
  30:     }
  31:  
  32:     // Execute all the requests in the request collection using a single web method call.
  33:     ExecuteMultipleResponse responseWithResults =
  34:         (ExecuteMultipleResponse)_serviceProxy.Execute(requestWithResults);
  35:  
  36:     // Display the results returned in the responses.
  37:     foreach (var responseItem in responseWithResults.Responses)
  38:     {
  39:         // A valid response.
  40:         if (responseItem.Response != null)
  41:             DisplayResponse(requestWithResults.Requests[responseItem.RequestIndex],
  42:                  responseItem.Response);
  43:  
  44:         // An error has occurred.
  45:         else if (responseItem.Fault != null)
  46:             DisplayFault(responseItem.Fault);
  47:     }


Como se ve, se puede utilizar el mensaje “ExecuteMultipleRequest” como una sola petición a los web services de CRM que hagan múltiples operaciones.

Además se dispone de dos parámetros:
  • ContinueOnError: para determinar si queremos que se detenga en caso de algún error
  • ReturnResponses: para que devuelva una colección con las respuestas

Próximamente intentaré probar esta funcionalidad (cuando disponga de un CRM con UR12…)

Además una nueva posibilidad es que ahora se puede añadir filtros al consultar metadatos de forma que esta consulta nos de solo lo que necesitemos y funcione mas rápido. un ejemplo en este blog: http://mscrmtools.blogspot.com.es/2013/01/sdk-5013-yes-you-can-get-only-metadata.html

Un saludo,

viernes, 28 de diciembre de 2012

“Polaris” (UR12) y su impacto en implantaciones actuales

Hola, como muchos conocerán, este mes está saliendo la nueva actualización de Dynamics CRM 2011 conocida como “Polaris”, “UR12”, o “December 2012 Service Update”. Sinceramente esto de los nombres, versiones y demás, cada vez es mas complicado. Creo que el lío de los nombres pasa porque hay que ponerle un nombre técnico, otro de “marketing” y otro con un marco temporal.

En definitiva, está saliendo el nuevo rollup, que incluye entre otras mejoras integración con Yammer, Skype, y Bing Maps, compatibilidad con Microsoft Office 2013, y la nueva API de gestión de datos masivos (bulk data API). Además se incluyen nuevos navegadores soportados por Dynamics CRM (el tan esperado “cross-browser”)

Las fechas estimativas de despliegue de esta actualización son las siguientes (https://community.dynamics.com/product/crm/crmnontechnical/b/nakedcrm/archive/2012/12/18/polaris-release-dates.aspx):

  • Nuevos CRM trial registrados en EEUU desde el 14 ene 2013
  • Nuevos CRM trial registrados en EMEA y APAC desde el 16 ene 2013
  • Clientes existentes desde el 1 de ene 2013 hasta el 31 de ene 2013
  • Para versiones “On premise” estará disponible el 10 de ene 2013
  • Integración con Yammer y IPAD desde feb 2013 hasta el 28 de feb 2013

Bien, como ven esto se nos viene encima a partir del año nuevo, pero la pregunta es: ¿podemos actualizar sin mas nuestros entornos actuales a la nueva UR12?

Antes de hacer esta actualización, lo mejor sería tener en cuenta unos controles y pasos a seguir que nos harán dar el paso de forma segura (basado en lo recomendado por Steven Foster):

  1. Descargar e instalar el “Microsoft Dynamics CRM 2011 Custom Code Validation Tool”, desde Microsoft (gratis): http://www.microsoft.com/en-us/download/details.aspx?id=30151
  2. Importar la solución en el CRM en el entorno de desarrollo
  3. Ejecutando la solución, nos identificará con colores que partes del código podrían fallar con el UR12
  4. Será necesario un desarrollador para solucionar estos errores modificando el código javascript
  5. Una vez modificado el javascript, se deberá probar la actualización, a ver si funciona todo ok.

Existen una serie de videos en la “Microsoft Partner Network” (MPN) que enseñan como serán las nuevas funcionalidades (http://blogs.msdn.com/b/ukcrm/archive/2012/11/16/crm-online-polaris-release-q4-2012-details.aspx):

Ver también el artículo de Steven Foster: https://community.dynamics.com/product/crm/crmnontechnical/b/nakedcrm/archive/2012/12/27/microsoft-dynamics-crm-2011-polaris-release-and-its-potential-impact-on-current-deployments.aspx?wa=wsignin1.0

un saludo,

martes, 11 de diciembre de 2012

Usuarios y Roles de seguridad

Hola, hoy voy a poner un par de ejemplos de como trabajar con los temas de los roles de seguridad y los usuarios con un par de métodos que suelen ser necesarios.
Frecuentemente necesitamos consultar que usuarios tienen un rol o que roles tiene un usuario determinado. Los roles de seguridad tienen un funcionamiento un poco extraño. Al crearnos un nuevo rol de seguridad, en realidad se duplica el rol por cada una de las unidades de negocio que hay en el sistema. Por esto hay que tener mucho cuidado, ya que si nuestro sistema tiene una gran cantidad de unidades de negocio (mas de mil, por ejemplo), con cada rol que creemos, en realidad se irán creando mil registros. Esto provoca que todo el sistema se ralentice mucho, así que hay que tener mucho cuidado de no crear grandes volúmenes de unidades de negocio.
A continuación, detallo un par de métodos que pueden ser útiles para el trabajo con usuarios y sus roles. En realidad son simplemente dos ejemplos que muestran como mediante consultas de tipo “FetchXml”, se puede consultar. Ambos métodos devuelven un objeto de tipo ArrayList con los resultados.

1) Para consultar que roles tiene un usuario (por guid del usuario):

   1: public ArrayList getUserRoles(string User_Guid)

   2:        {
   3:            ArrayList user_roles = new ArrayList();
   4:            StringBuilder fetch2 = new StringBuilder();
   5:            fetch2.Append("<fetch distinct='true' mapping='logical' output-format='xml-platform' version='1.0'> ");
   6:            fetch2.Append(" <entity name='role'>");
   7:            fetch2.Append(" <attribute name='name'/> ");
   8:            fetch2.Append(" <order descending='false' attribute='name'/> ");
   9:            fetch2.Append("     <link-entity name='systemuserroles' intersect='true' visible='false' to='roleid' from='roleid'>");
  10:            fetch2.Append("         <link-entity name='systemuser' to='systemuserid' from='systemuserid' alias='aa'> ");
  11:            fetch2.Append("             <filter type='and'> ");
  12:            fetch2.Append(String.Concat("   <condition attribute='systemuserid' value='{0}' uitype='systemuser' operator='eq'/> ",User_Guid));
  13:            fetch2.Append("             </filter> ");
  14:            fetch2.Append("         </link-entity> ");
  15:            fetch2.Append("     </link-entity> ");
  16:            fetch2.Append(" </entity> ");
  17:            fetch2.Append("</fetch>");
  18:  
  19:            EntityCollection result = _serviceProxy.RetrieveMultiple(new FetchExpression(fetch2.ToString()));
  20:  
  21:            foreach (var c in result.Entities)
  22:            {
  23:                user_roles.Add(c.Attributes["name"].ToString());
  24:            }
  25:            return user_roles;
  26:        }



2) Para consultar qué usuarios están en un determinado rol (por nombre del rol):


   1: public ArrayList getUserinRole(string Role_Name)
   2:         {
   3:             ArrayList usersinrole = new ArrayList();
   4:             StringBuilder fetch2 = new StringBuilder();
   5:             fetch2.Append("<fetch distinct='true' mapping='logical' output-format='xml-platform' version='1.0'> ");
   6:             fetch2.Append(" <entity name='systemuser'>");
   7:             fetch2.Append(" <attribute name='systemuserid'/> ");
   8:             fetch2.Append("     <link-entity name='systemuserroles' intersect='true' visible='false' to='systemuserid' from='systemuserid'> ");
   9:             fetch2.Append("         <link-entity name='role' to='roleid' from='roleid' alias='aa'> ");
  10:             fetch2.Append("                <filter type='and'> ");
  11:             fetch2.Append(String.Concat("                     <condition attribute='name' value='{0}' operator='eq'/> ",Role_Name));
  12:             fetch2.Append("                 </filter> ");
  13:             fetch2.Append("         </link-entity> ");
  14:             fetch2.Append("     </link-entity>");
  15:             fetch2.Append(" </entity> ");
  16:             fetch2.Append("</fetch>");
  17:  
  18:             EntityCollection result = _serviceProxy.RetrieveMultiple(new FetchExpression(fetch2.ToString()));
  19:  
  20:             foreach (var c in result.Entities)
  21:             {
  22:                 usersinrole.Add(c.Attributes["systemuserid"].ToString());
  23:             }
  24:             return usersinrole;
  25:         }
 
 

Un saludo,

jueves, 29 de noviembre de 2012

Microsoft Community Contributor (MCC)

MCC12_Logo_Horizontal_Full-color

Ayer he recibido un email informándome que he sido galardonado con el reconocimiento como “Microsoft Community Contributor” (MCC). Es la primera vez que he sido seleccionado para esta distinción.

Hoy me siento muy orgulloso y agradecido a Microsoft de haber sido seleccionado, y espero poder seguir ayudando a la gente como hasta ahora por diferentes vías (blog, foros, twitter, codeplex, etc.).

Ya aparezco en el listado con todos los MCC’s: https://www.microsoftcommunitycontributor.com/current-recipients.aspx

Descripción del programa MCC:

Through the Microsoft® Community Contributor badge program, we express our thanks to individuals who freely volunteer their time and energy to help improve the Microsoft online technical community experience for others.

More and more technology users are seeking ideas and solutions for enhancing their technology experience through online resources. At Microsoft, we help our customers find answers when and where they want them through online forums such as TechNet, MSDN® and Answers.

Today, up to 4,000,000 people gain valuable information through Microsoft online forums--and that number is growing.

These valuable resources are enhanced by the contributions of Microsoft Community Contributors, who help other participants in a range of ways, such as providing helpful answers, translating online resources into local languages and serving as moderators.

Un saludo,

lunes, 12 de noviembre de 2012

CRM2011GuidFinder en Codeplex (v1.0)

Hola, a raíz de una idea que me daba vueltas por la cabeza, he creado un nuevo proyecto en Codeplex.
Esta vez el funcionamiento que buscaba era que introduciendo un “GUID” (código interno de los registros en CRM), se pueda saber si existe en CRM y si es positivo saber en que entidad existe el mismo.
Para esto he publicado el proyecto en la dirección de codeplex: http://crm2011guidfinder.codeplex.com

Además el código fuente completo del plugin esta disponible aquí: http://crm2011guidfinder.codeplex.com/SourceControl/changeset/view/15414

La solución al importarla incluye:
  • Nueva entidad “Guid Finder”
  • Dll con un Plugin
  • Un paso en el pre-create de la entidad “Guid Finder”
El funcionamiento es muy sencillo. Al crear un nuevo registro de “Guid Finder” se puede introducir el Guid a buscar. Además se le puede decir al plugin que busque en todas las entidades de CRM, o solamente en algunas filtradas (separadas por comas en el campo “Filter Entities"").
Algunas capturas de esta nueva solución:
img1
img2
Además puede verse como resultado el campo “Found Entity” para saber si se ha encontrado el guid en algún sitio, y ademas de un “Execution Log” para ver como se ha ido ejecutando.
A pesar de que pueda parecer poco optimizado en cuanto a rendimiento, no suele tardar mucho en buscar en “All” las entidades.
Espero les sirva, un abrazo!
Demian.