Software Lab

SageCRM v7.1 – Calcular fechas de seguimiento de incidencias

Abr
08

Podemos incluir una función de fecha dentro de la select de la vista de incidencias para que en tiempo real, el sistema nos calcule los días que han pasado desde que estamos gestionando una incidencia.

Función para calcular los días que ha permanecido abierto un proceso:

.. , DATEDIFF(D, Case_createdDate, GETDATE()) AS DiasAbierto, ..

Este trozo de código se puede insertar dentro de la vista de incidencias -en el apartado de selección de campos- y en la pantalla de consulta de incidencias incluimos el nuevo campo ‘DiasAbierto’.

El resultado obtenido nos mostrará en tiempo real el número de días desde que una incidencia se ha abierto.

Se aprecian comentarios y sugerencias.

 

SageCRM v7.1 – Consultar una Procedure de SQL con JavaScript (server-side)

Feb
17

En este ejemplo vamos a analizar cómo lanzar una query de SQL, perteneciente a un procedimiento almacenado de Sage CRM, sirviéndonos de una función JavaScript que se ejecuta automáticamente al acceder a un formulario.

Esta función, que solo se puede ejecutar del lado del server (server-side), nos va a servir para devolvernos los valores de los campos que necesitamos incorporar en el formulario.

El jScript se puede insertar como código en una función ‘OnChange’ o en una función ‘OnCreate’ de html:

<script language=»JavaScript»>
window.attachEvent(«onload», seed);
// cuando se entra al formulario y al modificar el campo de seleccion
function grab(){
var dato;
dato = document.getElementById(«_HIDDENquot_comisionistaTEXT»).value;
return dato;
}
function getComiAddr(){
var strSQL,myQuery,dato1,CRM;
strSQL = «USE [CRM] GO «;
strSQL += «DECLARE    @return_value int,»;
strSQL += »        @xaddr_address1 varchar(100), «;
strSQL += »        @xaddr_address2 varchar(100), «;
strSQL += »        @xaddr_address3 varchar(100), «;
strSQL += »        @xaddr_address4 varchar(100), «;
strSQL += »        @xaddr_address5 varchar(100), «;
strSQL += »        @xaddr_city varchar(100), «;
strSQL += »        @xaddr_country varchar(100), «;
strSQL += »        @xaddr_postcode varchar(100), «;
strSQL += »        @xaddr_state varchar(100) «;
strSQL += «EXEC    @return_value = [dbo].[getCOMP_ADDRESS] «;
strSQL += »     @xprod_comisionista = » + document.getElementById(«quot_comisionista»).value + «, «;
strSQL += »        @xaddr_address1 = @xaddr_address1 OUTPUT, «;
strSQL += »        @xaddr_address2 = @xaddr_address2 OUTPUT, «;
strSQL += »        @xaddr_address3 = @xaddr_address3 OUTPUT, «;
strSQL += »        @xaddr_address4 = @xaddr_address4 OUTPUT, «;
strSQL += »        @xaddr_address5 = @xaddr_address5 OUTPUT, «;
strSQL += »        @xaddr_city = @xaddr_city OUTPUT, «;
strSQL += »        @xaddr_country = @xaddr_country OUTPUT, «;
strSQL += »        @xaddr_postcode = @xaddr_postcode OUTPUT, «;
strSQL += »        @xaddr_state = @xaddr_state OUTPUT «;
strSQL += «SELECT    @xaddr_address1 as N’@xaddr_address1′, «;
strSQL += »        @xaddr_address2 as N’@xaddr_address2′, «;
strSQL += »        @xaddr_address3 as N’@xaddr_address3′, «;
strSQL += »        @xaddr_address4 as N’@xaddr_address4′, «;
strSQL += »        @xaddr_address5 as N’@xaddr_address5′, «;
strSQL += »        @xaddr_city as N’@xaddr_city’, «;
strSQL += »        @xaddr_country as N’@xaddr_country’, «;
strSQL += »        @xaddr_postcode as N’@xaddr_postcode’, «;
strSQL += »        @xaddr_state as N’@xaddr_state’ «;
strSQL += «SELECT    ‘Return Value’ = @return_value «;
strSQL += «GO»;
myQuery = CRM.CreateQueryObj(strSQL,»»);
myQuery.ExecSQL();
dato1 = myQuery.FieldValue(«@xaddr_address1»);
//alert(dato1);
return dato1;
}
function seed(){
EntryForm.quot_comis_emp.value = grab();
EntryForm.quot_comis_addr1.value = getComiAddr();
}
</script>

Y el procedimiento almacenado que crearemos en MsSqlServer:

//STORED PROCEDURE

USE CRM
GO

CREATE PROCEDURE getCOMP_ADDRESS
        @xprod_comisionista INT,
        @xaddr_address1 varchar(100) OUTPUT,
        @xaddr_address2 varchar(100) OUTPUT,
        @xaddr_address3 varchar(100) OUTPUT,
        @xaddr_address4 varchar(100) OUTPUT,
        @xaddr_address5 varchar(100) OUTPUT,
        @xaddr_city varchar(100) OUTPUT,
        @xaddr_country varchar(100) OUTPUT,
        @xaddr_postcode varchar(100) OUTPUT,
        @xaddr_state varchar(100) OUTPUT
    AS
    BEGIN
        select top 1 @xaddr_address1 = a.addr_address1
        , @xaddr_address2 = a.addr_address2
        , @xaddr_address3 = a.addr_address3
        , @xaddr_address4 = a.addr_address4
        , @xaddr_address5 = a.addr_address5
        , @xaddr_city = a.addr_city
        , @xaddr_country = a.addr_country
        , @xaddr_state = a.addr_state
        , @xaddr_postcode = a.addr_postcode
        from address a, address_link ali
        where ali.adli_companyid = @xprod_comisionista
        and a.addr_addressid = ali.adli_addressid
        and ali.adli_personid is null and a.addr_deleted is null
    END
  
Para concluir, solo recordar que estas funciones solo se pueden ejecutar del lado del server; no funcionan del lado del cliente. Para ejecutar funciones del lado del cliente que accedan desde html directamente a base de datos podemos utilizar Ajax. Pero eso lo veremos en otro artículo.

Gracias por dejar tu comentario.

 

SageCRM v7.1 – Checkboxes selectivos

Ene
10

En SageCRM, al igual que como hemos explicado para otros tipos de datos, podemos interactuar sobre el valor de un campo de tipo checkbox (Casilla) en función del valor de otro campo checkbox.

Para nuestro ejemplo vamos a trabajar con dos campos nuevos creados en la ficha de la empresa que son de tipo checkbox:

En este caso lo que buscamos es que sean excluyentes o antagónicos, es decir: si uno de ellos está activado que el otro automáticamente se desactive. Lo que buscamos con esta función es no dejar en manos del usuario un posible error al marcar ambos campos simultáneamente y que el sistema desmarque automáticamente el campo checkbox sobre el que no está el foco en caso de estar ambos marcados.

La solución es mediante un JavaScript en la propiedad OnChange de la pantalla.

Cada uno de los campos de tipo checkbox tendrá en su propiedad OnChange una llamada a la función que verifica los valores de los checkboxes y que en caso de ser ambos iguales desmarca aquél de ellos en el cual no se encuentre el foco en ese momento.

Y para el segundo campo…

El Script es el siguiente:

<script>
function handleChange1() {  
    if (document.getElementById(«_IDcomp_clientecompra»).checked === true && document.getElementById(«_IDcomp_revisarpptos»).checked === true) {
    document.getElementById(«_IDcomp_revisarpptos»).checked = false;
    }
  }

function handleChange2() {
    if (document.getElementById(«_IDcomp_clientecompra»).checked === true && document.getElementById(«_IDcomp_revisarpptos»).checked === true) {
    document.getElementById(«_IDcomp_clientecompra»).checked = false;
    }
}
</script>

El resultado lo tienes en el siguiente vídeo:

SageCRMv7.1 Checkboxes Selectivos

Con mucho gusto seguiremos atendiendo todas vuestras consultas y sugerencias.

 

SageCRM v7.1 – Trucos para formatear los campos en pantalla.

Dic
02

Con SageCRM tenemos una ventana abierta a la programación con javascript y con ASP. Desde las funciones OnChange y OnCreate de las pantallas y listas podemos desencadenar las funciones javascript que se van a procesar en tiempo real del lado del cliente.

Código para modificar el color de la etiqueta en un formulario:

[Screen.OnCreate]

if (Values(«comp_pr_informatica»))
    {
    Caption = «<font color=’red’>»+CRM.GetTrans(«colnames»,»comp_pr_informatica»)+»:</font>»;

Código para modificar valores de las etiquetas de campos:

[Definición de campos]

<span style=»color:red»>PRODUCTOS:</span><br /><span style=»color:black»>Informática Pr</span>;

 

¿Deseas compartir con nosotros alguno de tus trucos de codificación?

 

 

SageCRM v7.1 – Consulta de seguimiento de oportunidades, con datos de zona, vendedor y empresa.

Dic
02

Llegado el momento de explotar la información creada en nuestro CRM se ponene a nuestra disposición varias alternativas. Una de ellas es crear una vista específica en SageCRM empleando el gestor de informes estándar y otras de ellas es Crystal Reports, posiblemente el mejor gestor de reporting de los últimos 15 años.

En el siguiente ejemplo mostramos una consulta de seguimiento de oportunidades mediante la cual tendremos la posibilidad de agrupar oportunidades por zona y vendedor, incluyendo información complementaria de la ficha de la empresa.

Código de la query SQL con todos sus campos:

SELECT c.*, o.*,op.*
FROM Opportunity o,OpportunityProgress op, Company c
where o.Oppo_OpportunityId = op.Oppo_OpportunityId
and C.comp_CompanyId = o.Oppo_PrimaryCompanyId

En esta consulta hemos mostrado todos los campos de las tablas relacionadas.

Código de la query SQL con una selección de campos, filtrada y clasificada:

SELECT c.comp_name, c.COMP_territory , c.comp_referencia, c.comp_type, c.comp_status, c.comp_source, t.terr_caption
, o.Oppo_Description, o.Oppo_Note, o.Oppo_CustomerRef, o.Oppo_Opened, o.Oppo_Closed, o.Oppo_Status, o.Oppo_Certainty, o.Oppo_Priority
, u.user_lastname, u.User_FirstName, op.Oppo_Status, op.Oppo_Stage, op.Oppo_Forecast, op.oppo_certainty, op.Oppo_ProgressNote, op.Oppo_Description, op.oppo_forecast
FROM Opportunity o,OpportunityProgress op, Company c, Territories t, Users u
where o.Oppo_OpportunityId = op.Oppo_OpportunityId
and C.comp_CompanyId = o.Oppo_PrimaryCompanyId
and t.Terr_TerritoryID = c.Comp_secterr
and u.User_UserId = op.Oppo_AssignedUserId
order by c.comp_name,o.Oppo_Description,o.Oppo_Opened

Análisis de la consulta:

El resultado es un informe de seguimiento de oportunidades en curso, perdidas o ganadas, con sus valores de previsión de venta y nota de seguimineto comercial, agrupadas por zona primero y después por vendedor y ordenada cronológicamente por fecha de apertura.

Recordemos que el seguimiento de las oportunidades nos muestra información de la evolución de las etapas que se han realizado a través del gestor de flujos de procesos.

Para más información y sugerencias, esperamos tus comentarios.

 

 

SageCRM 7.1 – Vista SQL que concatena 3 campos en la descripción de línea de venta para mostrar en documento Word

Dic
01

En SageCRM 7.1SP1  hay veces que necesitamos modelar  o incluso crear nuevos campos en la línea de documento para enviar a la plantilla Word de presupuesto o pedido.

En nuestro ejemplo hemos trabajado con artículos que pueden ser productos finales o incluso escandallos -esto es, productos con un desglose o estructura de componentes- empleados en montaje, despiece o fabricación.

La vista que emplea SageCRM es vLineItemsQuote:

El código programado es:

CREATE VIEW vLineItemsQuote AS
SELECT ( newproduct.prod_code + ‘ ‘ + char(13) + char(10) + newproduct.prod_kit
+ ‘ ‘ + ( case when QuoteItems.quit_nota is null then ‘ ‘ else QuoteItems.quit_nota end ) ) as metadescripcion, QuoteItems.*, NewProduct.* FROM QuoteItems
LEFT JOIN NewProduct ON QuIt_ProductID = Prod_ProductId WHERE QuIt_Deleted IS NULL

Análisis funcional de la query:

El nuevo campo creado en tiempo real metadescripcion se compone del código de producto más un retorno de carro, más un salto de línea, más un campo de usuario llamado prod_kit (que muestra el detalle de referencias de componentes en caso de que sea un artículo-padre de tipo ‘escandall0’) más un campo condicional empleando el contenido del campo de usuario quit_nota que se emplea para comentarios y cuyo valor puede ser nulo.

Es una solución interesante que nos permitió explorar toda la profundidad de SQL en combinación con las posibilidades de la programación web orientada a gestión documental.

Se aceptan comentarios y sugerencias.

SageCRM 7.1 – Vista SQL que envía datos de dirección 2ª empresa de Presupuesto a combinación con documento Word

Nov
01

Si en SageCRM 7.1SP1  necesitamos enviar datos de un presupuesto a Word con tablas enlazadas en segundo o tercer nivel, o incluso con datos de tablas que no están directamente vinculadas a la cabecera del presupuesto, la solución es modificar la vista ‘vMailMergeQuotes’.

Brain status when you find a solution

"Brain status when you find a solution", by ATG

vMailMergeQuotes

Esta vista de la entidad PRESUPUESTOS es la que utiliza SageCRM para realizar la consulta de envío de datos del presupuesto hacia la Macro de MsWord que crea la combinación. MsWord recbe como parámetros los campos seleccionados en la vista y los sitúa en el lugar del documento Word que se ha definido.

CREATE VIEW vMailMergeQuotes AS
SELECT Quotes.*, person.*
, COMISIONISTA.comp_name AS Comi_nombre, DireccionCOMI.addr_address1 AS comi_direccion1
, DireccionCOMI.addr_address2 AS comi_direccion2, DireccionCOMI.addr_address3 AS comi_direccion3
, DireccionCOMI.addr_address4 AS comi_direccion4, DireccionCOMI.addr_address5 AS comi_direccion5
, DireccionCOMI.addr_city AS comi_ciudad, DireccionCOMI.addr_state AS comi_provincia
, DireccionCOMI.addr_postcode AS comi_codigopostal, DireccionCOMI.addr_country AS comi_pais
FROM Quotes LEFT JOIN Company AS COMISIONISTA On quot_comisionista = comp_companyid
LEFT JOIN vAddress AS DireccionCOMI ON Comp_PrimaryAddressId = Addr_AddressId
LEFT JOIN person AS Person ON pers_companyId = comp_companyid
WHERE Quot_Deleted IS NULL

El formato del documento Word tiene que incluir los campos del alias de la consulta.

En nuestro ejemplo es una entidad Empresa alternativa a la entidad empresa de la oprtunidad de venta, que es la que por defecto toma el programa SageCRm en esta consulta.

 

 

SageCRM 7.1 – Automatización de campo texto con valor de campo selección de búsqueda avanzada

Sep
26

Sabemos que el valor que devuelve un campo de selección de búsqueda avanzada es integer, es decir, el identificador del registro de la entidad primaria a la que apunta. El dato de la selección no tiene que pertenecer a la identidad del contexto en el que estamos, por lo tanto no tenemos acceso implícito a sus campos.

Por ejemplo, en un campo de selección de empresa, el valor que devuelve no es el nombre (varchar), sino el identificador (int).

Pero podemos hacer uso de las funciones JavaScript de captura de datos del formulario para que en tiempo real, del lado del cliente, tomemos el texto del campo de selección y lo utilicemos para almacenarlo en otro campo varchar creado por nosotros.

El ejemplo está focalizado en la tabla de presupuestos (Quotes).

Estos son nuestros campos creados:

Ambos campos los hemos ubicado en la cabecera de presupuestos con el propósito de utilizar la entidad de empresa para seleccionar a un comisionista alternativo diferente a la empresa de la oportunidad de ventas en curso.

Al desplegar en el campo ‘Empresa Comisionista’ y seleccionar una empresa el programa rellena automáticamente el campo Empresa con el nombre de la misma.

Tengamos en cuenta que el valor texto no se pude tomar del contexto del presupuesto, que es una empresa diferente, y por lo tanto tiene una complicación mayor pues el dato que se guarda en el campo Empresa Comisionista es un integer.

La pantalla de Resumen de Presupuestos la hemos preparado así:

El script de contenido personalizado:

<script language=»JavaScript»>
window.attachEvent(«onload», seed);
//funciona al entrar al formulario y al modificar el campo de seleccion
function grab(){
var dato;
dato = document.getElementById(«_HIDDENquot_comisionistaTEXT»).value;
return dato;
}
function seed(){
EntryForm.quot_comis_emp.value = grab();
}
</script>

Eso es todo.
Se agradecen comentarios y sugerencias.

 

 

SageCRM 7.1 – Cómo formatear campos de texto con separadores de millares

Sep
11

En algunas ocasiones tenemos un campo no numérico que queremos formatear con separadores de millar sin convertirlo en numérico, es decir, sin convertir el campo texto en numérico entero o float (decimal).

En SageCRM 7.1 se hace así:

En la pantalla de entrada de datos de la entidad seleccionamos el campo en el que deseamos introducir la función de formateo.

En el ‘Script de Modificación’ introducimos la función

jscript: format(this)

 

En el ‘Contenido de Script personalizado’ introducimos la función:

<script>

function format(input)
{
var num = input.value.replace(/\./g,»»);
if(!isNaN(num)){
num = num.toString().split(«»).reverse().join(«»).replace(/(?=\d*\.?)(\d{3})/g,»$1.»);
num = num.split(«»).reverse().join(«»).replace(/^[\.]/,»»);
input.value = num;
}

else{ alert(«Solo se permiten numeros»);
input.value = input.value.replace(/[^\d\.]*/g,»»);
}
}

</script>

El resultado es que al editar el campo en cuestión el programa se encarga de rellenar automáticamente los puntos de los millares, comprobando además si introducimos un caracter no numérico y rechazándolo.

Antes …

 

… y después

 

En una misma pantalla se puede utilizar la función para varios campos diferentes, haciendo una llamada en cada campo a la función ‘jscript: format(this);’ siempre dentro de ‘Script de Modificación’.

 

SageCRM 7.1 – Preparación de una tabla en formato CSV para importar

Ago
16

Todos estamos acostumbrados a trabajar con Excel de una forma más o menos técnica pero siempre encontramos problemas para que Excel exporte bien nuestras tablas a formato CSV.

Otro de los grandes obstáculos que encontramos a la hora de preparar tablas en formato CSV es el formato que acepta el importador. Existe un único formato homologado CSV pero mil variantes, dependiendo de cada software importador.

CÓMO PREPARAR LA TABLA CSV PARA SAGECRM:

Estamos en Excel y tenemos una tabla con un registro en cada fila con campos de la empresa, de la persona, de la dirección, los teléfonos de empresa y persona así como el email de la empresa y el email de la persona.

 

Para que el parser o ‘comprobador sintáctico’ de SageCRM no rechace tu tabla CSV sigue el siguiente procedimiento:

  1. Utiliza la primera línea para poner los nombres de los campos. Si pones los nombres de los campos con la nomenclatura de SageCRM te quitas 1 hora de asignaciones manuales cuando importes el CSV en SageCRM al final. Desde Excel guardar como CSV(archivos de tipo texto). Cerrar Excel.
  2. Abrir el fichero CSV con el excelente programa freeware Notepad++ (http://notepad-plus-plus.org/).
  3. Ir al inicio del documento. Buscar/Reemplazar comillas dobles (“) por espacio vacío ().
  4. Buscar/Reemplazar punto y coma (;) por comillas dobles+coma simple+comillas dobles (“,”). Esto nos hace correctamente los separadores de campo siempre y cuando no haya un punto y coma dentro de un registro, que se debe evitar y limpiar previamente.
  5. Dejar la primera línea <nombres de campos> sin comillas dobles y separados por coma simple, hazlo a mano, es 1 minuto.
  6. Situarse en el campo 1 de la línea 2 y crear una macro para insertar comillas dobles en el carácter 1 ir al final de la línea con tecla <fin>, pulsar las comillas dobles y la flecha derecha para saltar de línea —– y finalizar macro.
  7. ejecutar la macro hasta el final del fichero y dejarle que procese. Tarda 2 segundos cada mil líneas más o menos.

Una vez listo el fichero CSV de dos o más líneas tendrá que quedar así:

Linea 1>

comp_name,comp_type,pers_firstname,pers_lastname,emai_emailaddress/company,emai_emailaddress/person,phon_number1/company,phon_number2/company,addr_address1/company,addr_postcode/company,addr_state/company,addr_city/company,comp_website

Linea 2>

«CLIENTE TESTS»,»CLIENTE»,»MANUEL»,»GONZÁLEZ GARCÍA»,»info@clientetest.com»,»m.gonzalezg@clientetest.com»,»(98456) 123-7888″,»(98456) 555-7888″,»Libertad, 33, 4º, 1ª»,»28555″,»MADRID»,»GUADARRAMA»,»www.clientetest.com»

la primera línea con los nombres de los campos y las demás líneas con los datos, una por cada registro, siguiendo las normas de formato de tablas a importar de SageCRM.

Si necesitas ayuda puedes contactar en qdk@cuadernodecarga.com