SDK Rest Retrieve con Expand

La librería SDK.REST es la mejor herramienta que tenemos para hacer queries a CRM desde Javascript. Esta librería ofrece una serie de métodos con los cuales podemos interactuar con la Api REST de CRM. Uno de esos métodos es el Retrieve que incluye el parámetro Expand que vamos a analizar.

Con el método Retrieve podemos obtener un registro de CRM indicándole la entidad y el Id del mismo. Además es siempre recomendable que le indiquemos los campos que necesitamos puesto que por defecto te devolverá todos, cosa que en la mayoría de los casos no necesitaremos y además ahorraremos recursos.

La definición del método RetrieveRecord según la librería es el siguiente:

El primer y el segundo parámetro son el Id y entidad del registro que queremos recuperar. Es importante notar que el nombre de la entidad es el Nombre de Esquema (Schema name) que se escribe con mayúsculas/minúsculas según está definido en la solución.

El tercer parámetro son los campos que queremos recuperar. En este caso sería una cadena de texto con los nombres (de esquema) de los campos que queremos obtener, separados por comas.

Las dos ultimas, son las funciones Callback de Exito/Error que se ejecutarán si el registro se ha devuelto bien o si se ha encontrado algún error respectivamente.

Finalmente, como cuarto parámetro tenemos el Expand. El Expand es una cadena de texto donde se incluirán los nombres de las relaciones que queremos expandir siempre en referencia al registro que estamos pidiendo. Se podrán incluir relaciones 1:N y N:1. En cada caso obtendremos un objeto distinto como resultado.

Relaciones 1:N de la entidad Account

Relaciones 1:N de la entidad Account

Es interesante recalcar que con los Expands no se indican qué campos de la entidad expandida quieres, sino que te devuelve todos. Es por esto que aunque en la definición de la librería diga que se pueden hasta expandir 6 relaciones, en mi opinión no es nada recomendable puesto que te devolverá en una sola llamada un volumen muy grande de datos [ 1 registro padre + (N1 registros hijos relación 1 * M1 campos cada registro)  + (N2 registros hijos relación 2 * M2 campos cada registro) + …  ]. Si multiplicamos esto por cada usuario de CRM que esté trabajando podemos sobrecargar el sistema.

Expand con relación 1:N

Un ejemplo sería obtener una cuenta y además todos los contactos asociados a la cuenta. Como es lógico, cuando hacemos esto obtenemos 1 resultado padre, la cuenta, y N hijos, todos los contactos relacionados con esa cuenta. La petición y deserialización sería del siguiente modo:

Como vemos en la siguiente imagen, el objeto response que nos devuelve como parámetro en el SuccessCallBack tiene primero los campos pedidos en el Select del registro padre (cuenta) y además, colgando del objeto contact_customer_accounts.results tenemos un Array con cada uno de los resultados hijos (contactos) y todos sus atributos.

Estructura del objeto response en un Retrieve con Expand 1:N

Estructura del objeto response en un Retrieve con Expand 1:N

Para recorrer el array de respuesta lo haremos como en se muestra en el código superior, con un bucle For que recorra todos los results de la expansión.

Expand con relación N:1

Ahora, en el caso opuesto, vamos a expandir una relación N:1. Esto es, queremos el padre del registro que estamos solicitando. Como no puede ser de otra manera, en este caso solo esperamos que nos devuelva un resultado y no N como en el ejemplo anterior.

Siguiendo con el ejemplo anterior, vamos a expandir la relación de “Contacto principal” de una Cuenta.

El código quedaría algo del estilo:

En este caso, al disponer de un solo resultado en la expansión, se ahorra el results del objeto account_primary_contact dentro del objeto response.

Estructura del objeto response en un Retrieve con Expand N:1

Estructura del objeto response en un Retrieve con Expand N:1

Expand con relación N:N

Desconozco si es posible expandir una relación N:N pero todas las pruebas que he hecho no han funcionado. Si alguien sabe cómo hacerlo le agradecería que indicase cómo en los comentarios!

Mezclando expansiones

Como hemos indicado con anterioridad, es totalmente posible expandir varias relaciones en la misma petición (hasta 6) y por cada una de ellas obtendremos un objeto colgando del response con el nombre de la relación. Si es 1:N además éste contendrá un Array denominado results con todos los hijos del registro.


Para terminar, indicar con la extensión para Chrome HUDCRM, en la pestaña “Query constructor” podéis obtener todos estos códigos mostrados en el post de manera muy sencilla.

Ejemplo constructor de queries SDK.REST con la extensión para Chrome HUDCRM

Ejemplo constructor de queries SDK.REST con la extensión para Chrome HUDCRM

 

Error al recuperar DateTime: nos devuelve un día menos

Algo que puede producirte un gran quebradero de cabeza tiene que ver con los objetos tipo DateTime, con la zona horaria y con los objetos Retrieve que ejecutes desde tu código C#.

Resulta que existe un problema en CRM que por el cual al hacer una petición de un objeto DateTime para posteriormente ser utilizado en código, la fecha que recibimos es distinta a la que hay en el CRM guardada. Cuando pidamos una fecha veremos que nos devuelve un día menos del que hay en CRM guardado. Esto podrá variar en función de la hora local que tengamos configurada en el servidor y la hora local del cliente que realice la petición.

Vamos a ver un ejemplo de código que selecciona un contacto de nuestro CRM y nos devuelve la fecha de nacimiento:

Para la prueba he creado un contacto con mi nombre y fecha de nacimiento de “21/04/1959”.

Fecha devuelta equivale a un día menos

Fecha devuelta equivale a un día menos

Nota: en el CRM, la fecha que se ve es “04/21/1959”. Esto tiene que ver con la configuración de mi usuario que tiene por defecto idioma ingles y formato de fecha de USA, sin embargo esta fecha es exactamente la misma que “21/04/1959”.

Como vemos en la imagen, la fecha obtenida tiene un día menos que la fecha guardada en el CRM. ¿Como solucionamos esto?. Bueno, seguramente existan muchos métodos que tienen que ver con la configuración horaria de los DateTimes devueltos por el OrganizationService u otros parámetros. La forma fácil y que yo utilizo siempre desde que la aprendí es la siguiente:

Una vez tengamos la fecha en un String, le concatenamos una “Z” al final del mismo, y volvemos a convertir a DateTime. ¿Y esto por qué es así? bueno por lo que he podido leer, al incluir una “Z” al final de una hora equivale a convertirla a hora local UTC. La Z viene de ZULU, utilizado por la marina estadounidense.

Con todo esto, nuestro código debería quedar del siguiente modo:

Con este cambio, el resultado que obtenemos pasará a ser el siguiente:

Fecha devuelta correcta

Fecha devuelta correcta