j.a.estevan

Si no eres parte de la solución, eres parte del poblema

Retrospectiva 2011, objetivos 2012 …

Este año 2011 que acabamos de cerrar he aprendido muchas cosas. No esas cosas normales que uno aprende con la vida y la experiencia sino cosas serias, de las que te hacen pensar y replantearte certezas, de las que consiguen cambiar viejos hábitos.

Una de esas cosas es que para ver donde estás es necesario detenerse a mirar atrás. Pisar el balón, parar de correr, levantar la cabeza y observar el juego desde arriba antes de seguir hacia un objetivo que puede no estar ya ahí. Es importante tener objetivos claros y medibles y de vez en cuando pararte a pensar si se están cumpliendo y qué puedes hacer para asegurarte de que se cumplan.

 

Trust, but verify

 

El año pasado hice una de esas listas de objetivos aunque no la publiqué, algunos de esos objetivos se han cumplido y otros no, este año la compartiré por otro de esos principios importantes que he adquirido este año:

 

If you want to go fast, walk alone. If you want to go far, walk together

 

  • Cambio de ambiente laboral: Hace mucho que me lo planteaba pero no un cambio de empresa porque sí. No necesariamente necesitaba un cambio de empresa sino un cambio de valores, de principios, de filosofía. Un cambio donde hacer las cosas bien no sea un extra sino una consecuencia lógica. En unos días se hará efectivo ese cambio así que este es un done de los buenos, mejorado con un cambio de residencia a Madrid, lo que a su vez contribuirá con el siguiente punto:
  • Mejorar mi networking 1.0: Es relativamente fácil mantener una red de contactos 2.0, redes sociales, etc. Pero los contactos no valen mucho si no son contactos reales y este año me propuse hacer algo al respecto. Lo cumplí bajo mínimos asistiendo a la Conferencia Agile Spain 2011.

Otra de las cosas importantes que he aprendido este año es la gran importancia que tiene perseguir una mejora continua. Da igual donde estés (o donde creas que estés), siempre se puede hacer algo para seguir mejorando y si te olvidas de esto, estas perdido. Estas son las mejoras que me planteo este año:

 

If you can’t measure it, you can’t manage it

 

  • Seguir intentando ser bueno en lo que se me da bien, y mejorar en todo lo demás. Ponerme las pilas en serio con AX 2012 y afrontar todo lo que venga en esta nueva etapa laboral que empieza. Motivación total a este respecto.
  • Ponerme las pilas de una vez con el inglés. Clases, reuniones, cualquier cosa. Y la consecuencia lógica de esto sería publicar los artículos del blog también en inglés. Este es uno de los puntos pendientes de 2011 y no puede quedar otro año en el tintero.
  • Para continuar con el networking 1.0 comentado antes, tengo ya en agenda unos cuantos eventos del mundo agile (CAS y AOS 2012) y desarrollo (Codemotion) y me gustaría encontrar alguno donde ampliar el circulo del mundo Dynamics AX en España. La experiencia del año pasado fue tan positiva que este año tengo que ampliar el objetivo a como mínimo 4 eventos.
  • Lanzar Open BOE: Llevo unos mese trabajando en mi tiempo libre en este proyecto y está casi a punto para lanzar una primera beta. No es ninguna virguería técnica pero es mi aportación al mundillo de los datos abiertos, transparencia y gobierno electrónico en el que creo con firmeza. Para quien le interese, hay una cuenta de twitter dedicada a este proyecto: @openboe

Y creo que con todo esto y algunos asuntos personales que he empezado con mucha ilusión tendré más que de sobra para conseguir un año productivo.

10 de enero de 2012 | hay 1 comentario

AX TIP: Mostrar label con saltos de línea mediante X++

Una característica bastante molesta que te encuentras programando para Microsoft Dynamics AX es la manera en la que se tratan los saltos de líneas al presentar texto en formularios utilizando etiquetas. Por ejemplo, la siguiente línea:

Box::yesNo("Línea 1 \n Línea 2", DialogButton::Yes, "Prueba multi línea!");

Presenta un diálogo normal con un texto en varias líneas (hace caso del carácter \n para poner un salto de línea):

strFmtLB 1 | Bien

Sin embargo al convertir el mismo texto en una etiqueta, el resultado es distinto:

// @TST001: Línea 1 \n Línea 2
Box::yesNo("@TST001", DialogButton::Yes, "Prueba multi línea!");

strFmtLB 2 | Mal

Y ocurre lo mismo si se utiliza una etiqueta con comodines (%1, %2, …) y la función strFmt de esta manera:

// @TST001: Línea 1 \n Línea 2
Box::yesNo(strFmt("@TST001"), DialogButton::Yes, "Prueba multi línea!");

Para que la etiqueta haga caso del salto de línea hay que utilizar la función strFmtLB:

// @TST001: Línea 1 \n Línea 2
Box::yesNo(strFmtLB("@TST001"), DialogButton::Yes, "Prueba multi línea!");

Y así si funcionará:

strFmtLB 3 | Bien

Pero esta función no sustituye a la anterior. Esto es, en caso de tener comodines y saltos de página habrá que incluir las dos funciones. Esto es bastante molesto cuando modificas una etiqueta y pones un salto de línea. Da la impresión de haberse roto algo que antes sí funcionaba, y es que esta función no esta incluida nunca en el código si no es necesaria de forma explícita.

26 de diciembre de 2011 | deja un comentario

Información de tablas durante el desarrollo en Dynamics AX

Cuando se desarrolla para Microsoft Dynamics AX es muy común tener que consultar tipos de datos, nombres de campos, tablas, etc. para mantener la coherencia entre objetos nuevos y estándar. Esta consulta se puede hacer mediante las propiedades de los formularios (el botón Configurar del menú contextual estándar) y consultando el diseño o la query que se muestra en este formulario o yendo directamente al objeto del AOT:

Pero si esta consulta la tenemos que hacer muy a menudo, como al principio de un gran desarrollo, es molesto tener que hacer todos estos pasos cada vez y se puede consultar mucho mas fácilmente de esta manera:

16 de diciembre de 2011 | deja un comentario

Definición de ‘hecho’ (DoD, Definition of Done)

  • Necesito precio para unos accesorios de baño para mañana {contrato a precio fijo, alcance fijo, plazo fijo}
  • Sin problema, le cuestan 50€ cada uno {confirmación del contrato}
  • Perfecto, pero los quiero colocados en la pared {ampliación de alcance no prevista}
  • OK, se los doy colocados en la pared {aceptación ¿? de la ampliación} :

Definition of Done - Fail

Obviamente esta situación es ficticia, pero el resultado es real. Esa “instalaciónlleva así desde hace más de un mes en un baño público y nada indica que la situación vaya a mejorar en a corto plazo. Alguien ha dado esa instalación por “hecho” pero esa no es la impresión que da cuando necesitas secarte las manos.

Me gustaría analizar cómo se ha llegado aquí porque es algo que vemos todos los días cuando hablamos de software, que es a lo que vamos:

Leer el resto del artículo →

29 de noviembre de 2011 | deja un comentario

HOWTO: Ejecutar tu propio código .NET en Dynamics AX 2009

Aunque esto es algo que tiende a desaparecer en el próximo Microsoft Dynamics AX 2012, de momento es una funcionalidad muy útil en la versión 2009, ya que es la única manera de solventar algunas limitaciones técnicas.

Me estoy refiriendo a la posibilidad de utilizar el .NET CLR Interop para ejecutar desde nuestro código X++ librerías desarrolladas en .NET (ya sea C# o VB.NET). Esta integración también tiene sus propias limitaciones pero amplía de manera notable las posibilidades de desarrollo en AX 2009.

Voy a hacer un ejemplo paso a paso, y el primer paso es crear la propia librería desde Visual Studio. En mi caso voy a utilizar (el ya súper antiguo) Visual Studio 2005 para crear un nuevo proyecto “Biblioteca de clases”:

Dynamics AX 2009 DLL Interop

El código va a ser muy sencillo para no complicar la prueba, simplemente devolverá el nombre del equipo donde se ejecuta el código (esto se puede utilizar para comprender la ejecución de código en el cliente (devolverá la máquina local) o en el servidor (devolverá el AOS):

01 de noviembre de 2011 | hay 3 comentarios

HOWTO: Enviar emails desde X++

Email

Enviar correos desde Microsoft Dynamics AX mediante código X++ es muy sencillo, pero requiere de demasiado código si se quiere aplicar de manera reutilizable.

Para enviar un email utilizando la clase SysMailer estándar haremos algo parecido a esto:

 

 

SysMailer   sysMailer;

SysEmailParameters  sysEmailParameters      = SysEmailParameters::find();
InteropPermission   interopPermissionClr    = new InteropPermission(InteropKind::ClrInterop);
InteropPermission   interopPermissionCOM    = new InteropPermission(InteropKind::ComInterop);
Set                 permissionset           = new set(Types::Class);

#define.DefaultFromAddress("from@jaestevan.com")
;

try
{
    // Permisos
    permissionset.add(interopPermissionClr);
    permissionset.add(interopPermissionCOM);
    CodeAccessPermission::assertMultiple(permissionset);

    //Inicialización de los parámetros de correo electrónico.
    sysMailer = new SysMailer();

    if (sysEmailParameters.smtpRelayServerName)
    {
        sysMailer.SMTPRelayServer(sysEmailParameters.smtpRelayServerName,
                                  sysEmailParameters.smtpPortNumber,
                                  sysEmailParameters.smtpUserName,
                                  sysEmailParameters::password(),
                                  sysEmailParameters.ntlm);
    }
    else
    {
        sysMailer.SMTPRelayServer(sysEmailParameters.smtpServerIPAddress,
                                  sysEmailParameters.smtpPortNumber,
                                  sysEmailParameters.smtpUserName,
                                  SysEmailParameters::password(),
                                  sysEmailParameters.ntlm);
    }

    // Dirección de origen
    sysMailer.fromAddress(#DefaultFromAddress);
}
catch
{
    throw error("No se puede inicializar el envío de emails");
}

// OK! SysMailer inicializado con parámetros y dirección de origen

// Añadir destinatario
sysMailer.tos().appendAddress("test@jaestevan.com");

// Se pueden añadir destinatarios en copia (CC)
sysMailer.ccs().appendAddress("cc@jaestevan.com");

// Subject del mensaje
sysMailer.subject("Mensaje de prueba");

// Cuerpo del mensaje
sysMailer.htmlBody("<a href='http://www.jaestevan.com'>BODY de ejemplo en HTML!</a>");

// Hasta se pueden añadir ficheros adjuntos!
sysMailer.attachments().add("ficherodeejemplo.txt");

// Let's dance!
sysMailer.sendMail();

// Renuncia de los permisos
CodeAccessPermission::revertAssert();

28 de octubre de 2011 | hay 4 comentarios

Un novato en la Conferencia Agile Spain 2011

Conferencia Agile Spain 2011

Voy a procurar no extenderme mucho para contar lo sucedido en estos dos días de conferencias que hemos podido disfrutar en la Universidad Jaime I de Castellón, empezando como no podía ser de otra manera felicitando la impecable organización por parte de los organizadores de Agile Spain. Un 10 para ellos y mi agradecimiento.

Después comentar que es mi primer evento “masivo” en la comunidad Agile Spain así que no tengo la oportunidad de hacer una valoración comparativa como otros compañeros están haciendo. Como es obvio, sólo voy a comentar las charlas a las que asistí. Ha quedado un poco largo, si te aburre puedes bajar directamente a las conclusiones :)

23 de octubre de 2011 | hay 5 comentarios

¿Agile en el canal Dynamics? ¿Locura?

Insanity: doing the same thing over and over again and expecting different results.- Albert Einstein
(Locura es hacer lo mismo una y otra vez y esperar resultados diferentes)

Como expuse en mi anterior post: ¿Sure Step vs Agile? Condenados a entendernos, estoy convencido de que un cambio de filosofía hacia el mundo ágil no sólo es positivo sino que es totalmente posible dentro del mundo de los grandes ERP en general, y del canal Dynamics en particular.

Como exponía en ese artículo, hay varios handicap que superar como la resistencia al cambio (hay que cambiar la mentalidad de muchas personas involucradas), la falta de confianza en el sistema para proyectos de largo alcance o incluso la falta de colaboración del cliente. Sin embargo hay ciertos trabajos muy típicos de esta industria que son ideales para empezar a experimentar con este cambio, a pesar de que el proyecto, en general, se gestione con Sure Step:

  • Migraciones (cambios de versión): Una migración es un proceso totalmente acotado con tareas claramente definidas y planificables, pero lo importante es que en este proceso no es tan importante la documentación (a menudo no es para nada importante) como la implicación del cliente en el proceso tanto para la realización de diversas pruebas al finalizar cada tarea, como para solucionar consultas sobre la marcha en caso de imprevistos (en las migraciones siempre hay imprevistos). Lo de “ágil” se vuelve literal ya que cuando el proceso de migración termina se tiene que implantar en tiempos de parada del cliente, casi siempre en un fin de semana.
  • Soporte post-arranque: Cuando se da por finalizada una implantación nueva y el cliente empieza a utilizar el sistema, a menudo se dará cuenta de que hay pequeños (o grandes) detalles que quiere modificar porque no se habían previsto durante las fases previas. La buena gestión de estas modificaciones puede diferenciar el éxito o el fracaso de una implantación ya que una cosa es que el proyecto finalice, y otra que el cliente de por cubiertas sus necesidades (o las que cree que lo son). Hacerle participe del coste y el esfuerzo de esos “extra” puede ser determinante para cerrar la implantación con todas las partes satisfechas.
  • Actualciones de mantenimiento: De la misma manera que en el punto anterior, trabajar con un sistema programable como lo son todos los grandes ERP’s hace que siempre haya pequeños o grandes cambios a realizar para optimizar el trabajo diario. La buena gestión de las necesidades, el desarrollo y la implantación de los cambios sin interferir el trabajo de los usuarios es determinante para que los mantenimientos se finalicen con éxito y sin fricciones.

Si alguien ya ha empezado o esta interesado en estos cambios me encantaría recibir opiniones en los comentarios. Y si alguien quiere comentar o debatir en persona estaré en la próxima Conferencia Agile-Spain 2011 (#cas_2011)

10 de octubre de 2011 | deja un comentario

AX TIP: Validar permisos (claves de seguridad) por código

A veces en nuestros desarrollos queremos limitar ciertos procesos a usuarios que tengan activa determinada clave de seguridad (Security Key):


(la imagen es de la documentación oficial)

 Para hacerlo utilizaremos las funciones que el estándar dispone para ello. Encontramos un ejemplo de utilización en la clase estándar SysTest:

// Only a developer can run unit tests
if (hasSecuritykeyAccess(securitykeynum(SysDevelopment), AccessType::Delete))
{
    // Código protegido
    ...
}
else
{
    throw error(strfmt("@SYS97038", securitykeystr(SysDevelopment), enum2str(AccessType::Delete)));
}
02 de octubre de 2011 | deja un comentario

Microsoft Dynamics AX Hotfix: Ley de Morosidad (España)

Están disponibles los objetos actualizados de Microsoft Dynamics AX para cumplir con los requisitos de la Ley de Morosidad según el BOE-A-2010-10708:

  • Microsoft Dynamics AX 2009 SP1

* requiere login

27 de septiembre de 2011 | deja un comentario