sábado, julio 31, 2010

XML, PDF, EMAIL en IBMi AS400


En el último mes estuve metido en un proyecto de modernización de la aplicación ERP de la empresa en la que presto mis servicios profesionales.

Antes que nada, tendré que mencionar que buscamos a alguien que nos ayudara en esta aventura de modernización de la aplicación ERP que corre en IBM i, mi jefe se contrató a un conocido suyo con experiencia de más de 15 años en RPG y AS400, pero después de un mes no hubo muchos progresos ya que no estaba totalmente empapado con las tecnologías actuales y un tanto diferentes a RPG ILE y pantalla verde, por lo que  finalmente se separó del proyecto, entonces me reasignaron y me dejaron con este proyecto.

Este proyecto requería el conocimiento y dominio de ciertas tecnologías como XML, RPG ILE /Free, IBM i (AS400), entender formato Adobe Acrobat PDF, HTML, FTP y un poco de operación básica de Unix/Linux e IFS de AS400.

Las especificaciones del proyecto en términos generales fueron:
  • Parsear un XML que ya generábamos desde hace años utilizando RPG y el IFS.
  • Crear Documentos PDF desde el XML.
  • Imprimir el PDF directamente a impresoras del IBM i.
  • Enviar el documento mediante correo electrónico.
  • Establecer una interfaz web para mostrar el contenido del Buzón de correo.
Cabe mencionar que esta funcionalidad ya existía en la aplicación ERP desde hace 8 años cuando un güerito llamado Peter Howe y su servidor lo hicimos, solo que ahora, teníamos que eliminar la dependencia de Linux al 100% además de un programa de Windows que servía para bajar el archivo e imprimirlo en una impresora de la red.

Seguramente te estás preguntando, ¿porqué carambas lo tenías que hacer desde cero si ya existe software para eso?... la respuesta es sencilla, primero, era caro, pero realmente la respuesta es que tenemos este ERP financiero instalado en varias máquinas de cada cliente y durante años las herramientas que nosotros hemos creado e integrado en nuestro software han sido totalmente escalables con costos mínimos o nulos cuando ha llegado el tiempo de hacer actualización de hardware, lo que se ha traducido en cero preocupaciones.

La aplicación ERP de la que hablo se llama FIN, y Nuvek la ha mantenido por más de 25 años en el mercado con al menos 200 clientes en su historia, yo he estado a cargo de la ingeniería del paquete por cerca de 10 años.

La tarea era un tanto especial, ya que la aplicación está desarrollada con RPG ILE de IBM y no quería yo alejarme mucho de ahí.

XML.
Para parsear XML desde RPG había 2 formas




Acrobat Reader Document PDF.
Para generar los PDFs aparte de las mismas herramientas de IBM (caras) y algunos paquetes comerciales de terceros, encontré algunas Open Source que me permitírían hacerlo:

  • Utilizar RPG 100% utilizando JPLTOOLS de Jean-Paul Lamontre, un Francés que le ha echado muchas ganas a su herramienta. Está muy poderosa, solo le encontré 2 peros: No acepta Fonts externos y no acepta de todo tipo imágenes para incluir en el Documento PDF.
  • iText, esta herramienta está desarrollada en Java, es tal vez la herramienta más poderosa y popular para crear PDFs en el mundo de Java, el único problema es que si no entiendes de Programación Orientada y Java, tal vez te resulte demasiado complicado para implementar desde RPG.
  • PDFBox es una herramienta de la fundación Apache para crear PDFs, aunque casi parecido a iText, en realidad cada uno está diseñado para diferentes objetivos.


Envío de correos electrónicos. 
Al igual que el PDF, aquí está la versión de IBM, otras versiones comerciales y Código Libre, me concentraré en solo las 2 opciones que revisé.

  • MMAIL de , utiliza el servicio SMTP del sistema operativo, así es que tendrás que configurarlo y, te permite transformar Archivos del spool como documentos PDF, ya sean del tipo SCS o AFP, además de permitirte enviar y recibir correo en tu IBM System i. La documentación es extensa.
  • RPGMAIL de Aaron Bartell, esta herramienta me encantó, ya que es simplemente un envío de correo electrónico, si no necesitas nada más que enviar email a través de un SMTP externo, esto es todo lo que requieres. Sin tediosas configuraciones.

El reto fué imprimir Documentos PDF directamente en impresoras del IBM i, mi solución fué utilizar ghostscript para convertir el PDF como PCL y luego mandarlo a la impresora. Aquí el artículo que describe como lo puedes implementar tu mismo.

Aún sigo en mi tarea de modernización de este proyecto, por lo que he dejado de lado mis tareas como gerente de proyectos de software por unas semanas, y mientras ando en este asunto de la programada, reitero mi pasión por el desarrollo de software profesional desde cualquier ángulo: Ya sea dirigiendo el proyecto con un equipo a mi cargo o haciéndolo la ingeniería e implementación por mi mismo.

En el IBMi (que es como se le llama hoy al AS400) se puede hacer TODO lo que se requiere y espera de una aplicación de clase mundial, combinando una podera base de datos como DB2, el poder el millones de transaciones y cientos de usuarios concurrentes, además de habilitar las aplicaciones por el Web, lo único que se requiere es querer y obtener las habilidades.

Este proyecto es en mi opinión, uno de los más importantes en la vida de FIN en los últimos 5 años, porque el poder que ahora daremos para generar documentos electrónicos es infinito. Ahora simplemente se escribe un archivo de spool con el XML que se requiere y se manda a ejecutar un conversor y se envía un PDF por correo electrónico o se imprime directamente en la impresora del IBM i de forma silenciosa, así de fácil.

Por ahora, estoy implementando:

  • Facturas Electrónicas
  • Cheques de Nómina y Cuentas por Pagar (si, incluyendo el famoso numerito en font MICR para tóner magnético)
  • Estados de Cuenta para clientes.

Como menciono, las posibilidades son infinitas con ésta tecnología que desarrollé, ya que elimina el tener formas pre-impresas al 100%. En algún próximo post explicaré a detalle lo que hice para imprimir el PDF en el AS400 IBM i, y también publicaré algunos ejemplos del XML y el PDF resultante.

Lo que me gusta es que mi gran amigo del alma Angel Flores, ha empezado a utilizar éstas tecnologías y ha ampliado sus habilidades de modernización dentro del AS400 IBM i.

Como siempre estoy a las órdenes para cualquier asesoría.

Links:
http://itextpdf.com/
http://www.scottklement.com/expat/
http://pdfbox.apache.org/
http://jplamontre.free.fr/jpltools.htm
http://www.mowyourlawn.com/RPGMail.html
http://www.easy400.net/mmail/start
http://www.ghostscript.com/

24 comentarios:

  1. hola que tal buenas tardes, esta muy intresante el proyecto que mencionas, me gustaria aprender a hacer lo mismo, eso de no ocupar papel en un 100% esta muy chido no se si me podrias orientar para hacer algo igual gracias y espero tu respuesta mi correo es matadamas0605@hotmail.com

    ResponderEliminar
  2. Hola, Buenas.

    ¿Bajo que plataforma lo quieres hacer? ¿Windows, Linux, IBM i (AS400) ? ¿es para el web o escritorio?

    Dependiendo de la plataforma, tendrás que usar algún lenguaje: C#, Visual Basic, PHP, RPG ILE, Cobol, Java, Ruby... y dependiendo del lenguaje ya hay herramientas que puedes utilizar, en java por ejemplo, hay herramientas con las que puedes convertir de HTML.

    Si puedes ejecutar Java en el servidor o computadora, entonces tienes casi todo resuelto, java es universal, y por esa razón, hay herramientas existentes que corren donde sea.

    A veces el problema es java mismo, porque o no te gusta o no quieres meterte en esos rollos, entonces ya hay herramientas, librerías o frameworks también para casi cada lenguaje, y hay veces que incluso ya hay herramientas incorporadas como para Zend Framework en PHP.

    ResponderEliminar
  3. mira me interesaria hacer el proyecto en xml, pero si no es posible en php, para mi que xml es casi igual a html pero mas ordenado en plataforma windows y pues es para intranet bueno eso es todo y espero tu respuesta de antemano grcias por reponder

    ResponderEliminar
  4. HTML sigue el mismo sistema de marcado que proporciona XML, con la diferencia que HTML tiene ciertas reglas a seguir de acuerdo a los estándares de la W3C. HTML es universal, pero cada browser tiene su propia implementación, es decir lo que veas en Internet Explorer (IE), no serán los mismos resultados que en FireFox, u Opera, o cualquier otro browser y su versión. De igual forma, el IE de Windows no funciona igual que en una Mac.

    No entiendo bien lo que quieres hacer. ¿Es un portal web pero en corriendo en una intranet?

    ¿Que tipo de documentos PDF quieres crear?
    ¿Quieres convertir páginas HTML como PDF?

    Te agradeceré que me expliques más acerca de tu proyecto.

    Intentando adivinar y asumiendo un poco acerca de tu proyecto, aquí te dejo algunas opciones:
    1) Tal vez lo que quieres es generar un documento PDF desde PHP directamente. En tal caso, puedes instalar la librería FPDF que puedes bajar de http://www.fpdf.org/ y escribir directamente desde PHP. Esto es lo más fácil.
    2) Tal vez quieres convertir una página web (HTML) a PDF utilizando PHP, entonces hay que instalar HTMLDOC http://www.htmldoc.org/. Lo he usado por años, funciona bastante bien.
    3) Tal vez quieres que cualquiera de tus programas en PHP genera archivos XML y quieres trasladarlos a PDF. Entonces tienes que inventar tu propio marcado de XML, luego tienes que hacer un programa para leer el XML y convertirlo a PDF. Otra opción, es que uses Apache FOP http://xmlgraphics.apache.org/fop/ que te dá chance de irte de XML a PDF directamente.

    Si no es ninguna de las opciones arriba, con gusto te puedo ampliar la duda. :D solo explícame más a detalle lo que tienes en mente.

    Saludos

    ResponderEliminar
  5. Hola!! qué tal, me parece muy interesante el proyecto que llevaste a cabo, oye yo apenas me estoy iniciando como programador, y estoy llevando a cabo un proyecto de factura electrónica aquí en México (ya que será obligatorio para 2011), la idea es llevarla a cabo dentro del AS-400 o de manera externa en un servidor Windows donde se cree el XML a partir de un spool del AS-400, se le añadan algunos campos obligatorios que pide Hacienda, se firme electrónicamente con algoritmo RSA de clave privada y se regrese al mismo sistema AS-400 para su impresión y almacenamiento con Quick Press... Espero y me puedas dar algunas ideas de cómo hacerlo... Que estés muy bien! Gracias de antemano...

    ResponderEliminar
  6. Hola Emmanuel, gracias por pasar por aquí a saludar.

    ¿habrás de casualidad leído http://blog.jmerinoh.com/2010/09/documentos-electronicos-as400-ibmi.html ? Ahí tengo un algoritmo de cómo implementar este proyecto.

    Me parece que cualquier cosa que quieras hacer, la puedes implementar desde el AS400, ya sea con herramientas de código libre o licencias de terceros.

    Para sugerirte algo más concreto, ¿que versión de OS tienes en tu AS400.

    Quick-press suena una opción viable para almacenar y diseñar PDFs, ¿ya tienes ese software instalado? ¿o estás evaluando la compra apenas?

    Lo único que sé acerca de la factura electrónica en México es que es obligatoria a partir del 2011.

    Seguimos aquí a tus órdenes.

    ResponderEliminar
  7. Ahh.. claro que lo he leído, la vdd es que se me hace muy interesante lo que hiciste... pero al parecer tú llevaste a cabo el proyecto desde cero, es decir, no tenías un software para realizar la gestión de impresión, en este caso no contabas con Quick Press, en mi caso, si lo tengo instalado en el i de IBM con versión OS 5.1 y creo que sería buena opción echar mano de esta herramienta... Pero de cualquier forma me interesa también la opción de utilizar las herramientas de las que echaste mano...Peerooo... Ahorita acabo de desarrollar una aplicación que construye un archivo XML con los atributos requeridos por el SAT y lo sella con el proceso de encriptación descrito en la miscelanea fiscal (Anexo 20). Lo realicé en C# y para la creación del PDF utilicé iTextSharp (una variante de iText para .NET), y quisiera utilizar este desarrollo para realizar el proceso de sellado fuera del AS400 en una plataforma Windows... La pregunta es: ¿Qué me recomendarías? ¿hacerlo fuera , o dentro del AS400?... y si así es ¿Cómo se realizaría el proceso de encripción?¿En Java o RPG?

    ResponderEliminar
  8. Soy medio práctico, así es que si ya lo tienes implementado, así lo dejaría por aquello de tiempos de entrega y presupuestos. Sin embargo, he trabajado con la plataforma MS windows y aunque es "fácil" de programar, a largo plazo es más problemático de mantener que cualquier belleza hecha de forma nativa en el IBM i.

    Dentro del IBM i, yo lo haría con RPG por aquello del performance.

    JAVA lo recomiendo sólo por alguna de 2 razones:
    1) Si no hay forma de hacerlo con RPG.
    2) Si ya existe un programa que puedes reusar.
    Si se cumple alguna de las anteriores, entonces sólo para procesos que corren en QBATCH como programa sin fin (de esos que se ciclan infinitamente esperando por una nueva entrada y/o despertándose cada X minutos), ya que la máquina virtual de Java toma unos segundos para inicializar antes de ejecutar y si corre de forma interactiva y por varias sesiones a la vez, quita performance a la máquina. La optimización de JAVA llegó en el V5R4, pero aún así, me asusta el proceso de inicialización, ya que JAVA no corre de forma nativa en el IBM i.

    Para un proceso sin fin, normalmente utilizo Colas de datos (DTAQ) para procesar nuevas entradas y "despertar" el proceso cada X minutos por aquello de pendientes por ser procesados por cualquier razón.

    Ahh, una cosa más, si ya tienes un programa JAVA que haga la encriptación (buscando un poco por ahí seguramente ya existe alguno) y lo quieres llamar desde RPG, asegúrate de que le pones el candado de los threads en la hoja de H thread(*serialize), por aquello de que corren múltiples instancias del programa en diferentes sesiones y te podrían compartir los mismos apuntadores en memoria.

    iTextSharp es muy chido, también lo hemos usado, en nuestra experiencia, vá un poco atrás de la última versión disponible de iText, pero lo notarás solo con cosas como FDF (formularios en el PDF).

    Seguimos a tus órdenes.

    ResponderEliminar
  9. Qué tal Jorge, oye fíjate que sigo trabajando con lo del proyecto de factura electrónica fuera del AS-400, tengo ya la aplicación que firma la cadena, y te crea el XML correspondiente, todo esto en una aplicación en C# pero ahora necesito que el AS-400, cree un spool con los datos de la factura correspondientes, y lo convierta a .TXT para que mi programa lo pueda procesar y firmar. ¿Crees que sea posible esto?. De ser así, ¿Cómo?. He escuchado hablar de el comando CVTSPLSTMF el cual te convierte un archivo de Spool a Texto, pero no entiendo muy bien esa parte.

    ResponderEliminar
  10. Hola BJK, ¡que milagrazo!

    Claro que es posible convertir tu spool a archivo de texto, te pongo más adelante las instrucciones si lo quieres hacer manualmente, un par de aclaraciones:
    1) CVTSPLSTMF no es un comando nativo de AS400, pero puedes encontrarlo como herramienta de código libre y bajarlo en la página http://systeminetwork.com/article/cvtsplstmf-makes-spools-cool , lamentablemente yo ya tenía esas herramientas desarrolladas por eso nunca lo usé. Si necesitas ayuda para instalarlo, con gusto.
    2) ¿Cómo vas a crear tu spool? ¿es un programa RPG? Pregunto, porque puedes escribir al IFS (Sistema de archivos) para crear tu archivo de texto directamente sin necesidad de pasar por un spool. Scott Klement tiene una guía excelente para escribir al IFS desde RPG, y la encuentras aqui: http://www.scottklement.com/rpg/ifs_ebook/

    =====================================
    Te pongo aquí las instrucciones de cómo hacer la copia si lo hicieras manualmente para que te familiarizes, y al final, te pongo un pequeño programa CL que hice para tí:

    --------------------------------------
    1) WRKSPLF para ver tu spool, y a la izquierda de tu spool, le das la opción 8=attributos, ejemplo de lo que deberías ver:
    Trabajo . . . . . . : SJMERINOH1 Archivo . . . . . . : QSYSPRT
    Usuario . . . . . : JMERINOH Número . . . . . . : 000002
    Número . . . . . . : 801858 Fecha creación . . . : 11/19/10
    Nombre sist trabajo : PUB1 Hora creación . . . : 04:43:46

    2) Crea tu archivo de datos
    CRTPF FILE(QTEMP/BJK) RCDLEN(255)
    3) Copia el spool a un archivo de datos
    CPYSPLF FILE(QSYSPRT) TOFILE(QTEMP/BJK) JOB(801858/JMERINOH/SJMERINOH1) SPLNBR(000002)
    4) Verifica si el Spool fué copiado copiado al archivo de datos:
    WRKF FILE(QTEMP/BJK)
    5) Copiar de tu archivo de datos a archivo de texto (en el IFS):
    CPYTOSTMF FROMMBR('/qsys.lib/QTEMP.lib/bjk.file/bjk.mbr') TOSTMF('/home/TuUsuario/bjk.txt') STMFOPT(*REPLACE)
    6) Ver tu archivo de texto:
    dspf '/home/TuUsuario/bjk.txt'
    Tambien puedes usar WRKLNK '/home/Tusuario/*' para ver los archivos.
    Si lo prefieres, puedes usar Filezilla o cualquier otro programa FTP para accesar tus archivos desde windows.


    ----
    Programa CL:

    Pgm
    /* Borra archivo temporal */
    DLTF FILE(QTEMP/BJK)
    MONMSG CPF2105

    /* Crea archivo temporal */
    CRTPF FILE(QTEMP/BJK) RCDLEN(255)

    /* Copia Ultimo Archivo Spool de esta sesion */
    /* a el archivo de datos temporal */
    CPYSPLF FILE(QSYSPRT) TOFILE(QTEMP/BJK) SPLNBR(*LAST)

    /* Crea Folder en IFS que recibira archivo Texto */
    CRTDIR DIR('/home/JMERINOH')
    monmsg CPFA0A0

    /* Copia Archivo de Datos a archivo texto en IFS */
    CPYTOSTMF +
    FROMMBR('/qsys.lib/QTEMP.lib/bjk.file/bjk.mbr') +
    TOSTMF('/home/JMERINOH/bjk.txt')STMFOPT(*REPLACE)
    CPYSPLF FILE(QSYSPRT) TOFILE(QTEMP/BJK) SPLNBR(*LAST)

    /* Crea Folder en IFS que recibira archivo Texto */
    CRTDIR DIR('/home/JMERINOH')
    monmsg CPFA0A0

    /* Copia Archivo de Datos a archivo texto en IFS */
    CPYTOSTMF +
    FROMMBR('/qsys.lib/QTEMP.lib/bjk.file/bjk.mbr') +
    TOSTMF('/home/JMERINOH/bjk.txt')STMFOPT(*REPLACE)

    EndPgm
    --------
    Si necesitas ayuda más concreta para instalar la herramienta de código libre, o para echar a andar el CL que te puse aquí, o cualquier cosa, estoy a tus órdenes.

    Un saludo afectuoso.

    ResponderEliminar
  11. Wooo, cada día me sorprendes más, agradezco tu información, la verdad es que es muy concreta, por ahora experimentaré un poco con lo que me diste y pues espero que se me clareen las dudas :D la vdd te agradezco... ;) Saludos, quisiera saber si puedo tener tu correo personal para estar en contacto... Saludos!! y Gracias de verdad!

    ResponderEliminar
  12. ohh, tate, ¡que me pones rojito!

    Déjame un comentario aquí con tu correo, no lo publico y de ahí ya te mando un correo, ¿sale?

    Saludos.

    ResponderEliminar
  13. Hola necesito saber , si tu lo sabes, si puedo tomar un archivo PDF como input para un programa RPG para luego convertirlo a otro tipo de salida.... gracias

    ResponderEliminar
  14. Con ILE RPG puramente se te dificultaría un poco, pero podrías usar iText que es excelente para eso para parsear el PDF... y luego ya con RPG haces la salida.

    iText corre en Java, tendrías que mapear sus objetos de Java dentro de RPG...

    ResponderEliminar
  15. Hola Jorge, ojala y me pudieras ayudar, tengo que enviar varios reportes del AS/400 en un solo PDF, ya hice el CPYSPLF y luego el CPYTOSTMF pare que si funciona pero al querer abrir el archivo PDF marca un error, que el archivo esta corrupto
    Mil Gracias

    ResponderEliminar
  16. Hola,
    CPYSPLF lo puedes usar para copiar el spool a un PDF o a un archivo de base de datos.
    CPYTOSTMF para copiar un archivo de base de datos al IFS.

    ¿Me puedes decir los parámetros que estás usando?

    Por otro lado, si estás usando CPYSPLF para crear el PDF, normalmente no puedes unir más de un PDF con un simple copy o un merge, ya que cada archivo de PDF tiene sus propios encabezados, detalles, piés de página, registros control de bytes para saber la página, donde está cada elemento, etc; normalmente unes más de un PDF utilizando un programa para ello, como iText.

    Contáctamente por twitter o google plus, y te ayudo más directamente.
    https://plus.google.com/113303776193516091962
    https://twitter.com/jmerinoh

    ResponderEliminar
  17. Hola he leído un poco de su blog y me parece de los mas interesantes quizá muy pronto me convierta en un asiduo preguntón jjajajaa. Un abrazo y exitos

    ResponderEliminar
  18. Seguro, la intención es aportar a la comunidad!

    ResponderEliminar
    Respuestas
    1. Hola Jorge,

      Me llamo jim y estoy ofreciendo unas soluciones de modernización de RPG o Cobol.

      1. Conversion de RPG a Windows/Linux/AIX/Unix
      2. Conversion de RPG a ASP dentro de AS/400
      3. Conversion de RPG a Rational Hats 8.0
      4. Conversion de RPG a Web 2.0 con Applet

      Me acuerdo yo use lo de JPL en Jafra para convertir DB2 a XLS, pero tuve que hacer un cambio para expandir los encabezados.

      Tambien hay una API en la IBM i que te convierte los espools a pdf.

      www.z56tech.com.mx

      Eliminar
    2. La API en cuestión es más sencillo que eso, es hacer un override antes de mandar a traer el programa que genera el reporte y dejará el spool en el IFS:
      OVRPRTF FILE(ArchivoImpr) DEVTYPE(*AFPDS) TOSTMF('/home/tufolder/tuarchivoImpr.pdf') WSCST(*PDF)

      Funciona tanto con todo tipo de spools y hasta puedes generar PDFs con colores, tipos de letras imágenes, etc.

      Solo disponible para la V6R1 en adelante.

      Eliminar
  19. Hola Jorge, encantado de haber pasado por tu blog.
    Tengo un requerimiento que no tengo claro como abordarlo, lo mismo con tu experiencia puedes darme una orientación.

    Verás, almacenamos ficheros pdfs procedentes del exterior en el IFS, lo que pretendo es ver la manera de poder imprimir el pdf desde el IFS en una impresora IP conectada al AS/400 (perdón system-i)

    ¿Se te ocurre algo? gracias anticipado.

    Saludos, Rodrigo

    ResponderEliminar
  20. Hola Rodrigo, gracias por pasarte por acá.

    Si, se me ocurren un par de cosas, que versión de sistema operativo tienes?

    ResponderEliminar
  21. Hola, Jorge la verdad muy interesante tu blog. Te cuento, estoy en un proyecto que pretende imprimir desde el AS400 en una impresora conectada al mismo, con la complejidad que las impresiones contienen imágenes y fuentes de distinto tipo. Contamos con la versión V5R4. Se podrá hacer esto? gracias desde ya! Saludos

    ResponderEliminar
    Respuestas
    1. Gracias por los cebollazos. Ando metido en otras actividades y por eso dejé de escribir. Un día lo retomaré.

      Tienes 2 opciones para la impresión:
      1) Si tienes presupuesto, pagar licencias de terceros, ya sea IBM u otros.
      2) Si lo quieres hacer por ti mismo, te recomiendo el link
      http://blog.jmerinoh.com/2010/09/documentos-electronicos-as400-ibmi.html

      Contáctame por google plus y te guío para tu implementación, o te mando código para hacerlo.

      Eliminar