A veces necesitamos mostrar un mensaje en el "alert" de USD, pero necesitamos hacerlo con saltos de línea. Es fácil:
Crear una Action Call de esta forma:
Control Hospedado: CRM Global Manager
Accion: Display Message
Datos:
text=$Multiline(haciendo
saltos de linea
)
Mostrando entradas con la etiqueta CRM. Mostrar todas las entradas
Mostrando entradas con la etiqueta CRM. Mostrar todas las entradas
martes, 16 de enero de 2018
viernes, 20 de octubre de 2017
USD: Cómo refrescar una vista asociada
Es muy sencillo, basta con crear una Llamada a la acción de tipo RunXrmCommand.
Pongamos el siguiente ejemplo: En USD se nos muestra una pestaña con el formulario de un contacto, este formulario tiene una vista asociada a los casos de dicho contacto. Podrás comprobar que si creas un caso no se actualiza esta vista. ¿cómo refrescarla?
Crear una Llamada a la acción con los siguientes datos:
Damos por supuesto que el control "Contacto", es un control hospedado de tipo Página de Microsoft Dynamics 365
Si no sabes como obtener el nombredelavistaasociadaId edita en CRM el formulario de la entidad (en este caso Contacto), haces doble clic sobre el elemento de la vista asociada y en el campo nombre ahí lo tienes.
Pongamos el siguiente ejemplo: En USD se nos muestra una pestaña con el formulario de un contacto, este formulario tiene una vista asociada a los casos de dicho contacto. Podrás comprobar que si creas un caso no se actualiza esta vista. ¿cómo refrescarla?
Crear una Llamada a la acción con los siguientes datos:
Nombre: Refrescar vista de casos en contacto
Pedido:
Control Hospedado: Contacto
Accion: RunXrmCommand
Datos: Xrm.Page.ui.controls.get("nombredelavistaasociadaId").refresh();
Damos por supuesto que el control "Contacto", es un control hospedado de tipo Página de Microsoft Dynamics 365
Si no sabes como obtener el nombredelavistaasociadaId edita en CRM el formulario de la entidad (en este caso Contacto), haces doble clic sobre el elemento de la vista asociada y en el campo nombre ahí lo tienes.
Etiquetas:
associatedview,
CRM,
Dynamics365,
Refresh,
RunXrmCommand,
USD,
Vistas asociadas,
Xrm
viernes, 10 de febrero de 2017
Llamar a función desde popup en CRM con Javascript
Pongámonos en situación, en un CRM 2016 online, desde el formulario principal de Contacto queremos abrir un popup y una vez abierto, desde éste llamar a una función que está en el formulario de Contacto.
Tenemos un fichero contacto.js donde cargamos toda la lógica de negocio de javascript en relación a la entidad Contacto. En la configuración del formulario le añadimos al evento OnLoad la función onLoadContacto que estará en el .js
El popup se abrirá desde uno de los botones del ribbon y queremos desde este popup llamar a una función que está en contacto.js ¿cómo?
En el parent, que es contacto.js añadimos el siguiente código a la función onLoadContacto()
Además creamos la función que se llamará desde el popup:
Desde el formulario del popup sólo hay que poner la siguiente instrucción:
Tenemos un fichero contacto.js donde cargamos toda la lógica de negocio de javascript en relación a la entidad Contacto. En la configuración del formulario le añadimos al evento OnLoad la función onLoadContacto que estará en el .js
El popup se abrirá desde uno de los botones del ribbon y queremos desde este popup llamar a una función que está en contacto.js ¿cómo?
En el parent, que es contacto.js añadimos el siguiente código a la función onLoadContacto()
function onLoadContacto() {
Xrm.Page.test = test;
}
Además creamos la función que se llamará desde el popup:
function test() {
alert('test');
}
Desde el formulario del popup sólo hay que poner la siguiente instrucción:
window.top.opener.Xrm.Page.test();
Etiquetas:
child,
CRM,
Dynamics365,
Funciones,
JavaScript,
opener,
parent,
popup,
Xrm
domingo, 29 de enero de 2017
USD - Cómo cambiar el nombre y el logo
Cómo no, para estos menesteres ya hay que ir tocando algo de código, pero no demasiado ;)
Paso 1: Cambiar nombre
Para cambiar el nombre y/o apariencia de la denominada splash screen al abrir USD tenemos que agregar un fichero XAML a la carpeta donde tengamos instalado el cliente de USD.
Éste es el código:
Fijaros bien en las líneas 9 y 15, son las que mostrarán el nombre de nuestra compañía, empresa, cliente, etc...
Lo guardamos con el nombre CustomerSplashStyles.xaml en la carpeta donde se instaló el cliente de USD y al abrir USD tendremos esto:
Paso 2: Cambiar el logo que se mostrará cuando USD se abra.
Comprobamos el cambio abriendo el cliente de USD
Paso 1: Cambiar nombre
Para cambiar el nombre y/o apariencia de la denominada splash screen al abrir USD tenemos que agregar un fichero XAML a la carpeta donde tengamos instalado el cliente de USD.
Éste es el código:
1: <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
2: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
3: xmlns:resx1="clr-namespace:Microsoft.Crm.UnifiedServiceDesk.Properties">
4: <Style x:Key="FormAppNameStyle" TargetType="TextBlock">
5: <Setter Property="Foreground" Value="Blue"></Setter>
6: <Setter Property="FontFamily" Value="Segoe UI"></Setter>
7: <Setter Property="FontSize" Value="40"></Setter>
8: <Setter Property="Background" Value="White"></Setter>
9: <Setter Property="Text" Value="[Nombre de la Compañía]"></Setter>
10: </Style>
11: <Style x:Key="SplashAppNameStyle" TargetType="Label">
12: <Setter Property="Foreground" Value="Blue"></Setter>
13: <Setter Property="FontFamily" Value="/UnifiedServiceDesk;component/Fonts/#Segoe UI"></Setter>
14: <Setter Property="FontSize" Value="40"></Setter>
15: <Setter Property="Content" Value="[Nombre de la Compañía]"></Setter>
16: </Style>
17: <Style x:Key="SplashScreenDefaultFontStyle" TargetType="TextBlock">
18: <Setter Property="FontSize" Value="14px"/>
19: <Setter Property="Foreground" Value="Black"/>
20: <Setter Property="TextWrapping" Value="Wrap"/>
21: <Setter Property="TextTrimming" Value="WordEllipsis"/>
22: <Setter Property="FontFamily" Value="Calibri"/>
23: </Style>
24: <Style x:Key="SplashGridBgColor" TargetType="Grid">
25: <Setter Property="Background" Value="Gray"></Setter>
26: </Style>
27: </ResourceDictionary>
Fijaros bien en las líneas 9 y 15, son las que mostrarán el nombre de nuestra compañía, empresa, cliente, etc...
Lo guardamos con el nombre CustomerSplashStyles.xaml en la carpeta donde se instaló el cliente de USD y al abrir USD tendremos esto:
Paso 2: Cambiar el logo que se mostrará cuando USD se abra.
- Lo primero de todo como imaginarás es tener el logo [de la compañía], yo me he creado una imagen PNG simplemente con el MsPaint de Windows de 160 x 25 pixels

- Subir esta imagen como un webresource al entorno de Dynamics 365
- Editar el Hosted Control "Custom Panel": Ir a Configuración, Unified Service Desk, Hosted Controls
- Cambiar la línea 25
25: <Image Style="{DynamicResource USDLogo}" Grid.Column="0" ToolTip="Unified Service Desk" AutomationProperties.Name="Unified Service Desk" />
Por esta otra:
25: <Image Source="{Binding Source=new_logo, Converter={StaticResource CRMImageLoader}}" Style="{DynamicResource USDLogo}" Grid.Column="0" ToolTip="[Nombre de la Compañía] Service Desk" AutomationProperties.Name="Unified Service Desk" />
Importante recalcar que "new_logo" es el nombre que le hemos dado al WebResource que contiene el logo.
Etiquetas:
CRM,
Dynamics365,
logo,
Unified Service Desk,
USD 2.2
USD - Arrancando
Aunque podéis encontrar bastante documentación sobre Unified Service Desk, escribo este post para haceros más fácil entrar en el mundo del Contact Center, Customer Services o como lo queráis llamar.
Paso 1: Descarga del cliente y del instalador en el servidor
https://www.microsoft.com/en-US/download/details.aspx?id=50355
Paso 2: Instalación
La instalación del cliente es muy sencilla, la típica "next, next, finish"
Para la instalación en el servidor, deberíamos disponer previamente de un entorno de Dynamics 365, si aún no lo tienes ve a este link donde podrás conseguir una trial gratuita de 30 días.
Ahora vamos a instalar USD en nuestro entorno de Dynamics:
Paso 1: Descarga del cliente y del instalador en el servidor
https://www.microsoft.com/en-US/download/details.aspx?id=50355
Paso 2: Instalación
La instalación del cliente es muy sencilla, la típica "next, next, finish"
Para la instalación en el servidor, deberíamos disponer previamente de un entorno de Dynamics 365, si aún no lo tienes ve a este link donde podrás conseguir una trial gratuita de 30 días.
Ahora vamos a instalar USD en nuestro entorno de Dynamics:
- Ejecuta el Dynamics USD Package Deployer
- Selecciona un directorio en tu equipo para extraer todos los ficheros y cuando llegues a esta ventana: Selecciona la primera opción para hacer una instalación en limpio. Básicamente instala dos soluciones UiiForMicrosoftDynamicsCRM201 y DynamicsUnifiedServiceDesk con lo mínimo para abrir un USD conectado a ese entorno. El resto de opciones instalan además datos de configuración de ejemplo.
Paso 3: Abrir nuestro nuevo USD
- Ejecuta el acceso directo al cliente de USD que te creó el instalador.
- Cambia las credenciales, apuntando a tu entorno de Dynamics 365
y listo!
Etiquetas:
configurar,
CRM,
Dynamics365,
instalar,
Unified Service Desk,
USD 2.2
jueves, 29 de enero de 2015
Cómo depurar plugins en CRM 2013 / 2015 / 2016 Online
Vamos a depurar código de nuestro plugin de una forma muy sencilla y en breves pasos:
Requisitos previos:
Descargar la SDK de CRM2013
Paso 1
Una vez instalada/descomprimida la SDK ir a la carpeta Tools y ejecutar PluginRegistration.exe
Tendremos que indicar la conexión, usuario, etc... para conectar con el entorno de desarrollo y obtendremos una ventana parecida a esta:
Paso 2
Hay que seleccionar el step que vamos a depurar y después pulsar en el botón Start Profiling.
No es necesario modificar el popup de la configuración del profiler, pulsa directamente OK.
Paso 3
Abrir el registro que vayamos a depurar, realizar la acción que hayamos programado, en este caso es al activar una oferta. (Recordar registrar el evento en el constructor de la clase del plugin)
base.RegisteredEvents.Add(new Tuple>(40, "SetStateDynamicEntity", "quote", new Action(PostActivate)));
Nos saldrá el siguiente popup:
Paso 4
Descargamos el fichero de texto y lo adjuntaremos al Plugin Registration, para ello hay que pulsar el botón Debug en la barra del Plugin Registration, aparece la siguiente ventana, deberéis rellenar los campos y adjuntar en VS2012 el Pluginregistratrion process para depurar.
Finalmente sólo hay que pulsar el botón "Start Execution" para que arranque la depuración, acordaos de poner algún breakpoint porque sino... pasará de corrido.
Etiquetas:
CRM,
debugg,
Plugin Registration,
profiler,
sdk2013
lunes, 30 de abril de 2012
Valores de los Picklist en tus consultas SQL
Si te dedicas a personalizar el CRM de tu compañía lo más probable es que ya le hayas metido mano "por debajo" al entramado de SQL. Y este código que os paso aquí es bastante útil a la hora de obtener el literal de un picklist para una consulta o report.
Es tan sencillo como crearos una función en la BD del CRM, tal que así:
CREATE FUNCTION ObtenerValor ( @entidad varchar(50),
@atributo varchar(50),
@id int
)
RETURNS varchar(500)
BEGIN
DECLARE @return varchar(500)
SET @return = (
SELECT StringMap.Value AS DisplayValue
FROM StringMap
INNER JOIN MetadataSchema.Entity
ON StringMap.ObjectTypeCode = etadataSchema.Entity.ObjectTypeCode
WHERE (MetadataSchema.Entity.Name Like @entidad)
AND (StringMap.AttributeName Like @atributo)
AND (StringMap.AttributeValue = @id)
)
return @return
END
y después la llamáis en vuestra consulta:
SELECT
dbo.ObtenerValor('new_candidato', 'New_Departamento', c.New_Departamento) AS DEPARTAMENTO
FROM New_candidatoExtensionBase
Acordaos de darle permisos de ejecución de la función al usuario que lance la query.
Es tan sencillo como crearos una función en la BD del CRM, tal que así:
CREATE FUNCTION ObtenerValor ( @entidad varchar(50),
@atributo varchar(50),
@id int
)
RETURNS varchar(500)
BEGIN
DECLARE @return varchar(500)
SET @return = (
SELECT StringMap.Value AS DisplayValue
FROM StringMap
INNER JOIN MetadataSchema.Entity
ON StringMap.ObjectTypeCode = etadataSchema.Entity.ObjectTypeCode
WHERE (MetadataSchema.Entity.Name Like @entidad)
AND (StringMap.AttributeName Like @atributo)
AND (StringMap.AttributeValue = @id)
)
return @return
END
y después la llamáis en vuestra consulta:
SELECT
dbo.ObtenerValor('new_candidato', 'New_Departamento', c.New_Departamento) AS DEPARTAMENTO
FROM New_candidatoExtensionBase
Acordaos de darle permisos de ejecución de la función al usuario que lance la query.
jueves, 30 de junio de 2011
Cómo incluir ficheros .JS externos en nuestro CRM 4.0
Desarrollar introduciendo javascript en los eventos de los formularios es un verdadero coñazo porque tienes que grabar, publicar, probar, etc... Existe un método más sencillo y es, referenciar en el evento del formulario un fichero .js publicado en un sitio externo pudiendo ser incluso en una parte del site de nuestro CRM. De este modo solo tenemos que edita el .js con Visual Studio y probarlo directamente una vez subidos los cambios.
Cread un .js que contenga al menos una función llamada ejecutarOnLoad() y dentro de ella todo el código que querais que ejecute el evento en el formulario. Publicadlo y después escribid este código en el evento OnLoad()
Publicar la entidad y listo!
Cread un .js que contenga al menos una función llamada ejecutarOnLoad() y dentro de ella todo el código que querais que ejecute el evento en el formulario. Publicadlo y después escribid este código en el evento OnLoad()
var scriptEntidad = document.createElement('script');
scriptEntidad.language = 'javascript';
scriptEntidad.src = 'http://servidor/sitioweb/JS/vacacionesOnLoad.js';
scriptEntidad.onreadystatechange = OnScriptReadyState;
document.getElementsByTagName('head')[0].appendChild(scriptEntidad);
function OnScriptReadyState() {
if (event.srcElement.readyState == "loaded" || event.srcElement.readyState == "complete") {
ejecutarOnLoad();
}
}
Publicar la entidad y listo!
jueves, 4 de noviembre de 2010
¿Cómo eliminar un equipo?
Al menos la versión 4.0 del Dynamics no permite desde su interfaz eliminar un equipo, un poco raro ¿verdad? bueno, no pasa nada, para todo hay una solución :-)
Tenemos que acceder a la base de datos del CRM y borrar el registro del equipo de la tabla TeamBase. Previamente deberemos quitar a los integrantes del equipo.
Nota: Existen dos tablas (Team y TeamBase) pero con solo eliminar el registro de TeamBase es suficiente porque automáticamente se elimina de la otra tabla.
Tenemos que acceder a la base de datos del CRM y borrar el registro del equipo de la tabla TeamBase. Previamente deberemos quitar a los integrantes del equipo.
Nota: Existen dos tablas (Team y TeamBase) pero con solo eliminar el registro de TeamBase es suficiente porque automáticamente se elimina de la otra tabla.
miércoles, 27 de octubre de 2010
Incluir un link referente a una entidad en emails con un Triggers
Esto es otra opción además de la que anteriormente escribí en el post Incluir un link referente a una entidad bastante más sencilla (desde mi punto de vista) aunque tocando la base de datos del CRM, lo que puede poner nervioso a más de uno. Pero a mi me funciona :-)
PASO 1:
Crear un atributo de tipo nvarchar con una longitud de 250 en la entidad que queramos al que llamare 'new_enlace', en mi caso en una entidad personalizada llamada "new_vacaciones". Publicamos los cambios en la entidad.
PASO 2:
Hay que crear un Trigger tal que así:
PASO 3:
Agregar al cuerpo del email del workflow de turno la típica frase:
"Para visualizar este registro puede hacer clic" y añadimos el campo 'new_enlace' de la entidad 'new_vacaciones'. Obsérvese que el tag href ya lleva el texto 'aquí.' por lo que quedaría completa la frase.
PASO 1:
Crear un atributo de tipo nvarchar con una longitud de 250 en la entidad que queramos al que llamare 'new_enlace', en mi caso en una entidad personalizada llamada "new_vacaciones". Publicamos los cambios en la entidad.
PASO 2:
Hay que crear un Trigger tal que así:
CREATE TRIGGER [dbo].[TR_Link_Vacaciones] ON [dbo].[New_vacacionesExtensionBase] AFTER INSERT AS DECLARE @ID AS uniqueidentifier BEGIN SET NOCOUNT ON SELECT @ID = (SELECT New_vacacionesId FROM Inserted ) UPDATE New_vacacionesExtensionBase SET New_enlace = '<a href=''http://miservidorCRM/UNIDADPRINCIPAL/userdefined/edit.aspx?etc=10025&id=' + cast(@ID AS nvarchar(50)) + '''>aquí.</a>' END
PASO 3:
Agregar al cuerpo del email del workflow de turno la típica frase:
"Para visualizar este registro puede hacer clic" y añadimos el campo 'new_enlace' de la entidad 'new_vacaciones'. Obsérvese que el tag href ya lleva el texto 'aquí.' por lo que quedaría completa la frase.
miércoles, 22 de septiembre de 2010
Vista asociada en un Iframe
Por requerimientos del cliente (como siempre) necesitaba poner en una pestaña la vista asociada de una entidad relacionada con la del formulario principal ¿que qué es esto? me explico: Tengo una entidad personalizada que llamamos Linea de venta (algo así como una linea de un presupuesto) que está relacionada con las Ofertas en N:1 respectivamente. El cliente no quiere hacer más clics de los necesarios por lo que me veo a mostrar la vista asociada de las lineas de venta de la oferta directamente en una de las pestañas del formulario, ¿dónde? en un Iframe, y aquí os pego el código:
En el evento OnLoad del formulario:
Notas:
"new_quote_new_linea" es el nombre de la relación 1:N entre ambas entidades.
IFRAME_view es el nombre del frame donde vamos a colocar la vista asociada.
En el evento OnLoad del formulario:
function GetFrameSource(tabSet) {
if (crmForm.ObjectId != null) {
var oId = crmForm.ObjectId;
var oType = crmForm.ObjectTypeCode;
var security = crmFormSubmit.crmFormSubmitSecurity.value;
return "areas.aspx?oId=" + oId + "&oType=" + oType + "&security=" + security + "&tabSet=" + tabSet;
}
else {
return "about:blank";
}
}
crmForm.all.IFRAME_view.src = GetFrameSource("new_quote_new_linea");
crmForm.all.IFRAME_view.allowTransparency=true;
Notas:
"new_quote_new_linea" es el nombre de la relación 1:N entre ambas entidades.
IFRAME_view es el nombre del frame donde vamos a colocar la vista asociada.
miércoles, 15 de septiembre de 2010
Aumentar en número de registros por página
Como sabéis existe un límite de registros por página que puede definir el usuario en el menú Herramientas > Opciones. El máximo que puedes elegir es 250 registros.
Pues con una pequeña consulta y un Update podemos cambiarlo y poner la cantidad que queramos.
Ahí va:
Pues con una pequeña consulta y un Update podemos cambiarlo y poner la cantidad que queramos.
Ahí va:
UPDATE UserSettings SET PagingLimit = 10000 WHERE SystemUserId = (SELECT su.SystemUserId FROM SystemUser su WHERE su.FullName Like 'Administrador%')
lunes, 28 de junio de 2010
Google Maps en nuestro CRM 4.0
En muchas ocasiones el comercial debemos consultar dónde están las oficinas del cliente al que va a visitar, con esto simplificamos mucho mas la tarea pues nos vamos a basar simplemente en los datos postales que contenga el cliente y una simple página HTML con un mínimo código Javascript.
PASO 1:
Creamos un fichero html con el siguiente código, incluye el javascript que llamará a las librerías de Google:
PASO 2:
En la entidad Cuenta (podríamos hacerlo en cualquiera que tuviera campos de dirección) editamos el evento onLoad del formulario para insertar el siguiente código que hará que cuando pulsemos en una pestaña se cargue el mapa:
tab5Tab - el número corresponde al la pestaña donde está el mapa, recordar que como un array, empieza en 0 el conteo. Esta es mi 6ª pestaña en realidad.
MIHOST/ - es donde está publicado el fichero html
PASO 3:
Creamos un campo iframe dentro de la pestaña que tendrá el mapa y lo llamamos IFRAME_mapa. Obviamente este nombre puede cambiarse si se hace también en el código anterior.
En la url del mapa escribimos: about:blank
Marcamos la casilla para que se expanda todo lo posible en el formulario.
PASO 4:
Publicamos los cambios de la entidad y nos quedará algo así:
PASO 1:
Creamos un fichero html con el siguiente código, incluye el javascript que llamará a las librerías de Google:
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title></title>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
var geocoder;
var map;
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng;
latlng = new google.maps.LatLng(40.396764, -3.713379);
var myOptions = { zoom: 15, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP };
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
var address = location.search;
address = address.substring(address.indexOf('=') + 1);
codeAddress(address);
}
function codeAddress(address) {
if (geocoder) {
geocoder.geocode({ 'address': address },
function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({ map: map, position: results[0].geometry.location });
}
else {
alert("Error cargando el mapa: "
+ status + "\n"
+ "Asegúrese de rellenar correctamente País, Provincia, Ciudad, Dirección y Código postal.");
}
});
}
}
</script>
</head>
<body style="margin: 0px; padding: 0px;" onload="initialize()">
<div id="map_canvas" style="width: 100%; height: 100%">
</div>
</body>
</html>
PASO 2:
En la entidad Cuenta (podríamos hacerlo en cualquiera que tuviera campos de dirección) editamos el evento onLoad del formulario para insertar el siguiente código que hará que cuando pulsemos en una pestaña se cargue el mapa:
crmForm.all.tab5Tab.onclick = function() {
var url = "";
if (crmForm.all.address1_country.DataValue != null)
url = crmForm.all.address1_country.DataValue;
if (crmForm.all.address1_stateorprovince.DataValue != null)
url += (url == "" ? "" : ", ") + crmForm.all.address1_stateorprovince.DataValue;
if (crmForm.all.address1_city.DataValue != null)
url += (url == "" ? "" : ", ") + crmForm.all.address1_city.DataValue;
if (crmForm.all.address1_line1.DataValue != null)
url += (url == "" ? "" : ", ") + crmForm.all.address1_line1.DataValue;
if (crmForm.all.address1_line2.DataValue != null)
url += (url == "" ? "" : ", ") + crmForm.all.address1_line2.DataValue;
if (crmForm.all.address1_line3.DataValue != null)
url += (url == "" ? "" : ", ") + crmForm.all.address1_line3.DataValue;
if (crmForm.all.address1_postalcode.DataValue != null)
url += (url == "" ? "" : ", ") + crmForm.all.address1_postalcode.DataValue;
if (url != "") {
url = "MIHOST/localizador.html?address=" + url;
crmForm.all.IFRAME_mapa.src = url; }
}
Consideraciones:tab5Tab - el número corresponde al la pestaña donde está el mapa, recordar que como un array, empieza en 0 el conteo. Esta es mi 6ª pestaña en realidad.
MIHOST/ - es donde está publicado el fichero html
PASO 3:
Creamos un campo iframe dentro de la pestaña que tendrá el mapa y lo llamamos IFRAME_mapa. Obviamente este nombre puede cambiarse si se hace también en el código anterior.
En la url del mapa escribimos: about:blank
Marcamos la casilla para que se expanda todo lo posible en el formulario.
PASO 4:
Publicamos los cambios de la entidad y nos quedará algo así:
martes, 9 de marzo de 2010
Botón en un formulario que ejecuta un Workflow
Lo primero de todo es crear un atributo personalizado en la entidad del formulario donde queremos poner el botón. El atributo tiene que ser de tipo nvarchar (texto) y establecer la propiedad Búsqueda en No.
Publicamos el cambio y creamos el workflow (tiene que ser a petición) que vamos a lanzar cuando se pulse el botón.
Editamos el evento onload del formulario de dicha entidad y este código es el que crea (transforma el atributo) en un botón:
function CrearBoton(fieldname, buttontext, buttonwidth,clickevent)
{
functiontocall=clickevent;
crmForm.all.new_button.DataValue = buttontext;
crmForm.all.new_button.style.borderRight="#3366cc 1px solid";
crmForm.all.new_button.style.paddingRight="5px";
crmForm.all.new_button.style.borderTop="#3366cc 1px solid";
crmForm.all.new_button.style.paddingLeft="5px";
crmForm.all.new_button.style.fontSize="11px";
crmForm.all.new_button.style.backgroundImage="url(/_imgs/btn_rest.gif)";
crmForm.all.new_button.style.borderLeft="#3366cc 1px solid";
crmForm.all.new_button.style.width=buttonwidth;
crmForm.all.new_button.style.cursor="pointer";
crmForm.all.new_button.style.lineHeight="18px";
crmForm.all.new_button.style.borderBottom="#3366cc 1px solid";
crmForm.all.new_button.style.backgroundRepeat="repeat-x";
crmForm.all.new_button.style.fontFamily="Tahoma";
crmForm.all.new_button.style.height="20px";
crmForm.all.new_button.style.backgroundColor="#cee7ff";
crmForm.all.new_button.style.textAlign="center";
crmForm.all.new_button.style.overflow="hidden";
crmForm.all.new_button.attachEvent("onmousedown",push_button);
crmForm.all.new_button.attachEvent("onmouseup",release_button);
crmForm.all.new_button.attachEvent("onclick",testfunction);
}
function push_button(){
window.event.srcElement.style.marginLeft="1px";
window.event.srcElement.style.marginTop="1px";
}
function release_button(){
window.event.srcElement.style.marginLeft="0px";
window.event.srcElement.style.marginTop="0px";
}
Función que ejecutará el workflow:
ExecuteWorkflow = function(entityId, workflowId)
{
var xml = "" +
"" +
"<envelope xmlns:soap="\"http://schemas.xmlsoap.org/soap/envelope/\"" xmlns:xsd="\"http://www.w3.org/2001/XMLSchema\"" xmlns:xsi="\"http://www.w3.org/2001/XMLSchema-instance\"">" +
GenerateAuthenticationHeader() +
" " +
" <execute xmlns="\"http://schemas.microsoft.com/crm/2007/WebServices\"">" +
" <request xsi:type="\"ExecuteWorkflowRequest\"">" +
" <entityid>" + entityId + "</entityid>" +
" <workflowid>" + workflowId + "</workflowid>" +
" </request>" +
" </execute>" +
" " +
"</envelope>" +
"";
var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
xmlHttpRequest.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
xmlHttpRequest.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/Execute");
xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlHttpRequest.setRequestHeader("Content-Length", xml.length);
xmlHttpRequest.send(xml);
var resultXml = xmlHttpRequest.responseXML;
return(resultXml.xml);
}
Función del evento OnClick del botón que llamará al la que ejecuta el workflow pasándole el id del de la entidad y el del wf.
function testfunction()
{
var theWorkflowId = "5F63397D-2868-4B74-9E6E-A5C6012981F3"; //change to your workflow Id
ExecuteWorkflow(crmForm.ObjectId, theWorkflowId);
}
create_button_from_textattribute('new_button', 'email','184px',testfunction);
lunes, 1 de marzo de 2010
Ocultar botón de vista asociada
En el evento OnLoad() del formulario de la entidad principal (candidato en mi caso) pegamos este código:
Consideraciones a tener en cuenta:
Por último
¿Cómo localizo los nombres de mi Frame, botón y barra de navegación? Por ejemplo con el IExplorer 8.0 abriendo la ventana (en mi caso del candidato) y pulsando F12 que te muestra el código fuente. Luego hacemos búsquedas tipo *Frame, _MBtoplocAssocOneToMany* o nav_*.
y eso es todo, esperos haberos ayudado.
Fuente: be CRM
_tryhide = function()
{
try
{
// Localizamos el Frame que contiene el elmento a ocultar.
with (document.all['new_new_candidato_new_experienciaprofesionalFrame'].contentWindow.document)
{
if (readyState != 'complete') return setTimeout(arguments.callee,100);
// Id del boton que queremos ocultar
with (getElementById ('_MBtoplocAssocOneToMany10002newnewcandidatonewexperienciaprofesional'))
{
style.display='none';
}
}
}
catch(e)
{
return setTimeout(arguments.callee,100);
}
}
//Ponemos el elemento que queremos que capture el evento que ejecuta la funcion
document.getElementById('nav_new_new_candidato_new_experienciaprofesional').attachEvent('onfocus',_tryhide);
Consideraciones a tener en cuenta:
'new_new_candidato_new_experienciaprofesionalFrame'es el nombre del Frame donde está la vista asociada.
'_MBtoplocAssocOneToMany10002newnewcandidatonewexperienciaprofesional'es el botón que queremos ocultar, en mi caso es el Agregar Experiencia profesional existente.
Por último
'nav_new_new_candidato_new_experienciaprofesional'es la barra de navegación de la vista asociada.
¿Cómo localizo los nombres de mi Frame, botón y barra de navegación? Por ejemplo con el IExplorer 8.0 abriendo la ventana (en mi caso del candidato) y pulsando F12 que te muestra el código fuente. Luego hacemos búsquedas tipo *Frame, _MBtoplocAssocOneToMany* o nav_*.
y eso es todo, esperos haberos ayudado.
Fuente: be CRM
martes, 17 de noviembre de 2009
Incluir un link referente a una entidad en emails
En esto de empezar a personalizar el CRM hice un workflow que enviaba un email a un usuario específico cuando alguien creaba una oportunidad, pero claro, el email avisaba simplemente. ¿A qué oportunidad se refería el email? Así que se me ocurrió meter un link en el email que llevara directamente a dicha oportunidad.
Buscando, buceando y trasteando dí con esta solución: (aunque hay alguna más)
PASO 1:
Crear dos atributos en la entidad (Oportunidad x ejemplo) de tipo nvarchar, a uno le llamaremos 'enlace' y a otro 'flag' con una longitud de 250 y 15 respectivamente.
Agregamos estos atributos al formulario de la entidad.
PASO 2:
Abrimos las propiedades del formulario y en el evento ONLOAD escribimos esto:
PASO 3:
en el evento ONSAVE escribimos esto:
PASO 4:
Editamos la tarea 'Enviar email' del workflow.
Ahora podemos agregar el atributo 'enlace' de la entidad quedando de la siguiente forma:
Se ha creado una nueva Oportunidad con el tema {Tema(Oportunidad)} y requiere su validación.
Puede visualizarla haciendo clic {enlace(Oportunidad)}
CONSIDERACIONES:
La url que guardamos en el atributo 'enlace' en el ejemplo es
http://crm-dynamic/CRM/sfa/leads/edit.aspx?id= donde crm-dynamic es el nombre de nuestro servidor CRM y CRM es el nombre de la compañía matriz (es case sensitive). El resto de la url dependerá de la entidad que vayamos a manejar, copio aquí los posibles casos:
Sales Force Automation:
Accounts: http://<crm-url>/sfa/accts/edit.aspx
Contacts: http://<crm-url>/sfa/conts/edit.aspx
Leads: http://<crm-url>/sfa/leads/edit.aspx
Opportunities: http://<crm-url>/sfa/opps/edit.aspx
Marketing Automation
Campaigns: http://<crm-url>/ma/camps/edit.aspx
Marketing Lists: http://<crm-url>/ma/lists/edit.aspx
Campaign Response: http://<crm-url>/ma/campaignresponse/edit.aspx
Case Management:
Cases: http://<crm-url>/cs/cases/edit.aspx
Contracts: http://<crm-url>/cs/contracts/edit.aspx
KB Articles: http://<crm-url>cs/articles/edit.aspx
Custom Entities:
Custom: http://<crm-url>/userdefined/edit.aspx
Buscando, buceando y trasteando dí con esta solución: (aunque hay alguna más)
PASO 1:
Crear dos atributos en la entidad (Oportunidad x ejemplo) de tipo nvarchar, a uno le llamaremos 'enlace' y a otro 'flag' con una longitud de 250 y 15 respectivamente.
Agregamos estos atributos al formulario de la entidad.
PASO 2:
Abrimos las propiedades del formulario y en el evento ONLOAD escribimos esto:
//Ocultamos los atributos flag y enlace xq no interesan al usuario pero sí a nosotros.
crmForm.all.new_flag_c.style.display='none';
crmForm.all.new_flag_d.style.display='none';
crmForm.all.new_enlace_c.style.display='none';
crmForm.all.new_enlace_d.style.display='none';
var url ="<a href='http://crm-dynamic/CRM/sfa/leads/edit.aspx?id="
if(crmForm.FormType == 2)
{
//Si es el formulario de modificación
if ((crmForm.all.new_flag.DataValue == null )||(crmForm.all.new_flag.DataValue==""))
crmForm.all.new_enlace.DataValue= url + crmForm.ObjectId + "'> clic </a>";
else
{
//Comprobamos el Flag para saber en que estado nos encontramos
switch(crmForm.all.new_flag.DataValue)
{
case "SAVEANDCLOSE":
crmForm.all.new_flag.DataValue = "HECHO"
crmForm.all.new_enlace.DataValue= url + crmForm.ObjectId + "'>aqui.</a>";
crmForm.SaveAndClose();
break
case "SAVE":
crmForm.all.new_flag.DataValue = "HECHO"
crmForm.all.new_enlace.DataValue= url + crmForm.ObjectId + "'>aqui.</a>";
crmForm.Save();
break
case "SAVEANDNEW":
crmForm.all.new_flag.DataValue = "HECHO"
crmForm.all.new_enlace.DataValue= url + crmForm.ObjectId + "'>aqui.</a>";
crmForm.SubmitCrmForm(59, true, true, false);
break
default:
break
}
}
}
PASO 3:
en el evento ONSAVE escribimos esto:
//Si el Flag ya está relleno no haremos nada.
if ((crmForm.all.new_flag.DataValue == null )||(crmForm.all.new_flag.DataValue==""))
{
if (event.Mode==2)
crmForm.all.new_flag.DataValue="SAVEANDCLOSE";
else if (event.Mode==59)
crmForm.all.new_flag.DataValue="SAVEANDNEW";
else
crmForm.all.new_flag.DataValue="SAVE";
//Forzamos a guardar para que se cree el GUID del registro.
crmForm.Save();
//Impedimos que haga el guardado del evento original puesto que lo hemos manipulado
event.returnValue=false;
return false;
}
PASO 4:
Editamos la tarea 'Enviar email' del workflow.
Ahora podemos agregar el atributo 'enlace' de la entidad quedando de la siguiente forma:
Se ha creado una nueva Oportunidad con el tema {Tema(Oportunidad)} y requiere su validación.
Puede visualizarla haciendo clic {enlace(Oportunidad)}
CONSIDERACIONES:
La url que guardamos en el atributo 'enlace' en el ejemplo es
http://crm-dynamic/CRM/sfa/leads/edit.aspx?id= donde crm-dynamic es el nombre de nuestro servidor CRM y CRM es el nombre de la compañía matriz (es case sensitive). El resto de la url dependerá de la entidad que vayamos a manejar, copio aquí los posibles casos:
- SFA - Sales Force Automation (accounts,contacts etc)
- CS - Customer Service (cases,contracts etc)
- MA - Marketing Automation (campaigns, marketing lists etc)
Sales Force Automation:
Accounts: http://<crm-url>/sfa/accts/edit.aspx
Contacts: http://<crm-url>/sfa/conts/edit.aspx
Leads: http://<crm-url>/sfa/leads/edit.aspx
Opportunities: http://<crm-url>/sfa/opps/edit.aspx
Marketing Automation
Campaigns: http://<crm-url>/ma/camps/edit.aspx
Marketing Lists: http://<crm-url>/ma/lists/edit.aspx
Campaign Response: http://<crm-url>/ma/campaignresponse/edit.aspx
Case Management:
Cases: http://<crm-url>/cs/cases/edit.aspx
Contracts: http://<crm-url>/cs/contracts/edit.aspx
KB Articles: http://<crm-url>cs/articles/edit.aspx
Custom Entities:
Custom: http://<crm-url>/userdefined/edit.aspx
miércoles, 23 de septiembre de 2009
Cómo ocultar pestañas (tabs) en los formularios del CRM 4.0
Una vez más hay que recurrir a Javascript. En el evento OnLoad() del formulario hay que poner el siguiente código:
Fijaros en tab1Tab donde el número indica el ordinal de la pestaña que queremos ocultar, como los arrays, empieza por cero. He reutilizado la función UserHasRole() de la que ya hablé en el post Cómo habilitar un campo en función del rol del usuario.
Fuente: Todo Microsoft CRM
if (UserHasRole("Administrador")) {
crmForm.all.tab1Tab.style.display = 'inline';
}
else {
crmForm.all.tab1Tab.style.display = 'none';
}
Fijaros en tab1Tab donde el número indica el ordinal de la pestaña que queremos ocultar, como los arrays, empieza por cero. He reutilizado la función UserHasRole() de la que ya hablé en el post Cómo habilitar un campo en función del rol del usuario.
Fuente: Todo Microsoft CRM
jueves, 17 de septiembre de 2009
Cómo habilitar un campo en función del rol del usuario
Abrimos las propiedades del formulario.
Seleccionamos el evento OnLoad y pulsamos en el botón Editar.
Acuérdate de marcar el check "El evento está habilitado" porque si no, no funciona el codigo javascript que metas.
El código que tienes que meter dentro de function OnLoad() es:
Seleccionamos el evento OnLoad y pulsamos en el botón Editar.
Acuérdate de marcar el check "El evento está habilitado" porque si no, no funciona el codigo javascript que metas.
El código que tienes que meter dentro de function OnLoad() es:
if (UserHasRole("Director Ventas") || UserHasRole("Director Compras")) {
document.forms[0].all.new_validacioncomercial_d.disabled=false;
}
else {
document.forms[0].all.new_validacioncomercial_d.disabled=true;
}
/* *************************************************** */
function UserHasRole(roleName)
{
//oXml es un objeto que llama a obtener el rol
var oXml = GetCurrentUserRoles();
if(oXml != null)
{
//Selecciono el nodo Texto
var roles = oXml.selectNodes("//BusinessEntity/q1:name");
if(roles != null)
{
for( i = 0; i < roles.length; i++)
{
if(roles[i].text == roleName)
{
//Devuelve true si el rol es el indicado
return true;
}
}
}
}
//Sino devuelve falso
return false;
}
function GetCurrentUserRoles()
{
// Compongo el xml
var xml = "" +
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
GenerateAuthenticationHeader() +
" <soap:Body>" +
" <RetrieveMultiple xmlns=\"http://schemas.microsoft.com/crm/2007/WebServices\">" +
" <query xmlns:q1=\"http://schemas.microsoft.com/crm/2006/Query\" xsi:type=\"q1:QueryExpression\">" +
" <q1:EntityName>role</q1:EntityName>" +
" <q1:ColumnSet xsi:type=\"q1:ColumnSet\">" +
" <q1:Attributes>" +
" <q1:Attribute>name</q1:Attribute>" +
" </q1:Attributes>" +
" </q1:ColumnSet>" +
" <q1:Distinct>false</q1:Distinct>" +
" <q1:LinkEntities>" +
" <q1:LinkEntity>" +
" <q1:LinkFromAttributeName>roleid</q1:LinkFromAttributeName>" +
" <q1:LinkFromEntityName>role</q1:LinkFromEntityName>" +
" <q1:LinkToEntityName>systemuserroles</q1:LinkToEntityName>" +
" <q1:LinkToAttributeName>roleid</q1:LinkToAttributeName>" +
" <q1:JoinOperator>Inner</q1:JoinOperator>" +
" <q1:LinkEntities>" +
" <q1:LinkEntity>" +
" <q1:LinkFromAttributeName>systemuserid</q1:LinkFromAttributeName>" +
" <q1:LinkFromEntityName>systemuserroles</q1:LinkFromEntityName>" + " <q1:LinkToEntityName>systemuser</q1:LinkToEntityName>" +
" <q1:LinkToAttributeName>systemuserid</q1:LinkToAttributeName>" + " <q1:JoinOperator>Inner</q1:JoinOperator>" +
" <q1:LinkCriteria>" +
" <q1:FilterOperator>And</q1:FilterOperator>" +
" <q1:Conditions>" +
" <q1:Condition>" +
" <q1:AttributeName>systemuserid</q1:AttributeName>" +
" <q1:Operator>EqualUserId</q1:Operator>" +
" </q1:Condition>" +
" </q1:Conditions>" +
" </q1:LinkCriteria>" +
" </q1:LinkEntity>" +
" </q1:LinkEntities>" +
" </q1:LinkEntity>" +
" </q1:LinkEntities>" +
" </query>" +
" </RetrieveMultiple>" +
" </soap:Body>" +
"</soap:Envelope>" +
"";
var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
xmlHttpRequest.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
xmlHttpRequest.setRequestHeader("SOAPAction"," http://schemas.microsoft.com/crm/2007/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);
}
CRM: Empezando...

Para empezar ¿qué es un CRM? las siglas son de "Customer Relationship Management" ¿lo cualo? sí tranquil@, no es ni más ni menos que una aplicación web de Microsoft orientada a la gestión de todo lo que tenga que ver con el cliente en tu empresa. Es decir, gestión de contactos, cuentas, clientes potenciales, ofertas, pedidos, campañas de marketing, catálogo de productos, etc... todo ello "salvaguardado" por un sistema de seguridad basado en roles de usuario.
¿Cómo meterle mano a esto?
El CRM de Microsoft se basa en "entidades", es algo parecido a los objetos en programación. Una entidad "Contacto" tiene una serie de atributos como "Nombre", "Teléfono", etc... además puede estar relacionada con otras entidades 1:N, N:1 o N:N. En el apartado Personalización del módulo Configuración tenéis el listado de todas ellas. Se pueden crear nuevas entidades.
¿Y cómo programo algo para el CRM?
Pues hay varias opciones, incluyendo JavaScript en los eventos de los formularios, desarrollando en Asp.Net un aspx y agregar un iFrame al formulario de la entidad cuyo contenido será este aspx, desarrollando un Plugin o hacer llamadas a WebServices.
Poco a poco iré publicando las utilidades que desarrolle o que haya encontrado por ahí.
Suscribirse a:
Entradas (Atom)














