jueves, 23 de febrero de 2012

Crystal mostrando la moneda incorrecta

Se presentó el problema en un cliente de que no importaba lo que hiciéramos en el reporte, al desplegarlo por Web, siempre traía los campos "Currency" formateados con Euros.

Luego de una intensa revisión y pruebas se determinó lo siguiente:

  1. Asegurarse de que el "Reports Portal" está apuntando a su Application Pool y que el pool esté configurado correctamente con WebDLL.
  2. Revisar las opciones en la pestaña "ASP.NET" del portal de reportes, y en la ventana emergente, ver las opciones en la pestaña "Application" que están relacionadas a la cultura.  En este lugar se puede colocar la cultura que desee.  Este cambio a nivel de portal, luego debería reflejarse en los ASP.NET de todos los "Virtual Directories" dentro de este portal, pero vale la pena revisarlos.
  3. Revisar la configuración regional y de idioma del usuario WebDLL (muy importante, firmarse al servidor con el WebDLL porque las opciones regionales son por usuario).  Cambiar el idioma, la ubicación, y el idioma en la pestaña "Advanced".
  4. Entrar y personalizar la cadena de moneda aunque aparente estar correcta.
  5. Reiniciar el application pool y el portal de reportes.
Con estos pasos nuestros reportes web deberían listarse con el formato de moneda correcto.

martes, 24 de enero de 2012

Fuentes más pequeñas en diálog Area-Category-Issue (SLX7.5.3 Web)

Este es un problema más que nada estético.

Resulta que las fuentes del control Area-Category-Issue son muy grandes y a veces se hace dificil seleccionar la opción adecuada.

Hasta que Sage no incorpore una propiedad para establecer el ancho de los "dependant" lookups estamos lmitados a por lo menos hacer más pequeñas las letras.

Para esto, buscamos en la carpeta "css" el archivo que se llama sage-styles.css y agregamos el siguiente estilo:

.formtable .yui-panel .hd select
{
    font-size: 80%;
}

Con esto haremos las letras más chicas y nos dará un pequeño espacio adicional para leer las opciones:





En este caso era para Area-Category-Issue, pero la verdad el cambio funciona para cualquier lookup dependiente.

Actualización:  Existe un post en CustomerFX de un conocido programador.  El enlace es http://customerfx.com/pages/integrationblog/2012/07/27/expanding-the-area-category-issue-picklist-popup-screen-in-the-saleslogix-web-client.aspx y en el mismo explica cómo modificar unos archivos "js" (javascript) internos del SalesLogix los cuales permiten ampliar este dependent lookup.

Actualización 2:  Utilizando CSS encontré un método mucho mejor, como mil veces más sencillo y aplica para cualquier campo que necesiten ampliar.  El post lo puse en:  http://www.slxdeveloper.com/forum.aspx?forumid=4002&postid=32203

Expandir los nombres de los reportes (SLX 7.5.3 Web)

Constantemente los clientes se quejan de que el espacio donde se ven los reportes es muy reducido, y el nombre de la mayoría siempre queda truncado por el tamaño del control.

Para solucionarlo, deben buscar el smartpart que se llama Reporting.ascx y buscar la línea que tiene el control de selección de reportes.  Pueden hacer una búsqueda de:  select name="reportname"

Seguidamente vamos a modificar el DIV que está al inicio, y le vamos a colocar 500 pixeles de ancho en el atributo STYLE.  También vamos a agregar el atributo STYLE al "select control" y le pondremos de ancho un 100%.  La línea completa debería quedar así:

<div style="width:500px"><select name="reportname" id="reportname" onchange="reportNameChanged()" size="12" style="width:100%"></select></div>

Puse en negrita lo que deben agregar.

Al visualizar el listado de reportes se debería ver así:


Mucho mejor para los usuarios que el pequeño espacio que trae por defecto!

lunes, 23 de enero de 2012

Mostrar formularios del DialogWorkSpace en un Sales Process (SLX7.5.3)

Muchos de ustedes habrán notado que no es posible mostrar formularios en los Sales Processes web.

Recientemente tuve la necesidad de revisar esto por un flujo muy interesante de un cliente, así que les traigo la solución, un poco "dirty" como dirían, pero totalmente funcional.

Paso 1 - Procesando los "Form" en los Sales Process:

Busquen dentro de la carpeta SmartParts, la carpeta OpportunitySalesProcess.  Dentro abran para editar en notepad el archivo que se llama OpportunitySalesProcess_ClientScript.js y realicen una búsqueda de la función executeAction.  Allí podrán ver que la opción case 'Form' no hace absolútamente nada, así que deberán cambiarla de la siguiente manera:

        case 'Form':
            ProcessAction.prototype.Init = Init_Form;
            boolExecute = true;
            break;


Paso 2 - Creando la función para mostrar el diálogo:

Ok, ahora vamos a crear la función que nos permitirá mostrar nuestro diálogo.  Busquemos un espacio para escribir nuestra función y escriban lo siguiente:

function Init_Form() {
    var xmlDoc = sp_GetXmlDoc(this.xml);
    var objFrm = xmlDoc.getElementsByTagName('FormAction');
    var strFormName = objFrm[0].getElementsByTagName('LanForm')[0].getElementsByTagName('Name')[0].firstChild.nodeValue;
    DialogWorkspace.show(strFormName,'800','800','800','800');
    this.Finish();
    return false;
}

Ven los 800?  Lastimósamente no he logrado que el formulario sea de más de 500x500 y que esté en otro lugar que no sea X=0 Y=0, pero como es funcional, no me molesta tanto.  Vieron también que dice LanForm?  Déjenlo así, ya verán por qué.

Paso 3 - Creando el formulario... perdón, los!

Esto es lo único que puede parecer trillado.  Hay que crear el formulario en LAN y en WEB, es decir, en Architect y en Application Architect.  Por qué? porque el campo para poner el Web Form en el Sales Process utiliza los formularios que se hagan desde el WebAdmin, y no vamos a regresar a 7.0 con su programación horrible...  queremos un formulario de 7.5.3.

Como la función que hice no pasa parámetros (si encuentran la manera correcta de hacerlo les ruego que me avisen) el formulario que van a abrir recibirá el ID de la oportunidad, así que es mejor que vayamos a la entidad Opportunity para crear el formulario y de allí ya depende de su ingenio para darle funcionalidad.

Yo le voy a llamar dlgTestDrive:


Recuerden crear en el Architect un formulario que se llame igual, aunque esté vacío!



Paso 4 - Incorporando el formulario al Sales Process:

Ahora creamos un Sales Process y en algún punto, seleccionamos acción Form, y buscamos nuestro formulario:

Ahora falta únicamente probarlo, para ellos abrimos un SalesLogix desde Web, buscamos alguna oportunidad, le ponemos el Sales Process y buscamos el paso con el form.  Le damos clic a la descripción y:

Excelente!

miércoles, 18 de enero de 2012

Problemas con los campos moneda en SalesLogix Web 7.5.3

Por alguna razón, los campos tipo moneda (Currency) fallan cuando se utilizan navegadores con localizaciones en lugares fuera de "en-US", como en mi caso que es "es-PA" porque estoy en Panamá.

El problema que se presenta es que o bien sale un mensaje que dice "input string not in correct format" que impide marcar el botón para guardar, o al guardar el número, por ejemplo "3.99", el maldito se guarda como "399000" y si seguimos presionando guardar el número se va multiplicando por 1000...  súmamente molesto...

Afortunadamente he encontrado una manera de lidiar con los campos moneda y consiste en cambiar los campos tipo moneda a tipo número (Numeric).

Esto depende en gran medida de la implementación, si se van a utilizar todas las pantallas con campos tipo moneda o solo algunos.  En todo caso, si se va a realizar input a estos campos, cambiarlos a tipo número me ha dado muy buenos resultados.

Algo importante es que al cambiar los campos a tipo número, hay que colocarles el formato que queremos.  En Panamá, el formato sería {0:#,##0.00} lo cual nos presentaría 3211.3 como 3,211.30.

Si estamos en un formulario nativo del Application Architect, hay una propiedad de todos los campos en los formularios que se llama Data Bindings.  Dentro se "bindea" el campo a un atributo en la base de datos, y bajo el campo llamado "Binding" hay uno que dice Format String, que sería el lugar para colocar el formato que mostré.

Si es un formulario custom, y se están usando los WebEntityBindings, se colocaría el formato así:

WebEnityBinding miControl = new WebEntityBinding("CampoEnBD", "Text", "{0:#,##0.00}", "");

En ambos casos es muy importante setearle la propiedad "Format Type" del campo a "Number" o el formato no funcionará de la manera correcta.

martes, 10 de enero de 2012

El SalesLogix Mobile 2011 R1 desde un BlackBerry OS 5

Esto es una solución simple y sencilla para aquellas personas que están en países donde por algún motivo no es fácil o barato tener un nuevo BlackBerry con OS 6.

Si tienen un Curve u otro modelo de aquellos que sólo soportan BBOS 5, me es grato informarles que podrán utilizar el nuevo portal Mobile de SalesLogix (2011 R1, si, el que es HTML5 y CSS3) simplemente instalando Opera Mini.

viernes, 22 de julio de 2011

Lookup se cambia a Nulo en un DialogWorkspace

En 7.5.3 me vi en una situación donde por código hay que crear un registro en una tabla al presionar un botón, pero hay que seleccionar un valor de una Lookup para crear el registro.

Se decidió crear la funcionalidad en un SmartPart ubicado en el DialogWorkspace, y además que se pudieran establecer condiciones en tiempo real para el filtrado.  Se agregaron 3 checkbox para establecer las condiciones del filtrado por lo que obviamente hay que setear los 3 checkboxes para autopostback, pero al probar la funcionalidad tanto de los 3 checks como del mismo Lookup, el valor devuelto por el Lookup siempre se cambia a nulo luego del postback.

Primero hay que estar seguro que el "Entity" tenga bien mapeado el campo de visualización.  Luego hay que asegurarse que el Lookup esté seteado para binding tipo "String" y no "Object".  Con esto el valor se mantiene pero al traer un elemento del Lookup lo que vendrá es el SLXId del registro.

Agregamos un campo TextBox en el formulario que llamaremos lkID y le ponemos visible = false.  También agregamos un handle al evento LookupResultValueChanged y dentro del procedimiento le asignamos el valor del Lookup así:  this.lkID.Text = this.MyLookup.LookupResultValue.ToString();

Luego agregamos un evento Pre_Render al formulario si no lo tiene ya, y colocamos:

     if (lkID.Text+"$" != "$")
      {
          Sage.Entity.Interfaces.IAccount swssel = Sage.Platform.EntityFactory.GetById<Sage.Entity.Interfaces.IAccount(lkID.Text);
this.MyLookup.Text = swssel.Account;
      }


Oviamente suponiendo que estabamos haciendo un Lookup sobre la entity IAccount.

De esta manera ya tendríamos el SLXId seleccionado en el campo lkID y el texto en la propiedad Text del mismo Lookup.

Luego complemento con lo de los filtros al Lookup en tiempo real porque me han preguntado muchas veces sobre el tema.