martes, 27 de enero de 2015

Cálculo de campos Rollup desde Workflows (Calculate Rollup Field)

Siguiendo un poco el hilo de mi post anterior, le he dado una vuelta mas.

He detectado una posible necesidad de forzar el cálculo de campos de Rollup en momentos determinados, y de forma dinámica. Me he puesto a pensar entonces una solución que pudiese ser reutilizada para cualquier campo de tipo Rollup, sin necesidad de estar compilando plugins todo el tiempo.

Entonces, he creado un nuevo componente que he publicado en Codeplex: http://calculaterollupfield.codeplex.com/

La idea es simple, crear una actividad de workflow, que ejecute un calculo de un campo de rollup de una entidad padre. Se puede descargar desde ahí el código fuente y la propia solución directo para ser ejecutada. Una vez instalada, tendrán disponible la nueva actividad de workflow:

image

Los parámetros que recibe esta actividad de workflow son:

image

Los parámetros que se reciben son:

  • FieldName: Nombre del campo de tipo consolidad (rollup) padre
  • Parent Record URL: Aquí deben añadir de forma dinámica el campo “URL del registro(Dynamics)” del registro padre

Esto de la URL es un “truco” (por llamarlo de alguna manera) para pasar un registro de tipo “EntityReference” a una actividad de Workflow, sin definir un tipo fijo. Esta URL tiene el siguiente formato
https://<orgname>.crm4.dynamics.com:443/main.aspx?etc=9105&id=67a87f79-7f98-e411-80d5-c4346bad10f0&histKey=474087586&newWindow=true&pagetype=entityrecord

Esta URL nos da el ObjectTypeCode (etc) desde el cual puedo recoger el nombre de esquema de la entidad, y el ID del registro.

Las funcionalidades que nos puede dar esta solución, pueden ser diversas y creo que bastante útiles ya que recogemos el control de algo que ocurre por “detrás” para que se comporte como requieran los usuarios.

Espero les guste, por favor añadir comentarios en codeplex o ideas de nuevas funcionalidades, así la voy mejorando por el bien de todos: http://calculaterollupfield.codeplex.com/workitem/list/basic

abrazo!

@demian_rasko

sábado, 24 de enero de 2015

Como hacer campos consolidados síncronos (Sync Rollups)

Buenas, como muchos ya conocen y (espero) estén utilizando ya, en Dynamics CRM 2015 tenemos la posibilidad de utilizar campos de tipo “Consolidados” o de tipo “Rollup” (a veces las traducciones no me suenan muy bien y prefiero hablar con conceptos en inglés).
Bien, este tipo de campos tiene la particularidad que se calculan de forma asíncrona, es decir que es posible que el dato que estemos consultando o viendo, no sea esté actualizado. Esto se puede minimizar, bajando los tiempos de cálculo hasta un mínimo de una hora, pero aún así, en algunos escenarios esto no alcanza y es requerido que los cálculos sean totalmente online.
Hoy les voy a enseñar como convertir un campo de tipo Rollup (asíncrono por naturaleza), a un campo de Rollup 100% síncrono.
Me he inventado un escenario donde tengo Cuentas y Contactos (muy original por cierto) y quiero un campo en las Cuentas que me muestre el total de Contactos relacionados que dispone.
El campo de Rollup en Cuenta tiene la siguiente definición:
image
image
Bien, solamente con esto ya dispongo del campo que me calcula el total de contactos relacionados con una Cuenta. Pero esto se calcula de forma asíncrona nomás, o síncrona de forma manual desde el mismo formulario.
Para convertirlo en totalmente síncrono, debemos crear un Plugin y hacer una llamada a un nuevo mensaje llamado “CalculateRollupFieldRequest” que permite disparar el cálculo de un campo de tipo Rollup.
El código completo del Plugin está aquí:
using Microsoft.Crm.Sdk.Messages;using Microsoft.Xrm.Sdk;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Web;
namespace Plugin_Recalculate_Rollup
{
    public class Recalculate_Rollup  :IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)    
        {
            ITracingService tracingService =(ITracingService)serviceProvider.GetService(typeof(ITracingService));        
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));        
            if (context.InputParameters.Contains("Target") &&            context.InputParameters["Target"] is Entity)        
            {
                Entity entity = (Entity)context.InputParameters["Target"];
                if (entity.LogicalName != "contact")
                    return;
                IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
                try
                {
                    Entity contact=(Entity)context.PostEntityImages["Imagen"];
                    CalculateRollupFieldRequest calculateRollup = new CalculateRollupFieldRequest();
                    calculateRollup.FieldName = "new_totaldecontactos";
                    calculateRollup.Target = new EntityReference("account", ((EntityReference)contact.Attributes["parentcustomerid"]).Id);
                    CalculateRollupFieldResponse resp = (CalculateRollupFieldResponse)service.Execute(calculateRollup);
                }
                catch (Exception ex)
                {
                    tracingService.Trace("MyPlugin: {0}", ex.ToString());
                    throw;
                }     
            }
        }
    }
}

En la llamada al “CalculateRollupFieldRequest”, solamente hay que pasarle los siguientes parámetros:
  • FieldName: con el nombre del campo Rollup en Cuenta
  • Target: que debe ser un EntityReference al registro “padre”
Este plugin, lo complilamos y lo registramos con el PluginRegistrationTool como siempre.

NOTA: para registrar plugins a mí el PluginRegistrationTool de la versión 7.0.0 (CRM 2015) no me funciona, ya que se me queda la pantalla en blanco al conectar. Para este ejemplo he utilizado el PluginRegistrationTool que viene en la SDK de CRM 2013 SP1 (6.1.0).

image

Adicionalmente he credo una Imagen Post para recoger el “ParenCustomerId” del contacto:

image

Ahora cada vez que crea un Contacto nuevo relacionado con una Cuenta, se recalcula el campo de tipo Rollup:

image

Advertencia!: los campos de tipo Rollup síncronos pueden penalizar (y mucho) el rendimiento del CRM, por esto, si bien una práctica 100% soportada, utilizarlos con cuidado.

lunes, 19 de enero de 2015

Paneles en CRM 2015 y Tablets

Hola, como ya estamos todos los del mundo del Dynamics CRM empezando a trabajar con CRM 2015, seguiré hablando de cosas nuevas, pruebas y ejemplos de código de nuevas funcionalidades.

Una de las nuevas funcionalidades de CRM 2015, es la posibilidad de definir que paneles (dashboards) estará visibles los clientes de Tablets.

Para definir esto, vamos al panel y hacemos click en Propiedades:

image

y luego ahí habilitamos la opción:

image

Una de las nuevas funcionalidades de CRM 2015 es la posibilidad de acceder a iframes desde las tablets. Por eso vamos a probarlo y añado un iframe llamando a Bing maps en un panel:

image

Guardo, publico y vuelvo a abrir la aplicacion movil de tablets y le damos a descargar lo nuevo:

image

Si entro ahora al panel de actividad de ventas lo veo así (no se ve el iframe):

image

Esto es porque no he habilitado esta funcionalidad de forma general que debe realizarse en la configuración del sistema:

image

Esta funcionalidad esta disponible sobre para temas de desarrollo y pruebas. Esperemos que con el feedback recibido de las mismas el equipo de producto lo deje como funcionalidad soportada e incluida en la plataforma, porque es un punto importante para la adopción de los clientes de movilidad.

Tener en cuenta unos temas importantes:

  • Es una funcionalidad en “preview” por lo tanto no utilizarlo en entornos de producción aún
  • Solo funciona en entornos CRM Online (no Onpremise)
  • Solo funciona para iPads y Android
  • No se pueden abrir popups (ventanas emergentes) desde los iframes
  • No disponible para web resources de tipo Silverlight o Imágenes

Genial! esto nos permitirá llegar a donde no podíamos hasta ahora con las aplicaciones móviles, y nos ofrece un nuevo abanico funcional, donde añadir desarrollos externos en un sitio donde hasta ahora no se podía.

Un abrazo!