miércoles, 2 de septiembre de 2009

Mostrar cantidad de Actividades/Historial en el formulario

He encontrado en el Blog de Jim Wang un pequeño desarrollo que me parece bastante útil.
Es simplemente un Javascript que sirve para que en el mismo "onLoad()" del formulario, nos muestre la cantidad de registros relacionados de Actividades (tanto programadas como cerradas).

Así es como se ve finalmente así por ejemplo en el formulario de "Contactos":


Lo único que hay que hacer es pegar el siguiente código en el "Onload()" de la entidad que se desea:

var buXml = GetRegardingActivity();

if(buXml != null)
{
var buNodes = buXml.selectNodes("//BusinessEntity/q1:statecode"); // CRM 4.0
var iActivity = 0;
var iHistory = 0;
if (buNodes != null) { /*get values*/

for (i = 0; i < buNodes.length; i++) {
switch (buNodes[i].text) {
case "Abierto": iActivity++; break;
case "Programado": iActivity++; break;
case "Completado": iHistory++; break;
case "Cancelado": iHistory++; break;
}
}
if (document.getElementById('navActivities') != null)
{
document.getElementById('navActivities').getElementsByTagName('NOBR')[0].innerText = document.getElementById('navActivities').getElementsByTagName('NOBR')[0].innerText + " (" + iActivity + ")";
}
if (document.getElementById('navActivityHistory') != null) {
document.getElementById('navActivityHistory').getElementsByTagName('NOBR')[0].innerText = document.getElementById('navActivityHistory').getElementsByTagName('NOBR')[0].innerText + " (" + iHistory + ")";
}
}
}
function GetRegardingActivity() {
var xml = "" + "" + "" + " " + " " + " activitypointer" + " " + " " + " statecode" + " " + " " + " false" + " " + " And" + " " + " " + " regardingobjectid" + " Equal" + " " + " " + crmForm.ObjectId + "" + " " + " " + " " + " " + " " + " " + "" + "";
var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
xmlHttpRequest.Open("POST", "/mscrmservices/2006/CrmService.asmx", false);
xmlHttpRequest.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2006/WebServices/RetrieveMultiple");
xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlHttpRequest.setRequestHeader("Content-Length", xml.length);
xmlHttpRequest.send(xml);
var resultXml = xmlHttpRequest.responseXML;
return resultXml;
}

Como se ve en el código, hace una llamada a los Web Services de CRM, para buscar en la entidad "ActivityPointer" todas las actividades que tiene relacionadas el registro en el que nos encontramos ("crmForm.ObjectId").
Luego, recorre los resultados para contar cuantas de esas actividades estan abiertas (iActivity) y cuantas estan completadas (iHistory).

Finalmente, hace algo "NO Soportado" como es el de "inyectar" html en el formulario de CRM para que muestre las cantidades entre paréntesis.

Espero les sirva.

un saludo

martes, 1 de septiembre de 2009

Curso Online introductorio de desarrollo sobre Dynamics CRM

En el último boletín MSDN Flash de esta semana han comunicado de un nuevo curso online sobre desarrolo para Microsoft Dynamics CRM.
Lo ha realizado el MVP de Microsoft Daniel Sabater y la verdad que me pareció muy bueno, tanto para personas que estan empezando con el desarrollo en Microsoft CRM como también para gente con mas experiencia en la plataforma.

Está publicado en la Web de Microsoft como un evento de tipo "WebCast a Petición" y la dirección URL de acceso es la siguiente:Curso introductorio de desarrollo sobre Dynamics CRM

Además da la opción de poder descargárselo completo (alrededor de 80 MB), tiene videos y ejemplos.

Un saludo,

sábado, 29 de agosto de 2009

Validaciones en el evento OnSave() de los formularios

Muchas veces necesitamos realizar validaciones en los formularios de CRM, que impidan que se guarden los datos introducidos en el mismo.
MSCRM 4.0 nos da la opción de recoger el evento que provocó la grabación del formulario, para poder realizar la validación que se necesite.
La documentación del evento OnSave() aparece en la SDK de CRM 4.0.
Allí nos detalla que podemos recoger la acción en el OnSave() accediendo a los valores de event.Mode que son los siguientes:


Hora intentaré hacer un par de ejemplos prácticos en relación con esto. Los ejemplos serán Javascripts que deberán ponerse en el evento OnSave() del formulario.

1) En una entidad donde tenemos una "Fecha desde" y una "Fecha hasta", no dejar guardar el formulario si la "Fecha hasta" es menor que la "Fecha desde":

if (event.Mode==1 event.Mode==2) // si es un evento de "Guardar" o "Guardar y cerrar"
{
var fechadesde=crmForm.all.new_fechadesde.DataValue;
var fechahasta=crmForm.all.new_fechahasta.DataValue;
if (fechadesde>fechahasta)
{
alert("La 'Fecha hasta' no puede ser menor que la 'fecha desde'.");
event.returnValue = false;
return false;
}
}

2) Ejemplo para no dejar completar una Cita, si no se rellena algo en el campo de descripción, para así obligar a rellenar los comentarios acerca de la misma:

if (event.Mode==58) // si es un evento de "Guardar como completado"
{
var comentarios=crmForm.all.description.DataValue;
if (comentarios==null || comentarios=="")
{
alert("Para completar la cita, debe rellenar los comentarios de la misma.");
event.returnValue = false;
return false;
}
}

viernes, 28 de agosto de 2009

Ha salido el Update Rollup 6

Esta semana ha salido un nuevo Rollup para el CRM 4.0.
la URL para la descarga está aquí:
Update Rollup 6 for Microsoft Dynamics CRM 4.0 (KB 970148)

Para ver un resumen de las actualizaciones entrar aquí:
El paquete acumulativo de actualizaciones 6 para Microsoft Dynamics CRM 4.0 supone disponible

Como toda actualización, tener mucho cuidado antes de instalarlo, antes que nada instalarlo en un servidor de desarrollo, probar todos los desarrollos y personalizaciones.

Un saludo!

miércoles, 26 de agosto de 2009

Importador de datos del CRM

En este artículo, intentaré dar algunas recomendaciones acerca de la utilización del importador de datos del CRM.
En primer lugar hay que tener en cuenta que el importador sólo permite la importación de datos desde ficheros en formato .CSV (separado por comas).
De esta forma podremos insertar datos de forma masiva en CRM.
Para explicarlo mejor, voy a realizar un ejemplo de importación de datos de una serie de Contactos, desde un fichero de Excel, hasta la inserción en CRM.

En primer lugar vamos a crear un Excel, con las columnas de información que queremos importar. Como recomendación, introducir como nombre de las columnas, los mismos "Nombres para mostrar" de cada uno de los atributos del CRM que queremos importar (respetanto mayúsculas y acentos).
El excel quedaría así (los nombres son todos ficticios):


Ahora lo que vamos a hacer, es guardar el excel en formato .CSV pulsando en "Guardar como" y seleccionando de la siguiente manera:


Para realizar la importación, debemos ir a Herramientas->Importar Datos...:


Debemos seleccionar el fichero .CSV y seleccionar como delimitador de campo "Punto y coma (;)":


Ahora se debe seleccionar el "Tipo de registro" a impotar (en este caso "Contacto"). Al haber introducido como cabecera los mismos nombres para mostrar que los atributos en CRM, la Asignación de datos es "Automático":


Seleccionar a quién se le asignarán los registros y si se desea que se importen duplicados:


Introducir un nombre para el trabajo de importación y confirmar la misma:


La importación se lanza en un proceso asíncrono. Para realizar un seguimiento del estado del proceso de importación, se puede ir a Área de trabajo->Importaciones (la importación va pasando por los estados "Enviado","Analisis","Transformacion","Importando","Completado"):


Una vez acabado se podrá abrir el registro del proceso asíncrono, y desde allí identificar los registros que se a creado, y los posibles errores y causas de los mismos. En este caso de los 7 registros, 2 han dado error, por no encontrar la referencia de la empresa "Sunny":


Finalmente los registros están creados en el CRM:


Cosas a tener en cuenta para la importación:

  • Las columnas de tipo referencia o "Lookup" deben ser rellenadas con los nombres de las entidades a los que se referencia. Los registros de la tabla referenciada, ya deben de estar creados.
  • La velocidad de las creaciones de los registros puede variar según el servidor de que se trate.
  • Las columnas de tipo desplegable o "Picklist" deben ser rellenadas con los valores en texto del desplegable.

martes, 25 de agosto de 2009

Ordenar registros por varias columnas

Muchas veces me han preguntado si se podía ordenar los registros que aparecen en las vistas del CRM por varias columnas a la vez.
La verdad que hasta ahora no lo sabía, pero sí que es posible.
Me han recomendado buscar en el famoso "Centro de recursos" de CRM, un área al que casi nunca solía acceder, pero navegando por la misma se nota que es de mucha utilidad para usuarios de CRM.
Allí se encuentra un articulo: Ordenar registros por varias columnas

Explica que para ordenar por varias columnas simplemente hay que hacer:
1) Ir a la vista que se desea ordenar (o busqueda avanzada).
2) Seleccionar la primera columa a ordenar.
3) Con las teclas CTRL+SHIFT presionados ir seleccionando las siguientes columnas.

Hasta aquí, todo bien.
Pero, me empezaron a surgir dudas de hasta donde se podía llegar con esta funcionalidad.
1) ¿Hasta cuantas columnas de orden se pueden seleccionar a la vez?: Yo llegué hasta las 25 columnas, y lo único que noté es que cada vez tardaba un poco mas en recargar la vista.
2) ¿Funciona para cualquier tipo de campo o con algun tipo de campo no te deja "Multi-ordenar"?: Funciona con cualquier tipo de campo.
3) ¿Funciona con campos de otras entidades?: Como no se puede ordenar las vistas por columnas de otras entidades, tampoco se puede "Multi-ordenar".

Me pareció una utilidad mas que intersante, en especial al exportar a Excel, ya que así podría ordenar rápidamente por lo que me interesa, y exportar a Excel sólo la página actual en la que me encuentro.

domingo, 23 de agosto de 2009

FilteredViews y autenticación de SQL Server.

Como todos saben, la información de MSCRM está almacenada en una base de datos en SQL Server.
La forma soportada y documentada en la SDK de Microsoft CRM 4.0 de acceder a la información directamente en el SQL Server, es a través de unas vistas que son llamadas "FilteredViews".
Las FilteredViews, son vistas en SQL Server cuyo nombre contiene el mismo nombre de la entidad, con el texto "Filtered" por delante. Por ejemplo "FilteredAccount" para la entidad de "Cuentas".

Al SQL Server uno se puede conectar de dos formas, y con cada una de las mismas, las FilteredViews se comportará de forma diferente:

1) Autenticación integrada de Windows:
Al conectarse de esta forma, y al realizar una consulta, automáticamente resolverá con el usuario conectado, los roles de seguridad, idioma, desplazamientos horarios, etc.
Así, por ejemplo podríamos de esta forma hacer la siguiente consulta:

SELECT * FROM FilteredAccount

Las FilteredViews detectan el usuario del directorio activo conectado al SQL Server, y lo relacionan con el usuario correspondiente de CRM.
Esto lo realiza con una función en SQL Server que podemos probar de la siguiente forma:

SELECT dbo.fn_FindUserGuid

2) Autenticación de SQL Server:
Al acceder mediante autenticación de SQL Server, las FilteredViews no pueden reconocer al usuario conectado, y si ejecutamos la consulta anterior, simplemente no devuelve nada, como si no se tuviese permisos para ver ningún registro.
Si nos conectamos de esta forma, y queremos hacer una consulta a las "FilteredViews" solo lo podemos haces "Impersonalizando" la consulta, es decir, ejecutando la misma como si fuesemos otro usuario.
Esto se puede lograr con la cláusula "EXECUTE AS USER=..." de la siguiente forma:
SELECT * FROM FilteredAccount EXECUTE AS USER='contoso\admin'

De esta forma, la consulta se realizará con los roles de seguridad y perfil del usuario que se determine.